Jump to content
43oh

wifi.h include stops sketch from working


Recommended Posts

Hey everyone,

 

I have a simple sketch for an energy monitor using a variation of http://openenergymonitor.org/emon/- on a CC3200 LaunchPad. This sketch works successfully, as does the WiFiWebClient sample project which comes with Energia.

 

However, if I simply add this line of code to my sketch, it uploads successfully but does not run. Serial returns nothing and the board is inactive.

#include <WiFi.h>

It works fine if I simply remove this line. The WiFi sample sketches on their own work fine too.

 

I'm using the latest version of Energia on windows (energia-0101E0014), board is Rev 4.1. Thanks for any help and have a great afternoon!

 

Rich

 

Sketch Code:

#include <WiFi.h>
#include <EmonLib.h>

EnergyMonitor emon1;				// CT1
EnergyMonitor emon2;				// CT2

struct POWERDATA {
	double w;
	double va;
	double v;
	double a;
	double f;
	double kwh;
	double kwhday;
} pwr;

const int ct1Pin = A0;
const int ct2Pin = A1;
const int acBiasPin = A2;

void setup()
{
    
  Serial.begin(115200);
  Serial.println("starting...");   // <-- never displayed if this line exists: #include <WiFi.h>
  
  pinMode(RED_LED, OUTPUT); 
  pinMode(GREEN_LED, OUTPUT);
  pinMode(ct1Pin, INPUT);			// CT1
  pinMode(ct2Pin, INPUT);			// CT2
  pinMode(acBiasPin, INPUT);			// AC Bias
  
  emon1.current(ct1Pin, 60.6);			// Current: input pin, calibration.
  emon1.voltage(acBiasPin, 123.5, 1.7);	        // Voltage: input pin, calibration, phase_shift

  emon2.current(ct2Pin, 60.6);			// Current: input pin, calibration.
  emon2.voltage(acBiasPin, 123.5, 1.7);	        // Voltage: input pin, calibration, phase_shift

}

void loop()
{

  digitalWrite(RED_LED, HIGH);
  emon1.calcVI(20, 2000);			// Calculate all. No.of wavelengths, time-out
  digitalWrite(RED_LED, LOW);
  digitalWrite(GREEN_LED, HIGH);
  emon2.calcVI(20, 2000);			// Calculate all. No.of wavelengths, time-out
  digitalWrite(GREEN_LED, LOW);

  pwr.w = emon1.realPower + emon2.realPower;
  pwr.va = emon1.apparentPower + emon2.apparentPower;
  pwr.v = (emon1.Vrms + emon2.Vrms) / 2.0;
  pwr.a = emon1.Irms + emon2.Irms;
  pwr.f = (emon1.powerFactor + emon2.powerFactor) / 2.0;
  pwr.kwh += (pwr.w / 3600000.0);		// 1000W/kW / 3600s/h
  pwr.kwhday += (pwr.w / 3600000.0);
  
  Serial.print(pwr.w);
  Serial.println(" w");

}


Update:

Just an added note that if I do the opposite and add the EmonLib.h library include to the Wifi sketch, the same problem occurs.

 

Code added to WifiLibClientRepeating.ino:

#include <EmonLib.h>

Maybe this is a library conflict? I'm confused because the compilation and upload are successful - so it must be a runtime issue. But as I mentioned above - both sketches work on their own - just not together.

 

Here is the EmonLib.h library for reference as the issue must be related to this:

/*
Emon.h - Library for openenergymonitor
Created by Trystan Lea, April 27 2010
GNU GPL
modified to use up to 12 bits ADC resolution (ex. Arduino Due)
by boredman@boredomprojects.net 26.12.2013
*/

#ifndef EmonLib_h
#define EmonLib_h

#if defined(ARDUINO) && ARDUINO >= 100

#include "Arduino.h"

#else

#include "WProgram.h"

#endif

// to enable 12-bit ADC resolution on Arduino Due,
// include the following line in main sketch inside setup() function:
// analogReadResolution(ADC_BITS);
// otherwise will default to 10 bits, as in regular Arduino-based boards.
#if defined(__arm__)
#define ADC_BITS 12
#else
#define ADC_BITS 10
#endif

#define ADC_COUNTS (1<<ADC_BITS)


class EnergyMonitor
{
public:

void voltage(int _inPinV, double _VCAL, double _PHASECAL);
void current(int _inPinI, double _ICAL);

void voltageTX(double _VCAL, double _PHASECAL);
void currentTX(int _channel, double _ICAL);

void calcVI(int crossings, int timeout);
double calcIrms(int NUMBER_OF_SAMPLES);
void serialprint();

long readVcc();
//Useful value variables
double realPower,
apparentPower,
powerFactor,
Vrms,
Irms;

private:

//Set Voltage and current input pins
int inPinV;
int inPinI;
//Calibration coeficients
//These need to be set in order to obtain accurate results
double VCAL;
double ICAL;
double PHASECAL;

//--------------------------------------------------------------------------------------
// Variable declaration for emon_calc procedure
//--------------------------------------------------------------------------------------
    int lastSampleV,sampleV; //sample_ holds the raw analog read value, lastSample_ holds the last sample
    int lastSampleI,sampleI;

