thinger-io / Arduino-Library

IOTMP Arduino Library for connecting devices to thinger.io #IoT
https://thinger.io
MIT License
114 stars 66 forks source link

Thinger locks up ESP8266 #7

Closed dudesky71 closed 7 years ago

dudesky71 commented 7 years ago

I'm using the basic example 8266 sketch on a WeMos D1 Mini Pro. The module will randomly lock up hard. It seems to do it more when I'm logged into my thinger dashboard.

Any ideas of what could be causing this? I've also posted on the 8266.

Thank you

alvarolb commented 7 years ago

Hi @dudesky71 can you share the sketch you are using? (without credentials).

Bests.

dudesky71 commented 7 years ago
#include <DNSServer.h>
#include <WiFiManager.h>
#include <ESP8266WiFi.h>
#include <ThingerESP8266.h>
#include <DHT.h>
#define USERNAME "xxx"
#define DEVICE_ID "esp8266"
#define DEVICE_CREDENTIAL "xxx"
// Initialize DHT sensor.
#define DHTPIN 4     // what digital pin we're connected to. Mapped to pin D2 on WeMOS
#define DHTTYPE DHT11   // DHT 11
#define ANALOG_PIN A0  // ADC pin 0
DHT dht(DHTPIN, DHTTYPE);
// Set up Thinger varibles
ThingerESP8266 thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL);
// Set up constants
float temp = 0;
int hum = 0;
int adc = 0;
unsigned long previousMillis = 0;
const long interval = 5000;
void setup() {
// start the serial connection
  Serial.begin(115200);
  Serial.println("");
//WiFiManager
  //Local intialization. Once its business is done, there is no need to keep it around
  WiFiManager wifiManager;
  //reset saved settings
  //wifiManager.resetSettings();
  //set custom ip for portal
  //wifiManager.setAPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0));
  //fetches ssid and pass from eeprom and tries to connect
  //if it does not connect it starts an access point with the specified name
  //here  "AutoConnectAP"
  //and goes into a blocking loop awaiting configuration
  //wifiManager.autoConnect("Test-DongleAP");
  //or use this for auto generated name ESP + ChipID
  wifiManager.autoConnect();
//if you get here you have connected to the WiFi
  Serial.println("");
  Serial.println("Connected to WiFi Network...");
  Serial.println(WiFi.SSID());
  //Serial.println(WiFi.psk());
  
// Setup Thinger IO feeds
  // more details at http://docs.thinger.io/arduino/
 // thing.add_wifi(SSID, SSID_PASSWORD);
  // digital pin input from Thinger control example (i.e. turning on/off a light, a relay, configuring a parameter, etc)
  thing["led"] << digitalPin(BUILTIN_LED);
  // resource output to Thinger example (i.e. reading a sensor value)
  thing["millis"] >> outputValue(millis());
    thing["temp"] >> outputValue(temp);
    thing["hum"] >> outputValue(hum);
    thing["adc"] >> outputValue(adc);
  dht.begin();
  delay(100);
  connectGoodLED();
}
void loop() {
  
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
      thing.handle();
      readDHT();
      readADC();
      showValues();
      dataSentLED();
  }
}
  //////////////////// FUNCTIONS ////////////////////
  
  void readDHT() {
  // Read the DHT Sensor
  Serial.print("Reading Sensor...");
  Serial.println("");
    temp = dht.readTemperature(true);
     delay (500);
         thing["temp"] >> outputValue(temp);
    hum = dht.readHumidity();
     delay (500);
         thing["hum"] >> outputValue(hum);
  }
  void readADC(){
 // Read ADC input
adc = analogRead(ANALOG_PIN);
    if (adc <= 10)adc = 0;
     delay (500);
         thing["adc"] >> outputValue(adc);
  }
  
  void connectGoodLED() {
 // Blink the blue LED three times for WiFi connection confirmation
    pinMode(2, OUTPUT); // set blue led pin to output
  digitalWrite(2, LOW);   // sets the LED on
    delay(50);
  digitalWrite(2, HIGH);   // sets the LED off
    delay(200);
  digitalWrite(2, LOW);   // sets the LED on
    delay(50);
  digitalWrite(2, HIGH);   // sets the LED off
    delay(200);
  digitalWrite(2, LOW);   // sets the LED on
    delay(50);
  digitalWrite(2, HIGH);   // sets the LED off
  Serial.println("");
   }
   void showValues(){
 // Print values to debug colsole window
  Serial.print("Wetness: ");
    Serial.print(adc);
    Serial.println("");
  
  Serial.print("Temperature: ");
    Serial.print(temp);
    Serial.println("F ");

  Serial.print("Humidity: ");
    Serial.print(hum);
    Serial.println("% ");
   }
  void dataSentLED(){
 // Blink the blue LED once for data sent confirmation
    Serial.println("Data Sent... ");
        Serial.println("");
    digitalWrite(2, LOW);   // sets the LED on
    delay(100);
    digitalWrite(2, HIGH);   // sets the LED off
    }
