New 2.1.5 beta

Discussion about Z-Uno product. Visit http://z-uno.z-wave.me for more details.
User avatar
PoltoS
Posts: 7562
Joined: 26 Jan 2011 19:36

New 2.1.5 beta

Post by PoltoS »

We are happy to make public the new beta of the Z-Uno software!

This build introduces a lot of changes, new cool features and fixes.

You can get it from our test repo: https://z-uno.z-wave.me/files/z-uno/tes ... index.json. For more infor check https://z-uno.z-wave.me/install

This beta will become 2.1.5 release soon.

What's new:

New features and changes
  • New style of channels mapped to a variable directly - very easy to use. Old syntax with getter/setter is working too for more flexible handling
  • Fast pins can be used on other pins than 9-16
  • New format of dynamic channels - much more flexible
  • New channel mapping to channel 0
  • System events are now reported to the sketch too - you can handle inclusion start/stop, firmware update start, system faults
  • New system 10ms timer
  • Easier handlers of external reports predefined for most cases
  • Configuration parameters interface changed a bit to use less space and be easier to use
  • New thermostat modes
  • Possibility to change Product Type Id and Prodyuct Id
  • Autoinclusion (NWI) added - Z-Uno will automatically include on power on if not in network (mains powered only)
  • Bootloader upgrade do not reset the frequency to default
  • S0 Security mode set via Z-Wave
  • You can now select which S2 security level to use: Unauthenticated, Authenticated or Access
  • You can now write to the EEPROM/NVM using USB - easy way to pre-load some specific data to the EEPROM to be used in the sketch (like fonts for the e-ink screen or some conversion table
  • Most of Z-Wave Command Classes available for the user moved into user code space to free more space - you can even contribute to them via GitHub
  • New ZUNO_Buttons library for easier buttons handling
  • New ZUNO_LCD library to work with LCDs
  • New ZUNO_Stepper library for step motors
  • New ZUNO_IAQCore library for air quality sensors
Enhencements:
  • Z-Uno boots from INT1 2.5 times faster: 57 ms from interrupt to enter in setup()
  • Bootloader/sketch upload via USB is now faster
  • Rescue mode is not shown as red LED blink instead of green
  • Maximum size of user code in S2 mode rised up to 12 kB
Fixes:
  • Fixed send queue filling problem with too many reports
  • Wrong Wakeup report fixed
  • Fixed Z-Wave Plus Info for FLiRS
  • Fixed wakeups in FLiRS mode and sleeps on low INT1
  • Fixed speed of SoftwareSerial, OneWire, DHT when USB is connected
  • Fixed Thermostat unsolicited report
  • Fixed OTA confirmation with param #20
  • Fixed negative temperature in ZUNO_DHT
  • Fixed memory overflow in ZUNO_DS18B20 autodetect on number of sensors greater than defined in the library
  • Fixed zunoFastPWMSet
And now details and examples:

New style of channels mapped to a variable directly
In addition to the getter/setter concept you can now use direct mapping of channel values to a variable. This simplifies the code and is much better in most cases (this is not working for thermostats and switchcolor)

Have a look on the following example with SwitchMultilevel:
Getter/setter concept:

Code: Select all

byte dimmerValue = 100;
ZUNO_SETUP_CHANNELS(ZUNO_SWITCH_MULTILEVEL(getSwitchMultilevelValue, setSwitchMultilevelValue));

...

void setSwitchMultilevelValue(byte newValue) {
  dimmerValue = newValue;
}

byte getSwitchMultilevelValue(void) {
  return dimmerValue;
}  
Direct mapping concept:

Code: Select all

ZUNO_SETUP_CHANNELS(ZUNO_SWITCH_MULTILEVEL(dimmerValue, NULL));
byte dimmerValue = 100;

...
Detect channel change
With the new direct mapping concept you can detect new value set using function zunoIsChannelUpdated(CH_NUM) that returns True if new value was set via Z-Wave.

For the example above:

Code: Select all

void loop() {
  if (zunoIsChannelUpdated(1)) {
    // Do something on new value received via Z-WAve
  }
}
Macro ZUNO_ENABLE(LIST), ZUNO_DISABLE(LIST)
Those allows to either remove some features from the sketch or add them for dynamic channels.

For dynamic channels you need to define every user Command Class that might be used.

Other common cases:
  • For a binary sensor you can suppress SensorBinary or Notification using ZUNO_DISABLE(WITH_CC_SENSOR_BINARY). By default both are in.
  • Any user macro that is used in the library (for debugging):
    example 1: ZUNO_ENABLE(MY_LIBRARY_DEBUG);
    example 2: ZUNO_ENABLE(MY_LIBRARY_DEBUG MY_LIBRARY_DEBUG_LEVEL=1);
  • System log to SerialL ZUNO_ENABLE(LOGGING_EVENTS LOGGING_UART=Serial);
  • Disable Service LEDs: ZUNO_DISABLE(SERVICE_LEDS); - to save battry and remove unwanted blinks
Fast pins can be used on other pins than 9-16
Macro ZUNO_REMAP_SPINS(portName), where portName:
  • FAST_P0 - (default) pins 9-16, for I2C: SCL=9 SDA=10
  • FAST_P1 - pins 17-23, for I2C: SCL=17 SDA=18
  • FAST_P2 - pins 0-2, for I2C: SCL=0 SDA=2
  • FAST_P3 - pins 3-6, for I2C: SCL=3 SDA=4
New format of dynamic channels - much more flexible
Now you need to define the max number of dynamic channels that can appear in Z-Uno during runtime. Do it with macro ZUNO_DYNAMIC_CHANNELS(NUM_CHANNELS). This will save memory if you don't need all 32

In runtime you can get it in variable g_channels_data.
Values of channels are referred via:
  • for one byte channels like SwitchBinary/SwitchMultilevel/SensorBinary/FlowStop/Siren/Doorlock/Blinds: g_channels_data[CH_NUMBER].bParam
  • for Meter/SensorMultilevel depending on the size of the value in the channel: g_channels_data[CH_NUMBER].bParam, g_channels_data[CH_NUMBER].wParam or g_channels_data[CH_NUMBER].dwParam
  • for SwitchColor: g_channels_data[CH_NUMBER].buffParam[color], color is SWITCH_COLOR_COMPONENT_* constant
  • for Thermostat: g_channels_data[CH_NUMBER].thermoParam.mode, g_channels_data[CH_NUMBER].thermoParam.temperature, i = 0 for Heat, i = 1 for Cool (for Auto, otherwise only [0] is used)


You can check if new value arrived using zunoIsChannelUpdated()

Sources are much more readable now. See our GitHub: https://github.com/Z-Wave-Me/Z-Uno-Test ... annel_2.15

New channel mapping to channel 0
If the channel appears only once, it will not be inside MultiChannel, but rather on the root (channel 0) device only. Additional channels are not created anymore for that case.

In case of more than one channel of the same type channel 0 is mapped to the first (as before).

All SensorMultilevel of different types are aggregated in the one channel. If more than one SensorMultilevel of the same type is defined, a new channel will be created.

This will make mostly non-channeled devices in many cases and simplify Z-Uno representation in most controllers.

System events
In 2.1.4 system events were logged only to the Serial0 or via Z-Wave configuration parameter #48. Now you can also catch them in the code.

  • Inclusion start/stop to notify the user
  • Firmware update start to notify the user
  • Z-Uno boot and go into sleep to make special handling
  • System faults like stack overflow or blocked packets due to the policy to debug

Code: Select all

ZUNO_SETUP_SYSEVENT_HANDLER(sys_event);

void sys_event(byte event, byte param) {
  switch(event) {
    case ZUNO_LOGGING_EVENT_LEARNSTART:
      // … <ACTIONS>
      break;
    case ZUNO_LOGGING_EVENT_LEARNCOMPLETE:
      // … <ACTIONS>
      break;
    case ZUNO_LOGGING_EVENT_FWAUTH:
      // … <ACTIONS>
      break;
    case ZUNO_LOGGING_EVENT_STACKOVERFLOW:
      // … OOOPS! Error handling
      break;
  } 
}
Full list of events is available here (ZUNO_LOGGING_EVENT_*): https://github.com/Z-Wave-Me/Z-Uno-Core ... initions.h

New system 10ms timer
10 ms time for easier async handling of buttons, LEDs and encoders

Code: Select all

ZUNO_SETUP_SYSTIMER_HANDLER(sys_timer);

void sys_timer(){
	digitalToggle(13);
}
Easier handlers of external reports
New style of handlers for each type of report:

Code: Select all

ZUNO_REPORTS_HANDLER(Battery, BatteryReport);
ZUNO_REPORTS_HANDLER(SensorMultilevel, SensorMultilevelReport);
ZUNO_REPORTS_HANDLER(SensorBinary, SensorBinaryReport);
ZUNO_REPORTS_HANDLER(Notification, NotificationReport);
ZUNO_REPORTS_HANDLER(SwitchMultilevel, SwitchMultilevelReport);
ZUNO_REPORTS_HANDLER(SwitchBinary, SwitchBinaryReport);
ZUNO_REPORTS_HANDLER(Meter, MeterReport);
ZUNO_REPORTS_HANDLER(Basic, BasicReport);

// dbg
#define LOGGER_SERIAL Serial0
ZUNO_ENABLE(LOGGING_DBG LOGGING_EVENTS);

void logReportTitle(char * text) {
    LOGGER_SERIAL.print(millis());
    LOGGER_SERIAL.print("    ");
    LOGGER_SERIAL.print(text);
    LOGGER_SERIAL.print(" NODE:");
    LOGGER_SERIAL.print(REPORT_NODE_ID());
    LOGGER_SERIAL.print(" VALUE:");
}

void BatteryReport() {
    logReportTitle("BATTERY");
    LOGGER_SERIAL.println(REPORT_BATTERY_VALUE(), HEX);
}

void SensorMultilevelReport() {
    logReportTitle("SENSOR MULTILEVEL");
    switch(REPORT_SENSOR_MULTILEVEL_SIZE()) {
        case 1:
            LOGGER_SERIAL.fixPrint(int(REPORT_SENSOR_MULTILEVEL_VALUE_1B()), REPORT_SENSOR_MULTILEVEL_PRECISION());
            break;
        case 2:
            LOGGER_SERIAL.fixPrint(int(REPORT_SENSOR_MULTILEVEL_VALUE_2B()), REPORT_SENSOR_MULTILEVEL_PRECISION());
            break;
        case 4:
            LOGGER_SERIAL.fixPrint(long(REPORT_SENSOR_MULTILEVEL_VALUE_4B()), REPORT_SENSOR_MULTILEVEL_PRECISION());
            break;
    }
    LOGGER_SERIAL.print(" TYPE:");
    LOGGER_SERIAL.print(REPORT_SENSOR_MULTILEVEL_TYPE(), HEX);
    LOGGER_SERIAL.print(" SCALE:");
    LOGGER_SERIAL.println(REPORT_SENSOR_MULTILEVEL_SCALE(), HEX);
}

void SensorBinaryReport() {
    logReportTitle("SENSOR BINARY");
    LOGGER_SERIAL.print(REPORT_SENSOR_BINARY_VALUE(), HEX);
    LOGGER_SERIAL.print(" TYPE:");
    LOGGER_SERIAL.println(REPORT_SENSOR_BINARY_TYPE());
}

void SwitchBinaryReport() {
    logReportTitle("SWITCH BINARY");
    LOGGER_SERIAL.println(REPORT_SWITCH_BINARY_VALUE(), HEX);
}

void SwitchMultilevelReport() {
    logReportTitle("SWITCH MULTILEVEL");
    LOGGER_SERIAL.println(REPORT_SWITCH_MULTILEVEL_VALUE(), HEX);
}

void NotificationReport() {
    logReportTitle("NOTIFICATION ");
    LOGGER_SERIAL.print(REPORT_NOTIFICATION_STATUS(), HEX);
    LOGGER_SERIAL.print(" TYPE:");
    LOGGER_SERIAL.print(REPORT_NOTIFICATION_TYPE(), HEX);
    LOGGER_SERIAL.print(" EVENT:");
    LOGGER_SERIAL.print(REPORT_NOTIFICATION_EVENT(), HEX);
    LOGGER_SERIAL.print(" PARAM:");
    LOGGER_SERIAL.println(REPORT_NOTIFICATION_EVENT_PARAM(0), HEX);
}

void MeterReport() {
     logReportTitle("METER");
     switch(REPORT_METER_SIZE()){
        case 1:
            LOGGER_SERIAL.fixPrint(int(REPORT_METER_VALUE_1B()), REPORT_METER_PRECISION());
            break;
        case 2:
            LOGGER_SERIAL.fixPrint(int(REPORT_METER_VALUE_2B()), REPORT_METER_PRECISION());
            break;
        case 4:
            LOGGER_SERIAL.fixPrint(long(REPORT_METER_VALUE_4B()), REPORT_METER_PRECISION());
            break;
    }
    LOGGER_SERIAL.print(" TYPE:");
    LOGGER_SERIAL.print(REPORT_METER_TYPE(), HEX);
    LOGGER_SERIAL.print(" SCALE:");
    LOGGER_SERIAL.println(REPORT_METER_SCALE(), HEX);
}

void BasicReport() {
    logReportTitle("BASIC");
    LOGGER_SERIAL.println(REPORT_BASIC_VALUE(), HEX);
}

void setup() {
    LOGGER_SERIAL.begin(115200);
    LOGGER_SERIAL.print("START");
}

void loop() {
    delay(1000);
}
Configuration parameters interface changed
In 2.1.4 and earlier it was:

Code: Select all

ZUNO_SETUP_CFGPARAMETER_HANDLER(config_parameter_changed);

void config_parameter_changed(byte param, word * value){
 // …
}

void setup() {
  word tmp;
	byte my_param;
	// loading of the parameter
  // Prototype: void zunoLoadCFGParam(byte num, word * value);
	zunoLoadCFGParam(MY_CFG_PARAM_NUM,&tmp);
  my_param = tmp;
  // saving of the parameter
  // Prototype: void zunoSaveCFGParam(byte num, word * value);
  tmp = my_param;
  zunoSaveCFGParam(MY_CFG_PARAM_NUM, &tmp);
}
Now it is:

Code: Select all

ZUNO_SETUP_CFGPARAMETER_HANDLER(config_parameter_changed);

void config_parameter_changed(byte param, word value){
 // …
}

void setup() {
	// loading of the parameter
  // Prototype: word zunoLoadCFGParam(byte num);
	uint8_t my_param = zunoLoadCFGParam(MY_CFG_PARAM_NUM);
  // saving of the parameter
  // Prototype: zunoSaveCFGParam(byte num, word value);
  zunoSaveCFGParam(MY_CFG_PARAM_NUM, my_param);
}
New thermostat modes
  • THERMOSTAT_MODE_FURNACE
  • THERMOSTAT_MODE_DRY
  • THERMOSTAT_MODE_MOIST
  • THERMOSTAT_MODE_FULL_POWER
  • THERMOSTAT_MODE_AUTO changed to THERMOSTAT_MODE_AUTO_CHANGEOVER
Possibility to change Product Type Id and Prodyuct Id
Before 2.1.5 all Z-Uno sketches were detected ProductType/ProductId 0x0110/0x0001. This lead to problems in some controllers that had a template for specific devices - two different Z-Uno were detected using the same UI template.

From 2.1.5 there are more options for ProductType/ProductId:
  • 0x0110/0x0001 - default
  • 0x0111/0x0000-0xffff - user defined Product ID - use this option if you want to make own templates for skethes for your controllers - it is not recommended to share them with the community as other people can use same Type/Id. Example:

    Code: Select all

    ZUNO_SETUP_PRODUCT_ID(0xAA, 0xBB);
    for Id 0xAABB
  • 0x0112/(automatic) - Z-Uno autogenerated Product Id based on channels types - use this if you are making a template that you want to share with other people. Sketches with same sequence of channels will share same template and hence will look in the same way. Only channel types and their order is used to generate the automatic Id. Example:

    Code: Select all

    ZUNO_ZSETUP_PRODUCT_AUTO();
  • Custom ManufacturerId/ProductType/ProductId - used only in agreement with Z-Wave.Me team and requires full Z-Wave certification - for own device manufacturing based on Z-Uno Module.
Security mode
Before the S0 security mode was possible to change using Arduino IDE. Now it can be changed using parameter #7 (1 - enabled, 0 - disabled). Re-inclusion required.

You can now select which S2 security level to use: Unauthenticated, Authenticated or Access
Example:

Code: Select all

ZUNO_SETUP_S2ACCESS(SKETCH_FLAG_S2_UNAUTHENTICATED_BIT|SKETCH_FLAG_S2_AUTHENTICATED_BIT);
Available S2 security levels:
  • SKETCH_FLAG_S2_UNAUTHENTICATED_BIT
  • SKETCH_FLAG_S2_AUTHENTICATED_BIT
  • SKETCH_FLAG_S2_ACCESS_BIT
You can now write to the EEPROM/NVM using USB
  • Code: Select all

    compiler dumpNVM -d <Z-Uno port> -f <file.hex/bin>
    read all user date to file
  • Code: Select all

    compiler restoreNVM -d <Z-Uno port> -f <file.hex/bin>
    write all user data from file
  • Code: Select all

    compiler restoreNVM -d <Z-Uno port> -a 1000 -f <file.hex/bin>
    write all user data from file to address 0x1000 and upper - then you can access it from the code using

    Code: Select all

    EEPROM.read(0x1000)
Most of Z-Wave Command Classes available for the user moved into user code space
This allowed us to free more space for your code. And you can even contribute to this part now - fork us on GitHub
https://github.com/Z-Wave-Me/Z-Uno-Core ... pport.ucxt

New ZUNO_Buttons library for easier buttons handling
You can use this library with handling in the loop() or with system 10ms timer

Example with handling in the loop() - might be problematic if the sketch is doing a lot of work in the loop().

Code: Select all

#include <ZUNO_Buttons.h>

#define BTN_PIN 0

PinButton btn1(BTN_PIN, true);
 
void setup() {
  Serial.begin(115200);
  pinMode(BTN_PIN, INPUT_PULLUP);
}

void loop() {
  btn1.update();

  btn1.startDispatch();
  if(btn1.isSingleClick()){
    Serial.println("Single click");
  }
  if(btn1.isLongClick()){
    Serial.println("Long click");
  }
  if(btn1.isDoubleClick()){
    Serial.println("Double click");
  }
  btn1.endDispatch();

  delay(20);
} 
Example with system 10ms timer - button handling do not depend on loop being too busy at some moments

Code: Select all

#include <ZUNO_Buttons.h>

#define BTN_PIN 0

PinButton btn1(BTN_PIN, true);

ZUNO_SETUP_SYSTIMER_HANDLER(sys_timer);

void sys_timer(){
  btn1.update();
}

void setup(){
  Serial.begin(115200);
  pinMode(BTN_PIN, INPUT_PULLUP);
}

void loop() {
  btn1.startDispatch();
  if (btn1.isSingleClick()) {
    Serial.println("Single click");
  }
  if (btn1.isLongClick()) {
    Serial.println("Long click");
  }
	if (btn1.isDoubleClick()) {
    Serial.println("Double click");
  }
  btn1.endDispatch();

  delay(20);
} 
New ZUNO_LCD library to work with LCDs

Появилась официальная библиотека ZUNO_LCD.
This library looks pretty much like Serial.

Code: Select all

#include <ZUNO_LCD.h>

LCD_I2C lcd(20,4, 0x27);

void setup() {
  lcd.begin();
  lcd.print("Z-Uno LCD TEST");
}

void loop() {
  lcd.gotoXY(2, 1);
  lcd.print("Time:  ");
  lcd.print(millis());
  delay(100);
}
New ZUNO_Stepper library for step motors
Examples on the forum.

New ZUNO_IAQCore library for air quality sensors
Examples on the forum. Thanks to @michap for porting it.
perjar
Posts: 57
Joined: 08 Apr 2018 18:02

Re: New 2.1.5 beta

Post by perjar »

Getting precompiler error that I did not get in 2.1.4.
Do I need to fix anything in the tool chain?
User avatar
PoltoS
Posts: 7562
Joined: 26 Jan 2011 19:36

Re: New 2.1.5 beta

Post by PoltoS »

There are some syntax chang s, so this might happen. Show us the error and the code (if possible, minimised to the block leading to the error)
perjar
Posts: 57
Joined: 08 Apr 2018 18:02

Re: New 2.1.5 beta

Post by perjar »

Hi,

See source code attached.

Error message:

Code: Select all

Preprocessing file: ZWSupport.cpp with SDCPP... 
Compiling ZWSupport_sdcpp_.cpp ...
ZWSupport_sdcpp_.cpp:870:2:error:no matching function for call to 'resetter_power'
uCxx returned error code:1
Some of the supplied sample sketches also generate compile errors btw...
Attachments
z-meter.zip
(3.18 KiB) Downloaded 293 times
p0lyg0n1
Posts: 242
Joined: 04 Aug 2016 07:14

Re: New 2.1.5 beta

Post by p0lyg0n1 »

Hi,
Seems we have to recheck the translation of line numbers from preprocessing files.
Anyway I have found the reason of fail.
There are 2 problems in your code:
1) You have to specify "void" as type of Smallfontnotmodified() here:

