Z-UNO blocked after several hours of operation

Discussion about Z-Uno product. Visit http://z-uno.z-wave.me for more details.
schmidmi
Posts: 55
Joined: 01 Dec 2016 16:45
Location: Germany (Karlsruhe)

Re: Z-UNO blocked after several hours of operation

Post by schmidmi »

I made some investigations during the WE. The problem is caused by using the ZUNO_OLED_I2C library.
If I don't use it, everything is working very well.
In my device I want to display the temperature on a local OLED-display like shown in the ZUNO examples. This works, but a some hours the Z-UNO is blocked.
So I made some changes in my sketch, to reproduce the error. For that, I don't use the DS18B20 but increment a variable in the loop and display that value on the OLED Display. With that the device will block after a few minutes.
I the first step I thought, it may be a memory leak somewhere. But with my my test procedure I saw that there is not a specific amount of cycles when the device stops. So there is something else going wrong. What I saw, is that the blinking of the green LED seems to be interrupted sometimes.. That means it is flickering a little bit from time to time. May be there are concurrent processes running on the device?
Nevertheless here the the sketch I used for testing.
Remark: I didn't test, if the problem will be solved by excluding the device from my HC 2.

Code: Select all

// Z-UNO used to connect a Mitsubishi A/C controller to Fibaro HC 2
// It provides the actual temperature and an ON/OFF switch.
// The device can be operated via HC 2 or with a local push button.
// Due to the small amount of ram, it was not possible to implement a connection to 
// the A/C controller via IR within this device.
// So the task of sending the 288 Bit IR codes is done by an additional Arduino device.
// The Z-UNO provides an binary output to talk to the Arduino.
// September 2017
// by Michael Schmidt

#include <ZUNO_DS18B20.h>
#include <ZUNO_OLED_I2C.h>
#include <EEPROM.h>


// pin connection ds18b20
#define PIN_DS18B20 11

// Shows the state of the device
#define LED_PIN 13

// Output to control the Arduino
#define ControlPin 6

// Input for the local On/Off button
#define SWITCH_LOCAL 18

// local push button handled with ISR
ZUNO_SETUP_ISR_INT0(int0_handler);

OneWire ow(PIN_DS18B20);

// local Display for temperature an state
OLED oled;
// onewire connection temperature sensors
DS18B20Sensor ds1820(&ow); 

byte addr1[8];
int temp = 0;           // here we will store the actual temperature
int lastTemp = 0;           // temperature during the last scan cycle
byte currentLEDValue;   // Last saved LED value
float temperature;

// set up channel
ZUNO_SETUP_CHANNELS(
   ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_TEMPERATURE, 
                          SENSOR_MULTILEVEL_SCALE_CELSIUS, 
                          SENSOR_MULTILEVEL_SIZE_TWO_BYTES, 
                          SENSOR_MULTILEVEL_PRECISION_TWO_DECIMALS,
                          getterTemp),
   ZUNO_SWITCH_BINARY(getSWBin,setSWBIN)
);

void setup() {

    pinMode(LED_PIN, OUTPUT);
    pinMode(SWITCH_LOCAL,INPUT_PULLUP);
    zunoExtIntMode(ZUNO_EXT_INT0, FALLING);

    pinMode(ControlPin, OUTPUT); 
    digitalWrite(ControlPin, LOW); 
  
    oled.begin();
    oled.clrscr();
      

    // Get the last state before shut down
    EEPROM.get(0,&currentLEDValue,1);
    
    setSWBIN(currentLEDValue);
    oled.gotoXY(0,5);
    oled.print("Status    : ");
    if (currentLEDValue == 0)
    {
      oled.print("Aus");
    }
    else
    {
      oled.print("Ein");
    }
    oled.gotoXY(0,2);
    oled.print("Temperatur:       *C");
}