dudesky71 commented 7 years ago

Keep in mind the same issue occurs even when WiFi Manager is not used.

alvarolb commented 7 years ago

Hi @dudesky71 looking at the code, there are a lot of optimizations to be done here, and also some problems while using the library.

First of all, the thing.handle() must be done inside the loop, without any delay (as much as possible). Also I suggest you to avoid the sensor readings inside the loop, and read the values only once required. This way, you can change easily the sampling frequency. Try this code instead:

#include <WiFiManager.h>
#include <ESP8266WiFi.h>
#include <ThingerESP8266.h>
#include <DHT.h>

#define USERNAME "xxx"
#define DEVICE_ID "esp8266"
#define DEVICE_CREDENTIAL "xxx"

// Initialize DHT sensor.
#define DHTPIN 4     // what digital pin we're connected to. Mapped to pin D2 on WeMOS
#define DHTTYPE DHT11   // DHT 11
#define ANALOG_PIN A0  // ADC pin 0
DHT dht(DHTPIN, DHTTYPE);

// Set up Thinger varibles
ThingerESP8266 thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL);

// Set up constants
float temp = 0;
int hum = 0;
int adc = 0;
unsigned long previousMillis = 0;
const long interval = 5000;

void setup() {

// start the serial connection
  Serial.begin(115200);
  Serial.println("");

//WiFiManager
  //Local intialization. Once its business is done, there is no need to keep it around
  WiFiManager wifiManager;
  //reset saved settings
  //wifiManager.resetSettings();

  //set custom ip for portal
  //wifiManager.setAPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0));

  //fetches ssid and pass from eeprom and tries to connect
  //if it does not connect it starts an access point with the specified name
  //here  "AutoConnectAP"
  //and goes into a blocking loop awaiting configuration
  //wifiManager.autoConnect("Test-DongleAP");
  //or use this for auto generated name ESP + ChipID
  wifiManager.autoConnect();

//if you get here you have connected to the WiFi
  Serial.println("");
  Serial.println("Connected to WiFi Network...");
  Serial.println(WiFi.SSID());
  //Serial.println(WiFi.psk());

// Setup Thinger IO feeds
  // more details at http://docs.thinger.io/arduino/

 // thing.add_wifi(SSID, SSID_PASSWORD);

  // digital pin input from Thinger control example (i.e. turning on/off a light, a relay, configuring a parameter, etc)
  thing["led"] << digitalPin(BUILTIN_LED);

  // resource output to Thinger example (i.e. reading a sensor value)
  thing["millis"] >> outputValue(millis());
  thing["temp"] >> outputValue(dht.readTemperature(true));
  thing["hum"] >> outputValue(dht.readHumidity());
  thing["adc"] >> analogPin(ANALOG_PIN);

  dht.begin();
  delay(100);
  connectGoodLED();
}

void loop() {
  thing.handle();
}

void connectGoodLED() {
 // Blink the blue LED three times for WiFi connection confirmation
    pinMode(2, OUTPUT); // set blue led pin to output
  digitalWrite(2, LOW);   // sets the LED on
    delay(50);
  digitalWrite(2, HIGH);   // sets the LED off
    delay(200);
  digitalWrite(2, LOW);   // sets the LED on
    delay(50);
  digitalWrite(2, HIGH);   // sets the LED off
    delay(200);
  digitalWrite(2, LOW);   // sets the LED on
    delay(50);
  digitalWrite(2, HIGH);   // sets the LED off
  Serial.println("");
 }

I recommend also to take a look to the example ESP8266WebConfig in the thinger.io libraries, as it uses WebConfig for setting both WIFI and username, device, and credentials.

