Chat freely about anything...

User avatar
By blackjf
#56185 First off, I am very new to this so bear with me. I have a bit of code I scavenged from someone else's project that was working for them according to the site. When I adjust and compile it without issue it blows up when it runs.

Much of the part about connecting to MQTT is the same as another piece of code that works just fine on the device. Any help would be appreciated.


ERROR:


Connecting to MJPEAKS
.......
WiFi connected
IP address:
10.0.0.2
Connecting to MQTT...
Exception (3):
epc1=0x4000bf3c epc2=0x00000000 epc3=0x00000000 excvaddr=0x4023085c depc=0x00000000

ctx: cont
sp: 3ffef500 end: 3ffef730 offset: 01a0

>>>stack>>>
3ffef6a0: 40105736 0000000b 3ffe8467 3ffee6fc
3ffef6b0: 3fffdad0 3ffee4f4 3ffee4f4 402031ae
3ffef6c0: 3ffe846c 3ffee5e0 3ffee6d0 3ffee6fc
3ffef6d0: 3ffe85f4 3ffee5e0 3ffee6d0 3ffee6fc
3ffef6e0: 00000003 3ffee4f4 3ffee6d0 40201fa2
3ffef6f0: 3fffdad0 00000000 3ffee6f4 40201fe8
3ffef700: 3ffe8738 0200000a feefeffe 3ffee6fc
3ffef710: 3fffdad0 00000000 3ffee6f4 40203ca4
3ffef720: feefeffe feefeffe 3ffee710 40100718
<<<stack<<<

ets Jan 8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1384, room 16
tail 8
chksum 0x2d
csum 0x2d
v00000000
~ld

DHT22 IoT


CODE:

/*
* Andrew Schneider
* 1.7.16
* DHT22
*/

#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"

// WiFi Access Point
#define WLAN_SSID "MJPEAKS"
#define WLAN_PASS "xxxxxxxxxxxxxx"

// Adafruit.io setup
#define AIO_SERVER "io.adafruit.com"
#define AIO_SERVERPORT 1883
#define AIO_USERNAME "xxxxxxxxxxxxxx"
#define AIO_KEY "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

/************ Global State (you don't need to change this!) ******************/
// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient client;
// Store the MQTT server, username, and password in flash memory.
// This is required for using the Adafruit MQTT library.
const char MQTT_SERVER[] PROGMEM = AIO_SERVER;
const char MQTT_USERNAME[] PROGMEM = AIO_USERNAME;
const char MQTT_PASSWORD[] PROGMEM = AIO_KEY;
// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, MQTT_SERVER, AIO_SERVERPORT, MQTT_USERNAME, MQTT_PASSWORD);
/******************************************************************************/

// Feeds
// Humidity Feed
const char DHT_H[] PROGMEM = AIO_USERNAME "/feeds/dht_h";
Adafruit_MQTT_Publish dht_h = Adafruit_MQTT_Publish(&mqtt, DHT_H);
// Temperature Feed
const char DHT_T[] PROGMEM = AIO_USERNAME "/feeds/dht_t";
Adafruit_MQTT_Publish dht_t = Adafruit_MQTT_Publish(&mqtt, DHT_T);
// Setup a feed called 'onoff' for subscribing to changes.
const char ONOFF_FEED[] PROGMEM = AIO_USERNAME "/feeds/onoff";
Adafruit_MQTT_Subscribe onoffbutton = Adafruit_MQTT_Subscribe(&mqtt, ONOFF_FEED);

// Sensors
// dht22
#include "DHT.h"
#define DHTPIN 4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
//

