-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathWorkshop3ArduinoCode
More file actions
238 lines (196 loc) · 8.16 KB
/
Copy pathWorkshop3ArduinoCode
File metadata and controls
238 lines (196 loc) · 8.16 KB
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
/**
IBM IoT Foundation managed Device
Based on code by Ant Elder with alerations by Tim Minter
License: Apache License v2
*/
#include <ESP8266WiFi.h>
#include <PubSubClient.h> // https://github.com/knolleary/pubsubclient/releases/tag/v2.3
#include <ArduinoJson.h> // https://github.com/bblanchon/ArduinoJson/releases/tag/v5.0.7
#include <Adafruit_NeoPixel.h> //LED (Neopixel) libray to include
#ifdef __AVR__
#include <avr/power.h>
#endif
//-------- Customise these values -----------
const char* ssid = "[wifinamehere]";
const char* password = "[wifipasswordhere]";
#define ORG "[orgnamehere]"
#define DEVICE_TYPE "esp8266"
#define DEVICE_ID "IoTWorkshopDevice"
#define TOKEN "[devicetokenhere]"
//LED (Neopixel) setup
#define LED_CONTROL_PIN D1
#define NUMBER_OF_LEDS_CONNECTED 3
//Input setup
#define INPUT_PIN D8 //this pin is "LOW" by default and will go "HIGH" if we connect it to the 5V pin
//-------- Customise the above values --------
int CURRENT_INPUT_PIN_VALUE = 0;
int NEW_INPUT_PIN_VALUE = 0;
char dataString[300];
char server[] = ORG ".messaging.internetofthings.ibmcloud.com";
char authMethod[] = "use-token-auth";
char token[] = TOKEN;
char clientId[] = "d:" ORG ":" DEVICE_TYPE ":" DEVICE_ID;
// Topic definitions. Messages being sent via the IoT platform have a Topic (you could consider this a "header") and payload (could be considered as "content").
// These lines of text are what the topics of the messages sent with from the IoT platform that we are interested in receiving.
// These are defined to some extent by the platform being used.
const char rebootTopic[] = "iotdm-1/mgmt/initiate/device/reboot";
const char commandTopic[] = "iot-2/cmd/command/fmt/json";
const char publishTopic[] = "iot-2/evt/status/fmt/json";
void callback(char* topic, byte* payload, unsigned int payloadLength);
WiFiClient wifiClient; // create a wifi client object
PubSubClient client(server, 1883, callback, wifiClient); // create an IoT/messaging object
// create an object representing the connected LED (Neopixel) strip
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMBER_OF_LEDS_CONNECTED, LED_CONTROL_PIN, NEO_GRB + NEO_KHZ800);
void setup() { // the setup function is a standard function run at start up by the Arduino
Serial.begin(115200); Serial.println(); // initate the serial port so output can be viewed in the serial monitor software
pixels.begin(); // This initializes the NeoPixel object.
wifiConnect(); // connect to wifi
IoTConnect(); // connect to the the IoT platform
initManagedDevice(); // subscribe to the relevant IoT channels on the IoT platform
pinMode(INPUT_PIN, INPUT);
}
void loop() { // the loop function is a standard function that is run continuously by the Arduino
// If we need to do stuff continuously, put it here
//Test input pin value
NEW_INPUT_PIN_VALUE = digitalRead(INPUT_PIN);
if(CURRENT_INPUT_PIN_VALUE==0 && NEW_INPUT_PIN_VALUE==1){
CURRENT_INPUT_PIN_VALUE=1;
Serial.println("Pin=1");
publishData(1); //input pin has been set "HIGH"
} else if (CURRENT_INPUT_PIN_VALUE==1 && NEW_INPUT_PIN_VALUE==0) {
CURRENT_INPUT_PIN_VALUE=0;
Serial.println("Pin=0");
publishData(0); //input pin has been set "LOW"
} else {
//do nothing
}
if (!client.loop()) { // if we loose the connection to the client
IoTConnect(); // try to connect again
initManagedDevice(); // and initiate the device
}
}
// create a connection to wifi
void wifiConnect() {
Serial.print("Connecting to "); Serial.print(ssid);
setLEDpixelsRed();
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected, IP address: "); Serial.println(WiFi.localIP());
setLEDpixelsGreen();
}
// create a connection to the IoT platform
void IoTConnect() {
if (!!!client.connected()) {
Serial.print("Reconnecting IoT (MQTT) client to "); Serial.println(server);
while (!!!client.connect(clientId, authMethod, token)) {
Serial.print(".");
delay(500);
}
Serial.println();
}
}
// subscribe to the two Topics we are interested in. Many topics can be sent by the IoT platform. We subscribe
void initManagedDevice() {
bool successfull = true;
if (client.subscribe(commandTopic)) {
Serial.println("subscribe to commands OK");
} else {
Serial.println("subscribe to commands FAILED");
successfull = false;
}
if (client.subscribe(rebootTopic)) {
Serial.println("subscribe to reboot OK");
} else {
Serial.println("subscribe to reboot FAILED");
successfull = false;
}
if (successfull == false){
setLEDpixelsBlue(); // subscriptions failed
} else {
setLEDpixelsWhite(); // successfully connected to IoT and subscribed to topics
}
}
void publishData(int valueToSend) {
StaticJsonBuffer<200> jsonBuffer;
JsonObject& root = jsonBuffer.createObject();
root["sensor"] = "thing";
root["D8Value"] = valueToSend;
root.printTo(dataString);
Serial.print("Sending payload: "); Serial.println(dataString);
if (client.publish(publishTopic, (char*) dataString)) {
Serial.println("Publish OK");
} else {
Serial.println("Publish FAILED");
}
}
void callback(char* topic, byte* payload, unsigned int payloadLength) { // called whenever the IoT platform sends data to the device
// data arrives with a topic (or subject) and the actual data. The topic can be used to direct the program to do specific things with the data
Serial.print("callback invoked for topic: "); Serial.println(topic); // print out the topic of the data
if (strcmp (commandTopic, topic) == 0) { // if the topic of the recieved data is "iot-2/cmd/command/fmt/text" (see the Topic Definitions section above)
handleDataReception(payload, payloadLength);
}
if (strcmp (rebootTopic, topic) == 0) { // if the topic of the recieved data is "iotdm-1/mgmt/initiate/device/reboot" (see the Topic Definitions section above)
Serial.println("Rebooting...");
ESP.restart();
}
}
void handleDataReception(byte* payload, unsigned int payloadLength) {
Serial.println("Set LEDs");
const size_t bufferSize = JSON_OBJECT_SIZE(5) + 30;
DynamicJsonBuffer jsonBuffer(bufferSize);
const char* json = (char*)payload;
JsonObject& root = jsonBuffer.parseObject(json);
// The received json object looks like this {"LEDAddress":1, "R":255, "G":255, "B":255} or {"R":255, "G":255, "B":255}.
// This code allows for the "LEDAddress" value to be optional. If ommited then the colour is applied to ALL pixels
int LEDAddress = root["LEDAddress"];
int Red = root["Red"];
int Green = root["Green"];
int Blue = root["Blue"];
Serial.println(LEDAddress);
Serial.println(Red);
Serial.println(Green);
Serial.println(Blue);
if(LEDAddress >= 1 && Red >= 0 && Green >= 0 && Blue >= 0){
//change the colour of the specified LED (if the colour AND position has been sent)
Serial.print("Set specific LEDs");
pixels.setPixelColor(LEDAddress -1, pixels.Color(Red,Green,Blue));
pixels.show();
} else if (Red >= 0 && Green >= 0 && Blue >= 0){
//change the colour of all LEDs in any attached pixels if position (A) has not been sent
Serial.print("Set all LEDs");
for(uint16_t i=0; i<pixels.numPixels(); i++) {
pixels.setPixelColor(i, pixels.Color(Red,Green,Blue));
pixels.show();
}
} else {
Serial.println("Incorrect data received");
}
}
// set all the pixels to Red
void setLEDpixelsRed(){
for(uint16_t i=0; i<pixels.numPixels(); i++) {
pixels.setPixelColor(i, pixels.Color(255,0,0));
pixels.show();
}
}
void setLEDpixelsGreen(){
for(uint16_t i=0; i<pixels.numPixels(); i++) {
pixels.setPixelColor(i, pixels.Color(0,255,0));
pixels.show();
}
}
void setLEDpixelsBlue(){
for(uint16_t i=0; i<pixels.numPixels(); i++) {
pixels.setPixelColor(i, pixels.Color(0,0,255));
pixels.show();
}
}
void setLEDpixelsWhite(){
for(uint16_t i=0; i<pixels.numPixels(); i++) {
pixels.setPixelColor(i, pixels.Color(255,255,255));
pixels.show();
}
}