From 1c23a7c36099051f216a0f7636c61f9ad9aed246 Mon Sep 17 00:00:00 2001 From: Daniel Collin Date: Fri, 29 Jan 2016 10:52:10 +0100 Subject: [PATCH] Added oregon v2.1 support to ArduinoTellstick along with some code cleanup Former-commit-id: d05ee71fa4f2f91afd6452e894385bbcd7020917 --- .../ArduinoTellstickDuo.ino | 40 ++-- arduino/ArduinoTellstickDuo/archtech.cpp | 81 +++++-- arduino/ArduinoTellstickDuo/archtech.h | 5 - arduino/ArduinoTellstickDuo/buffer.cpp | 20 -- arduino/ArduinoTellstickDuo/buffer.h | 24 +- arduino/ArduinoTellstickDuo/config.h | 22 +- .../oregon protocol specification.txt | 29 --- arduino/ArduinoTellstickDuo/oregonV2.1.cpp | 210 ++++++++++++++++++ arduino/ArduinoTellstickDuo/oregonV2.1.h | 11 + arduino/ArduinoTellstickDuo/rf.cpp | 56 +++-- arduino/ArduinoTellstickDuo/rf.h | 9 +- 11 files changed, 391 insertions(+), 116 deletions(-) delete mode 100644 arduino/ArduinoTellstickDuo/oregon protocol specification.txt create mode 100644 arduino/ArduinoTellstickDuo/oregonV2.1.cpp create mode 100644 arduino/ArduinoTellstickDuo/oregonV2.1.h diff --git a/arduino/ArduinoTellstickDuo/ArduinoTellstickDuo.ino b/arduino/ArduinoTellstickDuo/ArduinoTellstickDuo.ino index 1168aa3c..1ee65e23 100644 --- a/arduino/ArduinoTellstickDuo/ArduinoTellstickDuo.ino +++ b/arduino/ArduinoTellstickDuo/ArduinoTellstickDuo.ino @@ -3,27 +3,30 @@ #include "buffer.h" #include "config.h" +/* +* Timer2 interrupt in 16kHz. Samples the RF Rx data pin +*/ +ISR(TIMER2_COMPA_vect) { -ISR(TIMER2_COMPA_vect) { //timer2 interrupt 16kHz. Samples the RF Rx data pin - - if (!RFRX) { //if no Radio Rx should be performed + if ( !IS_RADIO_RECIEVER_ON() ) { //if no Radio Rx should be performed return; } - uint8_t bit = digitalRead(RX_PIN); // optimized "digital_read(7)" = "PIND & 0x1" + uint8_t bit = RX_PIN_READ(); //will store "lows" on even buffer addresses and "highs" on odd buffer addresses - if ( ( ((int)bufferWriteP) & 0x1 ) != bit ) { //compare the bit and the buffer pointer address. true if one is odd and one is even. + if ( ( ((uintptr_t)bufferWriteP) & 0x1 ) != bit ) { //compare the bit and the buffer pointer address. true if one is odd and one is even. //step the buffer pointer - if ( bufferWriteP + 1 > RF_rxBufferEndP) { + if ( bufferWriteP+1 > RF_rxBufferEndP ) { + *RF_rxBufferStartP = 1; //reset the next data point before going there bufferWriteP = RF_rxBufferStartP; } else { + *(bufferWriteP+1) = 1; //reset the next data point before going there ++bufferWriteP; } - *bufferWriteP = 1; //reset and step once on this addess } else { - if (*bufferWriteP < 255) { //only values up to 255 - ++(*bufferWriteP); //step the buffer + if ( *bufferWriteP < 255 ) { //Do not step the value if it already is 255 (max value) + ++(*bufferWriteP); //step the buffer value } } @@ -34,26 +37,27 @@ void setup() { Serial.begin(9600); - pinMode(RX_PIN, INPUT); //set RX pin to input - pinMode(TX_PIN, OUTPUT); //ser TX pin as output + setupPins(); //setup timer2 interrupt at 16kHz for RF sampling - cli();//stop interrupts - TCCR2A = 0;// set entire TCCR2A register to 0 - TCCR2B = 0;// same for TCCR2B - TCNT2 = 0;//initialize counter value to 0 - OCR2A = 124;// = ( (16*10^6) / (16000Hz*8pc) ) - 1 (must be <256) + cli(); //stop interrupts + TCCR2A = 0; // set entire TCCR2A register to 0 + TCCR2B = 0; // same for TCCR2B + TCNT2 = 0; //initialize counter value to 0 + OCR2A = 124; // = ( (16000000Hz) / (16000Hz*8prescaler) ) - 1 (must be <256) TCCR2A |= (1 << WGM21); // turn on CTC mode TCCR2B |= (1 << CS21); // Set CS21 bit for 8 prescaler TIMSK2 |= (1 << OCIE2A); // enable timer compare interrupt - sei();//allow interrupts + sei(); //allow interrupts //reset buffer just to be sure for (uint8_t* p = RF_rxBufferStartP; p <= RF_rxBufferEndP; ++p) { *p = 0; } + + Serial.println(F("+V2")); - RFRX = true; //start receiving radio data + ACTIVATE_RADIO_RECEIVER(); };//end setup diff --git a/arduino/ArduinoTellstickDuo/archtech.cpp b/arduino/ArduinoTellstickDuo/archtech.cpp index 38a65ede..d81371a7 100644 --- a/arduino/ArduinoTellstickDuo/archtech.cpp +++ b/arduino/ArduinoTellstickDuo/archtech.cpp @@ -1,15 +1,70 @@ #include "archtech.h" #include "buffer.h" -bool parseArctechSelfLearning(uint8_t* bufStartP, uint8_t* bufEndP) { //start points to a "one" buffer byte, end points to a "zero" buffer byte +/******************************************************************************* + --ARCHTECH PROTOCOL SPECIFICATION-- + + ----SIGNAL---- +A signal consists of a PREAMBLE, DATA and an POSTAMBLE. +Each signal is sent 4 times in a row to increase the delivery success rate. + + ----PREAMBLE---- +send high for 250 microseconds +send low for 2,500 microseconds + + ----DATA---- +26 bits of transmitter id +1 bit indicating if the on/off bit is targeting a group +1 bit indicating "on" or "off" +4 bits indicating the targeted unit/channel/device +4 bits indicating a absolute dim level (optional) + +Total: 32 or 36 bits depending if absolute dimming is used + +Each real bit in the data field is sent over air as a pair of two inverted bits. + real bit bits over air + 1 = "01" + 0 = "10" + +Over air a "1"(one) is sent as: +send high for 250 microseconds +send low for 1,250 microseconds + +Over air a "0"(zero) is sent as: +send high for 250 microseconds +send low for 250 microseconds + + ----POSTAMBLE---- +send high for 250 microseconds +send low for 10,000 microseconds + +*******************************************************************************/ + +#define ARCHTECH_SHORT_MIN 2 +#define ARCHTECH_SHORT_MAX 7 +#define ARCHTECH_LONG_MIN 17 +#define ARCHTECH_LONG_MAX 23 + +#define IS_SHORT(b) ( ARCHTECH_SHORT_MIN <= b && b <= ARCHTECH_SHORT_MAX ) +#define IS_LONG(b) ( ARCHTECH_LONG_MIN <= b && b <= ARCHTECH_LONG_MAX ) + +#define IS_ZERO(b1,b2,b3,b4) ( IS_SHORT(b1) && IS_LONG(b2) && IS_SHORT(b3) && IS_SHORT(b4) ) +#define IS_ONE(b1,b2,b3,b4) ( IS_SHORT(b1) && IS_SHORT(b2) && IS_SHORT(b3) && IS_LONG(b4) ) + +bool parseArctechSelfLearning(uint8_t* bufStartP, uint8_t* bufEndP) { //start points to a "high" buffer byte, end points to a "low" buffer byte uint64_t data = 0; - bool dimValuePresent = false; + bool dimValuePresent; - for (uint8_t i = 0; i < 31; ++i) { - - if (calculateBufferPointerDistance(bufStartP, bufEndP) < 4) { //less than 4 more high/low rto read in buffer - return false; - } + uint16_t bitsInBuffer = calculateBufferPointerDistance(bufStartP, bufEndP) / 4; //each bit is representd by 4 high/low + if (bitsInBuffer == 32) { + dimValuePresent = false; + }else if(bitsInBuffer == 36){ + dimValuePresent = true; + } else { + return false; + } + + for (uint8_t i = 0; i < bitsInBuffer-1; ++i) { uint8_t b1 = *bufStartP; //no of high stepBufferPointer(&bufStartP); @@ -20,18 +75,10 @@ bool parseArctechSelfLearning(uint8_t* bufStartP, uint8_t* bufEndP) { //start uint8_t b4 = *bufStartP; //no of low stepBufferPointer(&bufStartP); - //TODO: add support for absolute dim values - - if (ARCHTECH_LOW_LOW <= b1 && b1 <= ARCHTECH_LOW_HIGH && - ARCHTECH_LOW_LOW <= b2 && b2 <= ARCHTECH_LOW_HIGH && - ARCHTECH_LOW_LOW <= b3 && b3 <= ARCHTECH_LOW_HIGH && - ARCHTECH_HIGH_LOW <= b4 && b4 <= ARCHTECH_HIGH_HIGH) { //"one" is sent over air + if (IS_ONE(b1,b2,b3,b4)) { //"one" is sent over air data <<= 1; //shift in a zero data |= 0x1; //add one - } else if (ARCHTECH_LOW_LOW <= b1 && b1 <= ARCHTECH_LOW_HIGH && - ARCHTECH_HIGH_LOW <= b2 && b2 <= ARCHTECH_HIGH_HIGH && - ARCHTECH_LOW_LOW <= b3 && b3 <= ARCHTECH_LOW_HIGH && - ARCHTECH_LOW_LOW <= b4 && b4 <= ARCHTECH_LOW_HIGH) { //"zero" is sent over air + } else if (IS_ZERO(b1,b2,b3,b4)) { //"zero" is sent over air data <<= 1; //shift in a zero } else { return false; diff --git a/arduino/ArduinoTellstickDuo/archtech.h b/arduino/ArduinoTellstickDuo/archtech.h index 9acd8332..c35e307b 100644 --- a/arduino/ArduinoTellstickDuo/archtech.h +++ b/arduino/ArduinoTellstickDuo/archtech.h @@ -3,11 +3,6 @@ #include "Arduino.h" -#define ARCHTECH_LOW_LOW 2 //a "low" is defined as at least this many "low" samples in a row -#define ARCHTECH_LOW_HIGH 7 //a "low" is defined as at most this many "low" samples in a row -#define ARCHTECH_HIGH_LOW 17 //a "high" is defined as at least this many "high" samples in a row -#define ARCHTECH_HIGH_HIGH 23 //a "high" is defined as at most this many "high" samples in a row - bool parseArctechSelfLearning(uint8_t* bufStartP, uint8_t* bufEndP); #endif //ARCHTECH_H \ No newline at end of file diff --git a/arduino/ArduinoTellstickDuo/buffer.cpp b/arduino/ArduinoTellstickDuo/buffer.cpp index b13e30bf..446a980c 100644 --- a/arduino/ArduinoTellstickDuo/buffer.cpp +++ b/arduino/ArduinoTellstickDuo/buffer.cpp @@ -4,23 +4,3 @@ uint8_t RF_rxBuffer[512]; //must have and even number of elements uint8_t* RF_rxBufferStartP = &RF_rxBuffer[0]; uint8_t* RF_rxBufferEndP = &RF_rxBuffer[511]; volatile uint8_t* bufferWriteP = RF_rxBufferStartP; - -uint16_t calculateBufferPointerDistance(uint8_t* bufStartP, uint8_t* bufEndP) { - if (bufStartP <= bufEndP) { - return bufEndP - bufStartP + 1; - } else { - return (RF_rxBufferEndP - bufStartP) + (bufEndP - RF_rxBufferStartP) + 2; - } -}; //end calculateBufferPointerDistance - -uint8_t* getNextBufferPointer(uint8_t* p) { - if ( p + 1 > RF_rxBufferEndP) { - return RF_rxBufferStartP; - } else { - return p + 1; - } -}; //end getNextBufferPointer - -void stepBufferPointer(uint8_t** p) { - *p = getNextBufferPointer(*p); -}; //end stepBufferPointer diff --git a/arduino/ArduinoTellstickDuo/buffer.h b/arduino/ArduinoTellstickDuo/buffer.h index 7bd1dc30..9cee3b1e 100644 --- a/arduino/ArduinoTellstickDuo/buffer.h +++ b/arduino/ArduinoTellstickDuo/buffer.h @@ -3,13 +3,29 @@ #include "Arduino.h" -uint16_t calculateBufferPointerDistance(uint8_t* bufStartP, uint8_t* bufEndP); -uint8_t* getNextBufferPointer(uint8_t* p); -void stepBufferPointer(uint8_t** p); - extern uint8_t RF_rxBuffer[512]; //must have and even number of elements extern uint8_t* RF_rxBufferStartP; extern uint8_t* RF_rxBufferEndP; extern volatile uint8_t* bufferWriteP; +inline uint16_t calculateBufferPointerDistance(uint8_t* bufStartP, uint8_t* bufEndP) { + if (bufStartP <= bufEndP) { + return bufEndP - bufStartP + 1; + } else { + return (RF_rxBufferEndP - bufStartP) + (bufEndP - RF_rxBufferStartP) + 2; + } +}; //end calculateBufferPointerDistance + +inline uint8_t* getNextBufferPointer(uint8_t* p) { + if ( p + 1 > RF_rxBufferEndP) { + return RF_rxBufferStartP; + } else { + return p + 1; + } +}; //end getNextBufferPointer + +inline void stepBufferPointer(uint8_t** p) { + *p = getNextBufferPointer(*p); +}; //end stepBufferPointer + #endif //BUFFER_H diff --git a/arduino/ArduinoTellstickDuo/config.h b/arduino/ArduinoTellstickDuo/config.h index 08c9825c..43101ad5 100644 --- a/arduino/ArduinoTellstickDuo/config.h +++ b/arduino/ArduinoTellstickDuo/config.h @@ -1,7 +1,25 @@ #ifndef CONFIG_H #define CONFIG_H -#define RX_PIN 7 -#define TX_PIN 8 +#include "Arduino.h" + +/* +* RX PIN = 7 +* TX PIN = 8 +*/ +inline void setupPins(){ + pinMode(7, INPUT); + pinMode(8, OUTPUT); +}; + +#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__) + //pin7 = PD7 = port D, bit 8 + #define RX_PIN_READ() ( PIND & 0b00000001 ) // optimized "digitalRead(7)" + //pin8 = PB0 = port B, bit 1 + #define TX_PIN_LOW() ( PORTB &= 0b01111111 ) // optimized "digitalWrite(8, LOW)" + #define TX_PIN_HIGH() ( PORTB |= 0b10000000 ) // optimized "digitalWrite(8, HIGH)" +#else + #unsupported architecture +#endif #endif //CONFIG_H \ No newline at end of file diff --git a/arduino/ArduinoTellstickDuo/oregon protocol specification.txt b/arduino/ArduinoTellstickDuo/oregon protocol specification.txt deleted file mode 100644 index 9c761af1..00000000 --- a/arduino/ArduinoTellstickDuo/oregon protocol specification.txt +++ /dev/null @@ -1,29 +0,0 @@ -SIGNAL -signal i s two times in a row with a "low" pause of 8192us between them - -The message buffer is 9 bytes long - -Each signal starts with a preampble, the data and a postamble - -PREAMBLE -consists of two "one"-bytes - -DATA -9 bytes - -POSTAMBLE -consists of one "zero"-byte - -A "one" bit is sent over the air as: -high for 512us -low for 1024us -high for 512us - -A "zero" bit is sent over the air as: -low for 512us -high for 1024us -low for 512us - -1 byte = 8*(512+512+1024)us = 16384us -one signal = 2+9+1 bytes = 12 bytes = 196608us -signal + 8192 + signal = 401408us = 401.408ms diff --git a/arduino/ArduinoTellstickDuo/oregonV2.1.cpp b/arduino/ArduinoTellstickDuo/oregonV2.1.cpp new file mode 100644 index 00000000..b0319daf --- /dev/null +++ b/arduino/ArduinoTellstickDuo/oregonV2.1.cpp @@ -0,0 +1,210 @@ +#include "oregonV2.1.h" +#include "buffer.h" + +/******************************************************************************* + --OREGON v2.1 PROTOCOL SPECIFICATION-- + + ----SIGNAL---- +A signal consists of a PREAMBLE, DATA and an POSTAMBLE. +Each signal is sent 2 times in a row to increase the delivery success rate. +Between the two times there is a "low" pause of 8192us. + + ----PREAMBLE---- +send 16 "1"(ones) over the air + + ----DATA---- +16 bits of sensor type +XX bits of data (where XX <= 64) + +The length XX depends on the sensor type. I.e. 0x1A2D => XX=56 + +Over air a "1"(one) is sent as: +send high for 512 microseconds +send low for 1024 microseconds +send high for 512 microseconds + +Over air a "0"(zero) is sent as: +send low for 512 microseconds +send high for 1024 microseconds +send low for 512 microseconds + + ----POSTAMBLE---- +send 8 "0"(zeros) over the air + +*******************************************************************************/ + +#define SMALL_PULSE(x) ( 4<=x && x<=13 ) +#define BIG_PULSE(x) ( 12<=x && x<=22 ) +#define MORE_DATA_NEEDED -1 +#define INVALID_DATA -2 + +enum { + PARSE_PREAMP = 0, + PARSE_ID, + PARSE_DATA +} static state = PARSE_PREAMP; + +static uint8_t byteCnt = 0; +static uint8_t bitCnt = 0; +static uint8_t totByteCnt = 0; +int8_t byteLength = -1; + +void reset() { + byteCnt = 0; + bitCnt = 0; + totByteCnt = 0; + state = PARSE_PREAMP; + byteLength = -1; +}; //end reset + +void parseOregonStream(bool level, uint8_t count) { + static uint8_t cnt = 0; //used for counting stuff independent in every state + static uint16_t sensorType = 0; + static int8_t byte; + static uint8_t bytesToParse = 0; //the number of bytes left in the data part to parse + static uint8_t buffer[8]; + + if (level) { + count+=3; + } else { + count-=3; + } + + switch(state) { + case PARSE_PREAMP: //look for 25 big pulses followed by one short in a row + if (BIG_PULSE(count)) { + ++cnt; + break; + } + if (SMALL_PULSE(count)) { + if (cnt > 25) { + state=PARSE_ID; + sensorType = 0; + } + cnt = 0; + } + break; + + case PARSE_ID: //get the two first Bytes + byte = getByte(level, count); + if (byte == INVALID_DATA) { + reset(); + cnt = 0; + break; + } else if (byte == MORE_DATA_NEEDED) { + break; + } else { + if (sensorType == 0) { + sensorType = byte << 8; + } else { + sensorType |= byte; + switch (sensorType) { + case 0xEA4C: + bytesToParse = 5; + byteLength = 63; + break; + case 0x0A4D: + case 0x1A2D: //sensor THGR2228N (channel + sensor_id + battery_level + temp + humidity + checksum) + bytesToParse = 7; + byteLength = 79; + break; + default: + reset(); + cnt = 0; + return; + } + state = PARSE_DATA; + cnt = 0; + } + } + break; + + case PARSE_DATA: //get the remaining data + byte = getByte(level, count); + if (byte == INVALID_DATA) { + reset(); + cnt = 0; + break; + } else if (byte == MORE_DATA_NEEDED) { + break; + } + buffer[cnt] = byte; + ++cnt; + if (bytesToParse == 0) { + Serial.print(F("+Wclass:sensor;protocol:oregon;model:0x")); + Serial.print(sensorType, HEX); + Serial.print(F(";data:0x")); + for (int8_t i = 0; i < cnt; ++i) { + Serial.print(buffer[i], HEX); + } + Serial.println(F(";")); + reset(); + cnt = 0; + } + --bytesToParse; + + break; + } + +}; //end parseOregonStream + +int8_t getByte(bool level, uint8_t count) { + int8_t bit = getBit(level, count); + static uint8_t byte = 0; + + if (bit == INVALID_DATA) { + return INVALID_DATA; + } else if (bit == MORE_DATA_NEEDED) { + return MORE_DATA_NEEDED; + } + byte >>= 1; + if (bit) { + byte |= (1<<7); + } + ++totByteCnt; + ++byteCnt; + if (byteCnt < 8) { + return MORE_DATA_NEEDED; + } + byteCnt=0; + return byte; +}; //end getByte + +int8_t getBit(bool level, uint8_t count) { + static bool bit = 0; + + if (bitCnt == 0) { + //First pulse must be small + if (!SMALL_PULSE(count)) { + return INVALID_DATA; + } + bitCnt = 1; + + } else if (bitCnt == 1) { + //Second pulse must be long + if (!BIG_PULSE(count) && totByteCnt!=byteLength){ //special check - last byte might have strange values + bitCnt = 0; + return INVALID_DATA; + } + + bit = level; + bitCnt = 2; + return bit; + + } else if (bitCnt == 2) { + //Prepare for next bit + if (level && SMALL_PULSE(count)) { + //Clean start + bitCnt = 0; + } else if (BIG_PULSE(count)) { + //Combined bit + bitCnt = 1; + } else if (SMALL_PULSE(count)) { + //Clean start + bitCnt = 0; + } + return MORE_DATA_NEEDED; + } + + return MORE_DATA_NEEDED; +}; //end getBit diff --git a/arduino/ArduinoTellstickDuo/oregonV2.1.h b/arduino/ArduinoTellstickDuo/oregonV2.1.h new file mode 100644 index 00000000..953a94c3 --- /dev/null +++ b/arduino/ArduinoTellstickDuo/oregonV2.1.h @@ -0,0 +1,11 @@ +#ifndef OREGONV21_H +#define OREGONV21_H + +#include "Arduino.h" + +void reset(); +void parseOregonStream(bool level, uint8_t sampleCount); +int8_t getByte(bool level, uint8_t count); +int8_t getBit(bool level, uint8_t count); + +#endif //OREGONV21_H \ No newline at end of file diff --git a/arduino/ArduinoTellstickDuo/rf.cpp b/arduino/ArduinoTellstickDuo/rf.cpp index 2ed0d6a5..980cd4a4 100644 --- a/arduino/ArduinoTellstickDuo/rf.cpp +++ b/arduino/ArduinoTellstickDuo/rf.cpp @@ -2,6 +2,9 @@ #include "buffer.h" #include "archtech.h" #include "config.h" +#include "oregonV2.1.h" + +#define SILENCE_LENGTH 100 //the number of samples with "low" that represents a silent period between two signals volatile bool RFRX = false; @@ -13,19 +16,29 @@ void parseRadioRXBuffer() { bool parse = false; while (bufferReadP != bufferWriteP) { //stop if the read pointer is pointing to where the writing is currently performed - - if ( (((int)bufferReadP) & 0x1) == 1 ) { //buffer pointer is odd (stores highs) + uint8_t sampleCount = *bufferReadP; + + if ( (((uintptr_t)bufferReadP) & 0x1) == 1 ) { //buffer pointer is odd (stores highs) if (prevValue >= SILENCE_LENGTH) { - startDataP = bufferReadP; //some new data must starrt here since this is the first "high" after a silent period + startDataP = bufferReadP; //some new data must start here since this is the first "high" after a silent period } + + //stream data to stream parsers + parseOregonStream(HIGH, sampleCount); + } else { //buffer pointer is even (stores lows) - if (*bufferReadP >= SILENCE_LENGTH) { //evaluate if it is time to parse the curernt data + if (sampleCount >= SILENCE_LENGTH) { //evaluate if it is time to parse the curernt data endDataP = bufferReadP; //this is a silient period and must be the end of a data parse = true; break; } + + //stream data to stream parsers + parseOregonStream(LOW, sampleCount); + } + //step the read pointer one step uint8_t* nextBufferReadP = getNextBufferPointer(bufferReadP); if (nextBufferReadP == startDataP) { //next pointer will point to startDataP. Data will overflow. Reset the data pointers. startDataP = 0; @@ -35,7 +48,7 @@ void parseRadioRXBuffer() { //advance buffer pointer one step bufferReadP = nextBufferReadP; - prevValue = *bufferReadP; //update previous value + prevValue = sampleCount; //update previous value } if (!parse) { @@ -51,50 +64,57 @@ void parseRadioRXBuffer() { * and the endDataP will point at the first (low) silent period after the data data start. */ - //make sure that the data set size is big enought to parse. - uint16_t dataSetSize = calculateBufferPointerDistance(startDataP, endDataP); - if (dataSetSize < 32) { //at least 32 low/high - return; - } - //Let all available parsers parse the data set now. parseArctechSelfLearning(startDataP, endDataP); //TODO: add more parsers here + //reset the data pointers since the data have been parsed at this point + startDataP = 0; + endDataP = 0; + }; //end radioTask void sendTCodedData(uint8_t* data, uint8_t T_long, uint8_t* timings, uint8_t repeat, uint8_t pause) { - RFRX = false; //turn off the RF reciever + ACTIVATE_RADIO_TRANSMITTER(); for (uint8_t rep = 0; rep < repeat; ++rep) { bool nextPinState = HIGH; for (int i = 0; i < T_long; ++i) { uint8_t timeIndex = (data[i / 4] >> (6 - (2 * (i % 4)))) & 0x03; if (timings[timeIndex] > 0 || i == T_long - 1) { - digitalWrite(TX_PIN, nextPinState); + if(nextPinState){ + TX_PIN_HIGH(); + }else{ + TX_PIN_LOW(); + } delayMicroseconds(10 * timings[timeIndex]); } nextPinState = !nextPinState; } - digitalWrite(TX_PIN, LOW); + TX_PIN_LOW(); if (rep < repeat - 1) { delay(pause); } } - RFRX = true; //turn on the RF reciever + ACTIVATE_RADIO_RECEIVER(); }; void sendSCodedData(uint8_t* data, uint8_t pulseCount, uint8_t repeat, uint8_t pause) { - RFRX = false; //turn off the RF reciever + ACTIVATE_RADIO_TRANSMITTER(); for (uint8_t rep = 0; rep < repeat; ++rep) { bool nextPinState = HIGH; for (int i = 0; i < pulseCount; ++i) { if (data[i] > 0 || i == pulseCount - 1) { - digitalWrite(TX_PIN, nextPinState); + if(nextPinState){ + TX_PIN_HIGH(); + }else{ + TX_PIN_LOW(); + } delayMicroseconds(data[i] * 10); } nextPinState = !nextPinState; } delay(pause); } - RFRX = false; //turn on the RF reciever + TX_PIN_LOW(); + ACTIVATE_RADIO_RECEIVER(); }; diff --git a/arduino/ArduinoTellstickDuo/rf.h b/arduino/ArduinoTellstickDuo/rf.h index a77a2b50..c8507c5c 100644 --- a/arduino/ArduinoTellstickDuo/rf.h +++ b/arduino/ArduinoTellstickDuo/rf.h @@ -3,12 +3,15 @@ #include "Arduino.h" -#define SILENCE_LENGTH 100 //the number of samples with "low" that represents a silent period between two signals +#define ACTIVATE_RADIO_RECEIVER() (RFRX = true) +#define ACTIVATE_RADIO_TRANSMITTER() (RFRX = false) +#define IS_RADIO_RECIEVER_ON() (RFRX) +#define IS_RADIO_TRANSMITTER_ON() (!RFRX) + +extern volatile bool RFRX; void parseRadioRXBuffer(); void sendTCodedData(uint8_t* data, uint8_t T_long, uint8_t* timings, uint8_t repeat, uint8_t pause); void sendSCodedData(uint8_t* data, uint8_t pulseCount, uint8_t repeat, uint8_t pause); -extern volatile bool RFRX; - #endif //RF_H