Browse Source

faster sync after long time no signal and fix negative temperature decoding

pull/478/head
golfi200 3 years ago
parent
commit
df58f1b2e7
  1. 52
      tools/nano/AhoyUL/FHEM/34_ahoyUL.pm
  2. 6
      tools/nano/AhoyUL/src/config.h
  3. 271
      tools/nano/AhoyUL/src/main.cpp

52
tools/nano/AhoyUL/FHEM/34_ahoyUL.pm

@ -1,9 +1,10 @@
package main;
use strict;
use warnings;
use DevIo; # load DevIo.pm if not already loaded
use Time::HiRes qw(gettimeofday);
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
my $last_hour=0;
@ -19,7 +20,7 @@ my %sets = (
);
my %Inv = { "1141xxxxxxxx", };
#my %Inv = { "1141xxxxxxxx" };
my $yield_day = 0; #todo make per inverter
my $yield_total = 0;
@ -46,7 +47,9 @@ sub ahoyUL_Define($$)
# set the device to open
$hash->{DeviceName} = $dev;
# open connection with custom init function
my $ret = DevIo_OpenDev($hash, 0, "ahoyUL_Init");
#my $ret = DevIo_OpenDev($hash, 0, "ahoyUL_Init");
my $ret = DevIo_OpenDev($hash, 0, undef);
InternalTimer(gettimeofday()+5, "ahoyUL_Init", $hash);
# start periodic reading
InternalTimer(gettimeofday()+15, "ahoyUL_GetUpdate", $hash);
@ -54,13 +57,12 @@ sub ahoyUL_Define($$)
}
# will be executed upon successful connection establishment (see DevIo_OpenDev())
sub ahoyUL_Init($)
{
my ($hash) = @_;
my $name = $hash->{NAME};
Log3 $name, 3, "ahoy device Init() called ...";
Log3 $name, 2, "ahoy device Init() called ...";
# send init to device, here e.g. enable automode to send DevInfoReq (0x15 ... 0x0B ....) every 120sec and enable simple decoding in ahoy-nano
DevIo_SimpleWrite($hash, "a120:\nd1\r\n", 2);
@ -73,16 +75,24 @@ sub ahoyUL_Init($)
sub ahoyUL_Initialize($)
{
my ($hash) = @_;
my $name = $hash->{NAME};
$hash->{DefFn} = "ahoyUL_Define";
$hash->{UndefFn} = "ahoyUL_Undef";
$hash->{SetFn} = "ahoyUL_Set";
$hash->{ReadFn} = "ahoyUL_Read";
$hash->{ReadyFn} = "ahoyUL_Ready";
$hash->{ParseFn} = "ahoyUL_Parse";
$hash->{ParseFn} = "ahoyUL_GetUpdate"; #to be initialized in X_Define with a period
#$hash->{AttrFn} = "ahoyUL_Attr";
$hash->{AttrList} = "disable:0,1 " .
"header " .
"inv_polling_sec " .
"$readingFnAttributes ";
Log3 $name, 2, "ahoy_Initialize called";
return undef;
}
@ -90,11 +100,11 @@ sub ahoyUL_GetUpdate($)
{
my ($hash) = @_;
my $name = $hash->{NAME};
Log3 $name, 3, "ahoy_GetUpdate called ...";
Log3 $name, 4, "ahoy_GetUpdate called ... todo later";
# neuen Timer starten in einem konfigurierten Interval.
#InternalTimer(gettimeofday()+$hash->{cmdInterval}, "ahoyUL_GetUpdate", $hash);
InternalTimer(gettimeofday()+120, "ahoyUL_GetUpdate", $hash);
InternalTimer(gettimeofday() + 1800, "ahoyUL_GetUpdate", $hash);
#todo: call cmd sender method or do it right here
}
@ -259,4 +269,26 @@ sub ahoyUL_Undef($$)
return undef;
}
1;
# default sub to set and del attributes, maybe used later
sub ahoyUL_Attr($$$$)
{
my ( $cmd, $name, $aName, $aValue ) = @_;
# $cmd - Vorgangsart - kann die Werte "del" (löschen) oder "set" (setzen) annehmen
# $name - Gerätename
# $aName/$aValue sind Attribut-Name und Attribut-Wert
if ($cmd eq "set") {
if ($aName eq "Regex") {
eval { qr/$aValue/ };
if ($@) {
Log3 $name, 3, "X ($name) - Invalid regex in attr $name $aName $aValue: $@";
return "Invalid Regex $aValue: $@";
}
}
}
return undef;
}
1;

