MYSbootloader not rebooting, help



  • I'm new to this OTA wireless programming. I've made some Mysensors working for a year or so. But before I fully implement other more complicated sensors in my home, I need to get this OTA working. Currently I'm testing the latest code from github version 1.3.0-rc1. Everything seems working ok, except the rebooting.

    The bootloader is custom compiled with Radio on channel #1, and Gateway in serial mode with Radio channel set to 1 as well. Whenever I send reboot command though MYScontroller, it's just not triggering note enter rebooting mode, and I have to physically reset the Mini Pro for it to start requesting firmware version.

    Here is the log shown in MYSController Debug:

    4/9/2019 12:39:01	TX	1;0;3;0;13;0
    4/9/2019 12:39:02	RX	0;255;3;0;9;12729500 !TSF:MSG:SEND,0-0-1-1,s=0,c=3,t=13,pt=0,l=1,sg=0,ft=0,st=NACK:0
    

    Anyone has the same problem? Can all of you rebooting node smoothly?


  • Admin

    @mythbai Looks like the node is not actively listening for incoming commands. Please post the full node sketch and node debug log for troubleshooting.



  • Here is my node's sketch, hmm... I wonder if it has to do with the sleep function.

    #include <OneWire.h>
    
    #include <DallasTemperature.h>
    
    /**
    * 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
    *
    * DESCRIPTION
    * Motion Sensor example using HC-SR501
    * http://www.mysensors.org/build/motion
    *
    */
    
    // Enable debug prints
    //#define MY_DEBUG
    #define MY_RF24_CHANNEL (1)
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    //#define MY_NODE_ID 3
    
    
    #include <MySensors.h>
    #include <DallasTemperature.h>
    #include <OneWire.h>
    
    #define LIGHT_SENSOR_ANALOG_PIN 0 // analogue LDR sensor read PIN
    #define DIGITAL_MOTION_SENSOR 3   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
    #define ONE_WIRE_BUS 4 // Pin where dallase sensor is connected 
    #define MAX_ATTACHED_DS18B20 8
    #define COMPARE_TEMP 0 // Send temperature only if changed? 1 = Yes 0 = No
    
    // light sensor configuration
    #define REF_RESISTANCE            10030  // measure this for best result
    #define MAX_ADC_READING           1023
    #define LUX_CALC_SCALAR           42208480
    #define LUX_CALC_EXPONENT         -1.5395
    
    OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
    DallasTemperature tempSensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. 
    
    int lastLightLevel;
    float lastTemperature[MAX_ATTACHED_DS18B20];
    int numTempSensors=0;
    bool receivedConfig = false;
    bool metric = true;
    
    unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)
    // Id of the children sensors
    #define CHILD_ID_MOTION 0
    #define CHILD_ID_LIGHT 1
    #define CHILD_ID_TEMP_BASE 2
    
    // Initialize messages
    MyMessage msg_m(CHILD_ID_MOTION, V_TRIPPED);
    MyMessage msg_l(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
    MyMessage msg_t(CHILD_ID_TEMP_BASE,V_TEMP);
    
    void before()
    {
      // Startup up the OneWire library
      tempSensors.begin();
    }
    
    void setup()
    {
      pinMode(DIGITAL_MOTION_SENSOR, INPUT);      // sets the motion sensor digital pin as input
      // requestTemperatures() will not block current thread
      tempSensors.setWaitForConversion(false);
    }
    
    void presentation()
    {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("Composite Sensor", "1.0");
      // Fetch the number of attached temperature sensors  
      numTempSensors = tempSensors.getDeviceCount();
      // Present all temperature sensors to controller
      for (int i=0; i<numTempSensors && i<MAX_ATTACHED_DS18B20; i++) {   
        present(i + CHILD_ID_TEMP_BASE, S_TEMP);
      }
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_MOTION, S_MOTION);
      present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
    }
    
    void loop()
    {
      int ldrRawData;
      float ldrResistance;
      int16_t ldrLux;
    
      // Read digital motion value
      bool tripped = digitalRead(DIGITAL_MOTION_SENSOR) == HIGH;
    
      Serial.println(tripped);
      send(msg_m.set(tripped?"1":"0"));  // Send tripped value to gw
    
      // Read analog LDR value
      ldrRawData = analogRead(LIGHT_SENSOR_ANALOG_PIN);
      // convert ldrReading to LDR resistance
      ldrResistance = (float)(MAX_ADC_READING-ldrRawData) / ldrRawData * REF_RESISTANCE;
      // LDR_LUX
      ldrLux = LUX_CALC_SCALAR * pow(ldrResistance, LUX_CALC_EXPONENT);
    
      Serial.println(ldrLux);
      if (ldrLux != lastLightLevel) {
        send(msg_l.set(ldrLux));
        lastLightLevel = ldrLux;
      }
    
      tempSensors.requestTemperatures();
      // query conversion time and sleep until conversion completed
      int16_t conversionTime = tempSensors.millisToWaitForConversion(tempSensors.getResolution());
      // sleep() call can be replaced by wait() call if node need to process incoming messages (or if node is repeater)
      wait(conversionTime);
      // Read temperatures and send them to controller 
      for (int i=0; i<numTempSensors && i<MAX_ATTACHED_DS18B20; i++) {
    
        // Fetch and round temperature to one decimal
        float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?tempSensors.getTempCByIndex(i):tempSensors.getTempFByIndex(i)) * 10.)) / 10.;
    
        Serial.print("Temperature: ");
        Serial.println(temperature);
        // Only send data if temperature has changed and no error
        #if COMPARE_TEMP == 1
        if (lastTemperature[i] != temperature && temperature != -127.00 && temperature != 85.00) {
        #else
        if (temperature != -127.00 && temperature != 85.00) {
        #endif
    
          // Send in the new temperature
          send(msg_t.setSensor(i + CHILD_ID_TEMP_BASE).set(temperature,1));
          // Save new temperatures for next compare
          lastTemperature[i]=temperature;
        }
      }
    
        // Sleep until interrupt comes in on motion sensor. Send update every two minute.
        sleep(digitalPinToInterrupt(DIGITAL_MOTION_SENSOR), CHANGE, SLEEP_TIME);
    }
    


  • Now I uploaded a simple Blink sketch, which is a modified version adding wdt_reset(). The reason I added wdt_reset() is if I don't, the node will just reboot by itself.

    Still I'm having trouble have MYScontroller to reboot the node remotely.

    Here is the sketch of my Blink.

    #include <avr/wdt.h>
    
    // the setup function runs once when you press reset or power the board
    void setup() {
      // initialize digital pin LED_BUILTIN as an output.
      pinMode(LED_BUILTIN, OUTPUT);
      wdt_disable();
      wdt_enable(WDTO_4S);
    }
    
    // the loop function runs over and over again forever
    void loop() {
      digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
      delay(1000);                       // wait for a second
      digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
      delay(1000);                       // wait for a second
      wdt_reset();
    }
    
    

    Any idea why the node won't reboot?


  • Mod

    @mythbai when sleeping, the radio is off so the node will not notice any incoming messages.
    Delay will block all processing on the node, including processing of incoming messages. So when in delay(), the node will not notice incoming messages.

    Documentation: https://www.mysensors.org/download/sensor_api_20#waiting
    https://www.mysensors.org/download/sensor_api_20#sleeping

    Depending on your use case, smartsleep might be what you need.



  • @mfalkvidd You're absolutely right! smartsleep() still won't make it reboot though. But I finally made it working.

    The "OTA wireless programming" tutorial and default sample firmware "Blink" doesn't allow the node to be rebootable. I added MySensors.h into the Blink sketch and defined basic configuration made the node rebootable. Loaded up some other basic MySensor sample node also works as long as I'm not using sleep().

    I originally thought the MYSBootloader will not be impacted by the firmware itself. I guess I'm wrong. It seems reboot function is post bootup and will rely on the loaded firmware to intepret the I_REBOOT command which is in the Mysensors library.

    I'm very new to the arduino programming and Mysensors, so please pardon my ignorance. Anyway, I'm very happy this forum gave me some momentum to move forward!


 

188
Online

8.7k
Users

9.5k
Topics

99.9k
Posts