void loop() {
//    ds1820.scanAloneSensor(addr1);
//    // obtaining readings from the sensor ds18b20
//    temperature = ds1820.getTemperature(addr1);
//    // make scaled word value for report
//    temp=int((temperature*100));
     temperature += 0.01;
     temp=int(temperature);
    // send data to channel
    // data will be send in case of a change of value only
    //if (abs(temp - lastTemp) >= 5)
    if (abs(temp - lastTemp) >= 0)
    {
      //zunoSendReport(1);
      lastTemp = temp; // store the actual value for the next compare

      oled.gotoXY(72,2);
      oled.print(temperature);
      zunoSendReport(1);
    }
    delay(10000);
//  delay(60000);
}

// methode to update the state of the device
void setSWBIN(byte value) {
  // value is a variable, holding a "new value"
  // which came from the controller or other Z-Wave device
  if (value > 0) {               // if greater then zero
    digitalWrite (LED_PIN, HIGH); //turn the LED on (HIGH is the voltage level)
  } else {                         // if equals zero
    digitalWrite(LED_PIN, LOW);   //turn the LED off by making the voltage LOW
  }
  // we'll save our value for the situation, when the controller will ask us about it
  if (currentLEDValue != value)
  {
    currentLEDValue = value;

    // Store the actual state in EEProm
    EEPROM.put(0,&currentLEDValue,1);

    // Update HC 2
    zunoSendReport(2);

    // Update local display
    oled.gotoXY(0,5);
    oled.print("Status    : ");
    
    if (currentLEDValue == 0)
    {
      oled.print("Aus");
    }
    else
    {
      oled.print("Ein");
    }
  }
  
}

// Interrupt handler to read the local switch
void int0_handler()
{
  if (currentLEDValue == 0)
  {
    setSWBIN(255);
  }
  else
  {
    setSWBIN(0);
  }
  
}

// Binary value read by HC2
byte getSWBin() {
  return currentLEDValue;
}

// Temperature read by HC2
word getterTemp() {
    return temp;
}



petergebruers
Posts: 255
Joined: 26 Jul 2015 17:29

Re: Z-UNO blocked after several hours of operation

Post by petergebruers »

I fully agree with what you are saying. I noticed the faint flickering of the green LED too. I will try to write a minimal sketch that only writes to the oled.

I noticed my Z-Uno crashed, so increasing the loop speed and oled printing has the same effect as your sketch... Keep digging!
petergebruers
Posts: 255
Joined: 26 Jul 2015 17:29

Re: Z-UNO blocked after several hours of operation

Post by petergebruers »

I am running this sketch right now, I want to share it so you do not have to run the same test as me. I do not see any flickering. I wonder if it makes a difference if you put zunoSendReport after the oled update... My minimalistic sketch does not have zunoSendReport right now, I'll add it if this test does not crash.

Code: Select all

// OLED test by petergebruers, based on DS18B20 sketch
// by Michael Schmidt

#include <ZUNO_DS18B20.h>
#include <ZUNO_OLED_I2C.h>
#include <EEPROM.h>
OLED oled;

// set up channel
ZUNO_SETUP_CHANNELS(
  ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_TEMPERATURE,
                         SENSOR_MULTILEVEL_SCALE_CELSIUS,
                         SENSOR_MULTILEVEL_SIZE_TWO_BYTES,
                         SENSOR_MULTILEVEL_PRECISION_TWO_DECIMALS,
                         getterTemp),
  ZUNO_SWITCH_BINARY(getSWBin, setSWBIN)
);

void setup() {
  oled.begin();
  oled.clrscr();
}

float counter;
void loop() {
  if (counter >= 99) counter = 0;
  else
    counter += 0.99;
  oled.gotoXY(0, 2);
  oled.print("Temperatur: ");
  oled.print(counter);
  oled.print(" C");
  delay(1000);
}
byte getSWBin() {
  return 0;
}

void setSWBIN(byte value) {}
word getterTemp() {
  return 0;
}
schmidmi
Posts: 55
Joined: 01 Dec 2016 16:45
Location: Germany (Karlsruhe)

Re: Z-UNO blocked after several hours of operation

Post by schmidmi »