    double lastFilteredV,filteredV; //Filtered_ is the raw analog value minus the DC offset
    double lastFilteredI, filteredI;

    double phaseShiftedV; //Holds the calibrated phase shifted voltage.

    double sqV,sumV,sqI,sumI,instP,sumP; //sq = squared, sum = Sum, inst = instantaneous

    int startV; //Instantaneous voltage at start of sample window.

    boolean lastVCross, checkVCross; //Used to measure number of times threshold is crossed.
    int crossCount; // ''


};

#endif

And EmonLib.cpp:


/*Emon.cpp - Library for openenergymonitorCreated by Trystan Lea, April 27 2010GNU GPLmodified to use up to 12 bits ADC resolution (ex. Arduino Due)by boredman@boredomprojects.net 26.12.2013*///#include "WProgram.h" un-comment for use on older versions of Arduino IDE#include "EmonLib.h"#if defined(ARDUINO) && ARDUINO >= 100#include "Arduino.h"#else#include "WProgram.h"#endif//--------------------------------------------------------------------------------------// Sets the pins to be used for voltage and current sensors//--------------------------------------------------------------------------------------void EnergyMonitor::voltage(int _inPinV, double _VCAL, double _PHASECAL){inPinV = _inPinV;VCAL = _VCAL;PHASECAL = _PHASECAL;}void EnergyMonitor::current(int _inPinI, double _ICAL){inPinI = _inPinI;ICAL = _ICAL;}//--------------------------------------------------------------------------------------// Sets the pins to be used for voltage and current sensors based on emontx pin map//--------------------------------------------------------------------------------------void EnergyMonitor::voltageTX(double _VCAL, double _PHASECAL){inPinV = 2;VCAL = _VCAL;PHASECAL = _PHASECAL;}void EnergyMonitor::currentTX(int _channel, double _ICAL){if (_channel == 1) inPinI = 3;if (_channel == 2) inPinI = 0;if (_channel == 3) inPinI = 1;ICAL = _ICAL;}//--------------------------------------------------------------------------------------// emon_calc procedure// Calculates realPower,apparentPower,powerFactor,Vrms,Irms,kwh increment// From a sample window of the mains AC voltage and current.// The Sample window length is defined by the number of half wavelengths or crossings we choose to measure.//--------------------------------------------------------------------------------------void EnergyMonitor::calcVI(int crossings, int timeout){#if defined emonTxV3    int SUPPLYVOLTAGE=3300;#else    int SUPPLYVOLTAGE = readVcc();#endifint crossCount = 0; //Used to measure number of times threshold is crossed.int numberOfSamples = 0; //This is now incremented//-------------------------------------------------------------------------------------------------------------------------// 1) Waits for the waveform to be close to 'zero' (500 adc) part in sin curve.//-------------------------------------------------------------------------------------------------------------------------boolean st=false; //an indicator to exit the while loopunsigned long start = millis(); //millis()-start makes sure it doesnt get stuck in the loop if there is an error.while(st==false) //the while loop...{startV = analogRead(inPinV); //using the voltage waveformif ((startV < (ADC_COUNTS/2+50)) && (startV > (ADC_COUNTS/2-50))) st=true; //check its within rangeif ((millis()-start)>timeout) st = true;}//-------------------------------------------------------------------------------------------------------------------------// 2) Main measurment loop//-------------------------------------------------------------------------------------------------------------------------start = millis();while ((crossCount < crossings) && ((millis()-start)<timeout)){numberOfSamples++; //Count number of times looped.lastSampleV=sampleV; //Used for digital high pass filterlastSampleI=sampleI; //Used for digital high pass filterlastFilteredV = filteredV; //Used for offset removallastFilteredI = filteredI; //Used for offset removal//-----------------------------------------------------------------------------// A) Read in raw voltage and current samples//-----------------------------------------------------------------------------sampleV = analogRead(inPinV); //Read in raw voltage signalsampleI = analogRead(inPinI); //Read in raw current signal//-----------------------------------------------------------------------------//  Apply digital high pass filters to remove 2.5V DC offset (centered on 0V).//-----------------------------------------------------------------------------filteredV = 0.996*(lastFilteredV+(sampleV-lastSampleV));filteredI = 0.996*(lastFilteredI+(sampleI-lastSampleI));//-----------------------------------------------------------------------------// C) Root-mean-square method voltage//-----------------------------------------------------------------------------sqV= filteredV * filteredV; //1) square voltage valuessumV += sqV; //2) sum//-----------------------------------------------------------------------------// D) Root-mean-square method current//-----------------------------------------------------------------------------sqI = filteredI * filteredI; //1) square current valuessumI += sqI; //2) sum//-----------------------------------------------------------------------------// E) Phase calibration//-----------------------------------------------------------------------------phaseShiftedV = lastFilteredV + PHASECAL * (filteredV - lastFilteredV);//-----------------------------------------------------------------------------// F) Instantaneous power calc//-----------------------------------------------------------------------------instP = phaseShiftedV * filteredI; //Instantaneous PowersumP +=instP; //Sum//-----------------------------------------------------------------------------// G) Find the number of times the voltage has crossed the initial voltage// - every 2 crosses we will have sampled 1 wavelength// - so this method allows us to sample an integer number of half wavelengths which increases accuracy//-----------------------------------------------------------------------------lastVCross = checkVCross;if (sampleV > startV) checkVCross = true;else checkVCross = false;if (numberOfSamples==1) lastVCross = checkVCross;if (lastVCross != checkVCross) crossCount++;}//-------------------------------------------------------------------------------------------------------------------------// 3) Post loop calculations//-------------------------------------------------------------------------------------------------------------------------//Calculation of the root of the mean of the voltage and current squared (rms)//Calibration coeficients applied.double V_RATIO = VCAL *((SUPPLYVOLTAGE/1000.0) / (ADC_COUNTS));Vrms = V_RATIO * sqrt(sumV / numberOfSamples);double I_RATIO = ICAL *((SUPPLYVOLTAGE/1000.0) / (ADC_COUNTS));Irms = I_RATIO * sqrt(sumI / numberOfSamples);//Calculation power valuesrealPower = V_RATIO * I_RATIO * sumP / numberOfSamples;apparentPower = Vrms * Irms;powerFactor=realPower / apparentPower;//Reset accumulatorssumV = 0;sumI = 0;sumP = 0;//--------------------------------------------------------------------------------------}//--------------------------------------------------------------------------------------double EnergyMonitor::calcIrms(int NUMBER_OF_SAMPLES){#if defined emonTxV3    int SUPPLYVOLTAGE=3300;#else    int SUPPLYVOLTAGE = readVcc();#endiffor (int n = 0; n < NUMBER_OF_SAMPLES; n++){lastSampleI = sampleI;sampleI = analogRead(inPinI);lastFilteredI = filteredI;filteredI = 0.996*(lastFilteredI+sampleI-lastSampleI);// Root-mean-square method current// 1) square current valuessqI = filteredI * filteredI;// 2) sumsumI += sqI;}double I_RATIO = ICAL *((SUPPLYVOLTAGE/1000.0) / (ADC_COUNTS));Irms = I_RATIO * sqrt(sumI / NUMBER_OF_SAMPLES);//Reset accumulatorssumI = 0;//--------------------------------------------------------------------------------------return Irms;}void EnergyMonitor::serialprint(){Serial.print(realPower);Serial.print(' ');Serial.print(apparentPower);Serial.print(' ');Serial.print(Vrms);Serial.print(' ');Serial.print(Irms);Serial.print(' ');Serial.print(powerFactor);Serial.println(' ');delay(100);}//thanks to http://hacking.majenko.co.uk/making-accurate-adc-readings-on-arduino//and J
Link to post
Share on other sites

