Initial version

This commit is contained in:
Pieter Paul
2013-11-20 14:54:07 +01:00
commit 5551d75750
9 changed files with 347 additions and 0 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+18
View File
@@ -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
+1
View File
@@ -0,0 +1 @@
/*
+38
View File
@@ -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);
}
+247
View File
@@ -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);
}
+43
View File
@@ -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