6
tools/nano/AhoyUL/src/config.h

@ -43,8 +43,10 @@
#define SERIAL_INTERVAL 5
// default send interval
#define SEND_INTERVAL 60 //send interval if Rx OK
#define SEND_INTERVAL_MIN 10 //send interval if no RX (used initial sync or signal loss), todo: shall be disabled over night
#define SEND_INTERVAL (60) //send interval if Rx OK
#define SEND_NOSIGNAL_SHORT (10) //short send interval if no RX (used initial sync or signal loss)
#define SEND_REPEAT (5) //number of tries of short send interval to sync faster to inverter after night
#define SEND_NOSIGNAL_LONG (20*60) //long TX interval whne no SIGNAL for long time, e.g. over night
// maximum human readable inverter name length
#define MAX_NAME_LENGTH 16

271
tools/nano/AhoyUL/src/main.cpp

@ -82,39 +82,33 @@ static RadioType hmRadio;
// static uint8_t radio_id[5]; //todo: use the mPayload[].id field ,this defines the radio-id (domain) of the rf24 transmission, will be derived from inverter id
// static uint64_t radio_id64 = 0ULL;
#define DEF_VERSION "\n version 2022-12-06 21:30"
#define DEF_VERSION "\n version 2022-12-15 23:00"
#define P(x) (__FlashStringHelper *)(x) // PROGMEM-Makro for variables
static const char COMPILE_DATE[] PROGMEM = {__DATE__};
static const char COMPILE_TIME[] PROGMEM = {__TIME__};
static const char NAME[] PROGMEM = {DEF_DEVICE_NAME};
static const char VERSION[] PROGMEM = {DEF_VERSION};
#define USER_PAYLOAD_MAXLEN 80 // user_payload buffer size, so far a max output length is 62 for 4ch Inverter
static uint8_t user_payload[USER_PAYLOAD_MAXLEN]; // buffer used for simple decoding and output only, one inverter only
static uint32_t user_pl_ts = 0;
static SerialUtils utSer; // class reference of serial utils
static char inSer; // one char input-buffer for most simple uart-cmds
static char *m_strout_p; // pointer of output buffer
static char **mParams; // pointer to char arrays used for input buffer str tokenizer output, array must get initialized with physical space!!!
//static char* mParam[MAX_SER_PARAM]; // optionally: array of pointers to char*
static SerialUtils utSer; // class reference of serial utils
static char inSer; // one char input-buffer for most simple uart-cmds
static char *m_strout_p; // pointer of output buffer
static char **mParams; // pointer to char arrays used for input buffer str tokenizer output, array must get initialized with physical space!!!
// static char* mParam[MAX_SER_PARAM]; // optionally: array of pointers to char*
static packet_t rfTX_packet; // structure of one received radio packet
static uint8_t rxch; // keeps the current RX channel
// volatile static uint32_t current_millis = 0;
static volatile uint32_t timer1_millis = 0L; // general loop timer
static volatile uint32_t timer2_millis = 0L; // send Request timer
static volatile uint32_t timer1_millis = 0L; // general loop timer
static volatile uint32_t timer2_millis = 0L; // send Request timer
static volatile uint32_t lastRx_millis = 0L;
static volatile uint32_t tcmd_millis = 0L; //timer for smac cmd
static volatile uint32_t tcmd_millis = 0L; // timer for smac cmd
#define ONE_SECOND (1000L)
#define ONE_MINUTE (60L * ONE_SECOND)
#define QUARTER_HOUR (15L * ONE_MINUTE)
#define SEND_INTERVAL_ms (ONE_SECOND * SEND_INTERVAL)
#define MIN_SEND_INTERVAL_ms (ONE_SECOND * MIN_SEND_INTERVAL)
static uint8_t c_loop = 0;
static volatile int sread_len = 0; // UART read length
// static volatile bool rxRdy = false; //will be set true on first receive packet during sending interval, reset to false before sending
@ -125,30 +119,36 @@ static bool automode = true;
static bool sendNow = false;
static bool doDecode = true;
static bool showMAC = true;
static bool smac_send = false; //cmd smac was send
static volatile uint32_t polling_inv_msec = SEND_INTERVAL_ms;
static bool smac_send = false; // cmd smac was send
static volatile uint16_t tmp16 = 0;
static uint8_t tmp8 = 0;
static uint8_t tmp81 = 0;
static uint32_t min_SEND_SYNC_msec = MIN_SEND_INTERVAL_ms;
// static uint32_t min_SEND_SYNC_msec = MIN_SEND_INTERVAL_ms;
static uint8_t mCountdown_noSignal = SEND_REPEAT;
static volatile uint32_t mSendInterval_ms = SEND_NOSIGNAL_SHORT * ONE_SECOND;
static volatile uint32_t polling_req_msec = SEND_INTERVAL * ONE_SECOND; // will be set via serial interface
static bool iv_devControlReq = false; //this is one kind of requests, see devControlCmds
static uint8_t iv_devControlCmd = ActivePowerContr; //for now the only devControlCmd
static uint16_t iv_powerLimit[2]; // limit power output
static bool iv_devControlReq = false; // this is one kind of requests, see devControlCmds
static uint8_t iv_devControlCmd = ActivePowerContr; // for now the only devControlCmd
static uint16_t iv_powerLimit[2]; // limit power output
/**
*
*
*
*
* setup()
*
***********************************************************************************************/
*
***********************************************************************************************/
void setup() {
// Serial.begin(115200);
Serial.begin(57600);
printf_begin(); // I guess, need for printf(), tocheck with F() and PROGMEM
Serial.flush();
Serial.print(P(NAME));
Serial.print(P(VERSION)); Serial.print(F(" /compiled ")); Serial.print(P(COMPILE_DATE)); Serial.print(F(" ")); Serial.print(P(COMPILE_TIME));
Serial.print(P(VERSION));
Serial.print(F(" /compiled "));
Serial.print(P(COMPILE_DATE));
Serial.print(F(" "));
Serial.print(P(COMPILE_TIME));
mSerialTicker = 0xffff;
resetSystem(); // reset allocated mPayload buffer
@ -179,22 +179,24 @@ void setup() {
// todo: load Inverter decoder depending on InvID
m_inv_ix = 0; //first inverter index
//global var for all inverter
m_inv_ix = 0; // first inverter index
// global var for all inverter
iv_powerLimit[1] = AbsolutNonPersistent;
iv_powerLimit[0] = 0xFFFF; //unlimited
iv_powerLimit[0] = 0xFFFF; // unlimited
if (automode) sendNow = true; // trigger initial first send until millis() counter is valid
} // end setup()
/**
*
*
*
*
* loop()
*
**********************************************************************************************************************/
*
**********************************************************************************************************************/
void loop() {
// the inverter id/ix I shall be handled in a loop if more than one inverter is registered for periodic polling
// counting the time reference of seconds
if (millis() - timer1_millis >= ONE_SECOND) {
timer1_millis = millis();
@ -213,12 +215,12 @@ void loop() {
if (Serial.available()) {
// wait char
inSer = Serial.read();
//delay(1);
// delay(1);
switch (inSer) {
case (char)'a': {
// enable automode with REQ polling interval via a10 => 10sec, a100 => 100sec or other range 5....3600sec
//extend automode with polling period in sec, inverter ix and id, all numerial value are optional from the back
//cmd: a[[[:<poll_sec>]:<invIX>]:<12digit invID>:] e.g. a:120:1:081511223344:, also polling only a:120: and polling and inv_ix via a:120:1
// extend automode with polling period in sec, inverter ix and id, all numerial value are optional from the back
// cmd: a[[[:<poll_sec>]:<invIX>]:<12digit invID>:] e.g. a:120:1:081511223344:, also polling only a:120: and polling and inv_ix via a:120:1
automode = true;
m_inv_ix = 0;
uint8_t invIX = 0;
@ -226,41 +228,41 @@ void loop() {
uint8_t invID5[5] = {0x01, 0x44, 0x33, 0x22, 0x11};
mParams = utSer.getParamsBuf();
tmp8 = utSer.read_uart_cmd_param(mParams);
if (tmp8 > 0) {
//get polling interval from first parameter
// get polling interval from first parameter
tmp81 = strlen(&mParams[0][0]);
if (tmp81 > 0 && tmp81 < 5) {
polling_inv_msec = 1000 * utSer.uart_eval_decimal_val(F("auto poll sec "), &mParams[0][0], 5, 5, 3600, 1);
polling_req_msec = 1000 * utSer.uart_eval_decimal_val(F("auto poll sec "), &mParams[0][0], 5, 5, 3600, 1);
}
if (tmp8 > 2) {
//get inverter index and inverter ID from parameter 2 and 3
if (utSer.uart_cmd_add_inverter_parsing( &mParams[1], MAX_SER_PARAM, &invIX, &invType, &invID5[0])) {
if (tmp8 > 2) {
// get inverter index and inverter ID from parameter 2 and 3
if (utSer.uart_cmd_add_inverter_parsing(&mParams[1], MAX_SER_PARAM, &invIX, &invType, &invID5[0])) {
// write to inverter structure at given index
mPayload[invIX].invType = invType;
memcpy(mPayload[invIX].invId, invID5, 5);
m_inv_ix = invIX;
DPRINT(DBG_INFO, F(" OK"));
// todo: save inverter list to eeprom depending on 4th parameter (e.g ":eep:" )
} //end if()
} else if (tmp8 > 1) {
//try to get and set the inverter-index onyl
tmp81 = (uint8_t) (utSer.uart_eval_decimal_val(NULL, &mParams[1][0], tmp8, 0, MAX_NUM_INVERTERS, 1));
if (mPayload[tmp81].invType != 0x0000) {
m_inv_ix = tmp81;
DPRINT(DBG_INFO, F(" inv_ix "));
_DPRINT(DBG_INFO, m_inv_ix);
DPRINT(DBG_INFO, F(" OK"));
} // end if()
} else if (tmp8 > 1) {
// try to get and set the inverter-index onyl
tmp81 = (uint8_t)(utSer.uart_eval_decimal_val(NULL, &mParams[1][0], tmp8, 0, MAX_NUM_INVERTERS, 1));
if (mPayload[tmp81].invType != 0x0000) {
m_inv_ix = tmp81;
DPRINT(DBG_INFO, F(" inv_ix "));
_DPRINT(DBG_INFO, m_inv_ix);
DPRINT(DBG_INFO, F(" OK"));
} else {
DPRINT(DBG_INFO, F(" ERR"));
} //end if-else
}//end if(tmp8 > 2)-else
} //end if(tmp8 > 0)
DPRINT(DBG_INFO, F(" ERR"));
} // end if-else
} // end if(tmp8 > 2)-else
} // end if(tmp8 > 0)
Serial.println();
break;
} // end case a
} // end case a
case (char)'d': {
// trigger decoding, enable periodic decoding via "d1" and disable via "d0"
@ -276,11 +278,12 @@ void loop() {
// sending smac commands which are send to the inverter, same format as from inverter, see details in funct. eval_uart_smac_cmd(...)
// e.g. "smac:ch03:958180....:rc40:" -- ch03 for Tx channel, <raw data with crc8>, -- rc40 for rx channel 40, if rx channel is left then default tx_ix+2
//todo: not yet tested much
// todo: not yet tested much
if (automode == true) {
automode = false;
DPRINT(DBG_INFO, F("automode ")); _DPRINT(DBG_INFO, automode);
DPRINT(DBG_INFO, F("automode "));
_DPRINT(DBG_INFO, automode);
}
mParams = utSer.getParamsBuf();
@ -298,21 +301,22 @@ void loop() {
m_inv_ix = getInvIX(mPayload, MAX_NUM_INVERTERS, &rfTX_packet.data[0]);
if (m_inv_ix == 0xFF) {
DPRINT(DBG_DEBUG, F("inv_id no match"));
m_inv_ix = MAX_NUM_INVERTERS - 1; //use last possition
m_inv_ix = MAX_NUM_INVERTERS - 1; // use last possition
}
DPRINT(DBG_DEBUG, F("m_inv_ix ")); _DPRINT(DBG_DEBUG, m_inv_ix);
DPRINT(DBG_DEBUG, F("m_inv_ix "));
_DPRINT(DBG_DEBUG, m_inv_ix);
tcmd_millis = millis();
smac_send = true;
payload_used[m_inv_ix] = !resetPayload(&mPayload[m_inv_ix]);
mPayload[m_inv_ix].isMACPacket = true; // MAC must be enabled to show the full MAC packet, no need for user_payload
mPayload[m_inv_ix].isMACPacket = true; // MAC must be enabled to show the full MAC packet, no need for user_payload
mPayload[m_inv_ix].receive = false;
hmRadio.sendPacket_raw(&mPayload[0].invId[0], &rfTX_packet, rxch); // 2022-10-30: byte array transfer working
mPayload[m_inv_ix].requested = true;
mPayload[m_inv_ix].invType = 0x1111; //used as dummy type, decode works external only with known type
}//end if(utSer.uart_cmd_smac_request_parser(...))
} // end if(mac)
} // end if(tmp8)
mPayload[m_inv_ix].invType = 0x1111; // used as dummy type, decode works external only with known type
} // end if(utSer.uart_cmd_smac_request_parser(...))
} // end if(mac)
} // end if(tmp8)
Serial.println();
break;
} // end case s
@ -370,15 +374,15 @@ void loop() {
mParams = utSer.getParamsBuf();
tmp8 = utSer.read_uart_cmd_param(mParams);
if (tmp8 > 0) {
tmp81 = (uint8_t) (utSer.uart_eval_decimal_val(F("scan "), &mParams[0][0], 5, 1, 255, 1));
tmp81 = (uint8_t)(utSer.uart_eval_decimal_val(F("scan "), &mParams[0][0], 5, 1, 255, 1));
while (tmp81--) {
hmRadio.scanRF();
if (Serial.available()) {
// wait char
inSer = Serial.read();
if (inSer >= '\n') break; //from while()
}//end if
}//end while()
if (inSer >= '\n') break; // from while()
} // end if
} // end while()
}
Serial.println();
break;
@ -394,98 +398,116 @@ void loop() {
case (char)'r': {
mParams = utSer.getParamsBuf();
tmp8 = utSer.read_uart_cmd_param(mParams,2);
tmp8 = utSer.read_uart_cmd_param(mParams, 2);
if (strstr(&mParams[0][0], "xch")) {
// sets rx channel via e.g via cmd rxch:63:
rxch = utSer.uart_eval_decimal_val(F("rx chan "), &mParams[1][0], 3, 0, 125, 1); //use first parameter after cmd
rxch = utSer.uart_eval_decimal_val(F("rx chan "), &mParams[1][0], 3, 0, 125, 1); // use first parameter after cmd
} else {
// query current radio information via "r"
hmRadio.print_radio_details();
}//end if-else()
} // end if-else()
break;
}
case (char)'p': {
//set or query power limit from inverter, parameter must be separated by ":"
//todo: extend para-check to reactive powerlimit "%var" and "var"
// set or query power limit from inverter, parameter must be separated by ":"
// todo: extend para-check to reactive powerlimit "%var" and "var"
mParams = utSer.getParamsBuf();
tmp8 = utSer.read_uart_cmd_param(mParams,3);
tmp8 = utSer.read_uart_cmd_param(mParams, 3);
if (strstr(&mParams[0][0], "?")) {
// cmd:/ "p?"
// query power setting
//not sure there is a query request
// not sure there is a query request
DPRINTLN(DBG_DEBUG, F("query: not yet, break"));
break;
} else if (strstr(&mParams[0][0], "%")) {
//make non persistent settings only
// set relative power
iv_powerLimit[0] = (uint16_t) utSer.uart_eval_decimal_val(F("Prel "), &mParams[0][0], 4, 0, 100, 1);
// make non persistent settings only
// set relative power
iv_powerLimit[0] = (uint16_t)utSer.uart_eval_decimal_val(F("Prel "), &mParams[0][0], 4, 0, 100, 1);
iv_powerLimit[1] = RelativNonPersistent;
} if (strstr(&mParams[0][0], "w")) {
//make non persistent settings only
// set absolute power
iv_powerLimit[0] = (uint16_t) utSer.uart_eval_decimal_val(F("Pabs "), &mParams[0][0], 5, 0, 65000, 1);
}
if (strstr(&mParams[0][0], "w")) {
// make non persistent settings only
// set absolute power
iv_powerLimit[0] = (uint16_t)utSer.uart_eval_decimal_val(F("Pabs "), &mParams[0][0], 5, 0, 65000, 1);
iv_powerLimit[1] = AbsolutNonPersistent;
}//end if-else()
} // end if-else()
//if (!iv_devControlReq) {
iv_devControlReq = true; //defines type of message, not that something is pending
sendNow = true;
// if (!iv_devControlReq) {
iv_devControlReq = true; // defines type of message, not that something is pending
sendNow = true;
//}
break;
}//end p
} // end p
case (char)'t': {
// set the time sec since Jan-01 1970 (UNIX epoch time) as decimal String value e.g. "t1612345678:" for Feb-03 2021 9:47:58
// timestamp is only used for sending packet timer, but not for the timing of Tx/Rx scheduling etc...
//ther is no need of exact timing, it must only increase (change) in REQ_INFO_CMDs
// ther is no need of exact timing, it must only increase (change) in REQ_INFO_CMDs
sread_len = utSer.serBlockRead_ms(utSer.getInBuf());
mTimestamp = utSer.uart_eval_decimal_val(F("time set "), utSer.getInBuf(), sread_len, 10 * 3600, 0xFFFFFFFF, 1);
break;
} // end case t
case (char)'?':{
case (char)'?': {
Serial.println(F("\ncmds: a:, c_, d, iadd:, idel:, ilst:, m_, p:, s, smac:, rxch_, t_, ?"));
break;
} //end case '?'
} // end switch-case
} // end if serial...
} // end case '?'
} // end switch-case
} // end if serial...
// automode RF-Tx-trigger
if (automode) {
// slow down the sending if no Rx for long time
if (millis() - lastRx_millis > QUARTER_HOUR) {
min_SEND_SYNC_msec = QUARTER_HOUR;
if (millis() < (SEND_INTERVAL * ONE_SECOND) && !lastRx_millis) {
// initial fast send as long as no rx
mSendInterval_ms = (SEND_NOSIGNAL_SHORT * ONE_SECOND);
} else if (millis() - lastRx_millis > (4 * polling_req_msec)) {
// no Rx in time reduce Tx polling
if (mCountdown_noSignal) {
// keep fast Tx on initial no-signal for countdown > 0
mSendInterval_ms = (SEND_NOSIGNAL_SHORT * ONE_SECOND);
} else {
// large no signal period
mSendInterval_ms = (SEND_NOSIGNAL_LONG * ONE_SECOND);
}
} else {
min_SEND_SYNC_msec = MIN_SEND_INTERVAL_ms;
// rx OK keep default Tx polling
mSendInterval_ms = polling_req_msec;
mCountdown_noSignal = SEND_REPEAT;
}
// trigger Tx if long period not send
if ((millis() - timer2_millis >= (SEND_NOSIGNAL_LONG * ONE_SECOND))) {
// no send for long time, trigger fast send for countdown time
mCountdown_noSignal = SEND_REPEAT;
}
// todo: add queue of cmds or schedule simple device control request for power limit values
if (millis() - timer2_millis >= min_SEND_SYNC_msec && ((millis() - lastRx_millis > polling_inv_msec) || millis() < 60000 || sendNow)) {
if (sendNow || (millis() - timer2_millis > mSendInterval_ms)) {
timer2_millis = millis();
// DISABLE_IRQ;
payload_used[m_inv_ix] = !resetPayload(&mPayload[m_inv_ix]);
mPayload[m_inv_ix].isMACPacket = true;
mPayload[m_inv_ix].receive = false;
mPayload[m_inv_ix].requested = true; // assume the previous sending is finished because of scheduled timing, therefore no check if still true
mPayload[m_inv_ix].requested = true; // assume the previous sending is finished because of scheduled timing, therefore no check if still true
sendNow = false;
if (mCountdown_noSignal) mCountdown_noSignal--;
if (iv_devControlReq) {
//send devControlReq
// send devControlReq
hmRadio.sendControlPacket(&mPayload[m_inv_ix].invId[0], iv_devControlCmd, iv_powerLimit);
iv_devControlReq = false; //todo: use timer that it is not send to quick (e.g. max once per 5sec)
sendNow = false;
iv_devControlReq = false; // todo: use timer that it is not send to quick (e.g. max once per 5sec)
} else {
//send regular info request
// send regular info request
hmRadio.sendTimePacket(&mPayload[m_inv_ix].invId[0], 0x0B, mTimestamp, 0x0000);
}
// RESTORE_IRQ;
}
}
@ -546,14 +568,15 @@ void loop() {
}
} else {
//no receive to smac cmd within timeout (of about 10 retransmissions) --> command_timeout == 4000
if (smac_send && (millis()-tcmd_millis > 4000)) {
// no receive to smac cmd within timeout (of about 10 retransmissions) --> command_timeout == 4000
if (smac_send && (millis() - tcmd_millis > 4000)) {
smac_send = false;
//shows number of retransmits, if rt>0 some response, but incomplete
Serial.print(F("rmac:rt")); Serial.print(mPayload[m_inv_ix].retransmits); Serial.println(F(":ERR"));
}//end if()
}
// shows number of retransmits, if rt>0 some response, but incomplete
Serial.print(F("rmac:rt"));
Serial.print(mPayload[m_inv_ix].retransmits);
Serial.println(F(":ERR"));
} // end if()
}
} // end loop()
//-----------------------------------------------------------------------------
@ -926,7 +949,7 @@ static uint8_t collect_and_return_userPayload(invPayload_t *_payload, uint8_t *_
_ixpl = 10; // index of position of payload start after pid
} // end if()
if (_payload->maxPackId < 1) return 0xff; //false, assume no valid data in payload
if (_payload->maxPackId < 1) return 0xff; // false, assume no valid data in payload
for (uint8_t i = 0; i < (_payload->maxPackId); i++) {
memcpy(&_user_payload[_offs], &_payload->data[i][_ixpl], (_payload->len[i] - _ixpl - 1));
@ -960,8 +983,8 @@ static void decodePayload(uint8_t _cmd, uint8_t *_user_payload, uint8_t _ulen, u
if (_cmd == 0x95 and _ulen == 42) {
//!!! simple HM600/700/800 2ch decoding for cmd=0x95 only !!!!
//snprintf_P(_strout, _strlen, PSTR("\nHM800/%04Xxxxxxxxx/"), _invtype);
//Serial.print(_strout);
// snprintf_P(_strout, _strlen, PSTR("\nHM800/%04Xxxxxxxxx/"), _invtype);
// Serial.print(_strout);
for (_x = 0; _x < HM2CH_LIST_LEN; _x++) {
// read values from given positions in payload
@ -971,8 +994,8 @@ static void decodePayload(uint8_t _cmd, uint8_t *_user_payload, uint8_t _ulen, u
if (_tmp8 != _bp.ch) {
snprintf_P(_strout, _strlen, PSTR("\nHM800/%04Xxxxxxxxx/ch%02d "), _invtype, _bp.ch);
Serial.print(_strout);
//snprintf_P(_strout, _strlen, PSTR("ch%02d/"), _bp.ch);
//Serial.print(_strout);
// snprintf_P(_strout, _strlen, PSTR("ch%02d/"), _bp.ch);
// Serial.print(_strout);
}
_tmp8 = _bp.ch;
@ -991,7 +1014,7 @@ static void decodePayload(uint8_t _cmd, uint8_t *_user_payload, uint8_t _ulen, u
_val <<= 8;
_val |= _user_payload[_bp.start];
} while (++_bp.start != _end);
_fval = _val / (float)_bp.div;
_fval = (int)_val / (float)_bp.div;
if (_bp.unitId == UNIT_NONE) {
Serial.print(_val);

Loading…
Cancel
Save