Skip to content

Instantly share code, notes, and snippets.

@JeeWeetje
Last active March 14, 2018 15:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JeeWeetje/3d5f4508cc0c59513e9881f84ffeee5a to your computer and use it in GitHub Desktop.
Save JeeWeetje/3d5f4508cc0c59513e9881f84ffeee5a to your computer and use it in GitHub Desktop.
Fixed and cleaned up version for ESP8266 only of the simple mqtt sample of AzureIoTHub Arduino library, to be used as sample code in blogposts on https://jeeweetje.net
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
/* This sample uses the _LL APIs of iothub_client for example purposes.
That does not mean that MQTT only works with the _LL APIs.
Simply changing the using the convenience layer (functions not having _LL)
and removing calls to _DoWork will yield the same results. */
#ifdef ARDUINO
#include "AzureIoTHub.h"
#else
#include "azure_c_shared_utility/threadapi.h"
#include "azure_c_shared_utility/platform.h"
#include "serializer.h"
#include "iothub_client_ll.h"
#include "iothubtransportmqtt.h"
#endif
#ifdef MBED_BUILD_TIMESTAMP
#include "certs.h"
#endif // MBED_BUILD_TIMESTAMP
/*String containing Hostname, Device Id & Device Key in the format: */
/* "HostName=<host_name>;DeviceId=<device_id>;SharedAccessKey=<device_key>" */
static const char* connectionString = "[device connection string]";
// Define the Model
BEGIN_NAMESPACE(WeatherStation);
DECLARE_MODEL(ContosoAnemometer,
WITH_DATA(ascii_char_ptr, DeviceId),
WITH_DATA(int, WindSpeed),
WITH_ACTION(TurnFanOn),
WITH_ACTION(TurnFanOff),
WITH_ACTION(SetAirResistance, int, Position)
);
END_NAMESPACE(WeatherStation);
EXECUTE_COMMAND_RESULT TurnFanOn(ContosoAnemometer* device)
{
(void)device;
(void)printf("Turning fan on.\r\n");
return EXECUTE_COMMAND_SUCCESS;
}
EXECUTE_COMMAND_RESULT TurnFanOff(ContosoAnemometer* device)
{
(void)device;
(void)printf("Turning fan off.\r\n");
return EXECUTE_COMMAND_SUCCESS;
}
EXECUTE_COMMAND_RESULT SetAirResistance(ContosoAnemometer* device, int Position)
{
(void)device;
(void)printf("Setting Air Resistance Position to %d.\r\n", Position);
return EXECUTE_COMMAND_SUCCESS;
}
void sendCallback(IOTHUB_CLIENT_CONFIRMATION_RESULT result, void* userContextCallback)
{
unsigned int messageTrackingId = (unsigned int)(uintptr_t)userContextCallback;
(void)printf("Message Id: %u Received.\r\n", messageTrackingId);
(void)printf("Result Call Back Called! Result is: %s \r\n", ENUM_TO_STRING(IOTHUB_CLIENT_CONFIRMATION_RESULT, result));
}
static void sendMessage(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, const unsigned char* buffer, size_t size)
{
static unsigned int messageTrackingId;
IOTHUB_MESSAGE_HANDLE messageHandle = IoTHubMessage_CreateFromByteArray(buffer, size);
if (messageHandle == NULL)
{
printf("unable to create a new IoTHubMessage\r\n");
}
else
{
if (IoTHubClient_LL_SendEventAsync(iotHubClientHandle, messageHandle, sendCallback, (void*)(uintptr_t)messageTrackingId) != IOTHUB_CLIENT_OK)
{
printf("failed to hand over the message to IoTHubClient");
}
else
{
printf("IoTHubClient accepted the message for delivery\r\n");
}
IoTHubMessage_Destroy(messageHandle);
}
free((void*)buffer);
messageTrackingId++;
}
/*this function "links" IoTHub to the serialization library*/
static IOTHUBMESSAGE_DISPOSITION_RESULT IoTHubMessage(IOTHUB_MESSAGE_HANDLE message, void* userContextCallback)
{
IOTHUBMESSAGE_DISPOSITION_RESULT result;
const unsigned char* buffer;
size_t size;
if (IoTHubMessage_GetByteArray(message, &buffer, &size) != IOTHUB_MESSAGE_OK)
{
printf("unable to IoTHubMessage_GetByteArray\r\n");
result = EXECUTE_COMMAND_ERROR;
}
else
{
/*buffer is not zero terminated*/
char* temp = malloc(size + 1);
if (temp == NULL)
{
printf("failed to malloc\r\n");
result = EXECUTE_COMMAND_ERROR;
}
else
{
memcpy(temp, buffer, size);
temp[size] = '\0';
EXECUTE_COMMAND_RESULT executeCommandResult = EXECUTE_COMMAND(userContextCallback, temp);
result =
(executeCommandResult == EXECUTE_COMMAND_ERROR) ? IOTHUBMESSAGE_ABANDONED :
(executeCommandResult == EXECUTE_COMMAND_SUCCESS) ? IOTHUBMESSAGE_ACCEPTED :
IOTHUBMESSAGE_REJECTED;
free(temp);
}
}
return result;
}
void simplesample_mqtt_run(void)
{
if (platform_init() != 0)
{
(void)printf("Failed to initialize platform.\r\n");
}
else
{
if (serializer_init(NULL) != SERIALIZER_OK)
{
(void)printf("Failed on serializer_init\r\n");
}
else
{
IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle = IoTHubClient_LL_CreateFromConnectionString(connectionString, MQTT_Protocol);
srand((unsigned int)time(NULL));
int avgWindSpeed = 10;
if (iotHubClientHandle == NULL)
{
(void)printf("Failed on IoTHubClient_LL_Create\r\n");
}
else
{
#ifdef MBED_BUILD_TIMESTAMP
// For mbed add the certificate information
if (IoTHubClient_LL_SetOption(iotHubClientHandle, "TrustedCerts", certificates) != IOTHUB_CLIENT_OK)
{
(void)printf("failure to set option \"TrustedCerts\"\r\n");
}
#endif // MBED_BUILD_TIMESTAMP
ContosoAnemometer* myWeather = CREATE_MODEL_INSTANCE(WeatherStation, ContosoAnemometer);
if (myWeather == NULL)
{
(void)printf("Failed on CREATE_MODEL_INSTANCE\r\n");
}
else
{
if (IoTHubClient_LL_SetMessageCallback(iotHubClientHandle, IoTHubMessage, myWeather) != IOTHUB_CLIENT_OK)
{
printf("unable to IoTHubClient_SetMessageCallback\r\n");
}
else
{
myWeather->DeviceId = "myFirstDevice";
myWeather->WindSpeed = avgWindSpeed + (rand() % 4 + 2);
{
unsigned char* destination;
size_t destinationSize;
if (SERIALIZE(&destination, &destinationSize, myWeather->DeviceId, myWeather->WindSpeed) != CODEFIRST_OK)
{
(void)printf("Failed to serialize\r\n");
}
else
{
IOTHUB_MESSAGE_HANDLE messageHandle = IoTHubMessage_CreateFromByteArray(destination, destinationSize);
if (messageHandle == NULL)
{
printf("unable to create a new IoTHubMessage\r\n");
}
else
{
if (IoTHubClient_LL_SendEventAsync(iotHubClientHandle, messageHandle, sendCallback, (void*)1) != IOTHUB_CLIENT_OK)
{
printf("failed to hand over the message to IoTHubClient");
}
else
{
printf("IoTHubClient accepted the message for delivery\r\n");
}
IoTHubMessage_Destroy(messageHandle);
}
free(destination);
}
}
/* wait for commands */
while (1)
{
IoTHubClient_LL_DoWork(iotHubClientHandle);
ThreadAPI_Sleep(100);
}
}
DESTROY_MODEL_INSTANCE(myWeather);
}
IoTHubClient_LL_Destroy(iotHubClientHandle);
}
serializer_deinit();
}
platform_deinit();
}
}
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#ifndef SIMPLESAMPLEHTTP_H
#define SIMPLESAMPLEHTTP_H
#ifdef __cplusplus
extern "C" {
#endif
void simplesample_http_run(void);
#ifdef __cplusplus
}
#endif
#endif /* SIMPLESAMPLEHTTP_H */
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
// Code cleaned for ESP8266 usage only by Jan Willem Groenenberg
// Use Arduino IDE 1.6.8 or later.
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <time.h>
#include <sys/time.h>
#include <SPI.h>
// for ESP8266
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <WiFiUdp.h>
#include <AzureIoTHub.h>
#include <AzureIoTUtility.h>
#include <AzureIoTProtocol_MQTT.h>
#include "simplesample_mqtt.h"
static char ssid[] = "[your SSID]"; // your network SSID (name)
static char pass[] = "[your passkey]"; // your network password (use for WPA, or use as key for WEP)
static WiFiClientSecure sslClient; // for ESP8266
static AzureIoTHubClient iotHubClient;
void setup() {
initSerial();
initWifi();
initTime();
iotHubClient.begin(sslClient);
}
void loop() {
simplesample_mqtt_run();
delay(12000);
}
void initSerial() {
// Start serial and initialize stdout
Serial.begin(115200);
Serial.setDebugOutput(true);
}
void initWifi() {
// check for the presence of the shield :
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
// don't continue:
while (true);
}
// attempt to connect to Wifi network:
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// Applied a change in code here compared to the original code. WiFi.begin needs more time to reach WL_CONNECTED status.
// Committed as Pull Request #42 as fix to Issue #33 of the repo: https://github.com/Azure/azure-iot-arduino-protocol-mqtt.
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
while (WiFi.begin(ssid, pass) != WL_CONNECTED) {
delay(5000);
if (WiFi.status() == WL_CONNECTED) {
break;
}
// unsuccessful, retry in 5 seconds
Serial.println("failed to connect... ");
Serial.println("retrying to connect... ");
}
Serial.println("Connected to wifi");
}
void initTime() {
time_t epochTime;
configTime(0, 0, "pool.ntp.org", "time.nist.gov");
while (true) {
epochTime = time(NULL);
if (epochTime == 0) {
Serial.println("Fetching NTP epoch time failed! Waiting 2 seconds to retry.");
delay(2000);
} else {
Serial.print("Fetched NTP epoch time is: ");
Serial.println(epochTime);
break;
}
}
}
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
// Use Arduino IDE 1.6.8 or later.
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <time.h>
#include <sys/time.h>
#include <SPI.h>
#ifdef ARDUINO_ARCH_ESP8266
// for ESP8266
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <WiFiUdp.h>
#elif ARDUINO_SAMD_FEATHER_M0
// for Adafruit WINC1500
#include <Adafruit_WINC1500.h>
#include <Adafruit_WINC1500SSLClient.h>
#include <Adafruit_WINC1500Udp.h>
#include <NTPClient.h>
#else
#include <WiFi101.h>
#include <WiFiSSLClient.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
#endif
#ifdef ARDUINO_SAMD_FEATHER_M0
// For the Adafruit WINC1500 we need to create our own WiFi instance
// Define the WINC1500 board connections below.
#define WINC_CS 8
#define WINC_IRQ 7
#define WINC_RST 4
#define WINC_EN 2 // or, tie EN to VCC
// Setup the WINC1500 connection with the pins above and the default hardware SPI.
Adafruit_WINC1500 WiFi(WINC_CS, WINC_IRQ, WINC_RST);
#endif
#include <AzureIoTHub.h>
#include <AzureIoTUtility.h>
#include <AzureIoTProtocol_MQTT.h>
#include "simplesample_mqtt.h"
static char ssid[] = "yourNetwork"; // your network SSID (name)
static char pass[] = "yourPassword"; // your network password (use for WPA, or use as key for WEP)
// In the next line we decide each client ssl we'll use.
#ifdef ARDUINO_ARCH_ESP8266
static WiFiClientSecure sslClient; // for ESP8266
#elif ARDUINO_SAMD_FEATHER_M0
static Adafruit_WINC1500SSLClient sslClient; // for Adafruit WINC1500
#else
static WiFiSSLClient sslClient;
#endif
static AzureIoTHubClient iotHubClient;
void setup() {
initSerial();
initWifi();
initTime();
iotHubClient.begin(sslClient);
}
void loop() {
simplesample_mqtt_run();
}
void initSerial() {
// Start serial and initialize stdout
Serial.begin(115200);
Serial.setDebugOutput(true);
}
void initWifi() {
#ifdef ARDUINO_SAMD_FEATHER_M0
// for the Adafruit WINC1500 we need to enable the chip
pinMode(WINC_EN, OUTPUT);
digitalWrite(WINC_EN, HIGH);
#endif
// check for the presence of the shield :
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
// don't continue:
while (true);
}
// attempt to connect to Wifi network:
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
while (WiFi.begin(ssid, pass) != WL_CONNECTED) {
// unsuccessful, retry in 4 seconds
Serial.print("failed ... ");
delay(4000);
Serial.print("retrying ... ");
}
Serial.println("Connected to wifi");
}
void initTime() {
#if defined(ARDUINO_SAMD_ZERO) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_FEATHER_M0)
#ifdef ARDUINO_SAMD_FEATHER_M0
Adafruit_WINC1500UDP ntpUdp; // for Adafruit WINC1500
#else
WiFiUDP ntpUdp;
#endif
NTPClient ntpClient(ntpUdp);
ntpClient.begin();
while (!ntpClient.update()) {
Serial.println("Fetching NTP epoch time failed! Waiting 5 seconds to retry.");
delay(5000);
}
ntpClient.end();
unsigned long epochTime = ntpClient.getEpochTime();
Serial.print("Fetched NTP epoch time is: ");
Serial.println(epochTime);
iotHubClient.setEpochTime(epochTime);
#elif ARDUINO_ARCH_ESP8266
time_t epochTime;
configTime(0, 0, "pool.ntp.org", "time.nist.gov");
while (true) {
epochTime = time(NULL);
if (epochTime == 0) {
Serial.println("Fetching NTP epoch time failed! Waiting 2 seconds to retry.");
delay(2000);
} else {
Serial.print("Fetched NTP epoch time is: ");
Serial.println(epochTime);
break;
}
}
#endif
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment