- Mon Jan 08, 2018 4:45 am
#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="refresh" content=ൗ">");
client.println("<head></head><body><h1>Oil temp & level check</h1><h3>Temperature: ");
client.println(temperature);
//Serial.print("Temp: ");
//Serial.println(temperature);
client.println("℃</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