User sketch not starting at power up

Discussion about Z-Uno product. Visit http://z-uno.z-wave.me for more details.
Post Reply
ncolomer
Posts: 2
Joined: 13 Sep 2019 00:25

User sketch not starting at power up

Post by ncolomer »

Hi there,

When I power up my z-uno board, it looks my sketch doesn't automatically start.
The Z-Wave layer appears to boot though: operation green led lights up and one of the following messages are received from controller:

Code: Select all

[2019-10-20 10:54:16.712] [D] [zway1] RECEIVED: ( 01 09 00 04 00 0E 03 80 03 FF 83 )
[2019-10-20 10:54:16.712] [D] [zway1] SENT ACK
[2019-10-20 10:54:16.713] [D] [zway1] SETDATA devices.14.data.lastReceived = 0 (0x00000000)
[2019-10-20 10:54:16.713] [D] [zway1] SETDATA devices.14.instances.0.commandClasses.128.data.history.0 = Empty
[2019-10-20 10:54:16.714] [D] [zway1] SETDATA devices.14.instances.0.commandClasses.128.data.history.0 = 1571561656 (0x5dac20b8)
[2019-10-20 10:54:16.714] [D] [zway1] SETDATA devices.14.instances.0.commandClasses.128.data.last = 0 (0x00000000)
[2019-10-20 10:54:16.873] [I] [core] Notification: warning (battery): Attention! Device is low battery >:> Z-Wave.Me Battery (#14)

[2019-10-20 10:55:35.661] [D] [zway1] RECEIVED: ( 01 09 00 04 00 0E 03 80 03 FF 83 )
[2019-10-20 10:55:35.662] [D] [zway1] SENT ACK
[2019-10-20 10:55:35.662] [D] [zway1] SETDATA devices.14.data.lastReceived = 0 (0x00000000)
[2019-10-20 10:55:35.663] [D] [zway1] SETDATA devices.14.instances.0.commandClasses.128.data.history.0 = 1571561735 (0x5dac2107)
[2019-10-20 10:55:35.663] [D] [zway1] SETDATA devices.14.instances.0.commandClasses.128.data.last = 0 (0x00000000)

[2019-10-20 10:56:37.756] [D] [zway1] RECEIVED: ( 01 09 00 04 00 0E 03 80 03 64 18 )
[2019-10-20 10:56:37.756] [D] [zway1] SENT ACK
[2019-10-20 10:56:37.757] [D] [zway1] SETDATA devices.14.data.lastReceived = 0 (0x00000000)
[2019-10-20 10:56:37.757] [D] [zway1] SETDATA devices.14.instances.0.commandClasses.128.data.lastChange = 1571561797 (0x5dac2145)
[2019-10-20 10:56:37.757] [D] [zway1] SETDATA devices.14.instances.0.commandClasses.128.data.history = Empty
[2019-10-20 10:56:37.758] [D] [zway1] SETDATA devices.14.instances.0.commandClasses.128.data.history.100 = Empty
[2019-10-20 10:56:37.758] [D] [zway1] SETDATA devices.14.instances.0.commandClasses.128.data.history.100 = 1571561797 (0x5dac2145)
[2019-10-20 10:56:37.758] [D] [zway1] SETDATA devices.14.instances.0.commandClasses.128.data.last = 100 (0x00000064)
I expect my sketch to blink the user led every 10s and the consumption to be <1mA most of the time because I enabled FLiRS.
But the board consumption stays at ~60mA and nothing happen.

However, it appears the node is responsive to incoming messages, because it answers to requests.

To actually start my sketch, I have no choice to force a message to the node (eg. get parameter or get battery).

Code: Select all

[2019-10-20 10:57:49.430] [I] [zway1] Adding job: Configuration Get
[2019-10-20 10:57:49.437] [D] [zway1] SENDING (cb 0x33): ( 01 0A 00 13 0E 03 70 05 40 05 33 E8 )
[2019-10-20 10:57:49.438] [D] [zway1] RECEIVED ACK
[2019-10-20 10:57:49.447] [D] [zway1] RECEIVED: ( 01 04 01 13 01 E8 )
[2019-10-20 10:57:49.447] [D] [zway1] SENT ACK
[2019-10-20 10:57:49.447] [D] [zway1] Delivered to Z-Wave stack
[2019-10-20 10:57:54.250] [D] [zway1] RECEIVED: ( 01 07 00 13 33 00 01 E1 38 )
[2019-10-20 10:57:54.250] [D] [zway1] SENT ACK
[2019-10-20 10:57:54.250] [I] [zway1] Job 0x13 (Configuration Get): Delivered
[2019-10-20 10:57:54.251] [D] [zway1] SendData Response with callback 0x33 received: received by recipient
[2019-10-20 10:57:54.251] [D] [zway1] SETDATA devices.14.data.lastSendInternal = **********
[2019-10-20 10:57:54.251] [D] [zway1] SETDATA devices.14.data.lastSend = 116522420 (0x06f1fdb4)
[2019-10-20 10:57:54.251] [D] [zway1] Job 0x13 (Configuration Get): success
[2019-10-20 10:57:54.251] [I] [zway1] Waiting for job reply: Configuration Get
[2019-10-20 10:57:54.265] [D] [zway1] RECEIVED: ( 01 0C 00 04 00 0E 06 70 06 40 02 01 2C E6 )
[2019-10-20 10:57:54.265] [D] [zway1] SENT ACK
[2019-10-20 10:57:54.266] [D] [zway1] SETDATA devices.14.data.lastReceived = 0 (0x00000000)
[2019-10-20 10:57:54.266] [D] [zway1] Received reply on job (Configuration Get)
[2019-10-20 10:57:54.266] [D] [zway1] SETDATA devices.14.instances.0.commandClasses.112.data.64.size = 2 (0x00000002)
[2019-10-20 10:57:54.266] [D] [zway1] SETDATA devices.14.instances.0.commandClasses.112.data.64.val = 300 (0x0000012c)
[2019-10-20 10:57:54.266] [D] [zway1] SETDATA devices.14.instances.0.commandClasses.112.data.64 = Empty
[2019-10-20 10:57:54.266] [I] [zway1] Node 14:0 CC Configuration: Parameter 0x40 = 300 (size = 2)
[2019-10-20 10:57:56.367] [D] [zway1] Job 0x13: deleted from queue
As soon as a message is received, the user led blinks and current consumption drops, showing my sketch has started as expected.

Note that the wake up service button (three times press) does nothing, neither a press on the reset button.

I attached my sketch to the thread.
Attachments
sketch_oct06b.zip
zipped sketch
(1.98 KiB) Downloaded 236 times
p0lyg0n1
Posts: 242
Joined: 04 Aug 2016 07:14

Re: User sketch not starting at power up

Post by p0lyg0n1 »

Hi,
I have tried your sketch. For me it works right. You have to add some delay to see the white led is blinking. I have found some things that make work of the sketch unstable or they lead to some unpredictable behavior:
1. It's a bad idea to use Serial for debugging purposes, cause it uses full speed USB stack and needs time to boot. Use Serial0/Serial1 instead of it. In this case you need an adapter (USB2UART), but it gives you right messages and stable connection to your device. Serial is only for non sleeping devices.
2. Don't use type float. Z-Uno has no hardware float point support, that means floating point operations occupies large amount of stack and CPU time. Use fix point math instead of it(int/dword/word and right order of operations).
3. Make all handlers as short as possible. Make all complex calculations in the loop() function and save their results for further use. You used this approach for humidity/temperature values already. Use the same one for battery value.
Thank you for your sketch it quite difficult to dig in it :) I have some fun )
Try my "simplified" variation of it, to check that loop() is able to work on FLIRS without forcing the request:

Code: Select all

#include "ZUNO_DHT.h"
#include "EEPROM.h"

#define TEMPERATURE_CHANNEL 1
#define HUMIDITY_CHANNEL 2
ZUNO_SETUP_CHANNELS(
  ZUNO_SENSOR_MULTILEVEL(
    ZUNO_SENSOR_MULTILEVEL_TYPE_TEMPERATURE, 
    SENSOR_MULTILEVEL_SCALE_CELSIUS, 
    SENSOR_MULTILEVEL_SIZE_TWO_BYTES, 
    SENSOR_MULTILEVEL_PRECISION_ONE_DECIMAL, 
    getTemperature
  ),
  ZUNO_SENSOR_MULTILEVEL(
    ZUNO_SENSOR_MULTILEVEL_TYPE_RELATIVE_HUMIDITY, 
    SENSOR_MULTILEVEL_SCALE_PERCENTAGE_VALUE, 
    SENSOR_MULTILEVEL_SIZE_TWO_BYTES, 
    SENSOR_MULTILEVEL_PRECISION_ONE_DECIMAL, 
    getHumidity
  )
);

ZUNO_SETUP_ASSOCIATIONS(
  ZUNO_ASSOCIATION_GROUP_SET_VALUE
);

ZUNO_SETUP_SLEEPING_MODE(ZUNO_SLEEPING_MODE_FREQUENTLY_AWAKE);