void setup() {
Serial.begin(115200);
delay(10);
Serial.println(F("DHT22 IoT"));

// Connect to WiFi access point.
Serial.println(); Serial.println();
Serial.print("Connecting to ");
Serial.println(WLAN_SSID);
WiFi.begin(WLAN_SSID, WLAN_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();

Serial.println("WiFi connected");
Serial.println("IP address: "); Serial.println(WiFi.localIP());
// Setup MQTT subscription for onoff feed.
mqtt.subscribe(&onoffbutton);

// Inialize DHT sensor
dht.begin();
}
uint32_t x = 0;

void loop() {
MQTT_connect();
// this is our 'wait for incoming subscription packets' busy subloop
Adafruit_MQTT_Subscribe *subscription;
while ((subscription = mqtt.readSubscription(5000))) {
if (subscription == &onoffbutton) {
Serial.print(F("Got: "));
Serial.println((char *)onoffbutton.lastread);
}
}
// DHT22 needs 2 seconds between measurements
delay(2000);

// Read humidity
float h = dht.readHumidity();
// Read temperature as Celsius (the default)
float t = dht.readTemperature();
// Read temperature as Fahrenheit (isFahrenheit = true)
float f = dht.readTemperature(true);

// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t) || isnan(f)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
// Now we can publish stuff
dht_h.publish(h);
dht_t.publish(f);

// ping the server to keep the mqtt connection alive
// if (! mqtt.ping()) {
// mqtt.disconnect();
// }
// delay(100);
}

// Function to connect and reconnect as necessary to the MQTT server.
// Should be called in the loop function and it will take care if connecting.
void MQTT_connect() {
int8_t ret;

// Stop if already connected.
if (mqtt.connected()) {
return;
}

Serial.print("Connecting to MQTT... ");

uint8_t retries = 3;
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
Serial.println(mqtt.connectErrorString(ret));
Serial.println("Retrying MQTT connection in 5 seconds...");
mqtt.disconnect();
delay(5000); // wait 5 seconds
retries--;
if (retries == 0) {
// basically die and wait for WDT to reset me
while (1);
}
}
Serial.println("MQTT Connected!");
}
User avatar
By ChrisH
#56241 You have to connect to the MQTT server before subscribing to a topic.
For some reason you have the connect to MQTT in the loop function, for some reason (it shouldn't be there)..

Code: Select all  Serial.println("IP address: "); Serial.println(WiFi.localIP());

  // Move it to here!!!!!!
  MQTT_connect();

  // Setup MQTT subscription for onoff feed.
  mqtt.subscribe(&onoffbutton);

  // Inialize DHT sensor
  dht.begin();
}
uint32_t x = 0;