Code: Select all

#ifndef OLED_SMALLFONT_MODIFIED
  // If this flag is not set, it means that the my modified ZUNO_OLED_I2C.cpp and .h have been overwritten
  // The flag is set in ZUNO_OLED_I2C.h
  // If flag missing then generate a compile error
  Smallfontnotmodified();
#endif
So the right syntax will be:

Code: Select all

#ifndef OLED_SMALLFONT_MODIFIED
  // If this flag is not set, it means that the my modified ZUNO_OLED_I2C.cpp and .h have been overwritten
  // The flag is set in ZUNO_OLED_I2C.h
  // If flag missing then generate a compile error
  void Smallfontnotmodified();
#endif
2) The prototype of meter "resetter" was changed and we forgot to add it to list. Now it has no parameters.
like this:

Code: Select all

void resetter_power() {
  // This function must also reset the energy meter beaseuse the Fibaro HC2 does not call the resetter for the energy meter
  DEBUGLN("Resetter - Power");
  currentpower = 0;
  previouspower = 0;
  DEBUGLN("Calling resetter_energy");
 // resetter_energy(0);
}
modified code was attached here.
Attachments
ZMeter.ino.zip
(3.65 KiB) Downloaded 308 times
perjar
Posts: 57
Joined: 08 Apr 2018 18:02