ZUNO_SETUP_CFGPARAMETER_HANDLER(configHandler);

ZUNO_SETUP_BATTERY_HANDLER(batteryHandler);

#define ZWAVE_CONFIG_DEFAULT 96
#define ZWAVE_CONFIG_WAKEUP_INTERVAL 64 // wakeup interval in seconds
#define ZWAVE_CONFIG_TEMPERATURE_RESOLUTION 65 // temperature resolution in 1/10 of celsius degre, only report when value change
#define ZWAVE_CONFIG_HUMIDITY_RESOLUTION 66 // temperature resolution in 1/10 of percent unit, only report when value change
struct ConfigStruct {
  uint16_t wakeupInterval;
  float temperatureResolution;
  float humidityResolution;
};
ConfigStruct config = {10, 0.5, 1.0};

struct ReadingsStruct {
  float temperature;
  float humidity;
};
ReadingsStruct readings;

DHT dht22(11, DHT22);
byte n;

#define MAGIC_BYTE 42
#define CAN_PRECISION_BITS 8
#define VCC_VOLTAGE 3.3 // 3.1 from internal regulator, 3.3 from booster
#define MAX_BATTERY_VOLTAGE 3.0

#define LED_PIN LED_BUILTIN
#define BAT_PIN A3 // A3 ADC3 11
//#define DEBUG

#ifdef DEBUG
  #define debug(...) {__VA_ARGS__}
#else
  #define debug(...)
#endif

void setup() {
  // Setup Z-Uno pins
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);

  pinMode(BAT_PIN, INPUT); 
  analogReadResolution(CAN_PRECISION_BITS);
  analogReference(ADC_HIGH_VCC | ADC_LOW_GND);

  // Setup logging
  debug(Serial.begin(115200);)

  // Load configuration
  if (zunoLoadCFGParam(ZWAVE_CONFIG_DEFAULT) == MAGIC_BYTE) {
    config.wakeupInterval = zunoLoadCFGParam(ZWAVE_CONFIG_WAKEUP_INTERVAL);
    config.temperatureResolution = zunoLoadCFGParam(ZWAVE_CONFIG_TEMPERATURE_RESOLUTION) / 10.0;
    config.humidityResolution = zunoLoadCFGParam(ZWAVE_CONFIG_HUMIDITY_RESOLUTION) / 10.0;
  } else {
    zunoSaveCFGParam(ZWAVE_CONFIG_WAKEUP_INTERVAL, config.wakeupInterval);
    zunoSaveCFGParam(ZWAVE_CONFIG_TEMPERATURE_RESOLUTION, config.temperatureResolution * 10);
    zunoSaveCFGParam(ZWAVE_CONFIG_HUMIDITY_RESOLUTION, config.humidityResolution * 10);
    zunoSaveCFGParam(ZWAVE_CONFIG_DEFAULT, MAGIC_BYTE);
  }
  
  // Initialize DHT22 library
  dht22.begin();
  srand(analogRead(A0));
}

float roundToResolution(float value, float resolution) {
  return round(value / resolution) * resolution;
}

void loadReadings() {
  NZRAM.get(0x0, &n, 1);
  if (n == MAGIC_BYTE) {
    debug(Serial.println("Found previous readings, loading...");)
    NZRAM.get(0x1, &readings, sizeof(readings));
  }
}

void saveReadings() {
  NZRAM.put(0x1, &readings, sizeof(readings));
  n = MAGIC_BYTE;
  NZRAM.put(0x0, &n, 1);
}

void loop() {

  debug(Serial.print("Sketch is starting... (wake up reason: "); Serial.print(zunoGetWakeReason(), DEC); Serial.println(")");)
  
  digitalWrite(LED_PIN, HIGH);
  readings.temperature = 1.25f*(rand()%30);
  readings.humidity = 0.75f*(rand()%100);
  zunoSendReport(TEMPERATURE_CHANNEL);
  zunoSendReport(HUMIDITY_CHANNEL);
  saveReadings();
  delay(100);
  /*
  dht22.read(true);
  float temperature = roundToResolution(dht22.readTemperature(), config.temperatureResolution);
  float humidity = roundToResolution(dht22.readHumidity(), config.humidityResolution);

  debug(Serial.println("---"); Serial.print("Millis: "); Serial.print(millis()); Serial.println("ms");)

  loadReadings();
  
  // Compare and publish temperature
  debug(Serial.print("Temperature: "); Serial.print(temperature); Serial.println("°C");)
  if (temperature != readings.temperature) {
    readings.temperature = temperature;
    debug(Serial.println(" -> reporting value");)
    zunoSendReport(TEMPERATURE_CHANNEL);
    zunoSendToGroupSetValueCommand(CTRL_GROUP_1, temperature);  
  }

  // Compare and publish humidity
  debug(Serial.print("Humidity: "); Serial.print(humidity); Serial.println("%");)
  if (humidity != readings.humidity) {
    readings.humidity = humidity;
    debug(Serial.println(" -> reporting value");)
    zunoSendReport(HUMIDITY_CHANNEL);
  }

  saveReadings();*/

  digitalWrite(LED_PIN, LOW);
  
  zunoSetBeamCountWU(config.wakeupInterval);
  zunoSendDeviceToSleep();
}