I made some further tests with the sketch.
I saw, that sometimes, when the device is blocked, also the white LED ist switched ON (#define LED_PIN 13).
From my point of view it looks like a problem in the stack.

@petergebruers:
I had the same idea with changing the position of the zunoSendReport(). But it doesn't make any change in the behaviour :cry:
petergebruers
Posts: 255
Joined: 26 Jul 2015 17:29

Re: Z-UNO blocked after several hours of operation

Post by petergebruers »

Thanks, your information is helpful. Together we will solve this mistery! ;-)

I think I have made some progress. I reduced the code and now it crashes randomly in less than 1 minute. Tell me what you think...

Code: Select all

// OLED test by petergebruers, based on DS18B20 sketch
// by Michael Schmidt

#include <ZUNO_DS18B20.h>
#include <ZUNO_OLED_I2C.h>
#include <EEPROM.h>
OLED oled;

// set up channel
ZUNO_SETUP_CHANNELS(
  ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_TEMPERATURE,
                         SENSOR_MULTILEVEL_SCALE_CELSIUS,
                         SENSOR_MULTILEVEL_SIZE_TWO_BYTES,
                         SENSOR_MULTILEVEL_PRECISION_TWO_DECIMALS,
                         getterTemp),
  ZUNO_SWITCH_BINARY(getSWBin, setSWBIN)
);

void setup() {
  oled.begin();
  oled.clrscr();
}

float counter;

void loop() {
  if (counter >= 99) counter = 0;
  else
    counter += 1;
  oled.gotoXY(0, 2);
  oled.print(counter);
}
byte getSWBin() {
  return 0;
}
void setSWBIN(byte value) {}
word getterTemp() {
  return int(counter);
}
petergebruers
Posts: 255
Joined: 26 Jul 2015 17:29

Re: Z-UNO blocked after several hours of operation

Post by petergebruers »

New observation: if you convert to int, the sketch does not crash. But I only let it run for one minute, the test time is a bit short

oled.print(int(counter));

conversion to long and doing math does not crash it within one minute either:

oled.print(long(counter*1000));

But printing a float with 0 precision crashes it in a few seconds:

oled.print(counter,0);

EDIT: I am going to let it rest for a few hours. I need to think... While I do that, I'll let the oled.print(int(counter)); version run...
schmidmi
Posts: 55
Joined: 01 Dec 2016 16:45
Location: Germany (Karlsruhe)

Re: Z-UNO blocked after several hours of operation

Post by schmidmi »

Converting the value to an int may be helpful tp províde a stable sketch. But the output on the display would not be as it should be ;)
petergebruers
Posts: 255
Joined: 26 Jul 2015 17:29

Re: Z-UNO blocked after several hours of operation

Post by petergebruers »

I agree... I have been delving in the source code of the Wire, ZUNO_OneWire and ZUNO_OLED_I2C libraries and lst files and it has not become any clearer to me. :? I'll try again later. Maybe it is a stack issue like you said and in that case it might be worth waiting for firmware 2.1.1 because that will improve stack space.
p0lyg0n1
Posts: 242
Joined: 04 Aug 2016 07:14

Re: Z-UNO blocked after several hours of operation

Post by p0lyg0n1 »

Hi )
The main reason is stack. OLED uses Print object as parrent, so for print purposes we have to go really deep in stack and if get an interrupt (Timer/Radio) at this moment it overflows the stack. I try to check this. Looks like it's time to reconstruct Print.cpp... and turn off interrupts when write method of OLED is used.
petergebruers
Posts: 255
Joined: 26 Jul 2015 17:29

Re: Z-UNO blocked after several hours of operation

Post by petergebruers »

Thank you for confirming our suspicion. As user schmidmi pointed out, he has "worked around the problem" and this is his topic, but I am still interested in one more thing... As you say, disabling interrupts might fix the issue... I wonder, what is the impact on the operation of the Z-Uno. For instance, will Z-Uno queue radio events? If so... what would be an acceptable period to disable interrupts? Maybe 0.5 seconds? I am thinking out loud: if it takes too long, the controller will not be happy and will start sending retries to the Z-Uno... Am I right?
Post Reply