void loop() {
  MQTT_connect(); // <-- Move this!!

  // this is our 'wait for incoming subscription packets' busy subloop..
  // .......



ProTip: Use the [ code ] [/ code ] (without spaces) BBCodes when posting code (it makes it easier to read)! ;D
User avatar
By rappare
#72959 @blackjf, did this solve your proble or did you find another solution? I'm having a similar problem and got the advise to add "ICACHE_RAM_ATTR" to my two interrupt routines (void Rising() and void Falling() ). Unfortunately it makes no difference.

I want to present three values on a 0,66" OLED and on an internal web server. It seems, when I give the processor to must to think about, this happends.

In the code below, for example, I get "Exception(3). But if I comment out the line
" if((R[0] != temperature) || (R[1] != level_mm) || (R[2] != diagnostic)) ShowValuesOnDisplay();" it will run without any Ecveptions (in the short run at least).

My code:
Code: Select all// Including the ESP8266 WiFi library
#include "HLW8012.h"
#include <ESP8266WiFi.h>
//#include <OneWire.h>
//#include <DallasTemperature.h>

#include <TimeLib.h>
#include <SimpleTimer.h>

// Replace with your network details
const char* ssid = "xxxxx";
const char* password = "xxxxx";

// Web Server on port 80
WiFiServer server(80);

//OLED
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <SFE_MicroOLED.h>  // Include the SFE_MicroOLED library
#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2
#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH  16
#define PIN_RESET 255  //
#define DC_JUMPER 0  // I2C Addres: 0 - 0x3C, 1 - 0x3D
int R[3] = {0};
int xPos[3] ={34,34,34};
int tempXpos, levelXpos, DiagXpos;

MicroOLED oled(PIN_RESET, DC_JUMPER);  // I2C Example


const int interruptPin = D7;                         // the number of the interrupt pin
volatile int pwmValue = 0;

volatile unsigned long startTime = 0;               // timer for interruptpin
volatile unsigned long stopTime = 0;                // timer for interruptpin 
volatile unsigned long connectionTime = 0;          // timer for the overall signal 

int countISR = 0;                                   
volatile unsigned int msTime[3] = {22,33,44};             

bool startUp = false;
bool fallingEdge = false;

unsigned int temperature;                           // 22 - 88 ms
unsigned int level;                                 // 22 - 88 ms
unsigned int diagnostic;                            // 22 - 88 ms
int level_mm;                // 20 - 80 mm
unsigned int periodTimeRecieved = 0;
unsigned int periodTime = 110;

//int LEDone = 31;
//int LEDtwo = 33;


/float levelRange[15] = {31.65,33.81,35.97,38.14,40.30,42.46,44.62,46.78,48.95,51.11,53.27,55.43,57.59,59.76};   //Level in [ms]
float levelRange[7] = {31.65,35.99,40.33,44.67,49.01,53.35,59.69};
float levelRange_mm[7] = {20,30,40,50,60,70,80};

WiFiClient client = server.available();


// only runs once on boot
void setup() {
  // Initializing serial port for debugging purposes
  Serial.begin(115200);
  delay(10);
 
  pinMode(interruptPin, INPUT);
  attachInterrupt(digitalPinToInterrupt(interruptPin), Rising, RISING);

  // Connecting to WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
 
  //WiFi.begin(ssid, password);
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
 
  // Starting the web server
  server.begin();
  Serial.println("Web server running. Waiting for the ESP IP...");
  delay(10000);
 
  // Printing the ESP IP address
  Serial.println(WiFi.localIP());
 
  if (client)
  {
    Serial.println("connected");
  }
  else
  {
    Serial.println("connection failed");
  }


  //OLED
   // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  oled.begin();     // Initialize the OLED
  // init done
  //oled.display();
  //delay(2000);
  // Clear the buffer.
  oled.clear(PAGE);
  oled.clear(ALL);
    // text display tests
  oled.setFontType(1);
  //oled.setTextColor(WHITE);
  oled.setCursor(16,0);
  oled.println("Oil");
  oled.display();
  delay(300);
  oled.setCursor(8,18);
  oled.print("Level");
  oled.display();
  delay(300);
  oled.setCursor(8,36);
  oled.print("Check");
  oled.display();
  delay(3000);
  oled.clear(PAGE);
  oled.clear(ALL);

}

// runs over and over again
void loop() {
  // Listenning for new clients
  //WiFiClient client = server.available();
 
  //if (client) {
    //Serial.println("New client");
    // bolean to locate when the http request ends
    boolean blank_line = true;
    //while (client.connected()) {
      if (client.available()) {
        char c = client.read();
       
        if (c == '\n' && blank_line) {
            //getValues();
            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html");
            client.println("Connection: close");
            client.println();
            // your actual web page that displays temperature
            client.println("<!DOCTYPE HTML>");
            client.println("<html>");
            client.println("<meta http-equiv=&#34refresh&#34 content=&#3415&#34>");
            client.println("<head></head><body><h1>Oil temp & level check</h1><h3>Temperature: ");
            client.println(temperature);
            //Serial.print("Temp: ");
            //Serial.println(temperature);
            client.println("&#8451;</h3><h3>Level: ");
            client.println(level_mm);
            //Serial.print("Level:         ");
            //Serial.print(level_mm);
            client.println("mm</h3><h3>Diagnostic: ");
            client.println(diagnostic);
            //Serial.print("Diagnostic:                ");
            //Serial.print(diagnostic);
            client.println("</h3></body></html>"); 
            //break;
        }
        if (c == '\n') {
          // when starts reading a new line
          blank_line = true;
        }
        else if (c != '\r') {
          // when finds a character on the current line
          blank_line = false;
        }
      }
    //} 
    // closing the client connection
    //delay(1);
    //client.stop();
    //Serial.println("Client disconnected.");
  //}

    while(!startUp) {
    ESP.wdtFeed();
    //Serial.println("Startup");
    pwmValue = (stopTime - startTime) / 1000;   //1000 före felsökning
    /*Serial.print("stopTime ");
    Serial.print(stopTime);
    Serial.print("     startTime ");
    Serial.print(startTime);
    Serial.print("   /1000000     =     ");
    Serial.println(pwmValue);*/
   
    delay(100);
    //Serial.println(pwmValue);
   
    if(pwmValue >= 10 && pwmValue <= 150) {
      //Serial.println("I if pwmValue");
      ESP.wdtFeed();
      connectionTime = millis();
      while((millis() - connectionTime) <= 500 && !digitalRead(interruptPin)) {
      //Serial.println("I while() millis()");
      ESP.wdtFeed();
        if(millis() - connectionTime >= 500) {
          ESP.wdtFeed();
          startUp = true;
          fallingEdge = false;
          Serial.println("Start OK");
          break;
        }       
      }
    }
  }

/*
 * Decode the diffrent phases in signal and
 * store measured value.
 * When three values are received the parse function is called.
 */
  if(fallingEdge) {

    fallingEdge = false;
    msTime[countISR] = (stopTime - startTime) / 1000;
    //Serial.println(msTime[countISR]);
    countISR++;
   
    if(countISR == 3) {
     
      ParseTime();
      countISR = 0; 
      //SetLED(level_mm);
      if((R[0] != temperature) || (R[1] != level_mm) || (R[2] != diagnostic)) ShowValuesOnDisplay();   
      //Print();                        // debug function
      connectionTime = millis();      //
    }
  }

/*
 * The length of the overall signal is 1000 [ms] (+- 10%)
 * If no information is received in the overall signal time,
 * this function sets the program in start mode.
 */
  if((millis() - connectionTime) > 1300 ) {
    Serial.println("no connection");                     
    msTime[3] = {0};
    startUp = false;
  } 
}
  /*
 * Detect rising edge of PWM signal and sets interrupt mode to trigger on falling edge
 */
void Rising()
{
  //Serial.println("Rising edge!");
  startTime = micros();
  //Serial.print(startTime);
  //Serial.print("     ");
  if(countISR == 1)
  {
    periodTimeRecieved = millis();
  }
  if(countISR == 2)
  {
    periodTimeRecieved = millis() - periodTimeRecieved;
    //Print();
  }
  attachInterrupt(digitalPinToInterrupt(interruptPin), Falling, FALLING);
}

/*
 * Detect rising edge of PWM signal and sets interrupt mode to trigger on rising edge
 */
void Falling()
{
  //Serial.println("Falling edge!");
  //Serial.print("   ");
  //Serial.println(countISR);
  stopTime = micros();
  //Serial.println(stopTime);
  //Serial.print("     ");
  //Serial.println((stopTime - startTime) / 1000);
  //Print();
  fallingEdge = true;
  attachInterrupt(digitalPinToInterrupt(interruptPin), Rising, RISING);
}

/*
 * Parse received information to right variable and
 * detect if information are in right range
 */
void ParseTime()
{
  for(int i=0; i < 2; i++) {
   
    if(msTime[i] <= 22 || msTime[i] > 150) {
      msTime[i] = NULL;
    }   
  }
 
  temperature = msTime[0];
  level_mm = 74/32*((msTime[1]-23))*periodTimeRecieved/periodTime;
  if(level_mm >500) level_mm = 0;
  diagnostic = msTime[2];
  //Serial.println(msTime[1]);
  //Serial.println(level_mm);
  //level_mm = 74/32*((level_mm-23)*(periodTimeRecieved/110));
  //level_mm = FmultiMap(level_mm, levelRange, levelRange_mm,7);
  Serial.print(periodTimeRecieved);
  Print();
}

/*
 * Debug print
 */
void Print()
{
  Serial.println("");
  Serial.println(millis());
  Serial.print("Temperature:   ");
  Serial.println(temperature);   //temperature före ändringen
  Serial.print("Level:              ");
  Serial.println(level_mm);    //level_mm före ändringen
  //Serial.print(2.3125 * (level-23));    // Level[mm]=74mm/32ms*(T2[ms]-23ms*T[ms]/110ms)
  //Serial.println("  mm");
  Serial.print("Diagnostic:              ");
  Serial.println(diagnostic);   //diagnostic före ändringen
  Serial.println("");
}

void ShowValuesOnDisplay()
{
  //tempXpos, levelXpos, DiagXpos
  /*Serial.print("ShowValuesOnDisplay");
  Serial.print("   ");   
  Serial.print(temperature);
  Serial.print("   ");
  Serial.print(level_mm);
  Serial.print("   ");
  Serial.println(diagnostic);
  //if(R[0] != T[0] || R[1] != T[1] || R[2] != T[2])
  //{*/
    //Serial.println("Update values on screen");
    //
    /*char buffer[7];
    itoa(temperature,buffer,10);*/
    String measString[0] = String(temperature);
    measString[1] = String(level_mm);
    measString[2] = String(diagnostic);
    //Serial.println(thisString.length());
    int q;
    String oledSpace[3];
    for(q; q < 3;q++)
    {
      ESP.wdtFeed();
      /*if(R[q] < 100 && msTime[q] > 99) //If previous value was 2 digit and the new is 3 digit, then (move cursor back 6 points) and erase the first char
      {
        xPos[q] = 34;          // ReWriteScreen();           //If previous value was 3 digits and the new one is not, clear
        oledSpace[q] = "";
      }
      else if(R[q] > 99 && msTime[q] < 100)
      {
        xPos[q] = 34;
        oledSpace[q] = " ";
      }*/

      if(measString[q].length() < 10) oledSpace[q] = "  ";
      if(measString[q].length() < 100) oledSpace[q] = " ";
      if(measString[q].length() < 1000) oledSpace[q] = "";
     
      //}
    }
   
    /*{
      oled.clear(PAGE);
      oled.clear(ALL);
    }*/
    R[0] = temperature;
    R[1] = level_mm;
    R[2] = diagnostic;
    oled.setCursor(xPos[0],0);
    oled.print(oledSpace[0]);
    oled.print(temperature);
    /*if(level_mm > 99)
    {
      level_mmXpos = 35;
      ReWriteScreen();
    }
    else
    {
      level_mmXpos = 40;
    }*/
    //if(R[1] > 99 && level_mm < 99)
    //{
      oled.setCursor(xPos[1],18);
      oled.print(oledSpace[0]);
      //oled.print(" ");
    //}
    //else
    //{
      //oled.setCursor(40,18);
    //}
    oled.print(level_mm);
    oled.setCursor(xPos[2],36);
    oled.print(oledSpace[0]);
    oled.print(diagnostic);
    oled.display();
    Print();
  //}
  /*oled.clear(PAGE);
  oled.clear(ALL);
    // text display tests
  oled.setFontType(1);
  //oled.setTextColor(WHITE);
  oled.setCursor(0,0);
  oled.println("Temp ");
  oled.print(T[0]);
  oled.setCursor(0,18);
  oled.println("Lev  ");
  oled.print(T[1]);
  oled.setCursor(0,36);
  oled.println("Diag ");
  oled.print(T[2]);
  oled.display();*/
}

void ReWriteScreen()
{
  //Put up the headlines Tmp, Lev and Dia on the display
  oled.clear(PAGE);
  oled.clear(ALL);
  oled.setFontType(1);
  //oled.setTextColor(WHITE);
  oled.setCursor(0,0);
  oled.println("Tmp ");
  //oled.print(T[0]);
  oled.setCursor(0,18);
  oled.println("Lev  ");
  //oled.print(T[1]);
  oled.setCursor(0,36);
  oled.println("Dia ");
  //oled.print(T[2]);
  oled.display();
}


Hoping for some tips and trix.

Best regards Richard