Through the process of elimination I have isolated the cause of this - but I'm even more baffled as to why it is happening or how to fix it.

 

If I edit EmonLib.cpp to remove the three references to the sqrt() function, everything works as expected - of course with the exception that the values are wrong due to the calculations being changed.

 

If I modify these three lines from EmonLib.cpp:

157 Vrms = V_RATIO * sqrt(sumV / numberOfSamples);
160 Irms = I_RATIO * sqrt(sumI / numberOfSamples);
200 Irms = I_RATIO * sqrt(sumI / NUMBER_OF_SAMPLES);

To removing the sqrt() functions as follows:

157 Vrms = V_RATIO * sumV / numberOfSamples;
160 Irms = I_RATIO * sumI / numberOfSamples;
200 Irms = I_RATIO * sumI / NUMBER_OF_SAMPLES;

Then everything works fine.

 

This is very strange as the calculations with sqrt() work fine when WiFi.h is not included as stated above. I am also able to add a simple test to WiFiWebClientRepeating.ino which also works - such as:

double test = sqrt(4);

 

I'd be grateful if anyone could shed some light on this. I really appreciate any help!

 

Cheers, Rich

Link to post
Share on other sites

Hey @@spirilis - thanks for looking at this.

 

Console shows nothing after the port is opened - and the board is essentially 'frozen'. i.e. If I turn on an LED or do a Serial write at the beginning of setup(), it does not execute.

 

Sorry it's so confusing, initially I didn't know where the problem originated. Here are the steps to reproduce this:

 

1. Open out of the box example WiFiWebClientRepeating sketch

 

2. Add EmonLib.h and EmonLib.cpp to your project or library folder

 

3. Add to top of Wifi sketch: #include <EmonLib.h>

 

4. Add to top of setup() for debugging: Serial.println("We should see this");

 

5. Compile and upload will work successfully but nothing will execute.

 

The interesting thing is the EmonLib class is never instanciated, only defined.

 

Now you can make it work by removing the three instances of the sqrt() function in EmonLib.cpp.

 

Thanks again and have a great day!

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...