I have a polling set on the HC2 once per 13 seconds. On top of that, I'm sending the unsolicited reports once per minute, but for all the channels (1-7) at once. If I overload the package queue with unsolicited reports, can it have a negative effect on all the polling too?
Code: Select all
ZUNO_SETUP_CHANNELS(
        ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_VOLTAGE, SENSOR_MULTILEVEL_SCALE_VOLT, SENSOR_MULTILEVEL_SIZE_FOUR_BYTES, SENSOR_MULTILEVEL_PRECISION_ONE_DECIMAL, getter1),           // PV1InputVoltage
        ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_CURRENT, SENSOR_MULTILEVEL_SCALE_AMPERE, SENSOR_MULTILEVEL_SIZE_FOUR_BYTES, SENSOR_MULTILEVEL_PRECISION_TWO_DECIMALS, getter2),        // PV1InputAmps
        ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_VOLTAGE, SENSOR_MULTILEVEL_SCALE_VOLT, SENSOR_MULTILEVEL_SIZE_FOUR_BYTES, SENSOR_MULTILEVEL_PRECISION_ONE_DECIMAL, getter3),           // PV2InputVoltage
        ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_CURRENT, SENSOR_MULTILEVEL_SCALE_AMPERE, SENSOR_MULTILEVEL_SIZE_FOUR_BYTES, SENSOR_MULTILEVEL_PRECISION_TWO_DECIMALS, getter4),        // PV2InputAmps
        ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_TEMPERATURE, SENSOR_MULTILEVEL_SCALE_CELSIUS, SENSOR_MULTILEVEL_SIZE_FOUR_BYTES, SENSOR_MULTILEVEL_PRECISION_ZERO_DECIMALS, getter5),  // InnerTemperature
        ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_CURRENT, SENSOR_MULTILEVEL_SCALE_AMPERE, SENSOR_MULTILEVEL_SIZE_FOUR_BYTES, SENSOR_MULTILEVEL_PRECISION_ONE_DECIMAL, getter6),         // ChargingCurrent, pozor muze nabyvat i negativnich hodnot pri vybijeni baterie
        ZUNO_SENSOR_MULTILEVEL(ZUNO_SENSOR_MULTILEVEL_TYPE_VOLTAGE, SENSOR_MULTILEVEL_SCALE_VOLT, SENSOR_MULTILEVEL_SIZE_FOUR_BYTES, SENSOR_MULTILEVEL_PRECISION_ONE_DECIMAL, getter7)            // BatteryVoltage
);
#include "SoftwareSerial.h"
#define LED_PIN 13                 // LED pin number 13 = vestavena USER LED bile barvy
#define MAX_BUFFER 200             // Velikost bufferu pro prijem odpovedi od Invertoru. Musi pojmout vsechny znaky az do zakonceni pomoci <CR>, kterym Invertor konci kazdou odpoved
#define SERIAL_Console Serial                // Seriovy interface pro DEBUG
SoftwareSerial SERIAL_Inverter(14, 12);      // Seriovy interface pro komunikaci s Invertorem, pins 12 RX and 14 TX
char input_buffer[MAX_BUFFER];     // Buffer pro prijem odpovedi od Invertoru pres Serial. Odpoved od invertoru je zakoncena znakem <CR>
int buffer_position = 0;           // Counter pro vycitani bufferu znak po znaku
unsigned long nowmillis;           // Counter pro milisekundy od startu programu
unsigned long timer1_LED;          // Timer pro blikani LEDkou
unsigned long timer2_CMD;          // Timer pro periodicke dotazovani invertoru
unsigned long timer3_REPORT;       // Timer pro odesilani unsolicited reportu
int ledState = LOW;                // HIGH/LOW pro blikani LEDkou
int blikni = 0;                    // Pri zapisu do teto promenne provede LEDka prislusny pocet bliku
// Nize jsou hodnoty, ktere parsujeme z retezce ktery vraci invertor.
char ReturnID[7];                 // Sem si ulozime prvnich 5 bytu retezce, ktery vraci invertor.
char PV1InputVoltage[7]; 
char PV2InputVoltage[7];
char PV1InputAmps[7];
char PV2InputAmps[7];
char BatteryVoltage[7];          
char ChargingCurrent[7];         
char InnerTemperature[7];
long VAL_PV1InputVoltage = 0; 
long VAL_PV2InputVoltage = 0;
long VAL_PV1InputAmps = 0;
long VAL_PV2InputAmps = 0;
long VAL_BatteryVoltage = 0;          
long VAL_InnerTemperature = 0;
signed long VAL_ChargingCurrent = 0;         //signed long kvuli odesilani zapornych hodnot
void setup ()
  {
  SERIAL_Inverter.begin (2400);
  SERIAL_Console.begin (9600);
  pinMode(LED_PIN, OUTPUT);       // Prepnuti LED_PIN do rezimu digitalni vystup
  } // end of setup
