-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathenergenie.c
139 lines (115 loc) · 4.07 KB
/
energenie.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
Depends libftdi and libusb
sudo apt install libftdi1 libusb-dev libftdi1-dev
Energenie remote code sender via FTDI bitbang
by Richud.com 2015
max 24 bit number 111111111111111111111111 = 16'777'215
on 12345 000000000011000000111001
off 12344 000000000011000000111000 ,always one less
Remote '4514' (sticker on plugs) code table
ON OFF
1 Received 12363535 Received 12363534
2 Received 12363527 Received 12363526
3 Received 12363531 Received 12363530
4 Received 12363523 Received 12363522
ALL Received 12363533 Received 12363532
Default pin codes, 0x00 all off, others OR'd for on.
#define PIN_TX 0x01
#define PIN_RX 0x02
#define PIN_RTS 0x04
#define PIN_CTS 0x08
#define PIN_DTR 0x10
#define PIN_DSR 0x20
#define PIN_DCD 0x40
#define PIN_RI 0x80
*/
#include <time.h>
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
#include <ftdi.h>
/* DEFINE are only things that should be changed */
#define DATA 0x02 /* This pin is the data line (DATA = ATAD on FS1000A, lol) */
#define VCC 0x80 /* This pin is used to power the device (VCC 3.3v) */
/* Generate a 1 or 0 pulse bit sequence and put it in array buffer */
void gen(char *buf, char **pos, int *t, char d)
{
buf = *pos; //set buffer array to next free row
int x;
for ( x = 0 ; x < *t; x++ ) //pulse
*buf++ = d;
*pos = buf; //update pointer to next free row of buffer array
}
/* Convert integer to 32bit binary stored in an char array */
void dec2bin(char *dst, int x)
{
int i;
for (i = sizeof x * CHAR_BIT - 1; i >= 0; i--)
*dst++ = (x >> i & 1) + '0';
}
/* Setup ftdi device */
struct ftdi_context ftdic;
void setupftdi(char **argv)
{
ftdi_init(&ftdic); //initialize context
if(ftdi_usb_open_desc(&ftdic, 0x0403, 0x6001, 0, argv[2]?argv[2]:0) < 0) {
printf("Can't open device with Serial Number:%s\nTry running with sudo?\n", argv[2]);
exit(1);
}
ftdi_usb_reset(&ftdic); //reset usb
ftdi_usb_purge_buffers(&ftdic); //clean buffers
ftdi_set_event_char(&ftdic, 0, 0); //disable event chars
ftdi_set_error_char(&ftdic, 0, 0); //disable error chars
ftdi_set_baudrate(&ftdic, 65536); //altering this value or moving it after setting bitbang mode will change timings!!
ftdi_set_bitmode(&ftdic, VCC | DATA, BITMODE_BITBANG); //set bitbang mode on both pins
}
/* MAIN */
int main(int argc, char **argv)
{
if (argc < 2) {
puts("Usage: ./energenie code [serial]\ncode: 1 to 16777215\nserial: 8 character string");
exit (1);
}
setupftdi(argv);
char b[32]; //binary digits
int n = atoi(argv[1]); //integer from command line
dec2bin(b,n); //convert supplied integer to 32 bit binary
/*
The timings, these rely on set baudrate, 1 bit 'lasts' 4 us
These times are 'relative' to OLS sample @ 50kHz. i.e. they changed when altering sample rate so not sure what true values are.
They match very accurately what the remote generates, (which is about half what '433Utils/RPi_utils/codesend' produces, although both work!)
*/
int s = 220/4; //short time, 220us
int l = 660/4; //long time, 660us [3x220]
int g = 6380/4; //inter packet gap, 6380us [9x220]
int bsiz = ( 25 * (s + l) ) + g ; //buffer size needed = 24 bits + 0 bit + interpacket gap
char buffer[bsiz]; //buffer to send to ftdi_write_data
char *buf = buffer;
char *pos = buf;
/* Generate each 24 binary digit to correct 0 or 1 pulse */
int x;
printf("Sending %d as ", n);
for (x = 8; x < sizeof n * CHAR_BIT; x++) { //24bit number so lop off first 8 0's from the 32bit dec2bin encoding
printf("%i", b[x]-'0'); //print binary out
if (b[x]-'0') { /* pulse 1 */
gen(buf, &pos, &l, VCC | DATA); //long on
gen(buf, &pos, &s, VCC); //short off
} else { /* pulse 0 */
gen(buf, &pos, &s, VCC | DATA); //short on
gen(buf, &pos, &l, VCC); //long off
}
}
/* Generate the trailing 0 pulse, aka the 25th bit */
gen(buf, &pos, &s, VCC | DATA);
gen(buf, &pos, &l, VCC);
/* Generate interpacket gap */
gen(buf, &pos, &g, VCC);
/* Send 7 repeat packets as per real remote */
for ( x = 0; x < 7; x++ ) {
ftdi_write_data(&ftdic, buf, bsiz);
}
puts("\nOk!\n");
//power off xmitter
char off = 0x00;
ftdi_write_data(&ftdic, &off , 1);
}