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;
}