2018-12-11 13:24:52 +00:00
/*
2019-10-27 10:13:24 +00:00
xsns_37_rfsensor . ino - RF sensor receiver for Tasmota
2018-12-11 13:24:52 +00:00
2019-12-31 13:23:34 +00:00
Copyright ( C ) 2020 Theo Arends
2018-12-11 13:24:52 +00:00
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# ifdef USE_RF_SENSOR
/*********************************************************************************************\
2018-12-17 17:06:19 +00:00
* RF receiver based on work by Paul Tonkes ( www . nodo - domotica . nl )
*
* Supported 434 MHz receiver is Aurel RX - 4 M50RR30SF
* Supported 868 MHz receiver is Aurel RX - AM8SF
*
* Connect one of above receivers with a 330 Ohm resistor to any GPIO
2018-12-11 13:24:52 +00:00
*
* USE_THEO_V2 Add support for 434 MHz Theo V2 sensors as documented on https : //sidweb.nl
2018-12-17 17:06:19 +00:00
* USE_ALECTO_V2 Add support for 868 MHz Alecto V2 sensors like ACH2010 , WS3000 and DKW2012 weather stations
2018-12-11 13:24:52 +00:00
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define XSNS_37 37
//#define USE_THEO_V2 // Add support for 434MHz Theo V2 sensors as documented on https://sidweb.nl
//#define USE_ALECTO_V2 // Add support for 868MHz Alecto V2 sensors like ACH2010, WS3000 and DKW2012
# define RFSNS_VALID_WINDOW 1800 // Number of seconds for sensor to respond (1800 = 30 minutes)
# define RFSNS_LOOPS_PER_MILLI 1900 // (345 voor 16MHz ATMega) Voor 80MHz NodeMCU (ESP-12E). Getest met TheoV2 Protocol.
# define RFSNS_RAW_BUFFER_SIZE 180 // (256) Maximum number of RF pulses that can be captured
# define RFSNS_MIN_RAW_PULSES 112 // (16) =8 bits. Minimaal aantal ontvangen bits*2 alvorens cpu tijd wordt besteed aan decodering, etc.
// Zet zo hoog mogelijk om CPU-tijd te sparen en minder 'onzin' te ontvangen.
# define RFSNS_MIN_PULSE_LENGTH 300 // (50) Pulsen korter dan deze tijd uSec. worden als stoorpulsen beschouwd.
# define RFSNS_RAWSIGNAL_SAMPLE 50 // Sample grootte / Resolutie in uSec waarmee ontvangen Rawsignalen pulsen worden opgeslagen
# define RFSNS_SIGNAL_TIMEOUT 10 // Pulse timings in mSec. Beyond this value indicate end of message
# define RFSNS_SIGNAL_REPEAT_TIME 500 // (500) Tijd in mSec. waarbinnen hetzelfde event niet nogmaals via RF mag binnenkomen. Onderdrukt ongewenste herhalingen van signaal
2018-12-17 17:06:19 +00:00
typedef struct RawSignalStruct // Variabelen geplaatst in struct zodat deze later eenvoudig kunnen worden weggeschreven naar SDCard
2018-12-11 13:24:52 +00:00
{
int Number ; // aantal bits, maal twee omdat iedere bit een mark en een space heeft.
2019-01-28 13:08:33 +00:00
uint8_t Repeats ; // Aantal maal dat de pulsreeks verzonden moet worden bij een zendactie.
uint8_t Multiply ; // Pulses[] * Multiply is de echte tijd van een puls in microseconden
2018-12-11 13:24:52 +00:00
unsigned long Time ; // Tijdstempel wanneer signaal is binnengekomen (millis())
2019-01-28 13:08:33 +00:00
uint8_t Pulses [ RFSNS_RAW_BUFFER_SIZE + 2 ] ; // Tabel met de gemeten pulsen in microseconden gedeeld door rfsns_raw_signal->Multiply. Dit scheelt helft aan RAM geheugen.
2018-12-11 13:24:52 +00:00
// Om legacy redenen zit de eerste puls in element 1. Element 0 wordt dus niet gebruikt.
2018-12-17 17:06:19 +00:00
} raw_signal_t ;
2018-12-11 13:24:52 +00:00
2019-03-26 17:26:50 +00:00
raw_signal_t * rfsns_raw_signal = nullptr ;
2018-12-11 13:24:52 +00:00
uint8_t rfsns_rf_bit ;
uint8_t rfsns_rf_port ;
2018-12-17 17:06:19 +00:00
uint8_t rfsns_any_sensor = 0 ;
2018-12-11 13:24:52 +00:00
/*********************************************************************************************\
* Fetch signals from RF pin
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2019-01-28 13:08:33 +00:00
bool RfSnsFetchSignal ( uint8_t DataPin , bool StateSignal )
2018-12-11 13:24:52 +00:00
{
uint8_t Fbit = digitalPinToBitMask ( DataPin ) ;
uint8_t Fport = digitalPinToPort ( DataPin ) ;
uint8_t FstateMask = ( StateSignal ? Fbit : 0 ) ;
if ( ( * portInputRegister ( Fport ) & Fbit ) = = FstateMask ) { // Als er signaal is
const unsigned long LoopsPerMilli = RFSNS_LOOPS_PER_MILLI ;
// Als het een herhalend signaal is, dan is de kans groot dat we binnen hele korte tijd weer in deze
// routine terugkomen en dan midden in de volgende herhaling terecht komen. Daarom wordt er in dit
// geval gewacht totdat de pulsen voorbij zijn en we met het capturen van data beginnen na een korte
// rust tussen de signalen. Op deze wijze wordt het aantal zinloze captures teruggebracht.
unsigned long PulseLength = 0 ;
2018-12-17 17:06:19 +00:00
if ( rfsns_raw_signal - > Time ) { // Eerst een snelle check, want dit bevindt zich in een tijdkritisch deel...
if ( rfsns_raw_signal - > Repeats & & ( rfsns_raw_signal - > Time + RFSNS_SIGNAL_REPEAT_TIME ) > millis ( ) ) { // ...want deze check duurt enkele micro's langer!
2018-12-11 13:24:52 +00:00
PulseLength = micros ( ) + RFSNS_SIGNAL_TIMEOUT * 1000 ; // Wachttijd
2018-12-17 17:06:19 +00:00
while ( ( ( rfsns_raw_signal - > Time + RFSNS_SIGNAL_REPEAT_TIME ) > millis ( ) ) & & ( PulseLength > micros ( ) ) ) {
2018-12-11 13:24:52 +00:00
if ( ( * portInputRegister ( Fport ) & Fbit ) = = FstateMask ) {
PulseLength = micros ( ) + RFSNS_SIGNAL_TIMEOUT * 1000 ;
}
}
2018-12-17 17:06:19 +00:00
while ( ( ( rfsns_raw_signal - > Time + RFSNS_SIGNAL_REPEAT_TIME ) > millis ( ) ) & & ( ( * portInputRegister ( Fport ) & Fbit ) ! = FstateMask ) ) ;
2018-12-11 13:24:52 +00:00
}
}
int RawCodeLength = 1 ; // We starten bij 1, dit om legacy redenen. Vroeger had element 0 een speciaal doel.
bool Ftoggle = false ;
unsigned long numloops = 0 ;
unsigned long maxloops = RFSNS_SIGNAL_TIMEOUT * LoopsPerMilli ;
2018-12-17 17:06:19 +00:00
rfsns_raw_signal - > Multiply = RFSNS_RAWSIGNAL_SAMPLE ; // Ingestelde sample groote.
2018-12-11 13:24:52 +00:00
do { // lees de pulsen in microseconden en plaats deze in de tijdelijke buffer rfsns_raw_signal
numloops = 0 ;
while ( ( ( * portInputRegister ( Fport ) & Fbit ) = = FstateMask ) ^ Ftoggle ) { // while() loop *A*
if ( numloops + + = = maxloops ) { break ; } // timeout opgetreden
}
PulseLength = ( numloops * 1000 ) / LoopsPerMilli ; // Bevat nu de pulslengte in microseconden
if ( PulseLength < RFSNS_MIN_PULSE_LENGTH ) { break ; }
Ftoggle = ! Ftoggle ;
2018-12-17 17:06:19 +00:00
rfsns_raw_signal - > Pulses [ RawCodeLength + + ] = PulseLength / ( unsigned long ) rfsns_raw_signal - > Multiply ; // sla op in de tabel rfsns_raw_signal
2018-12-11 13:24:52 +00:00
}
2018-12-17 17:06:19 +00:00
while ( RawCodeLength < RFSNS_RAW_BUFFER_SIZE & & numloops < = maxloops ) ; // Zolang nog ruimte in de buffer, geen timeout en geen stoorpuls
2018-12-11 13:24:52 +00:00
if ( ( RawCodeLength > = RFSNS_MIN_RAW_PULSES ) & & ( RawCodeLength < RFSNS_RAW_BUFFER_SIZE - 1 ) ) {
2018-12-17 17:06:19 +00:00
rfsns_raw_signal - > Repeats = 0 ; // Op dit moment weten we nog niet het type signaal, maar de variabele niet ongedefinieerd laten.
rfsns_raw_signal - > Number = RawCodeLength - 1 ; // Aantal ontvangen tijden (pulsen *2)
rfsns_raw_signal - > Pulses [ rfsns_raw_signal - > Number ] = 0 ; // Laatste element bevat de timeout. Niet relevant.
rfsns_raw_signal - > Time = millis ( ) ;
2018-12-11 13:24:52 +00:00
return true ;
}
else
2018-12-17 17:06:19 +00:00
rfsns_raw_signal - > Number = 0 ;
2018-12-11 13:24:52 +00:00
}
return false ;
}
# ifdef USE_THEO_V2
/*********************************************************************************************\
* Theo V2 protocol
* Dit protocol zorgt voor ontvangst van Theo sensoren met protocol V2
*
* Auteur : Theo Arends
* Support : www . sidweb . nl
* Datum : 17 Apr 2014
* Versie : 0.1 - Initiele versie
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Technische informatie :
*
* Theo Sensor V2 type 1 Message Format ( 7 Bytes , 57 bits ) :
* Checksum Type Chl BsVoltag Temperature Light
* S AAAAAAAA BBBBBCCC DEFFFFFF GGGGGGGG GGGGGGGG HHHHHHHH HHHHHHHH
* idx : 0 1 2 3 4 5 6
*
* Theo Sensor V2 type 2 Message Format ( 7 Bytes , 57 bits ) :
* Checksum Type Chl BsVoltag Temperature Humidity
* S AAAAAAAA BBBBBCCC DEFFFFFF GGGGGGGG GGGGGGGG HHHHHHHH HHHHHHHH
* idx : 0 1 2 3 4 5 6
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define RFSNS_THEOV2_MAX_CHANNEL 2 // Max number of ATTiny sensor channels supported
# define RFSNS_THEOV2_PULSECOUNT 114
# define RFSNS_THEOV2_RF_PULSE_MID 1000 // PWM: Pulsen langer zijn '1'
typedef struct {
uint32_t time ;
int16_t temp ;
uint16_t lux ;
uint8_t volt ;
} theo_v2_t1_t ;
typedef struct {
uint32_t time ;
int16_t temp ;
uint16_t hum ;
uint8_t volt ;
} theo_v2_t2_t ;
2019-03-26 17:26:50 +00:00
theo_v2_t1_t * rfsns_theo_v2_t1 = nullptr ;
theo_v2_t2_t * rfsns_theo_v2_t2 = nullptr ;
2018-12-17 17:06:19 +00:00
void RfSnsInitTheoV2 ( void )
{
rfsns_theo_v2_t1 = ( theo_v2_t1_t * ) malloc ( RFSNS_THEOV2_MAX_CHANNEL * sizeof ( theo_v2_t1_t ) ) ;
rfsns_theo_v2_t2 = ( theo_v2_t2_t * ) malloc ( RFSNS_THEOV2_MAX_CHANNEL * sizeof ( theo_v2_t2_t ) ) ;
rfsns_any_sensor + + ;
}
2018-12-11 13:24:52 +00:00
2018-12-17 17:06:19 +00:00
void RfSnsAnalyzeTheov2 ( void )
2018-12-11 13:24:52 +00:00
{
2018-12-17 17:06:19 +00:00
if ( rfsns_raw_signal - > Number ! = RFSNS_THEOV2_PULSECOUNT ) { return ; }
2018-12-11 13:24:52 +00:00
2019-01-28 13:08:33 +00:00
uint8_t Checksum ; // 8 bits Checksum over following bytes
uint8_t Channel ; // 3 bits channel
uint8_t Type ; // 5 bits type
uint8_t Voltage ; // 8 bits Vcc like 45 = 4.5V, bit 8 is batt low
2018-12-11 13:24:52 +00:00
int Payload1 ; // 16 bits
int Payload2 ; // 16 bits
2019-01-28 13:08:33 +00:00
uint8_t b , bytes , bits , id ;
2018-12-11 13:24:52 +00:00
2019-01-28 13:08:33 +00:00
uint8_t idx = 3 ;
uint8_t chksum = 0 ;
2018-12-11 13:24:52 +00:00
for ( bytes = 0 ; bytes < 7 ; bytes + + ) {
b = 0 ;
for ( bits = 0 ; bits < = 7 ; bits + + )
{
2018-12-17 17:06:19 +00:00
if ( ( rfsns_raw_signal - > Pulses [ idx ] * rfsns_raw_signal - > Multiply ) > RFSNS_THEOV2_RF_PULSE_MID ) {
2018-12-11 13:24:52 +00:00
b | = 1 < < bits ;
}
idx + = 2 ;
}
if ( bytes > 0 ) { chksum + = b ; } // bereken checksum
switch ( bytes ) {
case 0 :
Checksum = b ;
break ;
case 1 :
id = b ;
Channel = b & 0x7 ;
Type = ( b > > 3 ) & 0x1f ;
break ;
case 2 :
Voltage = b ;
break ;
case 3 :
Payload1 = b ;
break ;
case 4 :
Payload1 = ( b < < 8 ) | Payload1 ;
break ;
case 5 :
Payload2 = b ;
break ;
case 6 :
Payload2 = ( b < < 8 ) | Payload2 ;
break ;
}
}
2018-12-17 17:06:19 +00:00
if ( Checksum ! = chksum ) { return ; }
if ( ( Channel = = 0 ) | | ( Channel > RFSNS_THEOV2_MAX_CHANNEL ) ) { return ; }
Channel - - ;
2018-12-11 13:24:52 +00:00
2018-12-17 17:06:19 +00:00
rfsns_raw_signal - > Repeats = 1 ; // het is een herhalend signaal. Bij ontvangst herhalingen onderdukken
2018-12-11 13:24:52 +00:00
int Payload3 = Voltage & 0x3f ;
switch ( Type ) {
case 1 : // Temp / Lux
rfsns_theo_v2_t1 [ Channel ] . time = LocalTime ( ) ;
rfsns_theo_v2_t1 [ Channel ] . volt = Payload3 ;
rfsns_theo_v2_t1 [ Channel ] . temp = Payload1 ;
rfsns_theo_v2_t1 [ Channel ] . lux = Payload2 ;
break ;
case 2 : // Temp / Hum
rfsns_theo_v2_t2 [ Channel ] . time = LocalTime ( ) ;
rfsns_theo_v2_t2 [ Channel ] . volt = Payload3 ;
rfsns_theo_v2_t2 [ Channel ] . temp = Payload1 ;
rfsns_theo_v2_t2 [ Channel ] . hum = Payload2 ;
break ;
}
2019-03-08 14:15:42 +00:00
AddLog_P2 ( LOG_LEVEL_DEBUG , PSTR ( " RFS: TheoV2, ChkCalc %d, Chksum %d, id %d, Type %d, Ch %d, Volt %d, BattLo %d, Pld1 %d, Pld2 %d " ) ,
2018-12-11 13:24:52 +00:00
chksum , Checksum , id , Type , Channel + 1 , Payload3 , ( Voltage & 0x80 ) > > 7 , Payload1 , Payload2 ) ;
}
2018-12-17 17:06:19 +00:00
void RfSnsTheoV2Show ( bool json )
2018-12-11 13:24:52 +00:00
{
bool sensor_once = false ;
2019-06-30 15:44:36 +01:00
for ( uint32_t i = 0 ; i < RFSNS_THEOV2_MAX_CHANNEL ; i + + ) {
2018-12-11 13:24:52 +00:00
if ( rfsns_theo_v2_t1 [ i ] . time ) {
char sensor [ 10 ] ;
snprintf_P ( sensor , sizeof ( sensor ) , PSTR ( " TV2T1C%d " ) , i + 1 ) ;
2018-12-21 15:17:06 +00:00
char voltage [ 33 ] ;
2018-12-11 13:24:52 +00:00
dtostrfd ( ( float ) rfsns_theo_v2_t1 [ i ] . volt / 10 , 1 , voltage ) ;
if ( rfsns_theo_v2_t1 [ i ] . time < LocalTime ( ) - RFSNS_VALID_WINDOW ) {
if ( json ) {
2019-03-23 16:57:31 +00:00
ResponseAppend_P ( PSTR ( " , \" %s \" :{ \" " D_JSON_RFRECEIVED " \" : \" %s \" , \" " D_JSON_VOLTAGE " \" :%s} " ) ,
sensor , GetDT ( rfsns_theo_v2_t1 [ i ] . time ) . c_str ( ) , voltage ) ;
2018-12-11 13:24:52 +00:00
}
} else {
2018-12-21 15:17:06 +00:00
char temperature [ 33 ] ;
2018-12-11 13:24:52 +00:00
dtostrfd ( ConvertTemp ( ( float ) rfsns_theo_v2_t1 [ i ] . temp / 100 ) , Settings . flag2 . temperature_resolution , temperature ) ;
if ( json ) {
2019-03-23 16:57:31 +00:00
ResponseAppend_P ( PSTR ( " , \" %s \" :{ \" " D_JSON_TEMPERATURE " \" :%s, \" " D_JSON_ILLUMINANCE " \" :%d, \" " D_JSON_VOLTAGE " \" :%s} " ) ,
sensor , temperature , rfsns_theo_v2_t1 [ i ] . lux , voltage ) ;
2018-12-11 13:24:52 +00:00
# ifdef USE_DOMOTICZ
if ( ( 0 = = tele_period ) & & ! sensor_once ) {
DomoticzSensor ( DZ_TEMP , temperature ) ;
DomoticzSensor ( DZ_ILLUMINANCE , rfsns_theo_v2_t1 [ i ] . lux ) ;
sensor_once = true ;
}
# endif // USE_DOMOTICZ
# ifdef USE_WEBSERVER
} else {
2019-03-19 16:31:43 +00:00
WSContentSend_PD ( HTTP_SNS_TEMP , sensor , temperature , TempUnit ( ) ) ;
WSContentSend_PD ( HTTP_SNS_ILLUMINANCE , sensor , rfsns_theo_v2_t1 [ i ] . lux ) ;
2018-12-11 13:24:52 +00:00
# endif // USE_WEBSERVER
}
}
}
}
sensor_once = false ;
2019-06-30 15:44:36 +01:00
for ( uint32_t i = 0 ; i < RFSNS_THEOV2_MAX_CHANNEL ; i + + ) {
2018-12-11 13:24:52 +00:00
if ( rfsns_theo_v2_t2 [ i ] . time ) {
char sensor [ 10 ] ;
snprintf_P ( sensor , sizeof ( sensor ) , PSTR ( " TV2T2C%d " ) , i + 1 ) ;
2018-12-21 15:17:06 +00:00
char voltage [ 33 ] ;
2018-12-11 13:24:52 +00:00
dtostrfd ( ( float ) rfsns_theo_v2_t2 [ i ] . volt / 10 , 1 , voltage ) ;
if ( rfsns_theo_v2_t2 [ i ] . time < LocalTime ( ) - RFSNS_VALID_WINDOW ) {
if ( json ) {
2019-03-23 16:57:31 +00:00
ResponseAppend_P ( PSTR ( " , \" %s \" :{ \" " D_JSON_RFRECEIVED " \" : \" %s \" , \" " D_JSON_VOLTAGE " \" :%s} " ) ,
sensor , GetDT ( rfsns_theo_v2_t2 [ i ] . time ) . c_str ( ) , voltage ) ;
2018-12-11 13:24:52 +00:00
}
} else {
float temp = ConvertTemp ( ( float ) rfsns_theo_v2_t2 [ i ] . temp / 100 ) ;
2019-04-15 17:12:42 +01:00
float humi = ConvertHumidity ( ( float ) rfsns_theo_v2_t2 [ i ] . hum / 100 ) ;
2018-12-11 13:24:52 +00:00
if ( json ) {
2020-03-17 15:29:59 +00:00
ResponseAppend_P ( PSTR ( " , \" %s \" :{ " ) , sensor ) ;
ResponseAppendTHD ( temp , humi ) ;
ResponseAppend_P ( PSTR ( " , \" " D_JSON_VOLTAGE " \" :%s} " ) , voltage ) ;
2018-12-11 13:24:52 +00:00
if ( ( 0 = = tele_period ) & & ! sensor_once ) {
# ifdef USE_DOMOTICZ
2020-03-17 15:29:59 +00:00
DomoticzTempHumPressureSensor ( temp , humi ) ; //
2018-12-11 13:24:52 +00:00
# endif // USE_DOMOTICZ
# ifdef USE_KNX
KnxSensor ( KNX_TEMPERATURE , temp ) ;
KnxSensor ( KNX_HUMIDITY , humi ) ;
# endif // USE_KNX
sensor_once = true ;
}
# ifdef USE_WEBSERVER
} else {
2020-03-17 15:29:59 +00:00
WSContentSend_THD ( sensor , temp , humi ) ;
2018-12-11 13:24:52 +00:00
# endif // USE_WEBSERVER
}
}
}
}
}
# endif // USE_THEO_V2 ************************************************************************
# ifdef USE_ALECTO_V2
/*********************************************************************************************\
* Alecto V2 protocol
* Dit protocol zorgt voor ontvangst van Alecto weerstation buitensensoren
*
* Auteur : Nodo - team ( Martinus van den Broek ) www . nodo - domotica . nl
* Support ACH2010 en code optimalisatie door forumlid : Arendst
* Support : www . nodo - domotica . nl
* Datum : 25 Jan 2013
* Versie : 1.3
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Technische informatie :
* DKW2012 Message Format : ( 11 Bytes , 88 bits ) :
* AAAAAAAA AAAABBBB BBBB__CC CCCCCCCC DDDDDDDD EEEEEEEE FFFFFFFF GGGGGGGG GGGGGGGG HHHHHHHH IIIIIIII
* Temperature Humidity Windspd_ Windgust Rain____ ________ Winddir Checksum
* A = start / unknown , first 8 bits are always 11111111
* B = Rolling code
* C = Temperature ( 10 bit value with - 400 base )
* D = Humidity
* E = windspeed ( * 0.3 m / s , correction for webapp = 3600 / 1000 * 0.3 * 100 = 108 ) )
* F = windgust ( * 0.3 m / s , correction for webapp = 3600 / 1000 * 0.3 * 100 = 108 ) )
* G = Rain ( * 0.3 mm )
* H = winddirection ( 0 = north , 4 = east , 8 = south 12 = west )
* I = Checksum , calculation is still under investigation
*
* WS3000 and ACH2010 systems have no winddirection , message format is 8 bit shorter
* Message Format : ( 10 Bytes , 80 bits ) :
* AAAAAAAA AAAABBBB BBBB__CC CCCCCCCC DDDDDDDD EEEEEEEE FFFFFFFF GGGGGGGG GGGGGGGG HHHHHHHH
* Temperature Humidity Windspd_ Windgust Rain____ ________ Checksum
*
* DCF Time Message Format : ( NOT DECODED ! )
* AAAAAAAA BBBBCCCC DDDDDDDD EFFFFFFF GGGGGGGG HHHHHHHH IIIIIIII JJJJJJJJ KKKKKKKK LLLLLLLL MMMMMMMM
* 11 Hours Minutes Seconds Year Month Day ? Checksum
* B = 11 = DCF
* C = ?
* D = ?
* E = ?
* F = Hours BCD format ( 7 bits only for this byte , MSB could be ' 1 ' )
* G = Minutes BCD format
* H = Seconds BCD format
* I = Year BCD format ( only two digits ! )
* J = Month BCD format
* K = Day BCD format
* L = ?
* M = Checksum
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define RFSNS_DKW2012_PULSECOUNT 176
# define RFSNS_ACH2010_MIN_PULSECOUNT 160 // reduce this value (144?) in case of bad reception
# define RFSNS_ACH2010_MAX_PULSECOUNT 160
2018-12-11 17:00:12 +00:00
# define D_ALECTOV2 "AlectoV2"
const char kAlectoV2Directions [ ] PROGMEM = D_TX20_NORTH " | "
D_TX20_NORTH D_TX20_NORTH D_TX20_EAST " | "
D_TX20_NORTH D_TX20_EAST " | "
D_TX20_EAST D_TX20_NORTH D_TX20_EAST " | "
D_TX20_EAST " | "
D_TX20_EAST D_TX20_SOUTH D_TX20_EAST " | "
D_TX20_SOUTH D_TX20_EAST " | "
D_TX20_SOUTH D_TX20_SOUTH D_TX20_EAST " | "
D_TX20_SOUTH " | "
D_TX20_SOUTH D_TX20_SOUTH D_TX20_WEST " | "
D_TX20_SOUTH D_TX20_WEST " | "
D_TX20_WEST D_TX20_SOUTH D_TX20_WEST " | "
D_TX20_WEST " | "
D_TX20_WEST D_TX20_NORTH D_TX20_WEST " | "
D_TX20_NORTH D_TX20_WEST " | "
D_TX20_NORTH D_TX20_NORTH D_TX20_WEST ;
2018-12-11 13:24:52 +00:00
typedef struct {
uint32_t time ;
float temp ;
float rain ;
float wind ;
float gust ;
uint8_t type ;
uint8_t humi ;
uint8_t wdir ;
} alecto_v2_t ;
2019-03-26 17:26:50 +00:00
alecto_v2_t * rfsns_alecto_v2 = nullptr ;
2018-12-11 13:24:52 +00:00
uint16_t rfsns_alecto_rain_base = 0 ;
2018-12-17 17:06:19 +00:00
void RfSnsInitAlectoV2 ( void )
{
rfsns_alecto_v2 = ( alecto_v2_t * ) malloc ( sizeof ( alecto_v2_t ) ) ;
rfsns_any_sensor + + ;
}
void RfSnsAnalyzeAlectov2 ( )
2018-12-11 13:24:52 +00:00
{
2018-12-17 17:06:19 +00:00