void parse_RESPONSE ()            // Parsovani odpovedi od Invertoru na zaklade prvnich 5-ti bytu, ktere idenfikuji, jakou informaci nam menic predava. Napriklad: ^D0860500,0400,0300,0070,0800,010,+00400,2318,,,4995,0000,,,2316,,,4995,,,,028,028,000,0
{
   ReturnID[0] = input_buffer[0]; 
   ReturnID[1] = input_buffer[1]; 
   ReturnID[2] = input_buffer[2]; 
   ReturnID[3] = input_buffer[3]; 
   ReturnID[4] = input_buffer[4]; 
   ReturnID[5] = 0;
   if (strcmp(ReturnID, "^D086") == 0) {            // Return_ID pro command ^P003GS=^D086
       PV1InputVoltage[0] = input_buffer[5]; 
       PV1InputVoltage[1] = input_buffer[6]; 
       PV1InputVoltage[2] = input_buffer[7]; 
       PV1InputVoltage[3] = input_buffer[8]; 
       PV1InputVoltage[4] = 0;
       VAL_PV1InputVoltage = atoi(PV1InputVoltage);
       PV2InputVoltage[0] = input_buffer[10]; 
       PV2InputVoltage[1] = input_buffer[11]; 
       PV2InputVoltage[2] = input_buffer[12]; 
       PV2InputVoltage[3] = input_buffer[13]; 
       PV2InputVoltage[4] = 0;       
       VAL_PV2InputVoltage = atoi(PV2InputVoltage);
       PV1InputAmps[0] = input_buffer[15]; 
       PV1InputAmps[1] = input_buffer[16]; 
       PV1InputAmps[2] = input_buffer[17];
       PV1InputAmps[3] = input_buffer[18];
       PV1InputAmps[4] = 0;
       VAL_PV1InputAmps = atoi(PV1InputAmps);
       PV2InputAmps[0] = input_buffer[20]; 
       PV2InputAmps[1] = input_buffer[21]; 
       PV2InputAmps[2] = input_buffer[22]; 
       PV2InputAmps[3] = input_buffer[23]; 
       PV2InputAmps[4] = 0;    
       VAL_PV2InputAmps = atoi(PV2InputAmps);
       BatteryVoltage[0] = input_buffer[25]; 
       BatteryVoltage[1] = input_buffer[26]; 
       BatteryVoltage[2] = input_buffer[27]; 
       BatteryVoltage[3] = input_buffer[28]; 
       BatteryVoltage[4] = 0; 
       VAL_BatteryVoltage = atoi(BatteryVoltage);
       ChargingCurrent[0] = input_buffer[34]; 
       ChargingCurrent[1] = input_buffer[35]; 
       ChargingCurrent[2] = input_buffer[36]; 
       ChargingCurrent[3] = input_buffer[37]; 
       ChargingCurrent[4] = input_buffer[38]; 
       ChargingCurrent[5] = input_buffer[39]; 
       ChargingCurrent[6] = 0; 
       VAL_ChargingCurrent = atoi(ChargingCurrent);
       InnerTemperature[0] = input_buffer[75]; 
       InnerTemperature[1] = input_buffer[76]; 
       InnerTemperature[2] = input_buffer[77]; 
       InnerTemperature[3] = 0; 
       VAL_InnerTemperature = atoi(InnerTemperature);
        } 
      
      if (strcmp(ReturnID, "^D061") == 0) {   // Return_ID pro command ^P003PS=^D061
                                              // response ^D061 vyparsovat zde
       SERIAL_Console.println("Valid response for ^P003PS received.");
       }
      
      if (strcmp(ReturnID, "XXXXX") == 0) {  // Return_ID pro budouci command CCCCCC=XXXXX
                                             // response XXXXX vyparsovat zde
        } 
   
   // Vypsani hodnot vyparsovanych z bufferu
   SERIAL_Console.print("PARSED: "); SERIAL_Console.println(input_buffer);
   SERIAL_Console.print("PV1InputVoltage>"); SERIAL_Console.println(VAL_PV1InputVoltage);
   SERIAL_Console.print("PV1InputAmps>"); SERIAL_Console.println(VAL_PV1InputAmps);
   SERIAL_Console.print("PV2InputVoltage>"); SERIAL_Console.println(VAL_PV2InputVoltage);
   SERIAL_Console.print("PV2InputAmps>"); SERIAL_Console.println(VAL_PV2InputAmps);
   SERIAL_Console.print("InnerTemperature>"); SERIAL_Console.println(VAL_InnerTemperature);
   SERIAL_Console.print("ChargingCurrent>"); SERIAL_Console.println(VAL_ChargingCurrent);
   SERIAL_Console.print("BatteryVoltage>"); SERIAL_Console.println(VAL_BatteryVoltage);
}
void processIncomingByte (byte inByte)    // Tato funkce bude zavolana pokazde, kdyz na seriove rozhrani prijde novy znak
  {
  switch (inByte)
    {
    case '\r':                              // <CR> 0x0D narazili jsme na znak <CR> kterym Invertor oznamuje konec retezce
      input_buffer [buffer_position] = 0;   // Zapisujeme zakoncovaci nulu do input bufferu, tak aby se z nej stal zero_terminated_char_array
      buffer_position = 0;                  // Resetujeme counter pro vycitani obsahu bufferu zpet na pozici 0
      parse_RESPONSE();                     // Volame parsovani obsahu bufferu
      break;
    case '\n':                              // <LF> 0x0A na znak <LF> nereagujeme
      break;
    default:
      if (buffer_position < (MAX_BUFFER-1)) input_buffer [buffer_position++] = inByte; // Posun pozice v bufferu
      break;
    }  // end of switch
  } 
