Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESP8266 servo causes crash after updating from core 2.0.0 to 2.2.0 #2083

Closed
p4yl04d3r opened this issue Jun 2, 2016 · 44 comments
Closed

ESP8266 servo causes crash after updating from core 2.0.0 to 2.2.0 #2083

p4yl04d3r opened this issue Jun 2, 2016 · 44 comments

Comments

@p4yl04d3r
Copy link

p4yl04d3r commented Jun 2, 2016

Basic Infos

Hardware

Hardware: ESP-12F
Core Version: 2.2.0

Description

Servo movement to specific positions causes esp8266 to crash. I am using Arduino IDE 1.6.9.
I am using the same function to call the servo and only passing in a different value. But only when I pass in a lower/mid value does the controller crash. I have confirmed the following values (5,30,40,45) trigger a crash.
Other values (0 90,100,175,180) are OK.
Having a servo connected is optional to trigger the crash.

Settings in IDE

Module: Generic ESP8266 Module
Flash Size: 4MB
CPU Frequency: 80Mhz
Flash Mode: dio
Flash Frequency: 40Mhz
Upload Using: SERIAL
Reset Method: ck

#include <Servo.h>  
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

/* Setup number of servos */
#define SERVO1
//#define SERVO2
//#define SERVO3
/* ENABLE DEBUG */
int debug = 1;            //Set this to 1 for serial debug output
/* Configure GPIO servo pins*/
const int servoPin1=13;     //Pin for servo1
//const int servoPin2=12;     //Pin for servo2
//const int servoPin3=14;     //Pin for servo3
const int button_pin=4 ;  //Button or relay driven by x10 switch for manual control
/* Blind tilt settings */
const int OPEN=90;      //Global settings for open
const int HALF=30;       //Global settings for half way opened
const int CLOSE=0;       //Global settings for close in down position
const int CLOSEUP=180;   //Global setting to close in the up position
Servo myservo;     // create servo object to control a servo 
int button_value;  //high or low button values
int next=1;

void moveblinds(int value) {
#ifdef SERVO1
        delay(60);
        debug and Serial.print("Moving blind1 to: ");
        debug and Serial.println(value);
        myservo.attach(servoPin1);
        myservo.write(value);
        delay(600); 
        myservo.detach();
#endif
#ifdef SERVO2
        delay(60);
        debug and Serial.print("Moving blind2 to: ");
        debug and Serial.println(value);
        myservo.attach(servoPin2);
        myservo.write(value);
        delay(600); 
        myservo.detach();
#endif
#ifdef SERVO3
        delay(60);
        debug and Serial.print("Moving blind3 to: ");
        debug and Serial.println(value);
        myservo.attach(servoPin3);
        myservo.write(value);
        delay(600); 
        myservo.detach();
#endif     
}

void loop(void) { 
    if (!client.connected()) {
       delay(10);
       reconnect();
    }
    client.loop();
    button_value = digitalRead(button_pin); 
    if(button_value==LOW){  // button press
      debug and Serial.println("button pressed: "); 
      if (next > 4) {
        next=1;
      }
      if (next == 1) { //First pull is OPEN
        moveblinds(OPEN);     //Move to next position
      } 
      if (next == 2) {                //Second pull is HALF
        moveblinds(HALF);
      } 
      if (next == 3) {                //Third pull is CLOSE 
        moveblinds(CLOSE);                    
      } 
      if (next == 4) {                 //Forth pull is CLOSEUP 
        moveblinds(CLOSEUP);                  
      }
      next++;
   }
   delay(60);
}

Debug Messages

Connecting to <ssid>
......
WiFi connected
IP address: xx.xx.xx.xx
Moving blind1 to: 180 <-- never on this move
button pressed: 
Moving blind1 to: 90  <-- never on this move
button pressed: 
Moving blind1 to: 30  <-- I crash here almost every time.

Exception (0):
epc1=0x40201134 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

ctx: sys 
sp: 3ffffc70 end: 3fffffb0 offset: 01a0

>>>stack>>>
3ffffe10:  4021250c 3ffed750 3ffffed0 00000016  
3ffffe20:  3fffc200 40106c24 00000020 40106c40  
3ffffe30:  402102b5 3ffffed0 3fffc248 4000050c  
3ffffe40:  4000437d 00000030 00000016 ffffffff  
3ffffe50:  60000200 00000008 00000000 80000000  
3ffffe60:  20000000 3fff0da8 80000000 203fc060  
3ffffe70:  80000000 3fffc6fc 3ffeed1c 3fff0dac  
3ffffe80:  00000294 003fc060 3ffecf40 00000030  
3ffffe90:  3ffedd78 40201154 00000000 bfffffff  
3ffffea0:  ffffffff 3fffc6fc 3ffedd78 3ffeed1c  
3ffffeb0:  3ffedda0 03d3a63d 60000600 00000030  
3ffffec0:  40000f58 00000000 00000020 00000000  
3ffffed0:  00000013 40201154 3ffedd78 00000000  
3ffffee0:  ffffffff 3ffecef4 3ffedd78 3fffdab0  
3ffffef0:  00000000 3fffdcb0 3ffeddb0 00000030  
3fffff00:  3fff04a4 3ffee9d8 00002238 40105cb0  
3fffff10:  401051fc 004f9272 3ffe89d4 00000000  
3fffff20:  3ffedda0 3ffe89d4 0000000f 4010707c  
3fffff30:  00000000 400042db 402053c7 3ffecf40  
3fffff40:  40004b31 3fff0d4c 000002f4 003fc000  
3fffff50:  401054a2 00000000 3ffece40 401070c0  
3fffff60:  40208621 3ffece40 00000000 3fffdc00  
3fffff70:  3fff0d4c 00001000 40208ab6 00000002  
3fffff80:  4021a282 3fffdab0 40209cb7 3fffdab0  
3fffff90:  00000000 3fffdab0 3ffeee08 40203ceb  
3fffffa0:  40000f49 40000f49 3fffdab0 40000f49  
<<<stack<<<


Decoding 25 results
0x4021250c: cnx_update_bss_more at ?? line ?
0x40106c24: timer0_isr_handler at C:\Users\chris\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.2.0\cores\esp8266/core_esp8266_timer.c line 71
0x40106c40: timer0_isr_handler at C:\Users\chris\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.2.0\cores\esp8266/core_esp8266_timer.c line 71
0x402102b5: scan_parse_beacon at ?? line ?
0x40201154: delay_end at C:\Users\chris\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.2.0\cores\esp8266/core_esp8266_wiring.c line 38
0x40201154: delay_end at C:\Users\chris\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.2.0\cores\esp8266/core_esp8266_wiring.c line 38
0x40105cb0: _UserExceptionVector_1 at ?? line ?
0x401051fc: ets_timer_arm_new at ?? line ?
0x4010707c: pvPortMalloc at C:\Users\chris\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.2.0\cores\esp8266/heap.c line 13
0x402053c7: pp_enable_noise_timer at ?? line ?
0x401054a2: spi_flash_read at ?? line ?
0x401070c0: pvPortZalloc at C:\Users\chris\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.2.0\cores\esp8266/heap.c line 33
0x40208621: pm_set_sleep_time at ?? line ?
0x40208ab6: pm_get_sleep_type at ?? line ?
0x4021a282: ets_timer_handler_isr at ?? line ?
0x40209cb7: pm_post at ?? line ?
0x40203ceb: loop_task at C:\Users\chris\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.2.0\cores\esp8266/core_esp8266_main.cpp line 43

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

@p4yl04d3r p4yl04d3r changed the title ESP8266 crash after updating from core 2.0.0 to 2.2.0 ESP8266 servo causes crash after updating from core 2.0.0 to 2.2.0 Jun 2, 2016
@igrr
Copy link
Member

igrr commented Jun 3, 2016

The sketch doesn't compile for me,

B2083_ServoException:56: error: 'client' was not declared in this scope
     if (!client.connected()) {
          ^
B2083_ServoException:58: error: 'reconnect' was not declared in this scope
        reconnect();
                  ^
B2083_ServoException:60: error: 'client' was not declared in this scope
     client.loop();
     ^

@igrr
Copy link
Member

igrr commented Jun 3, 2016

After commenting out some stuff and adding a setup method to your sketch, i got it to run. Works fine with the latest git version.

@p4yl04d3r
Copy link
Author

Sorry, I should have included the full or at least functioning sketch. If you cycle through the if statements a few times (button on gpio 4) the servo.write (HALF) causes a crash. I'll post the complete sketch in a bit. I am also publishing data to an mqtt broker.

@igrr
Copy link
Member

igrr commented Jun 3, 2016

tek00000
tek00001
tek00002
tek00003
tek00004

@p4yl04d3r
Copy link
Author

p4yl04d3r commented Jun 3, 2016

I wrote a quick sketch (bare bones) but close to the original sketch in regards to the code path that controls the servo. Took a bit more time but it did trigger a crash.


#include <Servo.h>  

/* Setup number of servos */
#define SERVO1
//#define SERVO2
//#define SERVO3
/* ENABLE DEBUG */
int debug = 1;            //Set this to 1 for serial debug output
/* Configure GPIO servo pins*/
const int servoPin1=13;     //Pin for servo1
//const int servoPin2=12;     //Pin for servo2
//const int servoPin3=14;     //Pin for servo3
/* Blind tilt settings */
const int OPEN=90;      //Global settings for open
const int HALF=30;       //Global settings for half way opened
const int CLOSE=0;       //Global settings for close in down position
const int CLOSEUP=180;   //Global setting to close in the up position
/***********************************************************************************/

Servo myservo;     // create servo object to control a servo 

void setup(void) {
  Serial.begin(9600); //Comment out this line if you don't want debugging enabled
  moveblinds(CLOSEUP);         // call function to close all blinds
  delay(2000);
}


void moveblinds(int value) {
#ifdef SERVO1
        delay(60);
        debug and Serial.print("Moving blind1 to: ");
        debug and Serial.println(value);
        myservo.attach(servoPin1);
        myservo.write(value);
        delay(600); 
        myservo.detach();
#endif
#ifdef SERVO2
        delay(60);
        debug and Serial.print("Moving blind2 to: ");
        debug and Serial.println(value);
        myservo.attach(servoPin2);
        myservo.write(value);
        delay(600); 
        myservo.detach();
#endif
#ifdef SERVO3
        delay(60);
        debug and Serial.print("Moving blind3 to: ");
        debug and Serial.println(value);
        myservo.attach(servoPin3);
        myservo.write(value);
        delay(600); 
        myservo.detach();
#endif     
}

void loop(void) { 
        moveblinds(HALF);  //Move to next position
delay(500);
        moveblinds(HALF);
delay(500); 
        moveblinds(HALF);          
delay(500);
}

Serial output:

Moving blind1 to: 180
Moving blind1 to: 30
<omitted 84 lines>
Moving blind1 to: 30
Moving blind1 to: 30
Moving blind1 to: 30
Moving blind1 to: 30
Moving blind1 to: 30

Exception (0):
epc1=0x40201110 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

ctx: sys 
sp: 3ffffc40 end: 3fffffb0 offset: 01a0

>>>stack>>>
3ffffde0:  3ffe95c0 40103d82 00000001 00000000  
3ffffdf0:  3fffc200 40106c24 00000020 40106c40  
3ffffe00:  00000001 00000000 3fffc248 4000050c  
3ffffe10:  400043a3 00000030 00000016 ffffffff  
3ffffe20:  60000200 00000006 0001cf00 80000000  
3ffffe30:  20000000 3fff05a0 80000000 203fc220  
3ffffe40:  00000000 3fffc6fc 3ffee994 3fff05a4  
3ffffe50:  000000d4 003fc220 60000600 00000030  
3ffffe60:  00000120 401029b9 00040000 00000001  
3ffffe70:  4010553b 00080000 3ffe93d8 3ffe93d8  
3ffffe80:  00000000 02194e7c 00000000 4000050c  
3ffffe90:  00000000 00000000 0000001f 4010103d  
3ffffea0:  4000050c 01fcb244 3fffc248 4000050c  
3ffffeb0:  40000f68 00000030 0000000e ffffffff  
3ffffec0:  40000f58 00000000 00000020 00000000  
3ffffed0:  feefeffe 3ffee994 3ffee994 fffffffe  
3ffffee0:  ffffffff 3ffefbf4 3ffee994 3fffdab0  
3ffffef0:  00000000 3fffdad0 3ffeea6c 00000030  
3fffff00:  00000000 400042db 3ffe9b51 60000600  
3fffff10:  40004b31 3fff036c 000002f4 003fc000  
3fffff20:  40101da6 3ffe8720 3ffe96e0 401070c0  
3fffff30:  4021a111 3ffe96e0 3ffe8720 07a101ba  
3fffff40:  3fff036c 00001000 4021a5a6 00000008  
3fffff50:  00000000 00000000 4021a653 3ffe9794  
3fffff60:  3ffe8720 01fd5fed 3ffe8b8c 40201138  
3fffff70:  40203299 3ffe9794 3ffe8720 07a0fee3  
3fffff80:  402032de 3fffdab0 00000000 3fffdcb0  
3fffff90:  3ffe8730 3fffdad0 3ffeea6c 402023d7  
3fffffa0:  40000f49 00022b3c 3fffdab0 40000f49  
<<<stack<<<

Decoding 26 results
0x40103d82: ppEnqueueRxq at ?? line ?
0x40106c24: timer0_isr_handler at C:\Users\chris\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.2.0\cores\esp8266/core_esp8266_timer.c line 71
0x40106c40: timer0_isr_handler at C:\Users\chris\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.2.0\cores\esp8266/core_esp8266_timer.c line 71
0x401029b9: lmacProcessTXStartData at ?? line ?
0x4010553b: wDev_ProcessFiq at ?? line ?
0x4010103d: ets_timer_disarm at ?? line ?
0x40101da6: spi_flash_read at ?? line ?
0x401070c0: pvPortZalloc at C:\Users\chris\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.2.0\cores\esp8266/heap.c line 33
0x4021a111: pm_set_sleep_time at ?? line ?
0x4021a5a6: pm_get_sleep_type at ?? line ?
0x4021a653: pm_get_sleep_type at ?? line ?
0x40201138: delay_end at C:\Users\chris\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.2.0\cores\esp8266/core_esp8266_wiring.c line 40
0x40203299: ets_timer_handler_isr at ?? line ?
0x402032de: ets_timer_handler_isr at ?? line ?
0x402023d7: loop_task at C:\Users\chris\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.2.0\cores\esp8266/core_esp8266_main.cpp line 43

@igrr
Copy link
Member

igrr commented Jun 3, 2016

@Makuna actually it crashes at timer0_detachInterrupt, which is in flash.
Maybe given this change (2425ee3) we need to move detacInterrupt functions into IRAM. Anything else which needs to go there?

@igrr
Copy link
Member

igrr commented Jun 3, 2016

@p4yl04d3r Could you please try the following: change line 53 of core_esp8266_timer.c from

void timer1_detachInterrupt() {

to

void ICACHE_RAM_ATTR timer1_detachInterrupt() {

@igrr igrr added this to the 2.3.0 milestone Jun 3, 2016
igrr added a commit that referenced this issue Jun 3, 2016
These functions are used from ISR in Servo library, so must be in IRAM.
@p4yl04d3r
Copy link
Author

@igrr changing line 53 was not enough. It still crashed. I also made the following change to line 48 same file:
void ICACHE_RAM_ATTR timer1_attachInterrupt(timercallback userFunc) {
//void timer1_attachInterrupt(timercallback userFunc) {

Stack of only changing line 53:
Decoding 26 results
0x40103d82: ppEnqueueRxq at ?? line ?
0x40106c20: timer0_isr_handler at C:\Users\chris\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.2.0\cores\esp8266/core_esp8266_timer.c line 72
0x40106c3c: timer0_isr_handler at C:\Users\chris\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.2.0\cores\esp8266/core_esp8266_timer.c line 72
0x402211ea: ieee80211_ht_updateparams at ?? line ?
0x40221c21: ieee80211_parse_beacon at ?? line ?
0x40101180: ets_timer_arm_new at ?? line ?
0x4010103d: ets_timer_disarm at ?? line ?
0x40101da6: spi_flash_read at ?? line ?
0x401070f0: pvPortZalloc at C:\Users\chris\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.2.0\cores\esp8266/heap.c line 33
0x4021a0d9: pm_set_sleep_time at ?? line ?
0x4021a56e: pm_get_sleep_type at ?? line ?
0x4021a61b: pm_get_sleep_type at ?? line ?
0x40201100: delay_end at C:\Users\chris\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.2.0\cores\esp8266/core_esp8266_wiring.c line 40
0x40203261: ets_timer_handler_isr at ?? line ?
0x402032a6: ets_timer_handler_isr at ?? line ?
0x4020239f: loop_task at C:\Users\chris\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.2.0\cores\esp8266/core_esp8266_main.cpp line 43

@Makuna
Copy link
Collaborator

Makuna commented Jun 3, 2016

I have yet had it fail, how long does it need to run before it fails?

@p4yl04d3r
Copy link
Author

@Makuna It took about 1 - 2 minutes. But the stack is random.

@Makuna
Copy link
Collaborator

Makuna commented Jun 3, 2016

I created https://gitter.im/Makuna/ArduinoEsp8266Issue2083 so we talk live.

@p4yl04d3r
Copy link
Author

@Makuna I tried the link above earlier, I got a 404 error.

@Makuna
Copy link
Collaborator

Makuna commented Jun 3, 2016

Basically, I have been running your sketch above for hours and still have not had a single repro. There is something more to causing this issue than just the servo code.

@pauloeduardosp
Copy link

Michael,
Sorry I didn't was online that time.
But do u do a web up date?
I just have a problem after do webupdate

Em Sex, 3 de jun de 2016 18:58, Michael Miller notifications@github.com
escreveu:

Basically, I have been running your sketch above for hours and still have
not had a single repro. There is something more to causing this issue than
just the servo code.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#2083 (comment),
or mute the thread
https://github.com/notifications/unsubscribe/ARI5EbnGK6XD8zbF10oxDNdZRJIVa2aIks5qIKOTgaJpZM4IswWu
.

@p4yl04d3r
Copy link
Author

I thought the same thing until I tried it with the minimal logic sketch above. Basically I removing all the MQTT stuff and was able to trigger. Could it be that I am not defining the ESP-12 correctly to the IDE?

@Makuna
Copy link
Collaborator

Makuna commented Jun 3, 2016

Ok, I got a repro. It does require that networking was configured. I merged in the code for the HelloServer sample.

My esp8266 I have cleared the network settings normally. Remember that the esp8266 will reconnect with the last settings unless they are cleared; so I suspect the networking is needed to apply pressure so it can reproduce.

@p4yl04d3r
Copy link
Author

Glad you could reproduce and it's not just my ESPs.

@Makuna
Copy link
Collaborator

Makuna commented Jun 4, 2016

@p4yl04d3r I was able to get a consistent repro every few minutes, I then applied the fix that @igrr referenced above and I have not be able to get it repro at all. It has been running for 5 hours straight without an issue.

Confirm that you really did apply the change that igrr referenced above.

@p4yl04d3r
Copy link
Author

I confirmed by looking at the line number in the stack trace. After applying @igrr fix the line in core_esp8266_timer.c was incremented by one.

@woodsgood
Copy link

Dear all,
I have 5 servos attached to an ESP8266 WeMos D1 Mini board, and similar to many of you, I am experiencing crashes with my code. The code works fine on an Arduino so I suspect that this is some ESP-related issues. Can someone please spell out exactly how to make the fix that @igrr referred to.
I am reasonably code-savvy but got lost in what changes are to me made to alleviate the problem.

Many thanks...

@p4yl04d3r
Copy link
Author

@woodsgood I am assuming you are using core 2.2.0. On windows the path for me was "C:\Users\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.2.0\cores\esp8266/core_esp8266_timer.c".
Change line 53 void timer1_detachInterrupt() { to void ICACHE_RAM_ATTR timer1_detachInterrupt() {
I then restarted the Arduino IDE and compiled the code. Let us know if this change resolves your problem.
If it does not then also make the same change to line 48 void timer1_attachInterrupt(timercallback userFunc) { to void ICACHE_RAM_ATTR timer1_attachInterrupt(timercallback userFunc) {

@woodsgood
Copy link

Thanks... This appears to be working fine although I'll see if the problems exist over the next few hours.

@p4yl04d3r
Copy link
Author

@woodsgood How did your testing go? Did you end up changing both timer1_attachInterrupt() and timer1_detachInterupt()?

@woodsgood
Copy link

Thanks p4yl04d3r
Yes... I changed both lines.
So far, the software has behaved itself and there have been no unexpected interrupts...
Many thanks for your timely advice and interest.

@woodsgood
Copy link

Now, I have another issue on another project which has two steppers.
Even with the most basic code (see below) and the addition of the line "ESP.wdtEnable(15000);" I get the following Soft WDT reset...
Any ideas?

`Soft WDT reset

ctx: cont
sp: 3ffef9c0 end: 3ffefbc0 offset: 01b0

stack>>>
3ffefb70: 00000001 0000002d 3ffeeadc 40201f1c
3ffefb80: 4010692c 00000090 00000000 40201f40
3ffefb90: 00000000 00000000 00000001 40201cc1
3ffefba0: feefeffe feefeffe 3ffeeb88 40202380
3ffefbb0: feefeffe feefeffe 3ffeeba0 40100114
<<<stack<<<

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

load 0x4010f000, len 1264, room 16
tail 0
chksum 0x0f
csum 0x0f
~ld`

Here's the simple code...
`// STEPPERS
#define carouselDIR D4 // carousel stepper direction
#define carouselSTP D5 // carousel stepper step
#define microSecDelay 200

int stepcount;
bool stepdir = LOW;

//****************************************************************************************//
// Initial Setup
//**
**************************************************************************************//
void setup() {
ESP.wdtEnable(15000);
pinMode(carouselDIR, OUTPUT); // Assign output mode to pin for direction
pinMode(carouselSTP, OUTPUT); // Assign output mode to pin for setp
digitalWrite(carouselDIR, stepdir); // Initialize dir pin
digitalWrite(carouselSTP, LOW); // Initialize step pin
stepcount=5000;
}

//****************************************************************************************//
// MAIN LOOP
//**
**************************************************************************************//
void loop() {
int steps = stepcount;
while(steps != 0) {
digitalWrite(carouselSTP, HIGH); // Step motor
delayMicroseconds(microSecDelay); // Wait microseconds
digitalWrite(carouselSTP, LOW); // Step motor
delayMicroseconds(microSecDelay); // Wait microseconds
steps--;
}
digitalWrite( carouselDIR, !digitalRead(carouselDIR) );
}
`

@igrr
Copy link
Member

igrr commented Jun 8, 2016

Messing with the WDT is a bad idea, you need to remove ESP.wdtEnable(15000); and add yield(); to your while loop. As mentioned in the documentation, you must call either yield or delay to allow other tasks to run.

@woodsgood
Copy link

Thanks igrr
This works like a charm... I had not come across the yield() statement before so thanks for the tip.

@p4yl04d3r
Copy link
Author

p4yl04d3r commented Jun 11, 2016

I am still having a problem. Went back and compiled the original program with MQTT and I am still crashing on the same statements.

button pressed:
Moving blind1 to: 30

Exception
(0):
epc1=0x402010d8 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000
ctx: sys
sp: 3ffffc70 end: 3fffffb0 offset: 01a0
Decoding 25 results
0x402124b8: cnx_update_bss_more at ?? line ?
0x40106c20: timer0_isr_handler at C:\Users\chris\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.2.0\cores\esp8266/core_esp8266_timer.c line 71
0x40106c3c: timer0_isr_handler at C:\Users\chris\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.2.0\cores\esp8266/core_esp8266_timer.c line 71
0x40210261: scan_parse_beacon at ?? line ?
0x40105cb0: _UserExceptionVector_1 at ?? line ?
0x402010f8: delay_end at C:\Users\chris\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.2.0\cores\esp8266/core_esp8266_wiring.c line 38
0x40105cb0: _UserExceptionVector_1 at ?? line ?
0x401004d8: malloc at C:\Users\chris\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.2.0\cores\esp8266\umm_malloc/umm_malloc.c line 1662
0x401070cc: pvPortMalloc at C:\Users\chris\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.2.0\cores\esp8266/heap.c line 13
0x401054a2: spi_flash_read at ?? line ?
0x40107110: pvPortZalloc at C:\Users\chris\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.2.0\cores\esp8266/heap.c line 33
0x402085cd: pm_set_sleep_time at ?? line ?
0x40208a62: pm_get_sleep_type at ?? line ?
0x4021a22e: ets_timer_handler_isr at ?? line ?
0x40209c63: pm_post at ?? line ?
0x40203c97: loop_task at C:\Users\chris\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.2.0\cores\esp8266/core_esp8266_main.cpp line 43

@p4yl04d3r
Copy link
Author

Forgot to mention I have modified the following lines in core_esp8266_timer.c
Line 53: void ICACHE_RAM_ATTR timer1_detachInterrupt() { and Line 48: void ICACHE_RAM_ATTR timer1_attachInterrupt(timercallback userFunc) {

@p4yl04d3r
Copy link
Author

p4yl04d3r commented Jun 11, 2016

This is the program:
I still only seem to die when moving to position 30.

#include <Servo.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

/* Setup number of servos */
#define SERVO1
//#define SERVO2
//#define SERVO3
/* ENABLE DEBUG */
int debug = 1; //Set this to 1 for serial debug output
/* Configure GPIO servo pins*/
const int servoPin1=5; //Pin for servo1
//const int servoPin2=12; //Pin for servo2
//const int servoPin3=14; //Pin for servo3
const int button_pin=4 ; //Button or relay driven by x10 switch for manual control
/* WIFI setup */
const char* ssid = "<ssid>"; // WIFI SSID
const char* password = "<pass>"; // WIFI password
/* MQTT setup */
const char* mqtt_server ="<mqtt server>";
const char* topic_setting = "OpenHab/blind1/setting";
const char* topic_status = "OpenHab/blind1/status";

/* Blind tilt settings */
const int OPEN=90; //Global settings for open
const int HALF=30; //Global settings for half way opened
const int CLOSE=0; //Global settings for close in down position
const int CLOSEUP=180; //Global setting to close in the up position
/***********************************************************************************/
WiFiClient espClient;
PubSubClient client(espClient);

Servo myservo; // create servo object to control a servo
int button_value; //high or low button values
int next=1;

void setup(void) {
Serial.begin(9600); //Comment out this line if you don't want debugging enabled
pinMode(button_pin, INPUT_PULLUP);
setup_wifi();
delay(100);
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
moveblinds(CLOSEUP); // call function to close all blinds
client.connect("ESPBlind1");
client.subscribe(topic_setting);
client.publish(topic_status, "Closed"); // publish current position at powerup
}`

void setup_wifi() {
// We start by connecting to a WiFi network
debug and Serial.println();
debug and Serial.print("Connecting to ");
debug and Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
delay(20);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
debug and Serial.print(".");
}
debug and Serial.println("");
debug and Serial.println("WiFi connected");
debug and Serial.print("IP address: ");
debug and Serial.println(WiFi.localIP());
}

void moveblinds(int value) {
#ifdef SERVO1
delay(60);
debug and Serial.print("Moving blind1 to: ");
debug and Serial.println(value);
myservo.attach(servoPin1);
myservo.write(value);
delay(600);
myservo.detach();
#endif
#ifdef SERVO2
delay(60);
debug and Serial.print("Moving blind2 to: ");
debug and Serial.println(value);
myservo.attach(servoPin2);
myservo.write(value);
delay(600);
myservo.detach();
#endif
#ifdef SERVO3
delay(60);
debug and Serial.print("Moving blind3 to: ");
debug and Serial.println(value);
myservo.attach(servoPin3);
myservo.write(value);
delay(600);
myservo.detach();
#endif
}

void callback(char* topic, byte* payload, unsigned int length) {
debug and Serial.print("Message arrived: [");
debug and Serial.print(topic);
debug and Serial.print(" ]");
char *payload_string = (char *) payload; // convert mqtt byte array into char array
payload_string[length] ='\0'; // Must delimit with 0
int payload_int=atoi(payload_string); // convert char array into int
debug and Serial.println(payload_int);

//Adjust blind to setting of payload if between the full sweep of the servo.
if ((payload_int >= 0) && (payload_int <= 180)) {
moveblinds(payload_int); // Call function to move the blinds
/* MQTT status ranges */
if ((payload_int >= 70) && (payload_int <= 120)) { //Open range
client.publish(topic_status, "Open");
} else if ((payload_int >= 25) && (payload_int <= 69)) { //Half range
client.publish(topic_status, "Half");
} else if ((payload_int >= 0) && (payload_int <= 24)) { //Close range
client.publish(topic_status, "Closed");
} else if (payload_int >= 140) {
client.publish(topic_status, "Closedup");
} else {
client.publish(topic_status, "error");
debug and Serial.println("Unknown setting in payload");
}
}
}

void reconnect() {
// Loop until we're reconnected
//while (!client.connected()) { //comment out so we go through main loop for manual control
debug and Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("ESPBlind1")) {
debug and Serial.println("connected");
client.subscribe(topic_setting);
} else {
debug and Serial.print("failed, rc=");
debug and Serial.print(client.state());
debug and Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(50);
}
//}
}

//MAIN LOOP
void loop(void) {
if (!client.connected()) {
delay(10);
reconnect();
}
client.loop();
button_value = digitalRead(button_pin); //Query button or relay switch
//Define the modes based on button press. Cycle through options
if(button_value==LOW){ // button press
debug and Serial.println("button pressed: ");
if (next > 4) {
next=1;
}
if (next == 1) { //First pull is OPEN
moveblinds(OPEN); //Move to next position
client.publish(topic_status, "Open"); // publish current position
}
if (next == 2) { //Second pull is HALF
moveblinds(HALF);
client.publish(topic_status, "Half"); // publish current position
}
if (next == 3) { //Third pull is CLOSE
moveblinds(CLOSE);
client.publish(topic_status, "Closed"); // publish current position
}
if (next == 4) { //Forth pull is CLOSEUP
moveblinds(CLOSEUP);
client.publish(topic_status, "Closedup"); // publish current position
}
next++;
}
delay(60);
}

@woodsgood
Copy link

Just shooting in the dark, but a couple of things to try...

  • Does your code crash when there is no servo connected? If not, the issue may be that a power "surge" on the servo is causing some instability on the ESP8266 power line. If so, try adding a large decoupling capacitor. (Bye the way, how are you connecting a 5v servo to the 3.3v ESP8266?)
  • you may wish to try adding a "yield();" statement after the "myservo.write(value);" statement in the servo loop?
  • Also, how about adding a short delay immediately after the attach statement?

@p4yl04d3r
Copy link
Author

It will crash with and without a servo attached.
I will report back once I add some yield() statements

@Makuna
Copy link
Collaborator

Makuna commented Jun 12, 2016

@p4yl04d3r Please edit your post above and the code attributes to it so it shows up correctly (right now the includes are hidden).
three "left single quotes" on its own line is used to start and stop a code block.

@woodsgood
Copy link

Any luck with the yield() statements??

@igrr
Copy link
Member

igrr commented Jun 13, 2016

yield should not matter here — exception 0 means that some code from flash got called when flash cache was disabled. I would like to know what code is at 0x402010d8.

@p4yl04d3r
Copy link
Author

I have updated my post above fixing the formatting.
@igrr How would I find the code at that address? The exception decoder did not decode that line.

@p4yl04d3r
Copy link
Author

@igrr I got the requested line:

0x402010d8: timer0_detachInterrupt at C:\Users\chris\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.2.0\cores\esp8266/core_esp8266_timer.c line 98

void timer0_detachInterrupt() {
timer0_user_cb = NULL;
ETS_CCOMPARE0_DISABLE();
}

I think I want to add ICACHE_RAM_ATTR
Should we move functions at lines 89, 93 and 98 to ICACHE?

@Makuna
Copy link
Collaborator

Makuna commented Jun 13, 2016

@p4yl04d3r I thought we stated above you needed to add ICACHE_RAM_ATTR to timer0_detachInterrupt() above? Did you not?

specifically referencing this change by @igrr

@p4yl04d3r
Copy link
Author

I added ICACHE_RAM_ATTR to line 53 void ICACHE_RAM_ATTR timer1_detachInterrupt() {

So I modified the base 2.2.0 core_esp8266_timer.c with the following:
Line 53 and line 98 adding void ICACHE_RAM_ATTR ....
My program seems stable now.

@p4yl04d3r
Copy link
Author

p4yl04d3r commented Jun 13, 2016

I ran an additional test removing the change on line 53 and only including the modified line 98. Program seems stable also.
But then I also reviewed the tagged change. I did not see line 98 in the original post so did not make the change there. I have implemented the change as @igrr has implemented. Seems stable.

@Makuna
Copy link
Collaborator

Makuna commented Jun 14, 2016

For the first 12 servos (unless a special define is used), it will use the timer0, only after 12 or the use of a special define does it then use timer 1.

@p4yl04d3r
Copy link
Author

I am happy with the proposed change in 2.3.0. we can close or promote this bug.

@woodsgood
Copy link

Dear all,
For someone listening to these discussions, it would appear that you have come to some consensus about what changes are really necessary. Without sounding too repetitious, can you please detail ALL of the recommended edits to the file core_esp8266_timer.c

Many thanks,
.. Adrian Jones

@igrr
Copy link
Member

igrr commented Jun 14, 2016

@woodsgood this commit has all necessary changes: d1fc700

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants