Skip to content

Commit

Permalink
Implemented the UDP sender and added documentation/help
Browse files Browse the repository at this point in the history
  • Loading branch information
bakkerr committed Jul 28, 2015
1 parent 561a99b commit fa2813a
Showing 1 changed file with 222 additions and 57 deletions.
279 changes: 222 additions & 57 deletions openmilight.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
/**
* On a Raspberry Pi 2 compile with:
*
* g++ -Ofast -mfpu=vfp -mfloat-abi=hard -march=armv7-a -mtune=arm1176jzf-s -I/usr/local/include -L/usr/local/lib -lrf24-bcm PL1167_nRF24.cpp MiLightRadio.cpp openmili.cpp -o openmilight
*
* for receiver mode run with:
* sudo ./openmilight
*
* for sender mode run with:
* sudo ./openmilight "B0 F2 EA 6D B0 02 f0"
*/

#include <cstdlib>
Expand All @@ -17,6 +8,9 @@

#include <sys/time.h>

#include <sys/socket.h>
#include <netinet/in.h>

using namespace std;

#include <RF24/RF24.h>
Expand All @@ -36,13 +30,13 @@ static int dupesPrinted = 0;
void receive()
{
while(1){
if (mlr.available()) {
if(mlr.available()) {
printf("\n");
uint8_t packet[7];
size_t packet_length = sizeof(packet);
mlr.read(packet, packet_length);

for (int i = 0; i < packet_length; i++) {
for(size_t i = 0; i < packet_length; i++) {
printf("%02X ", packet[i]);
fflush(stdout);
}
Expand All @@ -55,37 +49,62 @@ void receive()
}
}

void send(uint8_t color, uint8_t bright, uint8_t key,
uint8_t remote = 0x01, uint8_t remote_prefix = 0x00,
uint8_t prefix = 0xB8)
void send(uint8_t data[8])
{
static uint8_t seq = 1;

static uint8_t seq = 1;

uint8_t data[7];
data[0] = prefix;
data[1] = remote_prefix;
data[2] = remote;
data[3] = color;
data[4] = bright;
data[5] = key;
uint8_t resends = data[7];
if(data[6] == 0x00){
data[6] = seq;

if(debug){
printf("Sending: ");
for (int i = 0; i < 7; i++) {
printf("%02X ", data[i]);
}
printf("\n");
seq++;
}

if(debug){
printf("2.4GHz --> Sending: ");
for (int i = 0; i < 7; i++) {
printf("%02X ", data[i]);
}
printf(" [x%d]\n", resends);
}

mlr.write(data, sizeof(data));
mlr.write(data, 7);

for(int i = 0; i < 10; i++){
mlr.resend();
}
for(int i = 0; i < resends; i++){
mlr.resend();
}

seq++;
}

void send(uint64_t v)
{
uint8_t data[8];
data[7] = (v >> (7*8)) & 0xFF;
data[0] = (v >> (6*8)) & 0xFF;
data[1] = (v >> (5*8)) & 0xFF;
data[2] = (v >> (4*8)) & 0xFF;
data[3] = (v >> (3*8)) & 0xFF;
data[4] = (v >> (2*8)) & 0xFF;
data[5] = (v >> (1*8)) & 0xFF;
data[6] = (v >> (0*8)) & 0xFF;

send(data);
}

void send(uint8_t color, uint8_t bright, uint8_t key,
uint8_t remote = 0x01, uint8_t remote_prefix = 0x00,
uint8_t prefix = 0xB8, uint8_t seq = 0x00, uint8_t resends = 10)
{
uint8_t data[8];
data[0] = prefix;
data[1] = remote_prefix;
data[2] = remote;
data[3] = color;
data[4] = bright;
data[5] = key;
data[6] = seq;
data[7] = resends;

send(data);
}

double getTime()
Expand All @@ -95,29 +114,140 @@ double getTime()
return tv.tv_sec + ((double)tv.tv_usec) * 1e-6;
}

void fade(uint8_t prefix, uint8_t rem_p, uint8_t remote, uint8_t color, uint8_t bright, uint8_t resends)
{
while(1){
color++;
send(color, 0x00, 0x0F, 0x44, 0x00);
usleep(20000);
}
}

void strobe(uint8_t prefix, uint8_t rem_p, uint8_t remote, uint8_t bright, uint8_t resends)
{
while(1){
uint8_t color = rand() % 255;
send(color, bright, 0x0F, remote, resends);
usleep(50000);
}
}

void udp()
{
int sockfd;
struct sockaddr_in servaddr, cliaddr;
char mesg[42];

sockfd = socket(AF_INET, SOCK_DGRAM, 0);

bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(8899);
bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));

while(1){
socklen_t len = sizeof(cliaddr);
int n = recvfrom(sockfd, mesg, 41, 0, (struct sockaddr *)&cliaddr, &len);

mesg[n] = '\0';

if(n == 7){
if(debug){
printf("UDP --> Received hex value\n");
}
uint8_t data[7];
for(int i = 0; i < 7; i++){
data[i] = (uint8_t)mesg[i];
}
send(data);
}
else {
fprintf(stderr, "Message has invalid size %d (expecting 7)!\n", n);
}
}
}

void usage(const char *arg, const char *options){
printf("\n");
printf("Usage: sudo %s [%s]\n", arg, options);
printf("\n");
printf(" -h Show this help\n");
printf(" -d Show debug output\n");
printf(" -f Fade mode\n");
printf(" -s Strobe mode\n");
printf(" -l Listening (receiving) mode\n");
printf(" -u UDP mode\n");
printf(" -n NN<dec> Resends of the same message\n");
printf(" -p PP<hex> Prefix value (Disco Mode)\n");
printf(" -q RR<hex> First byte of the remote\n");
printf(" -r RR<hex> Second byte of the remote\n");
printf(" -c CC<hex> Color byte\n");
printf(" -b BB<hex> Brightness byte\n");
printf(" -k KK<hex> Key byte\n");
printf(" -v SS<hex> Sequence byte\n");
printf(" -w SSPPRRRRCCBBKKNN<hex> Complete message to send\n");
printf("\n");
printf(" Author: Roy Bakker (2015)\n");
printf("\n");
printf(" Inspired by sources from: - https://github.com/henryk/\n");
printf(" - http://torsten-traenkner.de/wissen/smarthome/openmilight.php\n");
printf("\n");
}

int main(int argc, char** argv)
{
mlr.begin();
int do_receive = 0;
int do_udp = 0;
int do_strobe = 0;
int do_fade = 0;
int do_command = 0;

uint8_t prefix = 0xB8;
uint8_t rem_p = 0x00;
uint8_t remote = 0x01;
uint8_t color = 0x00;
uint8_t bright = 0x00;
uint8_t key = 0x01;
uint8_t seq = 0x00;
uint8_t resends = 10;

uint64_t command = 0x00;

int c;

uint8_t prefix = 0xB8;
uint8_t rem_p = 0x00;
uint8_t remote = 0x01;
uint8_t color = 0x01;
uint8_t bright = 0x01;
uint8_t key = 0x01;

uint64_t tmp;

while((c = getopt(argc, argv, "dlq:r:c:b:k:w:")) != -1){
const char *options = "hdfslun:p:q:r:c:b:k:v:w:";

while((c = getopt(argc, argv, options)) != -1){
switch(c){
case 'h':
usage(argv[0], options);
exit(0);
break;
case 'd':
debug = 1;
break;
case 'f':
do_fade = 1;
break;
case 's':
do_strobe = 1;
break;
case 'l':
printf("Receiving mode, press Ctrl-C to end\n");
receive();
exit(0);
do_receive = 1;
break;
case 'u':
do_udp = 1;
break;
case 'n':
tmp = strtoll(optarg, NULL, 10);
resends = (uint8_t)tmp;
break;
case 'p':
tmp = strtoll(optarg, NULL, 16);
prefix = (uint8_t)tmp;
break;
case 'q':
tmp = strtoll(optarg, NULL, 16);
Expand All @@ -139,20 +269,21 @@ int main(int argc, char** argv)
tmp = strtoll(optarg, NULL, 16);
key = (uint8_t)tmp;
break;
case 'w':
case 'v':
tmp = strtoll(optarg, NULL, 16);
rem_p = (tmp >> (4*8)) & 0xFF;
remote = (tmp >> (3*8)) & 0xFF;
color = (tmp >> (2*8)) & 0xFF;
bright = (tmp >> (1*8)) & 0xFF;
key = (tmp >> (0*8)) & 0xFF;
seq = (uint8_t)tmp;
break;
case 'w':
do_command = 1;
command = strtoll(optarg, NULL, 16);
break;
case '?':
if(optopt == 'q' || optopt == 'r' || optopt == 'c' ||
optopt == 'b' || optopt == 'k' || optopt == 'w'){
if(optopt == 'n' || optopt == 'p' || optopt == 'q' ||
optopt == 'r' || optopt == 'c' || optopt == 'b' ||
optopt == 'k' || optopt == 'w'){
fprintf(stderr, "Option -%c requires an argument.\n", optopt);
}
else if(isprint (optopt)){
else if(isprint(optopt)){
fprintf(stderr, "Unknown option `-%c'.\n", optopt);
}
else{
Expand All @@ -165,6 +296,35 @@ int main(int argc, char** argv)
}
}

int ret = mlr.begin();

if(ret < 0){
fprintf(stderr, "Failed to open connection to the 2.4GHz module.\n");
fprintf(stderr, "Make sure to run this program as root (sudo)\n\n");
usage(argv[0], options);
exit(-1);
}

if(do_receive){
printf("Receiving mode, press Ctrl-C to end\n");
receive();
}

if(do_udp){
printf("UDP mode, press Ctrl-C to end\n");
udp();
}

if(do_fade){
printf("Fade mode, press Ctrl-C to end\n");
fade(prefix, rem_p, remote, color, bright, resends);
}

if(do_strobe){
printf("Strobe mode, press Ctrl-C to end\n");
strobe(prefix, rem_p, remote, bright, resends);
}

/*
double from = getTime();
Expand All @@ -177,7 +337,12 @@ int main(int argc, char** argv)
printf("Time: %f %f %f\n", time, time / 200, 1 / (time/200));
*/

send(color, bright, key, remote, rem_p, prefix);
if(do_command){
send(command);
}
else{
send(color, bright, key, remote, rem_p, prefix, seq, resends);
}

return 0;
}

0 comments on commit fa2813a

Please sign in to comment.