Hi
One question: I’ve noticed that if my Photon loses connection to the internet void loop() doesn’t work anymore. Is there a setting which I can choose that it the loop is still working?
Hi
One question: I’ve noticed that if my Photon loses connection to the internet void loop() doesn’t work anymore. Is there a setting which I can choose that it the loop is still working?
If you search for “no internet”, you’ll find countless topics discussing this already.
Have a look at system modes, and system threading. Both are documented, and shouldn’t be too hard to implement.
Hi
According to the docs SYSTEM_THREAD(ENABLED); is used for “seperate” the running of your code and system stuff. I’ve enabled it but my code still stops if it loses the connection to the cloud or wifi. AFAIK SYSTEM_MODE(SEMIAUTOMATIC); (which I use) is used if you want to start the connection not automatic but it will reconnect automatically to the cloud/wifi if it loses connection. Is that true?
But however, I still have the problem that my code isn’t running when the Photon loses connection.
Seeing your code may help.
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
// OLED display TWI address
#define OLED_ADDR 0x3C
Adafruit_SSD1306 display(-1);
#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
float tempf;
float tempc;
float humidity;
float inches;
int altitude = 73;
double pot3;
float pot2;
float pot1;
float pressurehpa;
char id[] = "xxxxxxxx";
char pwd[] = "xxxxxxx";
char data[180];
char data2[360];
char data3[180];
unsigned long previousMillis = 0; // will store last time LED was updated
// constants won't change:
const long interval = 600000; // interval at which to blink (milliseconds)
int counters = 0;
float sumwspavg = 0;
float sumwdiravg = 0;
float gustms = 0;
#include "Adafruit_Sensor.h"
#include "Adafruit_BME280.h"
#define BME_SCK D0
#define BME_MISO D3
#define BME_MOSI D2
#define BME_CS D1
char* SSID = "xxxxxxx";
char* PASSWORD = "";
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BME280 bme; // I2C
//Adafruit_BME280 bme(BME_CS); // hardware SPI
//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK);
SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(SEMI_AUTOMATIC);
STARTUP(WiFi.selectAntenna(ANT_EXTERNAL));
int VaneValue;// raw analog value from wind vane
int Direction;// translated 0 - 360 direction
int CalDirection;// converted value with offset applied
int LastValue;
#define Offset 0;
#include <math.h>
#define WindSensorPin (D6) // The pin location of the anemometer sensor
volatile unsigned long Rotations; // cup rotation counter used in interrupt routine
volatile unsigned long ContactBounceTime; // Timer to avoid contact bounce in interrupt routine
float WindSpeed; // speed miles per hour
float WindSpeedkt;
float WindSpeedms;
int displays = 0;
void setup() {
// initialize and clear display
LastValue = 1;
Serial.begin(9600);
Serial.println(F("BME280 test"));
pinMode(WindSensorPin, INPUT);
WiFi.on();
WiFi.disconnect();
WiFi.setCredentials(SSID, PASSWORD);
WiFi.connect();
waitUntil(WiFi.ready);
Particle.connect();
display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR);
display.clearDisplay();
display.display();
if (!bme.begin(0x76)) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
display.setTextSize(5);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.print("N/A");
display.display();
}
}
void loop() {
// put your main code here, to run repeatedly:
// display a line of text
Rotations = 0; // Set Rotations count to 0 ready for calculations
attachInterrupt(WindSensorPin, isr_rotation, FALLING);
delay(3000);
detachInterrupt(WindSensorPin);
// convert to mp/h using the formula V=P(2.25/T)
// V = P(2.25/3) = P * 0.75
WindSpeed = Rotations * 0.75;
WindSpeedkt = WindSpeed / 1.151;
WindSpeedms = WindSpeed / 2.237;
VaneValue = analogRead(A4);
Direction = map(VaneValue, 0, 4095, 0, 360);
CalDirection = Direction + Offset;
if(CalDirection > 360)
CalDirection = CalDirection - 360;
if(CalDirection < 0)
CalDirection = CalDirection + 360;
counters = counters + 1;
sumwspavg = sumwspavg + WindSpeedms;
sumwdiravg = sumwdiravg + CalDirection;
if (WindSpeedms >= gustms) {
gustms = WindSpeedms;
}
tempc = bme.readTemperature();
tempf = tempc * 1.8 + 32;
humidity = bme.readHumidity();
pressurehpa = (bme.readPressure() / 100.0F);
inches = 0.02952998751 * pressurehpa;
float a = 17.271;
float b = 237.7;
float taupunktTemp = (a * bme.readTemperature()) / (b + bme.readTemperature()) + log(humidity/100);
float pPre= (b * taupunktTemp) / (a - taupunktTemp);
float pf = pPre * 1.8 + 32;
pot1 = 1 - 0.0065 * altitude / (bme.readTemperature() + 0.0065 * altitude + 273.15);
pot2 = (0.03416 / 0.0065);
pot3 = pow(pot1,pot2);
float relhpa = pressurehpa / pot3;
float relinches = 0.02952998751 * relhpa;
displays = displays + 1;
if (displays > 3) {
displays = 0;
}
if ((displays == 0) or (displays == 1)) {
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.print(tempc,1);
display.print(" Grad");
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,20);
display.print(WindSpeedkt,1);
display.print(" kt");
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,40);
display.print(CalDirection);
display.print(" deg");
// update display with all of the above graphics
display.display();
}
if ((displays == 2) or (displays == 3)) {
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.print(tempc,1);
display.print(" Grad");
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,20);
display.print(relhpa,2);
display.print(" hP");
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,40);
display.print(humidity,1);
display.print(" %");
// update display with all of the above graphics
display.display();
}
snprintf(data, sizeof(data)
,"{\"id\":\"%s\""
",\"pw\":\"%s\""
",\"dt\":\"%s\""
",\"tf\":\"%.1f\""
",\"hum\":\"%.1f\""
",\"baro\":\"%.2f\""
",\"tau\":\"%.1f\""
",\"wsm\":\"%.1f\""
",\"wd\":\"%.d\""
"}"
,id
,pwd
,"now"
,tempf
,humidity
,relinches
,pf
,WindSpeed
,CalDirection
);
snprintf(data3, sizeof(data3)
,"{\"tf\":\"%.1f\""
",\"hum\":\"%.1f\""
",\"baro\":\"%.2f\""
",\"wsm\":\"%.1f\""
",\"wd\":\"%.d\""
",\"tau\":\"%.1f\""
"}"
,tempf
,humidity
,relinches
,WindSpeed
,CalDirection
,pPre
);
Particle.publish("spanienwunderground", data, PRIVATE);
Particle.publish("windyspain", data3, PRIVATE);
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
float wspdavg = sumwspavg / counters;
float wdiravg = sumwdiravg / counters;
int barw = relhpa * 10;
int humw = humidity;
int tempw = tempc * 10;
int wspdw = WindSpeedms * 10;
int wdirw = CalDirection;
int wspdavgw = wspdavg * 10;
int wdiravgw = wdiravg;
int wsphdiw = gustms * 10;
int dew = pPre * 10;
snprintf(data2, sizeof(data2)
,"{\"bar\":\"%d\""
",\"hum\":\"%d\""
",\"temp\":\"%d\""
",\"wspd\":\"%d\""
",\"wdir\":\"%d\""
",\"wspdavg\":\"%d\""
",\"wdiravg\":\"%d\""
",\"wspdhi\":\"%d\""
",\"dew\":\"%d\""
"}"
,barw
,humw
,tempw
,wspdw
,wdirw
,wspdavgw
,wdiravgw
,wsphdiw
,dew
);
Particle.publish("weathercloud", data2, PRIVATE);
gustms = 0;
counters = 0;
sumwspavg = 0;
sumwdiravg = 0;
}
}
void isr_rotation () {
if ((millis() - ContactBounceTime) > 15 ) { // debounce the switch contact.
Rotations++;
ContactBounceTime = millis();
}
}
any ideas or guesses?
I’ve seen multiple things I’d do differently but each of them by itself wouldn’t explain your issue.
However, they might interact in some non-obvious way to lead to some undesirable effects.
e.g. I’d not do this
attachInterrupt(WindSensorPin, isr_rotation, FALLING);
delay(3000);
detachInterrupt(WindSensorPin);
I’d rather leave the interrupt attached and avoid the delay()
.
I already have previously suggested some better way to update your display here (I’m somewhat wondering why I wasted my time to offer these suggestions since I didn’t even get a reply on that post).
Additionally these elaborate calculations may also benefit from some rework.
BTW, what kind of WindSensor are you using?
Does it have an external pull-up resistor attached?
If not, you need to set pinMode(WindSensorPin, INPUT_PULLUP);
However, one thing that would cause your code to block while it’s not connected is that you are calling Particle.publish()
irrespective of the connection. This is bad.
But this shouldn’t prevent an automatic reconnect.
Try this (slightly) cleand-up code
https://go.particle.io/shared_apps/5ce1777bec6e390005e3f612
Thank you!