Quantcast
Channel: MSP430 Technical Forums
Viewing all articles
Browse latest Browse all 2077

wifi.h include stops sketch from working

$
0
0

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 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
*/

//#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();
#endif

int 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 loop

unsigned 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 waveform
if ((startV < (ADC_COUNTS/2+50)) && (startV > (ADC_COUNTS/2-50))) st=true; //check its within range
if ((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 filter
lastSampleI=sampleI; //Used for digital high pass filter

lastFilteredV = filteredV; //Used for offset removal
lastFilteredI = filteredI; //Used for offset removal

//-----------------------------------------------------------------------------
// A) Read in raw voltage and current samples
//-----------------------------------------------------------------------------
sampleV = analogRead(inPinV); //Read in raw voltage signal
sampleI = analogRead(inPinI); //Read in raw current signal

//-----------------------------------------------------------------------------
// B) 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 values
sumV += sqV; //2) sum

//-----------------------------------------------------------------------------
// D) Root-mean-square method current
//-----------------------------------------------------------------------------
sqI = filteredI * filteredI; //1) square current values
sumI += sqI; //2) sum

//-----------------------------------------------------------------------------
// E) Phase calibration
//-----------------------------------------------------------------------------
phaseShiftedV = lastFilteredV + PHASECAL * (filteredV - lastFilteredV);

//-----------------------------------------------------------------------------
// F) Instantaneous power calc
//-----------------------------------------------------------------------------
instP = phaseShiftedV * filteredI; //Instantaneous Power
sumP +=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 values
realPower = V_RATIO * I_RATIO * sumP / numberOfSamples;
apparentPower = Vrms * Irms;
powerFactor=realPower / apparentPower;

//Reset accumulators
sumV = 0;
sumI = 0;
sumP = 0;
//--------------------------------------------------------------------------------------
}

//--------------------------------------------------------------------------------------
double EnergyMonitor::calcIrms(int NUMBER_OF_SAMPLES)
{

#if defined emonTxV3
    int SUPPLYVOLTAGE=3300;
#else
    int SUPPLYVOLTAGE = readVcc();
#endif


for (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 values
sqI = filteredI * filteredI;
// 2) sum
sumI += sqI;
}

double I_RATIO = ICAL *((SUPPLYVOLTAGE/1000.0) / (ADC_COUNTS));
Irms = I_RATIO * sqrt(sumI / NUMBER_OF_SAMPLES);

//Reset accumulators
sumI = 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érôme who alerted us to http://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/

long EnergyMonitor::readVcc() {
long result;

//not used on emonTx V3 - as Vcc is always 3.3V - eliminates bandgap error and need for calibration http://harizanov.com/2013/09/thoughts-on-avr-adc-accuracy/

#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined (__AVR_ATmega328P__)
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_AT90USB1286__)
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
ADCSRB &= ~_BV(MUX5); // Without this the function always returns -1 on the ATmega2560 http://openenergymonitor.org/emon/node/2253#comment-11432
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
ADMUX = _BV(MUX3) | _BV(MUX2);
    
#endif


#if defined(__AVR__)
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Convert
while (bit_is_set(ADCSRA,ADSC));
result = ADCL;
result |= ADCH<<8;
result = 1126400L / result; //1100mV*1024 ADC steps http://openenergymonitor.org/emon/node/1186
return result; //Arduino Due
#else
return (1400); //Changed from 3300 to 1400 for the TI CC3200 vref (note some users said its 1.46V to get full 4095 range)
#endif
}

Thanks for the help!

 

Cheers, Rich


Viewing all articles
Browse latest Browse all 2077

Trending Articles