Skip to content

Commit c0606cb

Browse files
committed
Add GCP IoT Core WiFi, GSM, and NB examples
1 parent eee3cae commit c0606cb

File tree

6 files changed

+616
-0
lines changed

6 files changed

+616
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
/*
2+
GCP (Google Cloud Platform) IoT Core GSM
3+
4+
This sketch securely connects to GCP IoT Core using MQTT over GSM/3G.
5+
It uses a private key stored in the ATECC508A and a JSON Web Token (JWT) with
6+
a JSON Web Signature (JWS).
7+
8+
It publishes a message every 5 seconds to "/devices/{deviceId}/state" topic
9+
and subscribes to messages on the "/devices/{deviceId}/config" and
10+
"/devices/{deviceId}/commands/#" topics.
11+
12+
The circuit:
13+
- MKR GSM 1400 board
14+
- Antenna
15+
- SIM card with a data plan
16+
- LiPo battery
17+
18+
This example code is in the public domain.
19+
*/
20+
21+
#include <ArduinoECCX08.h>
22+
#include <utility/ECCX08JWS.h>
23+
#include <ArduinoMqttClient.h>
24+
#include <Arduino_JSON.h>
25+
#include <MKRGSM.h>
26+
27+
#include "arduino_secrets.h"
28+
29+
/////// Enter your sensitive data in arduino_secrets.h
30+
const char pinnumber[] = SECRET_PINNUMBER;
31+
const char gprs_apn[] = SECRET_GPRS_APN;
32+
const char gprs_login[] = SECRET_GPRS_LOGIN;
33+
const char gprs_password[] = SECRET_GPRS_PASSWORD;
34+
35+
const char projectId[] = SECRET_PROJECT_ID;
36+
const char cloudRegion[] = SECRET_CLOUD_REGION;
37+
const char registryId[] = SECRET_REGISTRY_ID;
38+
const String deviceId = SECRET_DEVICE_ID;
39+
40+
const char broker[] = "mqtt.googleapis.com";
41+
42+
GSM gsmAccess;
43+
GPRS gprs;
44+
45+
GSMSSLClient gsmSslClient;
46+
MqttClient mqttClient(gsmSslClient);
47+
48+
unsigned long lastMillis = 0;
49+
50+
void setup() {
51+
Serial.begin(9600);
52+
while (!Serial);
53+
54+
if (!ECCX08.begin()) {
55+
Serial.println("No ECCX08 present!");
56+
while (1);
57+
}
58+
59+
// Calculate and set the client id used for MQTT
60+
String clientId = calculateClientId();
61+
62+
mqttClient.setId(clientId);
63+
64+
// Set the message callback, this function is
65+
// called when the MQTTClient receives a message
66+
mqttClient.onMessage(onMessageReceived);
67+
}
68+
69+
void loop() {
70+
if (gsmAccess.status() != GSM_READY || gprs.status() != GPRS_READY) {
71+
connectGSM();
72+
}
73+
74+
if (!mqttClient.connected()) {
75+
// MQTT client is disconnected, connect
76+
connectMQTT();
77+
}
78+
79+
// poll for new MQTT messages and send keep alives
80+
mqttClient.poll();
81+
82+
// publish a message roughly every 5 seconds.
83+
if (millis() - lastMillis > 5000) {
84+
lastMillis = millis();
85+
86+
publishMessage();
87+
}
88+
}
89+
90+
unsigned long getTime() {
91+
// get the current time from the cellular module
92+
return gsmAccess.getTime();
93+
}
94+
95+
void connectGSM() {
96+
Serial.println("Attempting to connect to the cellular network");
97+
98+
while ((gsmAccess.begin(pinnumber) != GSM_READY) ||
99+
(gprs.attachGPRS(gprs_apn, gprs_login, gprs_password) != GPRS_READY)) {
100+
// failed, retry
101+
Serial.print(".");
102+
delay(1000);
103+
}
104+
105+
Serial.println("You're connected to the cellular network");
106+
Serial.println();
107+
}
108+
109+
void connectMQTT() {
110+
Serial.print("Attempting to connect to MQTT broker: ");
111+
Serial.print(broker);
112+
Serial.println(" ");
113+
114+
while (!mqttClient.connected()) {
115+
// Calculate the JWT and assign it as the password
116+
String jwt = calculateJWT();
117+
118+
mqttClient.setUsernamePassword("", jwt);
119+
120+
if (!mqttClient.connect(broker, 8883)) {
121+
// failed, retry
122+
Serial.print(".");
123+
delay(5000);
124+
}
125+
}
126+
Serial.println();
127+
128+
Serial.println("You're connected to the MQTT broker");
129+
Serial.println();
130+
131+
// subscribe to topics
132+
mqttClient.subscribe("/devices/" + deviceId + "/config", 1);
133+
mqttClient.subscribe("/devices/" + deviceId + "/commands/#");
134+
}
135+
136+
String calculateClientId() {
137+
String clientId;
138+
139+
// Format:
140+
//
141+
// projects/{project-id}/locations/{cloud-region}/registries/{registry-id}/devices/{device-id}
142+
//
143+
144+
clientId += "projects/";
145+
clientId += projectId;
146+
clientId += "/locations/";
147+
clientId += cloudRegion;
148+
clientId += "/registries/";
149+
clientId += registryId;
150+
clientId += "/devices/";
151+
clientId += deviceId;
152+
153+
return clientId;
154+
}
155+
156+
String calculateJWT() {
157+
unsigned long now = getTime();
158+
159+
// calculate the JWT, based on:
160+
// https://cloud.google.com/iot/docs/how-tos/credentials/jwts
161+
JSONVar jwtHeader;
162+
JSONVar jwtClaim;
163+
164+
jwtHeader["alg"] = "ES256";
165+
jwtHeader["typ"] = "JWT";
166+
167+
jwtClaim["aud"] = projectId;
168+
jwtClaim["iat"] = now;
169+
jwtClaim["exp"] = now + (24L * 60L * 60L); // expires in 24 hours
170+
171+
return ECCX08JWS.sign(0, JSON.stringify(jwtHeader), JSON.stringify(jwtClaim));
172+
}
173+
174+
void publishMessage() {
175+
Serial.println("Publishing message");
176+
177+
// send message, the Print interface can be used to set the message contents
178+
mqttClient.beginMessage("/devices/" + deviceId + "/state");
179+
mqttClient.print("hello ");
180+
mqttClient.print(millis());
181+
mqttClient.endMessage();
182+
}
183+
184+
void onMessageReceived(int messageSize) {
185+
// we received a message, print out the topic and contents
186+
Serial.print("Received a message with topic '");
187+
Serial.print(mqttClient.messageTopic());
188+
Serial.print("', length ");
189+
Serial.print(messageSize);
190+
Serial.println(" bytes:");
191+
192+
// use the Stream interface to print the contents
193+
while (mqttClient.available()) {
194+
Serial.print((char)mqttClient.read());
195+
}
196+
Serial.println();
197+
198+
Serial.println();
199+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// GSM settings
2+
#define SECRET_PINNUMBER ""
3+
#define SECRET_GPRS_APN "GPRS_APN" // replace with your GPRS APN
4+
#define SECRET_GPRS_LOGIN "login" // replace with your GPRS login
5+
#define SECRET_GPRS_PASSWORD "password" // replace with your GPRS password
6+
7+
// Fill in your Google Cloud Platform - IoT Core info
8+
#define SECRET_PROJECT_ID ""
9+
#define SECRET_CLOUD_REGION ""
10+
#define SECRET_REGISTRY_ID ""
11+
#define SECRET_DEVICE_ID ""

0 commit comments

Comments
 (0)