Re: New 2.1.5 beta

Post by perjar »

Thank you very much! Changing the call to the resetter function did the trick!

Running on 2.1.5 now and I am very happy to see that there is no duplication of z-wave messages anymore which offloads the network.
User avatar
PoltoS
Posts: 7562
Joined: 26 Jan 2011 19:36

Re: New 2.1.5 beta

Post by PoltoS »

Would be great to get more feedback from you as next week we will release this version
perjar
Posts: 57
Joined: 08 Apr 2018 18:02

Re: New 2.1.5 beta

Post by perjar »

I am not a superuser and have not tried any of the new fantastic features in 2.1.5 so I would be in a position to give any useful feedback on it.

My only advise, but I am guessing you already have this covered, is to make sure that the reference documentation and code samples are updated when you release it. This very importande section for instance: https://z-uno.z-wave.me/reference/
Cyberax
Posts: 13
Joined: 15 Apr 2019 10:00

Re: New 2.1.5 beta

Post by Cyberax »

I keep getting "Error 0 Can't upload sketch! Something went wrong. Bad CRC16 :'( ." message. Is there anything I need to do to fix it?
rishamee
Posts: 20
Joined: 24 Aug 2018 18:56

Re: New 2.1.5 beta

Post by rishamee »

Ik am sorry to say, but I can't get it to work.

