mirror of
https://github.com/pyrou/X10RF-Arduino.git
synced 2026-07-27 19:56:18 +00:00
Merge pull request #5 from arcadien/fix/out_of_bounds
Fix out of bounds array access
This commit is contained in:
@@ -1,255 +1,328 @@
|
||||
/*
|
||||
x10rf.cpp
|
||||
x10rf.cpp
|
||||
Library for sending x10 messages by RF.
|
||||
Created by Pieter Paul Baron (embedded [at] ppbaron.nl), November 2013.
|
||||
Released into the public domain.
|
||||
|
||||
Library to send x10 messages via a cheap 433Mhz OOK device. No X10 Firecracker (CMA17A) necessary.
|
||||
Decoding messages is not implemented.
|
||||
This library can emulate x10 switches and security devices and also RFXMeter and RFXSensor devices manufactured by RFXCom. (www.rfxcom.com)
|
||||
Library to send x10 messages via a cheap 433Mhz OOK device. No X10 Firecracker
|
||||
(CMA17A) necessary. Decoding messages is not implemented. This library can
|
||||
emulate x10 switches and security devices and also RFXMeter and RFXSensor
|
||||
devices manufactured by RFXCom. (www.rfxcom.com)
|
||||
|
||||
Tested on a TI Stellarpad (LM4F120H5QR) and Energia 0101E0010. This should also work on Arduino (small modifications) or other TI Launchpad devices.
|
||||
Tested on a TI Stellaris Launchpad (LM4F120H5QR) and Energia 0101E0010. This
|
||||
should also work on Arduino (small modifications) or other TI Launchpad devices.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#include "Arduino.h"
|
||||
#elif defined(ENERGIA) // LaunchPad, FraunchPad and StellarPad specific
|
||||
#include "Energia.h"
|
||||
#include "Energia.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
#include "x10rf.h"
|
||||
|
||||
#define X10_RF_SB_LONG 8960 // Start burts (leader) = 9ms
|
||||
#define X10_RF_SB_SHORT 4500 //Start silecence (leader) = 4,5 ms
|
||||
#define X10_RF_BIT_LONG 1120 // Bit 1 pulse length
|
||||
#define X10_RF_BIT_SHORT 560 // Bit 1 pulse length
|
||||
#define X10_RF_GAP 40000 // Length between commands
|
||||
#define X10_RF_SB_LONG 8960 // Start burts (leader) = 9ms
|
||||
#define X10_RF_SB_SHORT 4500 // Start silecence (leader) = 4,5 ms
|
||||
#define X10_RF_BIT_LONG 1120 // Bit 1 pulse length
|
||||
#define X10_RF_BIT_SHORT 560 // Bit 1 pulse length
|
||||
#define X10_RF_GAP 40000 // Length between commands
|
||||
|
||||
void x10rf::begin()
|
||||
{
|
||||
pinMode(_tx_pin, OUTPUT);
|
||||
if (_led_pin > 0) pinMode(_led_pin, OUTPUT);
|
||||
}
|
||||
|
||||
x10rf::x10rf(uint8_t tx_pin, uint8_t led_pin, uint8_t rf_repeats)
|
||||
{
|
||||
_tx_pin = tx_pin;
|
||||
_led_pin = led_pin;
|
||||
_rf_repeats = rf_repeats;
|
||||
void x10rf::begin() {
|
||||
pinMode(_tx_pin, OUTPUT);
|
||||
if (_led_pin > 0)
|
||||
pinMode(_led_pin, OUTPUT);
|
||||
}
|
||||
|
||||
void x10rf::RFXmeter(uint8_t rfxm_address, uint8_t rfxm_packet_type, long rfxm_value){
|
||||
uint8_t x10buff[5]; // Set message buffer
|
||||
x10buff[0] = rfxm_address;
|
||||
x10buff[1] = (~x10buff[0] & 0xF0) + (x10buff[0] & 0xF); // Calculate byte1 (byte 1 complement upper nibble of byte0)
|
||||
if (rfxm_value > 0xFFFFFF) rfxm_value = 0; // We only have 3 byte for data. Is overflowed set to 0
|
||||
// Packet type goed into MSB nibble of byte 5. Max 15 (B1111) allowed
|
||||
// Use switch case to filter invalid data types
|
||||
switch(rfxm_packet_type) {
|
||||
case 0x00: //Normal. Put counter values in byte 4,2 and 3
|
||||
x10buff[4] = (uint8_t) ((rfxm_value >> 16) & 0xff);
|
||||
x10buff[2] = (uint8_t) ((rfxm_value >> 8) & 0xff);
|
||||
x10buff[3] = (uint8_t) (rfxm_value & 0xff);
|
||||
break;
|
||||
case 0x01: // New interval time set. Byte 2 should be filled with interval
|
||||
switch(rfxm_value) {
|
||||
case 0x01: break; // 30sec
|
||||
case 0x02: break; // 01min
|
||||
case 0x04: break; // 06min (RFXpower = 05min)
|
||||
case 0x08: break; // 12min (RFXpower = 10min)
|
||||
case 0x10: break; // 15min
|
||||
case 0x20: break; // 30min
|
||||
case 0x40: break; // 45min
|
||||
case 0x80: break; // 60min
|
||||
default:
|
||||
rfxm_value = 0x01; // Set to 30 sec if no valid option is found
|
||||
}
|
||||
x10buff[2] = rfxm_value;
|
||||
break;
|
||||
case 0x02: // calibrate value in <counter value> in µsec.
|
||||
x10buff[4] = (uint8_t) ((rfxm_value >> 16) & 0xff);
|
||||
x10buff[2] = (uint8_t) ((rfxm_value >> 8) & 0xff);
|
||||
x10buff[3] = (uint8_t) (rfxm_value & 0xff);
|
||||
break;
|
||||
case 0x03: break;// new address set
|
||||
case 0x04: break; // counter value reset to zero
|
||||
case 0x0B: // counter value set
|
||||
x10buff[4] = (uint8_t) ((rfxm_value >> 16) & 0xff);
|
||||
x10buff[2] = (uint8_t) ((rfxm_value >> 8) & 0xff);
|
||||
x10buff[3] = (uint8_t) (rfxm_value & 0xff);
|
||||
break;
|
||||
case 0x0C: break; // set interval mode within 5 seconds
|
||||
case 0x0D: break; // calibration mode within 5 seconds
|
||||
case 0x0E: break; // set address mode within 5 seconds
|
||||
case 0x0F: // identification packet (byte 2 = address, byte 3 = interval)
|
||||
switch(rfxm_value) {
|
||||
case 0x01: break; //30sec
|
||||
case 0x02: break; //01min
|
||||
case 0x04: break; //06min (RFXpower = 05min)
|
||||
case 0x08: break; //12min (RFXpower = 10min)
|
||||
case 0x10: break; // 15min1
|
||||
case 0x20: break; // 30min
|
||||
case 0x40: break; // 45min
|
||||
case 0x80: break; // 60min
|
||||
default:
|
||||
rfxm_value = 0x01; // Set to 30 sec if no valid option is found
|
||||
}
|
||||
x10buff[2] = rfxm_address;
|
||||
x10buff[3] = rfxm_value;
|
||||
break;
|
||||
default: //Unknown packet type. Set packet type to zero and set counter to rfxm_value
|
||||
rfxm_packet_type = 0;
|
||||
x10buff[4] = (uint8_t) ((rfxm_value >> 16) & 0xff);
|
||||
x10buff[2] = (uint8_t) ((rfxm_value >> 8) & 0xff);
|
||||
x10buff[3] = (uint8_t) (rfxm_value & 0xff);
|
||||
}
|
||||
x10buff[5] = (rfxm_packet_type << 4); // Packet type goes into byte 5's upper nibble.
|
||||
// Calculate parity which
|
||||
uint8_t parity = ~(((x10buff[0] & 0XF0) >> 4) + (x10buff[0] & 0XF) + ((x10buff[1] & 0XF0) >> 4) + (x10buff[1] & 0XF) + ((x10buff[2] & 0XF0) >> 4) + (x10buff[2] & 0XF) + ((x10buff[3] & 0XF0) >> 4) + (x10buff[3] & 0XF) + ((x10buff[4] & 0XF0) >> 4) + (x10buff[4] & 0XF) + ((x10buff[5] & 0XF0) >> 4));
|
||||
x10buff[5] = (x10buff[5] & 0xf0) + (parity & 0XF);
|
||||
SendCommand(x10buff, sizeof(x10buff)); // Send byte to be broadcasted
|
||||
x10rf::x10rf(uint8_t tx_pin, uint8_t led_pin, uint8_t rf_repeats) {
|
||||
_tx_pin = tx_pin;
|
||||
_led_pin = led_pin;
|
||||
_rf_repeats = rf_repeats;
|
||||
}
|
||||
|
||||
void x10rf::RFXsensor(uint8_t rfxs_address,uint8_t rfxs_type, char rfxs_packet_type, uint8_t rfxs_value){
|
||||
uint8_t x10buff[3]; // Set message buffer 4 bytes
|
||||
x10buff[0] = (rfxs_address << 2);
|
||||
switch (rfxs_type) {
|
||||
case 't': break; // Temperature (default)
|
||||
case 'a': // A/D
|
||||
x10buff[0] = x10buff[0] + B01;
|
||||
break;
|
||||
case 'm': // message
|
||||
x10buff[0] = x10buff[0] + B11;
|
||||
break;
|
||||
case 'v': // voltage
|
||||
x10buff[0] = x10buff[0] + B10;
|
||||
break;
|
||||
}
|
||||
x10buff[1] = (~x10buff[0] & 0xF0) + (x10buff[0] & 0xF); // Calculate byte1 (byte 1 complement MSB nibble of byte0)
|
||||
x10buff[2] = rfxs_value;
|
||||
switch(rfxs_packet_type) {
|
||||
case 't': //temperature sensor (MSB = 0.5 degrees bit off)
|
||||
x10buff[3] = 0x00;
|
||||
break;
|
||||
case 'T': //emperature sensor (MSB = 0.5 degrees bit on)
|
||||
x10buff[3] = 0x80;
|
||||
break;
|
||||
case 'h': //RFU (humidity sensor)
|
||||
x10buff[3] = 0x20;
|
||||
break;
|
||||
case 'p': //RFU (pressure sensor)
|
||||
x10buff[3] = 0x40;
|
||||
break;
|
||||
default:
|
||||
x10buff[3] = 0x00;
|
||||
}
|
||||
uint8_t parity = ~(((x10buff[0] & 0XF0) >> 4) + (x10buff[0] & 0XF) + ((x10buff[1] & 0XF0) >> 4) + (x10buff[1] & 0XF) + ((x10buff[2] & 0XF0) >> 4) + (x10buff[2] & 0XF) + ((x10buff[3] & 0XF0) >> 4));
|
||||
x10buff[3] = (x10buff[3] & 0xf0) + (parity & 0XF);
|
||||
SendCommand(x10buff, sizeof(x10buff));
|
||||
void x10rf::RFXmeter(uint8_t rfxm_address, uint8_t rfxm_packet_type,
|
||||
long rfxm_value) {
|
||||
|
||||
static const uint8_t BUFFER_SIZE = 6;
|
||||
uint8_t x10buff[BUFFER_SIZE];
|
||||
x10buff[0] = rfxm_address;
|
||||
x10buff[1] =
|
||||
(~x10buff[0] & 0xF0) +
|
||||
(x10buff[0] &
|
||||
0xF); // Calculate byte1 (byte 1 complement upper nibble of byte0)
|
||||
if (rfxm_value > 0xFFFFFF)
|
||||
rfxm_value = 0; // We only have 3 byte for data. Is overflowed set to 0
|
||||
// Packet type goed into MSB nibble of byte 5. Max 15 (B1111) allowed
|
||||
// Use switch case to filter invalid data types
|
||||
switch (rfxm_packet_type) {
|
||||
case 0x00: // Normal. Put counter values in byte 4,2 and 3
|
||||
x10buff[4] = (uint8_t)((rfxm_value >> 16) & 0xff);
|
||||
x10buff[2] = (uint8_t)((rfxm_value >> 8) & 0xff);
|
||||
x10buff[3] = (uint8_t)(rfxm_value & 0xff);
|
||||
break;
|
||||
case 0x01: // New interval time set. Byte 2 should be filled with interval
|
||||
switch (rfxm_value) {
|
||||
case 0x01:
|
||||
break; // 30sec
|
||||
case 0x02:
|
||||
break; // 01min
|
||||
case 0x04:
|
||||
break; // 06min (RFXpower = 05min)
|
||||
case 0x08:
|
||||
break; // 12min (RFXpower = 10min)
|
||||
case 0x10:
|
||||
break; // 15min
|
||||
case 0x20:
|
||||
break; // 30min
|
||||
case 0x40:
|
||||
break; // 45min
|
||||
case 0x80:
|
||||
break; // 60min
|
||||
default:
|
||||
rfxm_value = 0x01; // Set to 30 sec if no valid option is found
|
||||
}
|
||||
x10buff[2] = rfxm_value;
|
||||
break;
|
||||
case 0x02: // calibrate value in <counter value> in µsec.
|
||||
x10buff[4] = (uint8_t)((rfxm_value >> 16) & 0xff);
|
||||
x10buff[2] = (uint8_t)((rfxm_value >> 8) & 0xff);
|
||||
x10buff[3] = (uint8_t)(rfxm_value & 0xff);
|
||||
break;
|
||||
case 0x03:
|
||||
break; // new address set
|
||||
case 0x04:
|
||||
break; // counter value reset to zero
|
||||
case 0x0B: // counter value set
|
||||
x10buff[4] = (uint8_t)((rfxm_value >> 16) & 0xff);
|
||||
x10buff[2] = (uint8_t)((rfxm_value >> 8) & 0xff);
|
||||
x10buff[3] = (uint8_t)(rfxm_value & 0xff);
|
||||
break;
|
||||
case 0x0C:
|
||||
break; // set interval mode within 5 seconds
|
||||
case 0x0D:
|
||||
break; // calibration mode within 5 seconds
|
||||
case 0x0E:
|
||||
break; // set address mode within 5 seconds
|
||||
case 0x0F: // identification packet (byte 2 = address, byte 3 = interval)
|
||||
switch (rfxm_value) {
|
||||
case 0x01:
|
||||
break; // 30sec
|
||||
case 0x02:
|
||||
break; // 01min
|
||||
case 0x04:
|
||||
break; // 06min (RFXpower = 05min)
|
||||
case 0x08:
|
||||
break; // 12min (RFXpower = 10min)
|
||||
case 0x10:
|
||||
break; // 15min1
|
||||
case 0x20:
|
||||
break; // 30min
|
||||
case 0x40:
|
||||
break; // 45min
|
||||
case 0x80:
|
||||
break; // 60min
|
||||
default:
|
||||
rfxm_value = 0x01; // Set to 30 sec if no valid option is found
|
||||
}
|
||||
x10buff[2] = rfxm_address;
|
||||
x10buff[3] = rfxm_value;
|
||||
break;
|
||||
default: // Unknown packet type. Set packet type to zero and set counter to
|
||||
// rfxm_value
|
||||
rfxm_packet_type = 0;
|
||||
x10buff[4] = (uint8_t)((rfxm_value >> 16) & 0xff);
|
||||
x10buff[2] = (uint8_t)((rfxm_value >> 8) & 0xff);
|
||||
x10buff[3] = (uint8_t)(rfxm_value & 0xff);
|
||||
}
|
||||
x10buff[5] =
|
||||
(rfxm_packet_type << 4); // Packet type goes into byte 5's upper nibble.
|
||||
// Calculate parity which
|
||||
uint8_t parity = ~(((x10buff[0] & 0XF0) >> 4) + (x10buff[0] & 0XF) +
|
||||
((x10buff[1] & 0XF0) >> 4) + (x10buff[1] & 0XF) +
|
||||
((x10buff[2] & 0XF0) >> 4) + (x10buff[2] & 0XF) +
|
||||
((x10buff[3] & 0XF0) >> 4) + (x10buff[3] & 0XF) +
|
||||
((x10buff[4] & 0XF0) >> 4) + (x10buff[4] & 0XF) +
|
||||
((x10buff[5] & 0XF0) >> 4));
|
||||
x10buff[5] = (x10buff[5] & 0xf0) + (parity & 0XF);
|
||||
SendCommand(x10buff, BUFFER_SIZE);
|
||||
}
|
||||
|
||||
void x10rf::x10Switch(char house_code, uint8_t unit_code, uint8_t command){
|
||||
uint8_t x10buff[3]; // Set message buffer 4 bytes
|
||||
switch(tolower(house_code)) {
|
||||
case 'a': x10buff[0] = B0110; break;
|
||||
case 'b': x10buff[0] = B0111; break;
|
||||
case 'c': x10buff[0] = B0100; break;
|
||||
case 'd': x10buff[0] = B0101; break;
|
||||
case 'e': x10buff[0] = B1000; break;
|
||||
case 'f': x10buff[0] = B1001; break;
|
||||
case 'g': x10buff[0] = B1010; break;
|
||||
case 'h': x10buff[0] = B1011; break;
|
||||
case 'i': x10buff[0] = B1110; break;
|
||||
case 'j': x10buff[0] = B1111; break;
|
||||
case 'k': x10buff[0] = B1100; break;
|
||||
case 'l': x10buff[0] = B1101; break;
|
||||
case 'm': x10buff[0] = B0000; break;
|
||||
case 'n': x10buff[0] = B0001; break;
|
||||
case 'o': x10buff[0] = B0010; break;
|
||||
case 'p': x10buff[0] = B0011; break;
|
||||
default: x10buff[0] = 0; break;
|
||||
}
|
||||
x10buff[0] = x10buff[0] << 4; // House code goes into the upper nibble
|
||||
void x10rf::RFXsensor(uint8_t rfxs_address, uint8_t rfxs_type,
|
||||
char rfxs_packet_type, uint8_t rfxs_value) {
|
||||
|
||||
switch(command) {
|
||||
case ON:
|
||||
case OFF:
|
||||
case BRIGHT:
|
||||
case DIM:
|
||||
x10buff[2] = command; break;
|
||||
}
|
||||
// Set unit number
|
||||
unit_code = unit_code - 1;
|
||||
bitWrite(x10buff[2],6,bitRead(unit_code,2));
|
||||
bitWrite(x10buff[2],3,bitRead(unit_code,1));
|
||||
bitWrite(x10buff[2],4,bitRead(unit_code,0));
|
||||
bitWrite(x10buff[0],2,bitRead(unit_code,3));
|
||||
// Set parity
|
||||
x10buff[1] = ~x10buff[0];
|
||||
x10buff[3] = ~x10buff[2];
|
||||
SendCommand(x10buff, sizeof(x10buff));
|
||||
static const uint8_t BUFFER_SIZE = 4;
|
||||
|
||||
uint8_t x10buff[BUFFER_SIZE; 4 bytes
|
||||
x10buff[0] = (rfxs_address << 2);
|
||||
switch (rfxs_type) {
|
||||
case 't':
|
||||
break; // Temperature (default)
|
||||
case 'a': // A/D
|
||||
x10buff[0] = x10buff[0] + B01;
|
||||
break;
|
||||
case 'm': // message
|
||||
x10buff[0] = x10buff[0] + B11;
|
||||
break;
|
||||
case 'v': // voltage
|
||||
x10buff[0] = x10buff[0] + B10;
|
||||
break;
|
||||
}
|
||||
x10buff[1] = (~x10buff[0] & 0xF0) +
|
||||
(x10buff[0] &
|
||||
0xF); // Calculate byte1 (byte 1 complement MSB nibble of byte0)
|
||||
x10buff[2] = rfxs_value;
|
||||
switch (rfxs_packet_type) {
|
||||
case 't': // temperature sensor (MSB = 0.5 degrees bit off)
|
||||
x10buff[3] = 0x00;
|
||||
break;
|
||||
case 'T': // emperature sensor (MSB = 0.5 degrees bit on)
|
||||
x10buff[3] = 0x80;
|
||||
break;
|
||||
case 'h': // RFU (humidity sensor)
|
||||
x10buff[3] = 0x20;
|
||||
break;
|
||||
case 'p': // RFU (pressure sensor)
|
||||
x10buff[3] = 0x40;
|
||||
break;
|
||||
default:
|
||||
x10buff[3] = 0x00;
|
||||
}
|
||||
uint8_t parity = ~(((x10buff[0] & 0XF0) >> 4) + (x10buff[0] & 0XF) +
|
||||
((x10buff[1] & 0XF0) >> 4) + (x10buff[1] & 0XF) +
|
||||
((x10buff[2] & 0XF0) >> 4) + (x10buff[2] & 0XF) +
|
||||
((x10buff[3] & 0XF0) >> 4));
|
||||
x10buff[3] = (x10buff[3] & 0xf0) + (parity & 0XF);
|
||||
SendCommand(x10buff, BUFFER_SIZE);
|
||||
}
|
||||
|
||||
void x10rf::x10Security(uint8_t address, uint8_t command){
|
||||
uint8_t x10buff[3]; // Set message buffer 4 bytes
|
||||
x10buff[0] = address;
|
||||
x10buff[1] = (~x10buff[0] & 0xF) + (x10buff[0] & 0xF0); // Calculate byte1 (byte 1 complement
|
||||
x10buff[2] = command;
|
||||
x10buff[3] = ~x10buff[2];
|
||||
// x10buff[4] = code; // Couldn't get 48 bit security working.
|
||||
// if((x10buff[4] % 2) == 0) { x10buff[5] = 0;} //Calc even parity
|
||||
// else { x10buff[5] = 0x80;}
|
||||
SendCommand(x10buff, sizeof(x10buff));
|
||||
void x10rf::x10Switch(char house_code, uint8_t unit_code, uint8_t command) {
|
||||
static const uint8_t BUFFER_SIZE = 4;
|
||||
uint8_t x10buff[BUFFER_SIZE];
|
||||
4 bytes switch (tolower(house_code)) {
|
||||
case 'a':
|
||||
x10buff[0] = B0110;
|
||||
break;
|
||||
case 'b':
|
||||
x10buff[0] = B0111;
|
||||
break;
|
||||
case 'c':
|
||||
x10buff[0] = B0100;
|
||||
break;
|
||||
case 'd':
|
||||
x10buff[0] = B0101;
|
||||
break;
|
||||
case 'e':
|
||||
x10buff[0] = B1000;
|
||||
break;
|
||||
case 'f':
|
||||
x10buff[0] = B1001;
|
||||
break;
|
||||
case 'g':
|
||||
x10buff[0] = B1010;
|
||||
break;
|
||||
case 'h':
|
||||
x10buff[0] = B1011;
|
||||
break;
|
||||
case 'i':
|
||||
x10buff[0] = B1110;
|
||||
break;
|
||||
case 'j':
|
||||
x10buff[0] = B1111;
|
||||
break;
|
||||
case 'k':
|
||||
x10buff[0] = B1100;
|
||||
break;
|
||||
case 'l':
|
||||
x10buff[0] = B1101;
|
||||
break;
|
||||
case 'm':
|
||||
x10buff[0] = B0000;
|
||||
break;
|
||||
case 'n':
|
||||
x10buff[0] = B0001;
|
||||
break;
|
||||
case 'o':
|
||||
x10buff[0] = B0010;
|
||||
break;
|
||||
case 'p':
|
||||
x10buff[0] = B0011;
|
||||
break;
|
||||
default:
|
||||
x10buff[0] = 0;
|
||||
break;
|
||||
}
|
||||
x10buff[0] = x10buff[0] << 4; // House code goes into the upper nibble
|
||||
|
||||
switch (command) {
|
||||
case ON:
|
||||
case OFF:
|
||||
case BRIGHT:
|
||||
case DIM:
|
||||
x10buff[2] = command;
|
||||
break;
|
||||
}
|
||||
// Set unit number
|
||||
unit_code = unit_code - 1;
|
||||
bitWrite(x10buff[2], 6, bitRead(unit_code, 2));
|
||||
bitWrite(x10buff[2], 3, bitRead(unit_code, 1));
|
||||
bitWrite(x10buff[2], 4, bitRead(unit_code, 0));
|
||||
bitWrite(x10buff[0], 2, bitRead(unit_code, 3));
|
||||
// Set parity
|
||||
x10buff[1] = ~x10buff[0];
|
||||
x10buff[3] = ~x10buff[2];
|
||||
SendCommand(x10buff, BUFFER_SIZE);
|
||||
}
|
||||
|
||||
void x10rf::SendCommand(uint8_t *data, uint8_t size){
|
||||
if (_led_pin > 0) digitalWrite(_led_pin, HIGH);
|
||||
for (int i = 0; i < _rf_repeats; i++){
|
||||
SEND_HIGH();delayMicroseconds(X10_RF_SB_LONG);
|
||||
SEND_LOW();delayMicroseconds(X10_RF_SB_SHORT);
|
||||
for(int i=0; i <= size; i++) {
|
||||
SendX10RfByte(data[i]);
|
||||
}
|
||||
SendX10RfBit(1);
|
||||
delayMicroseconds(X10_RF_GAP);
|
||||
}
|
||||
if (_led_pin > 0) digitalWrite(_led_pin, LOW);
|
||||
void x10rf::x10Security(uint8_t address, uint8_t command) {
|
||||
static const uint8_t BUFFER_SIZE = 4;
|
||||
uint8_t x10buff[BUFFER_SIZE];
|
||||
4 bytes x10buff[0] = address;
|
||||
x10buff[1] = (~x10buff[0] & 0xF) +
|
||||
(x10buff[0] & 0xF0); // Calculate byte1 (byte 1 complement
|
||||
x10buff[2] = command;
|
||||
x10buff[3] = ~x10buff[2];
|
||||
// x10buff[4] = code; // Couldn't get 48 bit security working.
|
||||
// if((x10buff[4] % 2) == 0) { x10buff[5] = 0;} //Calc even parity
|
||||
// else { x10buff[5] = 0x80;}
|
||||
SendCommand(x10buff, BUFFER_SIZE);
|
||||
}
|
||||
|
||||
void x10rf::SendX10RfByte(uint8_t data){
|
||||
//Serial.println("\n");
|
||||
for (int i=7; i >= 0 ; i--){ // send bits from byte
|
||||
SendX10RfBit((bitRead(data,i)==1));
|
||||
//Serial.print(bitRead(data,i));
|
||||
}
|
||||
void x10rf::SendCommand(uint8_t *data, uint8_t size) {
|
||||
if (_led_pin > 0)
|
||||
digitalWrite(_led_pin, HIGH);
|
||||
for (int i = 0; i < _rf_repeats; i++) {
|
||||
SEND_HIGH();
|
||||
delayMicroseconds(X10_RF_SB_LONG);
|
||||
SEND_LOW();
|
||||
delayMicroseconds(X10_RF_SB_SHORT);
|
||||
for (int j = 0; j < size; j++) {
|
||||
SendX10RfByte(data[j]);
|
||||
}
|
||||
SendX10RfBit(1);
|
||||
delayMicroseconds(X10_RF_GAP);
|
||||
}
|
||||
if (_led_pin > 0)
|
||||
digitalWrite(_led_pin, LOW);
|
||||
}
|
||||
|
||||
void x10rf::SendX10RfBit(unsigned int databit){
|
||||
SEND_HIGH();delayMicroseconds(X10_RF_BIT_SHORT);
|
||||
SEND_LOW();delayMicroseconds(X10_RF_BIT_SHORT);
|
||||
if (databit) delayMicroseconds(X10_RF_BIT_LONG);
|
||||
void x10rf::SendX10RfByte(uint8_t data) {
|
||||
for (int i = 7; i >= 0; i--) {
|
||||
SendX10RfBit((bitRead(data, i) == 1));
|
||||
}
|
||||
}
|
||||
|
||||
void x10rf::SEND_HIGH() {
|
||||
digitalWrite(_tx_pin, HIGH);
|
||||
void x10rf::SendX10RfBit(unsigned int databit) {
|
||||
SEND_HIGH();
|
||||
delayMicroseconds(X10_RF_BIT_SHORT);
|
||||
SEND_LOW();
|
||||
delayMicroseconds(X10_RF_BIT_SHORT);
|
||||
if (databit)
|
||||
delayMicroseconds(X10_RF_BIT_LONG);
|
||||
}
|
||||
|
||||
void x10rf::SEND_LOW(){
|
||||
digitalWrite(_tx_pin, LOW);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void x10rf::SEND_HIGH() { digitalWrite(_tx_pin, HIGH); }
|
||||
|
||||
void x10rf::SEND_LOW() { digitalWrite(_tx_pin, LOW); }
|
||||
|
||||
Reference in New Issue
Block a user