word getTemperature(void) {
  loadReadings();
  return readings.temperature * 10;
}

word getHumidity(void) {
  loadReadings();
  return readings.humidity * 10;
}

void configHandler(byte param, word value) {
  switch(param) {
    case ZWAVE_CONFIG_WAKEUP_INTERVAL:
      config.wakeupInterval = value;
      break;
    case ZWAVE_CONFIG_TEMPERATURE_RESOLUTION:
      config.temperatureResolution = value / 10.0;
      break;
    case ZWAVE_CONFIG_HUMIDITY_RESOLUTION:
      config.humidityResolution = value / 10.0;
      break;
  }
}

byte batteryHandler() {
  // Constants
  const unsigned int CAN_RESOLUTION = pow(2, CAN_PRECISION_BITS);
  const unsigned int MAX_VALUE = CAN_RESOLUTION * MAX_BATTERY_VOLTAGE / VCC_VOLTAGE;
  // Measurement
  unsigned int value = 0;
  for (byte i = 0; i < 10; i++)
    value += analogRead(BAT_PIN);
  value /= 10;
  // Calculation
  float voltage = (float)value * VCC_VOLTAGE / CAN_RESOLUTION;
  byte percentage = constrain(map(value, 0, MAX_VALUE, 0, 100), 0, 100);
  debug(Serial.print("Battery: "); Serial.print(voltage); Serial.print("V"); Serial.print(" ("); Serial.print(percentage); Serial.println("%)");)
  return percentage;
}
Good luck.
Yours,
Alex.
ncolomer
Posts: 2
Joined: 13 Sep 2019 00:25

Re: User sketch not starting at power up

Post by ncolomer »

Wow, thanks for your detailed answer Alex!
p0lyg0n1 wrote:
21 Oct 2019 15:36
1. It's a bad idea to use Serial for debugging purposes, cause it uses full speed USB stack and needs time to boot. Use Serial0/Serial1 instead of it. In this case you need an adapter (USB2UART), but it gives you right messages and stable connection to your device. Serial is only for non sleeping devices.
Your advice makes me ask myself the following questions:
- Do you mean that using Serial0/Serial1 is a better way to debug?
- Do you think I can ship my Serial0/Serial1 "logs" in my "production" code, and just plug my adapter I want to debug?
- Do you know if I can just connect Ground + RX/TX, leaving VCC unconnected? so that I would be able to hook the Z-Uno while it is operating using a different power source.
- Does the Z-Uno in sleep/flirs mode will prevent from connecting to Serial0/Serial1?

I'm asking all those questions because debugging/uploading sketch using USB is convenient, it allows me to iterate quickly...
Anyway, I have some spare USB2UART adapters in stock, I'll give them a try.

p0lyg0n1 wrote:
21 Oct 2019 15:36
2. Don't use type float. Z-Uno has no hardware float point support, that means floating point operations occupies large amount of stack and CPU time. Use fix point math instead of it(int/dword/word and right order of operations).
Ok thanks for this information. float is really a handy type, especially when dealing with some basic decimal calculus. Relying on fixed point maths will make the implementation more complexe (I'm not used to). Sad there is no note about that in the float reference documentation.

p0lyg0n1 wrote:
21 Oct 2019 15:36
3. Make all handlers as short as possible. Make all complex calculations in the loop() function and save their results for further use. You used this approach for humidity/temperature values already. Use the same one for battery value.
Very useful feedback, thanks!

p0lyg0n1 wrote:
21 Oct 2019 15:36
Thank you for your sketch it quite difficult to dig in it :) I have some fun )
I had some fun writing it too ;-) Actually, this is the best experience I had coding on open home automation boards (I tried MySensors, Moteino and plain nRF24). Documentation is really good quality and Z-Uno helpers are really explicit and convenient to use! Integration with Z-Way is also really great.

Nicolas
Post Reply