mirror of
https://github.com/pyrou/X10RF-Arduino.git
synced 2026-07-27 19:56:18 +00:00
Initial version
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,18 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map x10rf
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
x10rf KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
init KEYWORD2
|
||||
RFXmeter KEYWORD2
|
||||
RFXsensor KEYWORD2
|
||||
x10Switch KEYWORD2
|
||||
x10Security KEYWORD2
|
||||
@@ -0,0 +1 @@
|
||||
/*
|
||||
@@ -0,0 +1,38 @@
|
||||
#include <x10rf.h>
|
||||
#include <Energia.h>
|
||||
#define tx 11 // Pin number for the 433mhz OOK transmitter
|
||||
#define reps 1 // Number of times that a RF command must be repeated.
|
||||
#define ledpin BLUE_LED // Pin for the led that blinks when a command is send. (0 = no blink)
|
||||
|
||||
|
||||
x10rf myx10 = x10rf(tx,ledpin,reps);
|
||||
|
||||
void setup()
|
||||
{
|
||||
myx10.begin();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// RFXmeter (Google RFXMeter for all possible commands and options)
|
||||
myx10.RFXmeter(12,0,123457); // Send '123457' as meter reading. = ID = 12
|
||||
delay(3000);
|
||||
|
||||
// RFXSensor (Google RFXsensor for all possible commands and options)
|
||||
myx10.RFXsensor(1,'t','T',21); //Send temperature 21c (two decimals.) ID = 1
|
||||
delay(3000);
|
||||
//myx10.RFXsensor(5,'v','t',21); //Send voltage = ID = 5
|
||||
delay(3000);
|
||||
|
||||
// x10 Security
|
||||
myx10.x10Security(3,0xCC); // Send state 'Normal + Tamper' ID =3
|
||||
delay(3000);
|
||||
myx10.x10Security(9,0xF0); // Send state 'Darkness detected' ID =9
|
||||
delay(3000);
|
||||
|
||||
// x10Switch
|
||||
myx10.x10Switch('B',4, 1); // Switch B4 on
|
||||
delay(3000);
|
||||
myx10.x10Switch('D',15,0); // Switch D15 off
|
||||
delay(3000);
|
||||
}
|
||||
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
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)
|
||||
|
||||
Tested on a TI Stellarpad (LM4F120H5QR) and Energia 0101E0010. This should also work on Arduino (small modifications) or other TI Launchpad devices.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <Energia.h>
|
||||
#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
|
||||
|
||||
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::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
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
x10buff[3] << 4;
|
||||
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::x10Switch(char house_code, uint8_t unit_code, uint8_t command){
|
||||
uint8_t x10buff[3]; // Set message buffer 4 bytes
|
||||
uint8_t bTmp = 0; // Tmp byte
|
||||
switch(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 0: x10buff[2] = (x10buff[2] | 0x20); break;
|
||||
case 1: x10buff[2] = (x10buff[2] & 0x20); 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));
|
||||
}
|
||||
|
||||
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::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::SendX10RfByte(uint8_t data){
|
||||
int i = 0;
|
||||
//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::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_HIGH() {
|
||||
digitalWrite(_tx_pin, HIGH);
|
||||
}
|
||||
|
||||
void x10rf::SEND_LOW(){
|
||||
digitalWrite(_tx_pin, LOW);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
x10rf.h
|
||||
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)
|
||||
|
||||
Tested on a TI Stellarpad (LM4F120H5QR) and Energia 0101E0010. This should also work on Arduino (small modifications) or other TI Launchpad devices.
|
||||
*/
|
||||
|
||||
// ensure this library description is only included once
|
||||
#ifndef x10rf_h
|
||||
#define x10rf_h
|
||||
|
||||
//#include "Arduino.h"
|
||||
//#include "Energia.h"
|
||||
#include <stdlib.h>
|
||||
#include <Energia.h>
|
||||
|
||||
class x10rf
|
||||
{
|
||||
public:
|
||||
x10rf(uint8_t tx_pin, uint8_t led_pin, uint8_t rf_repeats);
|
||||
void begin();
|
||||
void RFXmeter(uint8_t rfxm_address, uint8_t rfxm_packet_type, long rfxm_value);
|
||||
void RFXsensor(uint8_t rfxs_address,uint8_t rfxs_type, char rfxs_packet_type, uint8_t rfxs_value);
|
||||
void x10Switch(char house_code, uint8_t unit_code, uint8_t command);
|
||||
void x10Security(uint8_t address, uint8_t command);
|
||||
private:
|
||||
//void init(byte tx_pin, byte rf_repeats);
|
||||
void SendX10RfByte(uint8_t data);
|
||||
void SendX10RfBit(unsigned int databit);
|
||||
void SendCommand(uint8_t *date, uint8_t size);
|
||||
void SEND_HIGH();
|
||||
void SEND_LOW();
|
||||
uint8_t _tx_pin;
|
||||
uint8_t _led_pin;
|
||||
uint8_t _rf_repeats;
|
||||
};
|
||||
#endif
|
||||
Reference in New Issue
Block a user