Last active
July 14, 2018 09:08
-
-
Save andreareginato/813149ea661ec3066790 to your computer and use it in GitHub Desktop.
Create your first connected light using Arduino Ethernet
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SPI.h> | |
#include <Ethernet.h> | |
#include <PubSubClient.h> | |
/* ------------------ */ | |
/* SKETCH CREDENTIALS */ | |
/* ------------------ */ | |
char* deviceId = "<DEVICE-ID>"; // * set your device id (will be the MQTT client username) | |
char* deviceSecret = "<DEVICE-SECRET>"; // * set your device secret (will be the MQTT client password) | |
char* outTopic = "devices/<DEVICE-ID>/set"; // * MQTT channel where physical updates are published | |
char* inTopic = "devices/<DEVICE-ID>/get"; // * MQTT channel where lelylan updates are received | |
char* clientId = "<CLIENT-ID>"; // * set a random string (max 23 chars, will be the MQTT client id) | |
/* ------------ */ | |
/* SKETCH LOGIC */ | |
/* ------------ */ | |
/* Server settings */ | |
byte server[] = { 178, 62, 108, 47 }; // MQTT server address | |
/* Sample payload published to lelylan */ | |
/* The id is the status property id of the basic light /* | |
/* http://lelylan.github.io/types-dashboard-ng/#/types/518be107ef539711af000001/ */ | |
char* payloadOn = "{\"properties\":[{\"id\":\"518be5a700045e1521000001\",\"value\":\"on\"}]}"; | |
char* payloadOff = "{\"properties\":[{\"id\":\"518be5a700045e1521000001\",\"value\":\"off\"}]}"; | |
/* Ethernet configuration */ | |
byte mac[] = { 0xA0, 0xA0, 0xBA, 0xAC, 0xAE, 0x12 }; | |
EthernetClient ethClient; | |
/* MQTT communication */ | |
void callback(char* topic, byte* payload, unsigned int length); // subscription callback | |
PubSubClient client(server, 1883, callback, ethClient); // mqtt client | |
/* Pins configuration */ | |
int inPin = 2; // button | |
int outPin = 4; // led | |
/* Button and led logics */ | |
int state = HIGH; // current state of the output pin | |
int reading; // current reading from the input pin | |
int previous = LOW; // previous reading from the input pin | |
long time = 0; // the last time the output pin was toggled | |
long debounce = 200; // the debounce time, increase if the output flickers | |
/* arduino setup */ | |
void setup() { | |
Serial.begin(9600); | |
delay(500); | |
Ethernet.begin(mac); | |
Serial.print("Connected with IP: "); | |
Serial.println(Ethernet.localIP()); | |
lelylanConnection(); // MQTT server connection | |
pinMode(inPin, INPUT); // button pin setup | |
pinMode(outPin, OUTPUT); // led pin setup | |
} | |
/* arduino loop */ | |
void loop() { | |
lelylanConnection(); | |
char* value; | |
reading = digitalRead(inPin); // read the button state | |
// if the input just went from LOW and HIGH and we've waited long enough to ignore | |
// any noise on the circuit, toggle the output pin and remember the time | |
if (reading == HIGH && previous == LOW && millis() - time > debounce) { | |
if (state == LOW) { | |
Serial.println("[PHYSICAL] Led turned on"); | |
lelylanPublish("on"); | |
state = HIGH; | |
} else { | |
Serial.println("[PHYSICAL] Led turned off"); | |
lelylanPublish("off"); | |
state = LOW; | |
} | |
time = millis(); | |
} | |
// effectively update the light status | |
digitalWrite(outPin, state); | |
previous = reading; | |
} | |
/* MQTT server connection */ | |
void lelylanConnection() { | |
// add reconnection logics | |
if (!client.connected()) { | |
// connection to MQTT server | |
if (client.connect(clientId, deviceId, deviceSecret)) { | |
Serial.println("[PHYSICAL] Successfully connected with MQTT"); | |
lelylanSubscribe(); // topic subscription | |
} | |
} | |
client.loop(); | |
} | |
/* MQTT publish */ | |
void lelylanPublish(char* value) { | |
if (value == "on") | |
client.publish(outTopic, payloadOn); // light on | |
else | |
client.publish(outTopic, payloadOff); // light off | |
} | |
/* MQTT subscribe */ | |
void lelylanSubscribe() { | |
client.subscribe(inTopic); | |
} | |
/* Receive Lelylan message and confirm the physical change */ | |
void callback(char* topic, byte* payload, unsigned int length) { | |
// copu the payload content into a char* | |
char* json; | |
json = (char*) malloc(length + 1); | |
memcpy(json, payload, length); | |
json[length] = '\0'; | |
// update the physical status and confirm the executed update | |
if (String(payloadOn) == String(json)) { | |
Serial.println("[LELYLAN] Led turned on"); | |
lelylanPublish("on"); | |
state = HIGH; | |
} else { | |
Serial.println("[LELYLAN] Led turned off"); | |
lelylanPublish("off"); | |
state = LOW; | |
} | |
digitalWrite(outPin, state); | |
free(json); | |
} |
I'm sorry, but that code is not good. There's so many flaws with it that it just cannot work. You need to learn some of the basics about C programming, like constant pointers versus non-constant pointers, and comparing C strings. There are some bits there that are just "what?!?!"
void lelylanPublish(char* value) {
Why on earth pass a char pointer for what is effectively a boolean state?!
if (value == "on")
That is NOT how you compare C strings!
lelylanPublish("on");
That's a char array literal being passed to a variable pointer. Idiotic at best.
if (String(payloadOn) == String(json)) {
Oh... my... GOD! WHY?!?!
It all shows a severe basic lack of understanding of how to program in C and is symptomatic of the severe problems with much of the public code in the Arduino community.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Can someone explain how to get the information for lines 12 & 13 (OutTopic & InTopic). I have tried simply inputing the "Device Id" into the "Device Id" part of the line, but I'm still only getting a blinking LED, not a static ON/OFF light, when I control it in the Lelylan dashboard.