7

I am trying to setup a basic example of sending a message from the Arduino MKR1000 to the Azure IOT Event Hub but can't seem to get any of the online examples to work and I am new to Arduino.

Any pointers for a simple working example?

I tried this example and changing slightly to POST a message rather than receive but no luck. I can connect to the Wifi with no issues, its just when posting the HTTP request it errors with "HTTP Error 411. The request must be chunked or have a content length". It also doesn't seem like the most clean approach but I just wan't to get something basic up and running for now to play with :)

Code Example:

#include <SPI.h>
#include <WiFi101.h>

#include "arduino_secrets.h"

///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID;        // your network SSID (name)
char pass[] = SECRET_PASS;    // your network password (use for WPA, or use as key for WEP)

const int MKR1000_LED = 6 ;


///*** Azure IoT Hub Config ***///
//see: http://mohanp.com/  for details on getting this right if you are not sure.

char hostname[] = "*****.azure-devices.net";    // host name address for your Azure IoT Hub
char feeduri[] = "/devices/MKR1000/messages/events?api-version=2018-06-30"; //feed URI
char authSAS[] = "SharedAccessSignature sr=******.azure-devices.net%2Fdevices%2FMKR1000&sig=*****&se=******";

///*** Azure IoT Hub Config ***///

unsigned long lastConnectionTime = 0;
const unsigned long pollingInterval = 5L * 1000L; // 5 sec polling delay, in milliseconds

int status = WL_IDLE_STATUS;

WiFiSSLClient client;

void setup() {
  Serial.println("setup...");
  pinMode(MKR1000_LED, OUTPUT);

  //check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    // don't continue:
    while (true);
  }

  // attempt to connect to Wifi network:
  while (status != WL_CONNECTED) {
    status = WiFi.begin(ssid, pass);
    // wait 10 seconds for connection:
    delay(10000);
  }
  Serial.println("Wifi connected...");
}

void loop()
{
  String response = "";
  char c;
  ///read response if WiFi Client is available
  while (client.available()) {
    c = client.read();
    response.concat(c);
  }

  if (!response.equals(""))
  {
    Serial.println(response);
    //if there are no messages in the IoT Hub Device queue, Azure will return 204 status code.
    if (response.startsWith("HTTP/1.1 204"))
    {
      //turn off onboard LED
      digitalWrite(MKR1000_LED, LOW);
    }
    else
    {
      //turn on onboard LED
      digitalWrite(MKR1000_LED, HIGH);
    }
  }

  // polling..if pollingInterval has passed
  if (millis() - lastConnectionTime > pollingInterval) {
    digitalWrite(MKR1000_LED, LOW);
    azureHttpRequest("{TEST MESSAGE!}");
  }
}

// this method makes an HTTPS connection to the Azure IOT Hub Server:
void azureHttpRequest(String data) {

  // close any connection before send a new request.
  // This will free the socket on the WiFi shield
  client.stop();

  // if there's a successful connection:
  if (client.connect(hostname, 443)) {
    //make the GET request to the Azure IOT device feed uri
    client.print("POST ");  //Do a GET
    client.print(feeduri);  // On the feedURI
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(hostname);  //with hostname header
    client.print("Authorization: ");
    client.println(authSAS);  //Authorization SAS token obtained from Azure IoT device explorer
    //client.println("Connection: close");
    client.println("Content-Type: application/json");
    client.println("Content-Length: " + data.length());
    client.println("\r\n\r\n" + data);



    // note the time that the connection was made:
    lastConnectionTime = millis();
  }
  else {
    // if you couldn't make a connection:
    Serial.println("connection failed");
  }
}

Edit: I have seen that there is a full Azure IOT library with a simple HTTP example, but this also doesn't run (it gets passed the wifi connection and failing with call to azure) but this example project is fairly large and I was hoping for a simple example to build upon!

https://github.com/Azure/azure-iot-arduino

silent
  • 14,494
  • 4
  • 46
  • 86
Andrew
  • 9,967
  • 10
  • 64
  • 103
  • 3
    is there any specific reason why you are not using the IoT Device SDK and instead constructing the connection yourself? – silent Mar 19 '19 at 09:53
  • Are you referring to the Azure specific library as per my link? I have taken the code mainly from an example online so I am trying to get something working initially. If you have a clearer approach though please share – Andrew Mar 20 '19 at 18:37
  • Also: "I have seen that there is a full Azure IOT library with a simple HTTP example, but this also doesn't run (it gets passed the wifi connection and failing with call to azure) but this example project is fairly large and I was hoping for a simple example to build upon!" – Andrew Mar 20 '19 at 18:42
  • 1
    You absolutely sure `data.length()` returns something in the `client.println` near the end there? Print it out to serial console. [`Transfer-Encoding: chunked`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding#Syntax) should work as well (instead of `Content-Length`). – evilSnobu Mar 21 '19 at 11:25
  • I will double check when back near the Arduino, but i presume it should as I have passed in a static string. I will also try changing the header to use transfer-encoding – Andrew Mar 21 '19 at 11:45
  • No joy:22:39:23.631 -> 22:39:23.631 -> Bad Request 22:39:23.631 -> 22:39:23.631 ->

    Bad Request - Invalid Header

    22:39:23.631 ->

    HTTP Error 400. The request has an invalid header name.

    22:39:23.631 ->
    – Andrew Mar 21 '19 at 22:39
  • I also confirmed the length did return an integer greater than zero – Andrew Mar 26 '19 at 01:13
  • I had similar issue till yesterday but now it suddenly started working as if there has been update to Iot service. I noticed one thing that your content-type is "application/json" but actual message is not in key/value format like "{ "messagestring" : "test message" } .. I used NodeMCU esp32 module to test this – Rahul Ruikar Mar 26 '19 at 11:49
  • In addition to Rahul: if you're not sending a (correct) json file, you could replace Content-Type with: Content-Type: application/x-www-form-urlencoded; charset=UTF-8. I also suggest not to send a newline command on the last print (not a newline after the data) – Finn May 03 '19 at 10:49
  • @silent is likely referring to the various SDK's by Microsoft: https://github.com/Azure/azure-iot-sdks There is one for embedded C, which is probably what you need. – Marcel Dec 22 '20 at 13:53
  • You have a ready-to-use example here: https://github.com/firedog1024/mkr1000-iotc. Note that it uses Azure IoT Device Provisioning Service for provisioning so you will need to [setup a DPS instance](https://learn.microsoft.com/azure/iot-dps/quick-setup-auto-provision) alongside your IoT Hub. – kartben Sep 26 '19 at 17:13

0 Answers0