Burning the 2.1.5 bootloader seems OK, and I can compile and upload the sketch.

But when I bring the Z-Uno in rescue mode, the red led flashes instead of the green led.
I can't include the Z-Uno in my network (Razberry2, z-way 2.3.8, freq EU), the sensor multilevel interview fails.

I tried everything. With and without S0 security, with and without multi commands, erase all NVM, go back to the factory settings. I even manually cleaned up my controller's config.json, because all the inclusions and exclusions messed it up, but nothing works.

I begin th think something is wrong with my Z-Uno, because when I go back to 2.1.3 (with minor changes to the sketch) after the inclusion I miss the Battery and Wakeup command classes, and the controller thinks my Z-Uno is an Always On Slave.

Any ideas?

My sketch:

Code: Select all

//#include "EEPROM.h"

#undef DEBUG
define TEMPSENSORCHANNEL 2
define SUNSENSORCHANNEL 1

ZUNO_SETUP_SLEEPING_MODE(ZUNO_SLEEPING_MODE_SLEEPING);
ZUNO_SETUP_CFGPARAMETER_HANDLER(config_changed);


ZUNO_SETUP_CHANNELS(
        ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_GENERAL_PURPOSE_VALUE, 
                          SENSOR_MULTILEVEL_SCALE_PERCENTAGE_VALUE,
                          SENSOR_MULTILEVEL_SIZE_TWO_BYTES,
                          SENSOR_MULTILEVEL_PRECISION_ONE_DECIMAL,
                          sunGetter),
        ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_TEMPERATURE, 
                          SENSOR_MULTILEVEL_SCALE_CELSIUS, 
                          SENSOR_MULTILEVEL_SIZE_TWO_BYTES, 
                          SENSOR_MULTILEVEL_PRECISION_ONE_DECIMAL,
                          tempGetter));                        

const int ledPin  = 13;

void setup() {

  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
  peep(1,1000);
}

void loop() {

  zunoSendReport(SUNSENSORCHANNEL);
  zunoSendReport(TEMPSENSORCHANNEL);
  peep(3,100);
  zunoSendDeviceToSleep();
}

int sunGetter() {
  return 50;
}

int tempGetter() {
  return 20;
}

void config_changed(byte param, word value) {

}

void peep(int p,int m) {
  for ( int i = 0; i < p; i++ ) {
    digitalWrite(ledPin, LOW);
    delay(100);
    digitalWrite(ledPin, HIGH);
    delay(m);
  }
  digitalWrite(ledPin, LOW);
}
Post Reply