Hope it helps!

dudesky71 commented 7 years ago

I would also like to add that I've been testing for a few weeks and yesterday I stumbled across something. It appears that when connecting to my hotspot on my iPhone that it seems more stable than when connecting on my home network. I use a pfSense router with running 2.3.2-p1 firmware. Could my router/firewall slowly block the ports over time? Should I port forward port 25200 and port 25202 to the IP address of the module?

alvarolb commented 7 years ago

Try the above code, you should see a smooth interaction in the platform and your device. The API explorer will load quite fast, and you could see how changing sampling intervals over sensors will take effect on the charts. At this moment you were tied to the 5s delay that were stopping everything.

dudesky71 commented 7 years ago

@alvarolb I don't have to have the 5 seconds in there. I just added it so I wasnt hitting the Thinger server constantly. Could my code be timing out? Is it ok to delete my delays?

alvarolb commented 7 years ago

Don't worry about the thing.handle() call. This will not send any data to thinger if not required by the server. This handle is mainly for reading server commands. Your code is still bad if you delete the delays, as, this code thing["hum"] >> outputValue(hum); you use for sending data, will not actually send data, instead will redefine the resource, and will cause your device to crash eventually. Just test the code i provided, and you should see a great difference.

alvarolb commented 7 years ago

Notice that you were "sending" all data every 5 seconds, but thinger.io, lets you send any single value at a dynamic interval that can be configured from the console. So the handle is there to recognize when it is required to stream a value or another, change the sampling frequency, and so on.

dudesky71 commented 7 years ago

@alvarolb Great catch! I'm a dork :) thank you for the code example :) I'll try this and see how it goes. I like the web config example but for my project, I don't want to have to enter in the thinger credentials. I like it to be set constant.

alvarolb commented 7 years ago

ok! let me now how it goes ;)

dudesky71 commented 7 years ago

@alvarolb So.... with my original code, was I causing the module to eventually run out of RAM by redefining the resource? Also, Should I not add anything else into the main loop?

alvarolb commented 7 years ago

Yes, you were probably running your resource out of RAM by creating a lambda function once and again. The loop for your actual use case can be keep as is, with the thing.handle call.

dudesky71 commented 7 years ago

@alvarolb When i run your sketch by connecting directly to my iPhone hotspot, it seems to run fine. If I connect to my work WiFi, I stop getting reads from millis counter within a few minutes inside the thinger dashboard. I then get the thumbs down icons in my dashboard and it never recovers unless i reboot the module and then it happens again... I would imagine on my home network I will see the same thing happen. It will run for 8-10 hours then hang. I'll be running the new test at home this weekend.

alvarolb commented 7 years ago

Hi @dudesky71, did you have the latests Arduino libraries?

dudesky71 commented 7 years ago

I would also like to send an email via endpoint in my sketch. I need to look at the ADC value and if above a certain number, send the email. Before I had the if statement in the function that was called in the main loop. How would you suggest adding this to not affect the timing?

alvarolb commented 7 years ago

You can just introduce code in the loop, reading ADCs, or sensor values it not a problem at all. Check the example in the community that alerts when a plant is out of water:

https://community.thinger.io/t/internet-of-things-moisture-sensor-with-esp8266/24

dudesky71 commented 7 years ago

@alvarolb Yes. I have all the latest libraries and IDE.

dudesky71 commented 7 years ago

@alvarolb So far your code is running well :) I've been running tests all weekend. I've added in my ADC sensor read and flashing the LED in the main loop. So far so good. Each test ran for 24 hours with no issues. I'm now letting it run for 5 days to see how it goes. Thank you for the heads up on the Lamda function. I didn't realize I was even causing this issue with my original code.

alvarolb commented 7 years ago

Great! Good to know it is working right now! Thanks for testing @dudesky71 !! Let me know how your long running test work to close the issue! :)

alvarolb commented 7 years ago

Hi @dudesky71 ! Any results on your long running test?

dudesky71 commented 7 years ago

@alvarolb Hello and thanks for checking in. I kept tweaking my code for more data reporting so I've reset it a few times. The longest run I got out of it was 4.5 days because I had a power outage at home :( It's back up and running now so I will let it run and report back as to how long I get out of it :) So far so good :)