hal/arduino/NexaTellstick/NexaTellstick.ino

156 lines
5 KiB
Arduino
Raw Normal View History

#include "NexaSelfLearningReceiver.h"
#define TX_PIN 10
#define RX_PIN 4
#define RX_LED 13
//Radio RX
NexaSelfLearningReceiver receiver = NexaSelfLearningReceiver(RX_PIN, RX_LED);
short dim = 0;
uint64_t receivedSignal = 0;
//Serial RX
byte rxBuffer[79];
void setup(){
Serial.begin(9600);
};
void loop(){
//Receive and execute command over serial
if(Serial.available() > 0){
uint8_t rxDataSize = Serial.readBytesUntil('+', &rxBuffer[0], 79);
if(rxDataSize > 0){
if(parseRxBuffer(&rxBuffer[0], 0, rxDataSize, false, 3, 0)){
//Serial.println(F("DEBUG:PARSE OK"));
}else{
//Serial.println(F("DEBUG:PARSE ERROR"));
}
}
}
//Receive signal over air and send it over serial
receivedSignal = receiver.receiveSignal(NULL, NULL, NULL, NULL, &dim, 100);
if(receivedSignal > 0){
Serial.print(F("+Wclass:command;protocol:arctech;model:selflearning;data:0x"));
uint8_t hexToSend = (dim == NULL ? 8 : 9);
for(int8_t i = hexToSend-1; i >= 0; --i){
Serial.print( (byte)((receivedSignal>>(4*i))&0x0F), HEX);
}
Serial.println(F(";"));
}
};
bool parseRxBuffer(byte* buffer, uint8_t startIndex, uint8_t endIndex, bool debug, uint8_t repeat, uint8_t pause){
if(startIndex > endIndex){
return false;
}
char c = buffer[startIndex];
//Serial.print("DEBUG: char:"); Serial.println(c, DEC);
switch(c){
case 'S':
return handleS(buffer, startIndex+1, endIndex, debug, repeat, pause);
case 'T':
return handleT(buffer, startIndex+1, endIndex, debug, repeat, pause);
case 'V':
Serial.println(F("+V2"));
return parseRxBuffer(buffer, startIndex+1, endIndex, debug, repeat, pause);
case 'D':
return parseRxBuffer(buffer, startIndex+1, endIndex, !debug, repeat, pause);
case 'P':
if(endIndex-startIndex+1 < 3){return false;} //at least {'P',[p-value],'+'} must be left in the buffer
return parseRxBuffer(buffer, startIndex+2, endIndex, debug, repeat, buffer[startIndex+1]);
case 'R':
if(endIndex-startIndex+1 < 3){return false;} //at least {'R',[r-value],'+'} must be left in the buffer
return parseRxBuffer(buffer, startIndex+2, endIndex, debug, buffer[startIndex+1], pause);
case '+':
return true;
default:
//Serial.print("DEBUG: unknown char: '"); Serial.print(c, BIN); Serial.println("'");
return false;
}
};
bool handleS(byte* buffer, uint8_t startIndex, uint8_t endIndex, bool debug, uint8_t repeat, uint8_t pause){
//Parse message received from serial
uint8_t S_data[78]; //78 pulses
uint8_t pulseCount = 0;
for(uint8_t i = startIndex; i <= endIndex; ++i){
if(buffer[i] == '+'){
break;
}else if(i == endIndex){
return false;
}else{
S_data[pulseCount++] = buffer[i];
}
}
//Send message
for(uint8_t rep = 0; rep < repeat; ++rep){
bool nextPinState = HIGH;
for(int i = 0; i < pulseCount; ++i){
if(S_data[i] > 0 || i == pulseCount-1){
digitalWrite(TX_PIN, nextPinState);
delayMicroseconds(S_data[i]*10);
}
nextPinState = !nextPinState;
}
delay(pause);
}
//send confirmation over serial
Serial.println(F("+S"));
return true;
};
bool handleT(byte* buffer, uint8_t startIndex, uint8_t endIndex, bool debug, uint8_t repeat, uint8_t pause){
//Parse message received from serial
uint8_t T_data[72]; //0-188 pulses
if(endIndex - startIndex < 5){
//Serial.println("DEBUG: wrong size!");
return false;
}
uint8_t buff_p = startIndex;
uint8_t T_times[4] = {buffer[buff_p++], buffer[buff_p++], buffer[buff_p++], buffer[buff_p++]};
uint8_t T_long = buffer[buff_p++];
uint8_t T_bytes = 0;
if( (T_long/4.0) > (float)(T_long/4) ){
T_bytes = T_long/4 + 1;
}else{
T_bytes = T_long/4;
}
uint8_t j = 0;
while(j < T_bytes){
if(buffer[buff_p] == '+'){
break;
}else if(buff_p >= endIndex){
return false;
}else{
T_data[j++] = buffer[buff_p++];
}
}
if( j != T_bytes ){
return false;
}
//Send message
for(uint8_t rep = 0; rep < repeat; ++rep){
bool nextPinState = HIGH;
for(int i = 0; i < T_long; ++i){
uint8_t timeIndex = (T_data[i/4]>>(6-(2*(i%4))))&0x03;
if(T_times[timeIndex] > 0 || i == T_long-1){
digitalWrite(TX_PIN, nextPinState);
delayMicroseconds(10*T_times[timeIndex]);
}
nextPinState = !nextPinState;
}
digitalWrite(TX_PIN, LOW);
if(rep < repeat-1){
delay(pause);
}
}
//send confirmation over serial
Serial.println(F("+T"));
return parseRxBuffer(buffer, buff_p, endIndex, debug, repeat, pause);
};