Skip to content

Commit 6caa82a

Browse files
committed
Add: Demo for Wio Terminal connecting AWS IoT Bridge Broker
1 parent a6ccc85 commit 6caa82a

File tree

2 files changed

+350
-0
lines changed

2 files changed

+350
-0
lines changed

.travis.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,17 @@ script:
9191
- export BOARD=Seeeduino:samd:seeed_wio_terminal
9292
- arduino-cli compile --warnings all --fqbn $BOARD $PWD/examples/HID_PC_Media_Controller --verbose --build-properties build.flags.usbstack=-DUSE_TINYUSB
9393

94+
- echo "*************************************WioTerminal_AWSIoT_Bridge*********************************************"
95+
- rm -rf $HOME/Arduino/libraries/*
96+
- installLibrary Seeed-Studio/Seeed_Arduino_atWiFi
97+
- installLibrary Seeed-Studio/Seeed_Arduino_FreeRTOS
98+
- installLibrary Seeed-Studio/Seeed_Arduino_atUnified
99+
- installLibrary Seeed-Studio/esp-at-lib
100+
- installLibrary knolleary/pubsubclient
101+
- installLibrary bblanchon/ArduinoJson
102+
- export BOARD=Seeeduino:samd:seeed_wio_terminal
103+
- buildExampleSketch WioTerminal_AWSIoT_Bridge;
104+
94105
notifications:
95106
webhooks:
96107
urls:
Lines changed: 339 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,339 @@
1+
/*********************************************************************************
2+
MQTT Bridge to AWS Example
3+
4+
MQTT Client for MQTT AWS Bridge https://github.com/dnavarrom/aws_mosquitto_broker
5+
6+
Modifier: Anson He (Seeed Studio)
7+
Modified: To support Wio Terminal to use Wi-Fi to connect to local broker to AWS IoT. Also, update to ArduinoJson v6 API.
8+
9+
Tested on: Arduino Uno / Mega 2560 + Ethernet Shield
10+
11+
Written by Diego Navarro M
12+
Using PubSubClient library https://github.com/knolleary/pubsubclient
13+
Using ArduinoJson Library https://bblanchon.github.io/ArduinoJson/
14+
Using SoftReset Library https://github.com/WickedDevice/SoftReset
15+
MIT license, all text above must be included in any redistribution
16+
***********************************************************************************/
17+
18+
#include <AtWiFi.h>
19+
#include <PubSubClient.h>
20+
#include <ArduinoJson.h>
21+
22+
//Comment to disable debug output
23+
#define GENERAL_DEBUG
24+
25+
#ifdef GENERAL_DEBUG
26+
#define DEBUG_PRINT(string) (Serial.println(string))
27+
#endif
28+
29+
#ifndef GENERAL_DEBUG
30+
#define DEBUG_PRINT(String)
31+
#endif
32+
33+
#define SEND_BUTTON WIO_KEY_C // Button to send message
34+
int lastState = 1; // State variable
35+
36+
/************************* Wi-Fi Client Setup *****************************/
37+
38+
const char* ssid = "se.101"; // your network SSID
39+
const char* password = "qqqqqqqq9"; // your network password
40+
41+
char myIPAddress[20];
42+
43+
/************************* MQTT Client Config ********************************/
44+
45+
const char* mqttserver = "10.0.0.62"; // Local Broker
46+
const int mqttport = 1883; // MQTT port
47+
String subscriptionTopic = "awsiot_to_localgateway"; // Get messages from AWS
48+
String publishTopic = "localgateway_to_awsiot"; // Send messages to AWS
49+
50+
51+
/************************* MQTT Connection Monitoring ************************/
52+
53+
long connecionMonitoringFrequency = 10000UL; // (1000 = 1 sec)
54+
unsigned long lastConnectionCheck = 0;
55+
int connectionAttempt = 0;
56+
const int maxconnectionAttempt = 5; // Reset after x connection attempt
57+
const int maxConnectionCycles = 100; // Security Reset (Soft Reet)
58+
const int maxCiclosDiarios = 5000; // Full Reset
59+
int ConnectionCyclesCount = 0;
60+
int totalCyclesCount = 0;
61+
62+
63+
/********************* MQTT Broker Callback Function **************************
64+
65+
/*!
66+
@brief Process MQTT Messages (subscription)
67+
@param topic
68+
the topic the message arrived on (const char[])
69+
@param payload
70+
the message payload (byte array)
71+
@param length
72+
the length of the message payload (unsigned int)
73+
@return nothing.
74+
*/
75+
76+
void callback(char* topic, byte* payload, unsigned int length) {
77+
78+
/*
79+
Internally, the client uses the same buffer for both inbound and outbound messages. After the callback function returns,
80+
or if a call to either publish or subscribe is made from within the callback function, the topic and payload values passed
81+
to the function will be overwritten. The application should create its own copy of the values if they are required beyond this.
82+
*/
83+
84+
// Allocate the correct amount of memory for the payload copy
85+
byte* p = (byte*)malloc(length);
86+
// Copy the payload to the new buffer
87+
memcpy(p,payload,length);
88+
89+
char* chararray;
90+
chararray = (char*)p;
91+
92+
ProcessPayload(chararray);
93+
94+
free(p);
95+
}
96+
97+
/************************** PubSubClient Declaration *******************************/
98+
99+
WiFiClient client;
100+
PubSubClient mqttclient(mqttserver,mqttport,callback, client); //Callback function must be declared before this line
101+
102+
/************************** Sketch Code ********************************************/
103+
104+
void setup() {
105+
106+
#if defined(GENERAL_DEBUG)
107+
Serial.begin(9600);
108+
#endif
109+
110+
// Initialise button
111+
pinMode(SEND_BUTTON, INPUT_PULLUP);
112+
113+
// Configure mqttClient
114+
mqttclient.setServer(mqttserver, mqttport);
115+
mqttclient.setCallback(callback);
116+
117+
// Connect to WiFi
118+
WiFi.begin(ssid, password);
119+
while (WiFi.status() != WL_CONNECTED) {
120+
delay(500);
121+
Serial.println("Connecting to WiFi..");
122+
}
123+
Serial.println("Connected to the WiFi network");
124+
125+
DEBUG_PRINT("<SETUP> : Board IP = " + (String)getIpReadable(WiFi.localIP()));
126+
127+
// Connect to Broker
128+
if (reconnect()) {
129+
DEBUG_PRINT("<SETUP> : Connected to broker");
130+
}
131+
else {
132+
DEBUG_PRINT("<SETUP> : Initial Connection Failed");
133+
}
134+
DEBUG_PRINT("<SETUP> : End Config..");
135+
}
136+
137+
void loop() {
138+
139+
// Check connection Status
140+
if (millis() - lastConnectionCheck > connecionMonitoringFrequency) {
141+
lastConnectionCheck = millis();
142+
CheckConnection();
143+
}
144+
145+
// Send a message via pressing a button
146+
int state = digitalRead(SEND_BUTTON);
147+
if (state == 0) {
148+
delay(100); // Debounce
149+
if (state != lastState) {
150+
Publicar(publishTopic,"{\"message\": \"SENDING FROM WIO TERMINAL\"}");
151+
DEBUG_PRINT("MESSAGE SENT");
152+
}
153+
lastState = !lastState;
154+
delay(50);
155+
}
156+
157+
mqttclient.loop(); //end cycle
158+
}
159+
160+
/***************************** Payload Processing function ************************/
161+
162+
/*!
163+
@brief Process the Broker Payload
164+
@param chararray
165+
Payload from Callback Function
166+
@return nothing
167+
*/
168+
169+
void ProcessPayload(char* chararray) {
170+
171+
size_t charSize;
172+
173+
// Extract Json
174+
DynamicJsonDocument jsonBuffer(200);
175+
176+
auto error = deserializeJson(jsonBuffer, chararray);
177+
JsonObject root = jsonBuffer.as<JsonObject>();
178+
179+
if (error)
180+
{
181+
DEBUG_PRINT("<DecodeJson> parseObject() failed");
182+
return;
183+
}
184+
185+
for (JsonObject::iterator it=root.begin(); it!=root.end(); ++it) {
186+
DEBUG_PRINT(it->key().c_str());
187+
DEBUG_PRINT(it->value().as<char*>());
188+
}
189+
190+
delay(1000);
191+
192+
// Publish ACK
193+
Publicar(publishTopic,"{\"message\": \"OK\"}");
194+
}
195+
196+
/*!
197+
@brief Publish to MQTT Broker
198+
@param topic
199+
the topic the message to publish to
200+
@param value
201+
Message to send
202+
@return Return true if message sent successfully
203+
*/
204+
205+
bool Publicar(String topic, String value)
206+
{
207+
208+
bool success = false;
209+
char cpytopic [50];
210+
char message [50];
211+
value.toCharArray(message, value.length() + 1);
212+
topic.toCharArray(cpytopic,topic.length() + 1);
213+
success = mqttclient.publish(cpytopic, message);
214+
215+
return success;
216+
}
217+
218+
219+
220+
221+
/***************************** Broker Connection Functions ************************/
222+
223+
224+
/*!
225+
@brief Check Wi-Fi Connection
226+
@return Nothing
227+
*/
228+
229+
void CheckConnection()
230+
{
231+
ConnectionCyclesCount++;
232+
totalCyclesCount++;
233+
234+
//Restart Wi-Fi after x connection cycles
235+
if (ConnectionCyclesCount > maxConnectionCycles)
236+
{
237+
DEBUG_PRINT("<CheckConnection> : Restart Wi-Fi..");
238+
client.stop();
239+
WiFi.begin(ssid, password);
240+
ConnectionCyclesCount = 0;
241+
}
242+
else
243+
{
244+
// Daily Softreset
245+
if (totalCyclesCount > maxCiclosDiarios) {
246+
DEBUG_PRINT("<CheckConnection> : Reset Device..");
247+
totalCyclesCount = 0;
248+
delay(1000);
249+
NVIC_SystemReset(); // SAMD CMSIS function to reset
250+
}
251+
else
252+
{
253+
//Check MQTT Connection
254+
if (!mqttclient.connected()) {
255+
if (!reconnect()) {
256+
DEBUG_PRINT("<CheckConnection> : Disconnected.. connection attempt #: " + (String)connectionAttempt);
257+
connectionAttempt++;
258+
if (connectionAttempt > maxconnectionAttempt)
259+
{
260+
connectionAttempt = 0;
261+
DEBUG_PRINT("<CheckConnection> : Restart Wi-Fi!");
262+
client.stop();
263+
WiFi.begin(ssid, password);
264+
delay(1000);
265+
}
266+
}
267+
else
268+
{
269+
connectionAttempt = 0;
270+
DEBUG_PRINT("<CheckConnection> : Reconnected!");
271+
}
272+
}
273+
else
274+
{
275+
DEBUG_PRINT("<CheckConnection> : Connected!");
276+
}
277+
}
278+
}
279+
}
280+
281+
/*!
282+
@brief Reconnect to MQTT Broker
283+
@return Return true if reconnected
284+
*/
285+
286+
boolean reconnect() {
287+
if (mqttclient.connect("arduinoClient")) {
288+
289+
char topicConnection [50];
290+
291+
subscriptionTopic.toCharArray(topicConnection,25);
292+
mqttclient.subscribe(topicConnection);
293+
}
294+
295+
return mqttclient.connected();
296+
}
297+
298+
299+
300+
/******************************* Generic Helpers *********************************/
301+
302+
/*!
303+
@brief Convert IP address to readable string
304+
*/
305+
306+
char* getIpReadable(IPAddress ipAddress)
307+
{
308+
309+
unsigned char octet[4] = {
310+
0, 0, 0, 0 };
311+
for (int i = 0; i < 4; i++)
312+
{
313+
octet[i] = ( ipAddress >> (i * 8) ) & 0xFF;
314+
}
315+
316+
sprintf(myIPAddress, "%d.%d.%d.%d\0", octet[0], octet[1], octet[2], octet[3]);
317+
318+
return myIPAddress;
319+
}
320+
321+
/*!
322+
@brief Decode Json message
323+
*/
324+
325+
void DecodeJson(char json[]) {
326+
DynamicJsonDocument jsonBuffer(200);
327+
328+
auto error = deserializeJson(jsonBuffer, json);
329+
JsonObject root = jsonBuffer.as<JsonObject>();
330+
331+
if (error)
332+
{
333+
DEBUG_PRINT("<DecodeJson> parseObject() failed");
334+
return;
335+
}
336+
337+
const char* message = root["message"];
338+
long data = root["value"];
339+
}

0 commit comments

Comments
 (0)