void loop()                                                // Hlavni smycka. Zde je mozne kontrolovat citace, ovladat LED, cist tlacitka. Pozor, nesmi se pouzivat funkce Delay, jinak by se mohl v mezicase zaplnit a prepsat hardwarovy buffer serioveho rozhrani.
  {
  while (SERIAL_Inverter.available () > 0) {               // Jsou na seriovem rozhrani data?
    processIncomingByte (SERIAL_Inverter.read ());         // Nacti znak ze serioveho rozhrani
    if (blikni < 1) blikni = 1;                            // Blikni jednou, protoze z invertoru prisel znak. Pokud uz blikas, nedelej nic ani nerus stavajici blikani.
    }
  
  nowmillis = millis();                                    // Ulozeni citace doby behu programu do promenne nowmillis pro dalsi zpracovani
  if (nowmillis - timer2_CMD >= 10000) {                       // timer2_CMD, periodicke dotazovani invertoru kazdych XXXX milisekund na stav jednotlivych hodnot
     timer2_CMD = nowmillis;
     SERIAL_Console.println("Sending ^P003GS command now."); 
     SERIAL_Inverter.print("^P003GS");                    // Posilame do Invertoru command, aby nam vratil hodnoty
     SERIAL_Inverter.print('\r');                          // <CR>
     }
 if (nowmillis - timer3_REPORT >= 60000) {                        // timer3_REPORT, periodicke odesilani Z-WAVE unsolicited reportu kazdych xxx milisekund.
    timer3_REPORT = nowmillis;
    SERIAL_Console.println("Sending unsolicited Z-WAVE reports now."); 
    zunoSendReport(7);     // Send report without polling
    zunoSendReport(1);     // Send report without polling
    zunoSendReport(2);     // Send report without polling
    zunoSendReport(3);     // Send report without polling
    zunoSendReport(4);     // Send report without polling
    zunoSendReport(5);     // Send report without polling
    zunoSendReport(6);     // Send report without polling    
    }        
 if (nowmillis - timer1_LED >= 20) {                    // timer1_LED, blikani LEDkou pomoci drzeni stavu HIGH/LOW vzdy nekolik milisekund
    timer1_LED = nowmillis;
    if (ledState == LOW && blikni > 0){
       ledState = HIGH;
       blikni = blikni - 1;                               // Odecitame 1 pri kazdem rozviceni LED
       }
    else ledState = LOW;
    digitalWrite(LED_PIN, ledState);
    }
  }                                                       // Konec hlavni smycky
// Z-WAVE Getters
  word getter1(){
    return VAL_PV1InputVoltage;
    }
  
  word getter2(){
    return VAL_PV1InputAmps;
    }
  
  word getter3(){
    return VAL_PV2InputVoltage;
    }
  
  word getter4(){
    return VAL_PV2InputAmps;
    }
  word getter5(){
    return VAL_InnerTemperature;
    }
  signed long getter6(){                    //pozor, kvuli prenosu minusovych hodnot je treba definovat jako signed long
    return VAL_ChargingCurrent;
    }
  word getter7(){
    return VAL_BatteryVoltage;
    }