Hi there,
I am a very inexperienced programmer that is having a few errors come up from the attached code. I was hoping for some insight as to how to fix these.
I am using these weather meters:
A one wire temperature sensor to measure temperature and an accelerometer to measure wave weight.
I still have to include the MPU 6050 Accelerometer code, because of the issues I am having with the weather meters. Once those are fixed I will add the rest.
The temperature sensor is working well, with the Particle.Publish function and doing what I require it to do.
I am also looking for help to understand how to create a Particle.Publish line for the Wind Speed and Wind Direction, as I had a teacher help me with the first one, I am unsure how to create ones for these other variables.
The errors I am receiving are below the code.
Any help is greatly appreciated!!
CODE:
**// This #include statement was automatically added by the Particle IDE.**
**#include "OneWire/OneWire.h"**
**#include "SparkFun_Photon_Weather_Shield_Library/SparkFun_Photon_Weather_Shield_Library.h"**
**#include "ThingSpeak/ThingSpeak.h"**
**#include "SparkFun_Photon_Weather_Shield_Library.h"**
int WDIR = A0;
int WSPEED = D3;
int rainHour;
//Global Variables
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
long lastSecond; //The millis counter to see when a second rolls by
byte seconds; //When it hits 60, increase the current minute
byte seconds_2m; //Keeps track of the "wind speed/dir avg" over last 2 minutes array of data
byte minutes; //Keeps track of where we are in various arrays of data
byte minutes_10m; //Keeps track of where we are in wind gust/dir over last 10 minutes array of data
byte windspdavg[120]; //120 bytes to keep track of 2 minute average
int winddiravg[120]; //120 ints to keep track of 2 minute average
float windgust_10m[10]; //10 floats to keep track of 10 minute max
int windgustdirection_10m[10]; //10 ints to keep track of 10 minute max
//These are all the weather values that wunderground expects:
int winddir = 0; // [0-360 instantaneous wind direction]
float windspeedmph = 0; // [mph instantaneous wind speed]
float windgustmph = 0; // [mph current wind gust, using software specific time period]
int windgustdir = 0; // [0-360 using software specific time period]
float windspdmph_avg2m = 0; // [mph 2 minute average wind speed mph]
int winddir_avg2m = 0; // [0-360 2 minute average wind direction]
float windgustmph_10m = 0; // [mph past 10 minutes wind gust mph ]
int windgustdir_10m = 0; // [0-360 past 10 minutes wind gust direction]
long lastWindCheck = 0;
int avg[100];
int count = 0;
// volatiles are subject to modification by IRQs
volatile long lastWindIRQ = 0;
volatile byte windClicks = 0;
int now=0; //used for timer
int lasttime=0;
// Comment this out for normal operation
//SYSTEM_MODE(SEMI_AUTOMATIC); // skip connecting to the cloud for (Electron) testing
OneWire ds = OneWire(D4); // 1-wire signal on pin D4
unsigned long lastUpdate = 0;
void setup() {
Serial.begin(9600);
// Set up 'power' pins, comment out if not used!
pinMode(D3, OUTPUT);
pinMode(D5, OUTPUT);
digitalWrite(D3, LOW);
digitalWrite(D5, HIGH);
pinMode(WSPEED, INPUT_PULLUP); // input from wind meters windspeed sensor
// attach external interrupt pins to IRQ functions
attachInterrupt(WSPEED, wspeedIRQ, FALLING);
// turn on interrupts
interrupts();
}
// up to here, it is the same as the address acanner
// we need a few more variables for this example
void loop(void) {
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius, fahrenheit;
if ( !ds.search(addr)) {
Serial.println("No more addresses.");
Serial.println();
ds.reset_search();
delay(250);
return;
}
// The order is changed a bit in this example
// first the returned address is printed
Serial.print("ROM =");
for( i = 0; i < 8; i++) {
Serial.write(' ');
Serial.print(addr[i], HEX);
}
// second the CRC is checked, on fail,
// print error and just return to try again
if (OneWire::crc8(addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
return;
}
Serial.println();
ds.reset(); // first clear the 1-wire bus
ds.select(addr); // now select the device we just found
// ds.write(0x44, 1); // tell it to start a conversion, with parasite power on at the end
ds.write(0x44, 0); // or start conversion in powered mode (bus finishes low)
delay(1000); // maybe 750ms is enough, maybe not, wait 1 sec for conversion
present = ds.reset();
ds.select(addr);
ds.write(0xB8,0); // Recall Memory 0
ds.write(0x00,0); // Recall Memory 0
// now read the scratch pad
present = ds.reset();
ds.select(addr);
ds.write(0xBE,0); // Read Scratchpad
if (type_s == 2) {
ds.write(0x00,0); // The DS2438 needs a page# to read
}
// transfer and print the values
Serial.print(" Data = ");
Serial.print(present, HEX);
Serial.print(" ");
for ( i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
Serial.print(data[i], HEX);
Serial.print(" ");
}
Serial.print(" CRC=");
Serial.print(OneWire::crc8(data, 8), HEX);
Serial.println();
// Convert the data to actual temperature
// because the result is a 16 bit signed integer, it should
// be stored to an "int16_t" type, which is always 16 bits
// even when compiled on a 32 bit processor.
int16_t raw = (data[1] << 8) | data[0];
if (type_s == 2) raw = (data[2] << 8) | data[1];
byte cfg = (data[4] & 0x60);
switch (type_s) {
case 1:
raw = raw << 3; // 9 bit resolution default
if (data[7] == 0x10) {
// "count remain" gives full 12 bit resolution
raw = (raw & 0xFFF0) + 12 - data[6];
}
celsius = (float)raw * 0.0625;
break;
case 0:
// at lower res, the low bits are undefined, so let's zero them
if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms
if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
// default is 12 bit resolution, 750 ms conversion time
celsius = (float)raw * 0.0625;
break;
case 2:
data[1] = (data[1] >> 3) & 0x1f;
if (data[2] > 127) {
celsius = (float)data[2] - ((float)data[1] * .03125);
}else{
celsius = (float)data[2] + ((float)data[1] * .03125);
}
}
// Wind Speed and Direction Below
//Keep track of which minute it is
if(millis() - lastSecond >= 1000)
{
lastSecond += 1000;
//Take a speed and direction reading every second for 2 minute average
if(++seconds_2m > 119) seconds_2m = 0;
//Calc the wind speed and direction every second for 120 second to get 2 minute average
float currentSpeed = get_wind_speed();
//float currentSpeed = random(5); //For testing
int currentDirection = get_wind_direction();
windspdavg[seconds_2m] = (int)currentSpeed;
avg[seconds_2m] = currentDirection;
//if(seconds_2m % 10 == 0) displayArrays(); //For testing
//Check to see if this is a gust for the minute
if(currentSpeed > windgust_10m[minutes_10m])
{
windgust_10m[minutes_10m] = currentSpeed;
windgustdirection_10m[minutes_10m] = currentDirection;
}
//Check to see if this is a gust for the day
if(currentSpeed > windgustmph)
{
windgustmph = currentSpeed;
windgustdir = currentDirection;
}
if(++seconds > 59)
{
seconds = 0;
if(++minutes > 59) minutes = 0;
if(++minutes_10m > 9) minutes_10m = 0;
// rainHour[minutes] = 0; //Zero out this minute's rainfall amount
windgust_10m[minutes_10m] = 0; //Zero out this minute's gust
//Calc winddir
winddir = get_wind_direction();
//Calc windspeed
windspeedmph = get_wind_speed();
//Calc windgustmph
//Calc windgustdir
//Report the largest windgust today
windgustmph = 0;
windgustdir = 0;
//Calc windspdmph_avg2m
float temp = 0;
for(int i = 0 ; i < 120 ; i++)
temp += windspdavg[i];
temp /= 120.0;
windspdmph_avg2m = temp;
//Calc winddir_avg2m
temp = 0; //Can't use winddir_avg2m because it's an int
for(int i = 0 ; i < 120 ; i++)
temp += winddiravg[i];
temp /= 120;
winddir_avg2m = temp;
//Calc windgustmph_10m
//Calc windgustdir_10m
//Find the largest windgust in the last 10 minutes
windgustmph_10m = 0;
windgustdir_10m = 0;
//Step through the 10 minutes
for(int i = 0; i < 10 ; i++)
{
if(windgust_10m[i] > windgustmph_10m)
{
windgustmph_10m = windgust_10m[i];
windgustdir_10m = windgustdirection_10m[i];
}
}
}
}
}//end of loop
void wspeedIRQ()
// Activated by the magnet in the anemometer (2 ticks per rotation), attached to input D3
{
if (millis() - lastWindIRQ > 10) // Ignore switch-bounce glitches less than 10ms (142MPH max reading) after the reed switch closes
{
lastWindIRQ = millis(); //Grab the current time
windClicks++; //There is 1.492MPH for each click per second.
}
}
//---------------------------------------------------------------
void printInfo()
{
//This function prints the weather data out to the default Serial Port
Serial.print("Wind_Dir:");
switch (winddir)
{
case 0:
Serial.print("North");
break;
case 1:
Serial.print("NE");
break;
case 2:
Serial.print("East");
break;
case 3:
Serial.print("SE");
break;
case 4:
Serial.print("South");
break;
case 5:
Serial.print("SW");
break;
case 6:
Serial.print("West");
break;
case 7:
Serial.print("NW");
break;
default:
Serial.print("No Wind");
// if nothing else matches, do the
// default (which is optional)
}
Serial.print(" Wind_Speed:");
Serial.print(windspeedmph, 1);
Serial.print("mph, ");
}
//---------------------------------------------------------------
//Read the wind direction sensor, return heading in degrees
int get_wind_direction()
{
unsigned int adc;
adc = analogRead(WDIR); // get the current reading from the sensor
// The following table is ADC readings for the wind direction sensor output, sorted from low to high.
// Each threshold is the midpoint between adjacent headings. The output is degrees for that ADC reading.
// Note that these are not in compass degree order! See Weather Meters datasheet for more information.
//Wind Vains may vary in the values they return. To get exact wind direction,
//it is recomended that you AnalogRead the Wind Vain to make sure the values
//your wind vain output fall within the values listed below.
if(adc > 2270 && adc < 2290) return (0);//North
if(adc > 3220 && adc < 3299) return (1);//NE
if(adc > 3890 && adc < 3999) return (2);//East
if(adc > 3780 && adc < 3850) return (3);//SE
if(adc > 3570 && adc < 3650) return (4);//South
if(adc > 2790 && adc < 2850) return (5);//SW
if(adc > 1580 && adc < 1610) return (6);//West
if(adc > 1930 && adc < 1950) return (7);//NW
return (-1); // error, disconnected?
}
//---------------------------------------------------------------
//Returns the instataneous wind speed
float get_wind_speed()
{
float deltaTime = millis() - lastWindCheck; //750ms
deltaTime /= 1000.0; //Covert to seconds
float windSpeed = (float)windClicks / deltaTime; //3 / 0.750s = 4
windClicks = 0; //Reset and start watching for new wind
lastWindCheck = millis();
windSpeed *= 1.492; //4 * 1.492 = 5.968MPH
/* Serial.println();
Serial.print("Windspeed:");
Serial.println(windSpeed);*/
return(windSpeed);
}
now =millis();
if(now-lasttime>60000){
lasttime=now;
fahrenheit = celsius * 1.8 + 32.0;
Serial.print(" Temperature = ");
Serial.print(celsius);
Particle.publish("Water_Temperature", String::format("%.1f:%.1f",celsius,fahrenheit));
Serial.print(" Celsius, ");
Serial.print(fahrenheit);
Serial.println(" Fahrenheit");
}
ERRORS: