-->
Page 1 of 1

Node MCU freez after about 4 hours

PostPosted: Mon Jan 29, 2018 4:42 pm
by yogui
Hello
I have an issue with my nodemcu V1.0 it freez about each 4 hour.
I use it as mysensors gateway and with help from the software serial library I use it aloso for read information from my powermeter (teleinformation (I'm in france)) with this lib
my sketch is

Code: Select all/**
 * The MySensors Arduino library handles the wireless radio link and protocol
 * between your home built sensors/actuators and HA controller of choice.
 * The sensors forms a self healing radio network with optional repeaters. Each
 * repeater and gateway builds a routing tables in EEPROM which keeps track of the
 * network topology allowing messages to be routed to nodes.
 *
 * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
 * Copyright (C) 2013-2015 Sensnology AB
 * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
 *
 * Documentation: http://www.mysensors.org
 * Support Forum: http://forum.mysensors.org
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 *******************************
 *
 * REVISION HISTORY
 * Version 1.0 - Henrik EKblad
 * Contribution by a-lurker and Anticimex,
 * Contribution by Norbert Truchsess <norbert.truchsess@t-online.de>
 * Contribution by Ivo Pullens (ESP8266 support)
 *
 * DESCRIPTION
 * The EthernetGateway sends data received from sensors to the WiFi link.
 * The gateway also accepts input on ethernet interface, which is then sent out to the radio network.
 *
 * VERA CONFIGURATION:
 * Enter "ip-number:port" in the ip-field of the Arduino GW device. This will temporarily override any serial configuration for the Vera plugin.
 * E.g. If you want to use the defualt values in this sketch enter: 192.168.178.66:5003
 *
 * LED purposes:
 * - To use the feature, uncomment any of the MY_DEFAULT_xx_LED_PINs in your sketch, only the LEDs that is defined is used.
 * - RX (green) - blink fast on radio message recieved. In inclusion mode will blink fast only on presentation recieved
 * - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly
 * - ERR (red) - fast blink on error during transmission error or recieve crc error
 *
 * See http://www.mysensors.org/build/esp8266_gateway for wiring instructions.
 * nRF24L01+  ESP8266
 * VCC        VCC
 * CE         GPIO4
 * CSN/CS     GPIO15
 * SCK        GPIO14
 * MISO       GPIO12
 * MOSI       GPIO13
 * GND        GND
 *
 * Not all ESP8266 modules have all pins available on their external interface.
 * This code has been tested on an ESP-12 module.
 * The ESP8266 requires a certain pin configuration to download code, and another one to run code:
 * - Connect REST (reset) via 10K pullup resistor to VCC, and via switch to GND ('reset switch')
 * - Connect GPIO15 via 10K pulldown resistor to GND
 * - Connect CH_PD via 10K resistor to VCC
 * - Connect GPIO2 via 10K resistor to VCC
 * - Connect GPIO0 via 10K resistor to VCC, and via switch to GND ('bootload switch')
 *
  * Inclusion mode button:
 * - Connect GPIO5 via switch to GND ('inclusion switch')
 *
 * Hardware SHA204 signing is currently not supported!
 *
 * Make sure to fill in your ssid and WiFi password below for ssid & pass.
 */


// Enable debug prints to serial monitor
//#define MY_DEBUG

// Use a bit lower baudrate for serial prints on ESP8266 than default in MyConfig.h
//#define MY_BAUD_RATE 9600

// Enables and select radio type (if attached)
//#define MY_RADIO_NRF24

//#define MY_RF24_CHANNEL  83

//#define MY_RADIO_RFM69

#define MY_GATEWAY_ESP8266

#define MY_ESP8266_SSID "myssid"
#define MY_ESP8266_PASSWORD "mypassword"


// Enable UDP communication
//#define MY_USE_UDP

// Set the hostname for the WiFi Client. This is the hostname
// it will pass to the DHCP server if not static.
// #define MY_ESP8266_HOSTNAME "sensor-gateway"

// Enable MY_IP_ADDRESS here if you want a static ip address (no DHCP)
//#define MY_IP_ADDRESS 192.168.1.165
#define MY_MAC_ADDRESS 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0x14

// If using static ip you need to define Gateway and Subnet address as well
//#define MY_IP_GATEWAY_ADDRESS 192,168,1,1
//#define MY_IP_SUBNET_ADDRESS 255,255,255,0

// The port to keep open on node server mode
#define MY_PORT 5003

// How many clients should be able to connect to this gateway (default 1)
#define MY_GATEWAY_MAX_CLIENTS 2

// Controller ip address. Enables client mode (default is "server" mode).
// Also enable this if MY_USE_UDP is used and you want sensor data sent somewhere.
//#define MY_CONTROLLER_IP_ADDRESS 192, 168, 178, 68

// Enable inclusion mode
//#define MY_INCLUSION_MODE_FEATURE

// Enable Inclusion mode button on gateway
// #define MY_INCLUSION_BUTTON_FEATURE
// Set inclusion mode duration (in seconds)
//#define MY_INCLUSION_MODE_DURATION 60
// Digital pin used for inclusion mode button
//#define MY_INCLUSION_MODE_BUTTON_PIN  3


// Set blinking period
// #define MY_DEFAULT_LED_BLINK_PERIOD 300

// Flash leds on rx/tx/err
// Led pins used if blinking feature is enabled above
#define MY_DEFAULT_ERR_LED_PIN 16  // Error led pin
#define MY_DEFAULT_RX_LED_PIN  16  // Receive led pin
#define MY_DEFAULT_TX_LED_PIN  16  // the PCB, on board LED

#if defined(MY_USE_UDP)
#include <WiFiUdp.h>
#endif

//Mysensors libs
#include <ESP8266WiFi.h>
#include <MySensors.h>

/******************************************************************************************************
 *
 *
 *                          Teleinfo
 *
 *
 ******************************************************************************************************/
//#define DEBUG
#include <SoftwareSerial.h>
#include <LibTeleinfo.h>

#ifdef __AVR__ //for arduino
  SoftwareSerial SerialTI (4,4); // Teleinfo Serial
#else // for ESP8266
  SoftwareSerial SerialTI (D3,SW_SERIAL_UNUSED_PIN, false, 128); // Teleinfo Serial
#endif


TInfo          tinfo; // Teleinfo object
int16_t         test;


// paramètres des données téléinfo
// - ne pas toucher
// infos générales
///////////////////////////////////



#define CHILD_ID_ADCO             0
MyMessage msgVAR1                 ( 0, V_VAR1 );

#define CHILD_ID_OPTARIF          1

#define CHILD_ID_ISOUSC           2
MyMessage msgCURRENT              ( 0, V_CURRENT );

#define CHILD_ID_PTEC             3

#define CHILD_ID_IINST            4
#define CHILD_ID_ADPS             5
#define CHILD_ID_IMAX             6
#define CHILD_ID_PAPP             7
#define CHILD_ID_ADPS_PHASE       8

MyMessage msgWATT                 ( 0, V_WATT ); // pas vrai c'est des VA!

// infos tarif BASE
///////////////////////////////////
#define CHILD_ID_BASE             10
MyMessage msgKWH                  ( 0, V_KWH ); // en fait c'est des WH

// infos tarif HC/HP
///////////////////////////////////
#define CHILD_ID_HC_HC            20
#define CHILD_ID_HC_HP            21

// infos EJP
#define CHILD_ID_EJP_HN           30
#define CHILD_ID_EJP_HPM          31
#define CHILD_ID_PEJP 32

// infos tarif BBR (tempo)
///////////////////////////////////
#define CHILD_ID_BBR_HC_JB        40
#define CHILD_ID_BBR_HP_JB        41
#define CHILD_ID_BBR_HC_JW        42
#define CHILD_ID_BBR_HP_JW        43
#define CHILD_ID_BBR_HC_JR        44
#define CHILD_ID_BBR_HP_JR        45
#define CHILD_ID_DEMAIN           46


// sert à EJP/BBR
///////////////////////////////////
#define CHILD_ID_HHPHC            50


#define TARIF_BASE                1
#define TARIF_HCHP                2
#define TARIF_EJP                 4
#define TARIF_TEMPO               8

// cas du triphasé
//////////////////////////////////
#define CHILD_ID_IINST1           60
#define CHILD_ID_IINST2           61
#define CHILD_ID_IINST3           62
#define CHILD_ID_IMAX1            63
#define CHILD_ID_IMAX2            64
#define CHILD_ID_IMAX3            65
#define CHILD_ID_PMAX             66
#define CHILD_ID_PPOT             67


boolean triphase = false;
boolean presentationfinished = false;
boolean FirstSend= false;
boolean PresentationRequested= false;
boolean NewFrameRecived = false;
uint8_t PhasetoSend=0;
uint8_t oldPhasetoSend=0;
uint8_t tarif = 0;


/* ======================================================================
Function: ADPSCallback
Purpose : called by library when we detected a ADPS on any phased
Input   : phase number
            0 for ADPS (monophase)
            1 for ADIR1 triphase
            2 for ADIR2 triphase
            3 for ADIR3 triphase
Output  : -
Comments: should have been initialised in the main sketch with a
          tinfo.attachADPSCallback(ADPSCallback())
====================================================================== */
void ADPSCallback(uint8_t phase)
{
 
  // n = numero de la phase 1 à 3
  if (phase == 0)
    phase = 1;
#ifdef DEBUG
  Serial.print(F("ADPS : "));
  Serial.println ( phase);
#endif 
   PhasetoSend = phase;
 

}
/* ======================================================================
Function: NewFrame
Purpose : callback when we received a complete teleinfo frame
Input   : linked list pointer on the concerned data
Output  : -
Comments: -
====================================================================== */
void NewFrame(ValueList * me)
{
  char buff[32];
  NewFrameRecived = true;

  sprintf_P( buff, PSTR("New Frame (%ld Bytes free)"), ESP.getFreeHeap() );
 
  Serial.println(buff);
 
}


/* ======================================================================
Function: SendSensor
Purpose : send mysensors message value
Input   : label to check, actual label, value , poiter to mysensors message type ,Sensor id
Output  : -
Comments: -
====================================================================== */


bool SendSensor( const __FlashStringHelper *label,char *searchLabel, char *value, MyMessage &msg, int SENSOR_ID ) {
 
  uint32_t ValueToSend;
 
  if ( strcmp_P(searchLabel,(const char*)label)!=0){
    //Serial.println ("Fin SendSensor label different");
    return false;
   
  }
  if (   (strcmp_P (searchLabel , (const char*) F("ADCO")) == 0) 
      || (strcmp_P (searchLabel , (const char*) F("OPTARIF")) ==0 )
      || (strcmp_P (searchLabel , (const char*) F("PTEC")) ==0 )
      || (strcmp_P (searchLabel , (const char*) F("DEMAIN")) ==0 )
      || (strcmp_P (searchLabel , (const char*) F("HHPHC")) ==0 )
      || (strcmp_P (searchLabel , (const char*) F("PPOT")) ==0 )
     ){
      send( msg.setSensor( SENSOR_ID ).set( value) );
   
  }
  else{
     ValueToSend = atoi( value);
     send( msg.setSensor( SENSOR_ID ).set( ValueToSend ) );
  }
#ifdef DEBUG
   Serial.print(searchLabel) ;
   Serial.print(F(" : ")) ;
   Serial.print(value) ;
   Serial.println (F(" Value Sended")) ;
#endif   
 
  return true;
 
}
/* ======================================================================
Function: sendMysesors
Purpose : send mysensors value
Input   : linked list pointer on the concerned data
Output  : -
Comments: -
====================================================================== */

void sendMysesors()
{
 boolean first_item = false;
  // don't need to send value if presentation isn't done
  if (!presentationfinished)
    return;
  ValueList * me = tinfo.getList(); 
  // Got at least one ?
  if (me) {

    // Loop thru the node
    while (me->next) {
      // go to next node
     
         // go to next node
       if(! first_item) 
          me = me->next;
      first_item = true; 
      // uniquement sur les nouvelles valeurs ou celles modifiées
      // sauf si explicitement demandé toutes
      if (!FirstSend ||  (me->flags & (TINFO_FLAGS_UPDATED | TINFO_FLAGS_ADDED) ))
      {
        // we have at least something ?
        if (me->value && strlen(me->value))
        {
     
          // gestion mySensor,
          SendSensor( F( "ADCO" )    , me->name, me->value, msgVAR1, CHILD_ID_ADCO );
          SendSensor( F( "OPTARIF" ) , me->name, me->value, msgVAR1, CHILD_ID_OPTARIF );
          SendSensor( F( "ISOUSC" )  , me->name, me->value, msgCURRENT, CHILD_ID_ISOUSC );
          SendSensor( F( "PTEC" )    , me->name, me->value, msgVAR1, CHILD_ID_PTEC );
          SendSensor( F( "ADPS" )    , me->name, me->value, msgCURRENT, CHILD_ID_ADPS );
          SendSensor( F( "PAPP" )    , me->name, me->value, msgWATT, CHILD_ID_PAPP );
         
          //begin add @yogui
          if (triphase == true){
            SendSensor( F( "IINST1" )  , me->name, me->value, msgCURRENT, CHILD_ID_IINST1 );
            SendSensor( F( "IINST2" )  , me->name, me->value, msgCURRENT, CHILD_ID_IINST2 ); 
            SendSensor( F( "IINST3" )  , me->name, me->value, msgCURRENT, CHILD_ID_IINST3 ); 
       
            SendSensor( F( "IMAX1" )   , me->name, me->value, msgCURRENT, CHILD_ID_IMAX1 );
            SendSensor( F( "IMAX2" )   , me->name, me->value, msgCURRENT, CHILD_ID_IMAX2 );
            SendSensor( F( "IMAX3" )   , me->name, me->value, msgCURRENT, CHILD_ID_IMAX3 );
       
            SendSensor( F( "PMAX" )    , me->name, me->value, msgWATT, CHILD_ID_PMAX );
            SendSensor( F( "PPOT" )    , me->name, me->value, msgVAR1, CHILD_ID_PPOT );
           
            }else{ // end add @yogui
            SendSensor( F( "IINST" )   , me->name, me->value, msgCURRENT, CHILD_ID_IINST );
            SendSensor( F( "IMAX" )    , me->name, me->value, msgCURRENT, CHILD_ID_IMAX );
            }
       
         
       
          if ( tarif == TARIF_BASE ) {
            SendSensor( F( "BASE" )    , me->name, me->value, msgKWH, CHILD_ID_BASE );
          } else if ( tarif == TARIF_HCHP ) {
            SendSensor( F( "HC_HC" )   , me->name, me->value, msgKWH, CHILD_ID_HC_HC );
            SendSensor( F( "HC_HP" )   , me->name, me->value, msgKWH, CHILD_ID_HC_HP );
          } else if ( tarif == TARIF_EJP ) {
            SendSensor( F( "EJP_HN" )  , me->name, me->value, msgKWH, CHILD_ID_EJP_HN );
            SendSensor( F( "EJP_HPM" ) , me->name, me->value, msgKWH, CHILD_ID_EJP_HPM );
            SendSensor( F( "PEJP" )    , me->name, me->value, msgKWH, CHILD_ID_PEJP );
          } else if ( tarif == TARIF_TEMPO ) {
            SendSensor( F( "BBR_HC_JB" ) , me->name, me->value, msgKWH, CHILD_ID_BBR_HC_JB );
            SendSensor( F( "BBR_HP_JB" ) , me->name, me->value, msgKWH, CHILD_ID_BBR_HP_JB );
            SendSensor( F( "BBR_HC_JW" ) , me->name, me->value, msgKWH, CHILD_ID_BBR_HC_JW );
            SendSensor( F( "BBR_HP_JW" ) , me->name, me->value, msgKWH, CHILD_ID_BBR_HP_JW );
            SendSensor( F( "BBR_HC_JR" ) , me->name, me->value, msgKWH, CHILD_ID_BBR_HC_JR );
            SendSensor( F( "BBR_HP_JR" ) , me->name, me->value, msgKWH, CHILD_ID_BBR_HP_JR );
            SendSensor( F( "DEMAIN" )  , me->name, me->value, msgVAR1, CHILD_ID_DEMAIN );
          }
       
          if ( (tarif & TARIF_EJP) || (tarif & TARIF_TEMPO) ) {
            SendSensor( F( "HHPHC" )   , me->name, me->value, msgVAR1, CHILD_ID_HHPHC );
          }
   
        }
       
      }
     
      //send ADPS message
   
        if (PhasetoSend){
          send( msgVAR1.setSensor( CHILD_ID_ADPS ).set(1));   
          send( msgVAR1.setSensor( CHILD_ID_ADPS_PHASE ).set( PhasetoSend ) );
        }else if (oldPhasetoSend != PhasetoSend) {
         
          send( msgVAR1.setSensor( CHILD_ID_ADPS ).set(0));   
          send( msgVAR1.setSensor( CHILD_ID_ADPS_PHASE ).set( 0) );
 
        }
      oldPhasetoSend = PhasetoSend;
      PhasetoSend =0;
     
    }
    FirstSend = true;
  }

}

/* ======================================================================
Function: PresentationMysesors
Purpose : present the sensor depend the first readed frame
Input   : linked list pointer on the concerned data
Output  : -
Comments: -
====================================================================== */
void PresentationMysesors()
{
  ValueList * me = tinfo.getList();
  triphase = false;
  // Got at least one ?
  if (me) {
    // Loop thru the node
    while (me->next) {
      // go to next node
      me = me->next;

      // we have at least something ?
      if (me->value && strlen(me->value)){
        if ((strcmp (me->name , "IINST1") == 0)  || (strcmp (me->name , "IMAX1") ==0 )){
          triphase = true;
        }

        // tarif option       
        if ( (strcmp (me->name , "OPTARIF") == 0) && (strcmp( me->value, "BASE" ) == 0 )) {
          tarif = TARIF_BASE;
        } else if (( strcmp (me->name , "OPTARIF") == 0) && (strcmp( me->value, "HC.." ) == 0 )) {
          tarif = TARIF_HCHP;
        }else if ((strcmp (me->name , "OPTARIF") == 0) && (strcmp( me->value, "EJP." ) == 0 )) {
          tarif = TARIF_EJP;
        } else if ((strcmp (me->name , "OPTARIF") == 0) &&  (strstr( me->value, "BBR" ) != NULL )) { // ! c'est BBRx (x varie) d'ou un strstr et non strcmp
          tarif = TARIF_TEMPO;
        }
      }
    }
  }
  if (triphase == true){
    present( CHILD_ID_IINST1, S_POWER );
    present( CHILD_ID_IINST2, S_POWER );       
    present( CHILD_ID_IINST3, S_POWER );
    present( CHILD_ID_IMAX1, S_POWER );
    present( CHILD_ID_IMAX2, S_POWER );
    present( CHILD_ID_IMAX3, S_POWER );
    present( CHILD_ID_PMAX, S_POWER );     
    present( CHILD_ID_PPOT, S_POWER );     
  }
  else{
    present( CHILD_ID_IINST, S_POWER );
    present( CHILD_ID_IMAX, S_POWER );     
  }
 
  if ( tarif == TARIF_BASE) {
    present( CHILD_ID_BASE, S_POWER );
 
  } else if ( tarif = TARIF_HCHP ) {
    present( CHILD_ID_HC_HC, S_POWER );
    present( CHILD_ID_HC_HP, S_POWER );
 
  } else if ( tarif = TARIF_EJP) {
    present( CHILD_ID_EJP_HN, S_POWER );
    present( CHILD_ID_EJP_HPM, S_POWER );
    present( CHILD_ID_PEJP, S_POWER );
 
  } else if ( tarif = TARIF_TEMPO) {
    present( CHILD_ID_BBR_HC_JB, S_POWER );
    present( CHILD_ID_BBR_HP_JB, S_POWER );
    present( CHILD_ID_BBR_HC_JW, S_POWER );
    present( CHILD_ID_BBR_HP_JW, S_POWER );
    present( CHILD_ID_BBR_HC_JR, S_POWER );
    present( CHILD_ID_BBR_HP_JR, S_POWER );
    present( CHILD_ID_DEMAIN, S_POWER );
 
  }
  // cas particulier, appartient a EJP et TEMPO
  if ( (tarif & TARIF_EJP) || (tarif & TARIF_TEMPO) ) {
    present( CHILD_ID_HHPHC, S_POWER );
  }
  PresentationRequested= false;
  presentationfinished = true;

 
}



/* ======================================================================
Function: presentation
Purpose : Mysesors : presentation sensor to the controler
Input   : -
Output  : -
Comments: -
====================================================================== */


void presentation() {
 
  sendSketchInfo( "Teleinfo Sensor", "1.0" );
  present( CHILD_ID_ADCO, S_POWER );
  present( CHILD_ID_OPTARIF, S_POWER );
  present( CHILD_ID_ISOUSC, S_POWER );
  present( CHILD_ID_PTEC, S_POWER );
  present( CHILD_ID_ADPS, S_POWER );
  present( CHILD_ID_PAPP, S_POWER );
  present( CHILD_ID_ADPS_PHASE, S_POWER );


  presentationfinished = false;
  PresentationRequested = true;
  FirstSend = false; 
  //first read
  // Teleinformation processing
  if ( SerialTI.available() ) {
    tinfo.process(SerialTI.read());
  } 
 
 
}


/* ======================================================================
Function: setup
Purpose : Setup I/O and other one time startup stuff
Input   : -
Output  : -
Comments: -
====================================================================== */
void setup()
{
 
  // Set CPU speed to 160MHz
  system_update_cpu_freq(160);
    // Serial, pour le debug
  Serial.begin(115200);
#ifdef DEBUG 


  Serial.println(F("========================================"));
  Serial.println(F(__FILE__));
  Serial.println(F(__DATE__ " " __TIME__));
  Serial.println();
#endif

  SerialTI.begin(1200);

  // Init teleinfo
  tinfo.init();
  // Attacher les callback dont nous avons besoin
  // pour cette demo, ici attach data
  // Attacher les callback dont nous avons besoin
  tinfo.attachADPS(ADPSCallback);
  tinfo.attachNewFrame(NewFrame);

  Serial.println(F("Teleinfo started"));
 
}





/* ======================================================================
Function: loop
Purpose : infinite loop main code
Input   : -
Output  : -
Comments: -
====================================================================== */
void loop()
{
  char c;
   if (NewFrameRecived){
     if (presentationfinished){
        sendMysesors();
        NewFrameRecived = false;
     }
     else if (PresentationRequested){
      PresentationMysesors();
      NewFrameRecived = false;
     }
  }
 
   
  // Teleinformation processing
  if ( SerialTI.available()  ) {
    //tinfo.process(SerialTI.read());
    // Read Serial and process to tinfo
    c = SerialTI.read();
    //Serial1.print(c);
    tinfo.process(c); 
  }

 
}


I use the Arduino ide 1.8.5 on Linux Armbian.
my setings :
gnome-shell-screenshot-MLNADZ.png

I used the git version arduino ESP8266 drivers dowloded the 27/01/2018

the problem I have is that the nodemcu freezed after about 4 hours in most of case without any error in the debug consol.In some rare case I have a message dev 1153 (I don't know what that mean but is not comming from my code). I check the free memory with ESP.getFreeHeap() but it look stable (~200byte less) at about 40712Bytes free when crash. The power supply should not be an issu I Try to power it direct with the 3 ampers powersuply my orangepi 0 with the same effect.
What can I do to find the issue cause? have more debug info (without had a lot of serial print what I do but without any succes.)?
dou you have idea where the freeze comming from

thanks in advance for your help