Skip to Content
Author's profile photo Vladimir Savchenko

Direct publishing to HCP IOT Services with ESP8266 and Arduino IDE (2.0.0)

Existing Work

In this blog i will explain how to connect the ESP8266 with HCP IOT, by developing a simple sketch in the Arduino IDE. It is not meant as a standalone post, rather as a follow up to the great blogs by Prashantha H J, Jan Penninkhof, Rui Nogueira. They describe in detail how to wire an ESP8266, how to connect via a PHP gateway, a plain C program based on the Esspressiv SDK, and how to connect this to the HCP IOT Service and build a nice looking SAP UI5 Frontend.

For Reference, for those that want some background information, here are the links to those blog posts:

ESP8266 and HCP Internet Of Things Services (BETA) – Part 1

Connecting an ESP8266 to the SAP HANA Cloud Platform

RaspberryPi on SAP HCP – IoT blog series part 1: Setting-up your RaspberryPi

Arduino IDE and ESP8266

The folks at https://github.com/esp8266/Arduino, have done great work in bridging the Arduino IDE with ESP8266, making it very simple to develop sketches and deploy them to an ESP8266. As noted in the blogs by Jan and Prashantha, up to recently it did not support HTTPS connections, so connecting to HCP IOT required some workarounds.

Yet, few months ago HTTPS support has been included and as a bonus, a couple of weeks ago a built in HTTP Client has been included. This makes the whole story very easy to implement and brings it closer to a much wider community of makers.

When you download it, make sure to take the GIT version (not stable, nor staging), and follow the instructions to install it. Also make sure to use Arduino 1.6.5 and not 1.6.6 as it brought some incompatible changes. (This is as of 12.Dec.2015, perhaps soon the GIT version will be stable and can be directly installed from Arduino’s BoardManager)

ESP8266 to HCP IOT Service

The whole code to make this call is quite simple. Assuming that you have followed the posts above or already know the details, you should have your deviceID, authentication Token, messageId, variableName and of course the host name of your IOT MMS server.

(The whole sketch can be downloaded from my git Repository: vlast3k/HCPIOT_ESP8266_ArduinoIDE · GitHub (just make sure to store it in a directory called ‘HCPIOT_ESP8266_ArduinoIDE’))

In this example i am using the simplified syntax for calling the MMS server, that is – all parameters are sent in the URL, thus – no JSON needs to be constructed manually.

This syntax implies that you should build an url like this:


sprintf(url, "https://%s/com.sap.iotservices.mms/v1/api/http/data/%s/%s/sync?%s=%d",
                host, deviceId, messageId, variableName, value);

where host, deviceId and messageId are self-explanatory. “variableName” is the name of the variable in your message, whose “value” you want to update. With this syntax multiple variables can be sent as well.

Then sending the HTTPS call is simple:


 HTTPClient http;
  http.begin(url);
  http.addHeader("Content-Type",  "application/json;charset=UTF-8");
  http.addHeader("Authorization", String("Bearer ") + token);
  http.POST("");
 Serial.printf("Payload: [%s]\n", http.getString().c_str());

In case it is Ok, the response should be something like


Payload: [52
{"msg":"1 message(s) received from device [c5c73d69-6a19-4c7d-9da3-b32198ba71f9]"}
0
]

If there was a problem to establish connection the response code is <0, with the following meanings


#define HTTPC_ERROR_CONNECTION_REFUSED  (-1)
#define HTTPC_ERROR_SEND_HEADER_FAILED  (-2)
#define HTTPC_ERROR_SEND_PAYLOAD_FAILED (-3)
#define HTTPC_ERROR_NOT_CONNECTED       (-4)
#define HTTPC_ERROR_CONNECTION_LOST     (-5)
#define HTTPC_ERROR_NO_STREAM           (-6)
#define HTTPC_ERROR_NO_HTTP_SERVER      (-7)

Else – the response code is a standard HTTP response code.

Conclusion

I believe that those new enhancements to this framework will make a big step towards enabling it for various developers to do interesting things. Previously a bit more expertise was required to use this functionality (e.g. as Jan described in his post of using the Esspresiv SDK to make HTTPS calls), or using some bridge to do the needful.

Also I would recommend to use some of the existing development boards for ESP8266. A month ago a very appealing board was released – the Wemos D1 mini. It costs 4$ at Aliexpress, which is an astonishing low price, given the fact that the components if bought separately cost more. I do not want to make advertisement of this board, but i am just excited of it (so i bought 15 already πŸ™‚ ).

I hope this blog will be useful and of course in case of problems or questions – feel free to comment.

Assigned Tags

      12 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Prashantha H J
      Prashantha H J

      Thanks a lot for this blog. I have updated my blogs accordingly πŸ™‚

      Author's profile photo Vladimir Savchenko
      Vladimir Savchenko
      Blog Post Author

      Great !

      Btw it seems like soon also the other limitation will be overcomed. Esspessiv is currently on their way to include WPA Enterprise for authentication.

      Author's profile photo Arthur Fuscella Silva
      Arthur Fuscella Silva

      Great document,

      Is it mandatory to generate a token in IoT cockpit in Device tile when transmitting data from Arduino to the Cloud?


      Let's say a device wants to send data to the cloud, and the application endpoint is a xsjs service, or a xsodata service, what do I need to do to make this connection work? I already have an example, but the arduino is always showing me a 301(redirect) message while sending data to the service.

      Kindly regards,

      Arthur Silva

      Author's profile photo Vladimir Savchenko
      Vladimir Savchenko
      Blog Post Author

      Maybe you already solved it, but i just got back from vacation πŸ™‚

      You need the token only if you send the data to the IOT service. If you have an xsjs service

      you need to follow its authentication scheme. In case you receive 301, the reason is perhaps that it is redirecting you to somewhere to authenticate.

      Just make sure to dump the whole response in your program, so that you understand what is the problem.

      Also try the same call from your pc, to validate if it is correct

      Regards, Vladimir

      Author's profile photo Arthur Fuscella Silva
      Arthur Fuscella Silva

      No worries, problem solved by fixing few problems in Arduino program. And you're right about the authentication, some data were sent wrong causing error 301, but now I'm able to send data through Arduino.

      Arthur Silva

      Author's profile photo Former Member
      Former Member

      Hi Arthur,

      Could you please share your code. I am also exploring Arduino and ESP8266 but unable to send the data to HCP.

      Thanks,

      Author's profile photo Former Member
      Former Member

      Hi Vladimir Savchenko,

      I am trying to replicate your scenario using Arduino with ESP8226. I have successfully added both library <ESP8266wifi.h> and <ESP8266HTTPClient.h>. After copying your code from GIT, when I am trying to compile it in Arduino IDE version 1.6.8, it its giving me below error.

      Error -C:\Users\Lenovo\Documents\Arduino\libraries\ESP8266HTTPClient/ESP8266HTTPClient.h:28:18: fatal error: memory: No such file or directory

      Could you please suggest how to rectify this error or should I install a lower version of Arduino IDE?

      Thanks

      Author's profile photo Vladimir Savchenko
      Vladimir Savchenko
      Blog Post Author

      Version 1.6.8 is fine

      So you have installed the ESP8266 addon?

      Try first with one of the examples, e.g. ESP8266HttpClient/BasicAuthClient

      if this compiles and uploads, this means that everything is working fine

      Author's profile photo Former Member
      Former Member

      Hi Vladimir,

      Yes, I have installed ESP addon.

      When I choose Board - Generic ESP Module, it is getting complied but on Board - Arduino Uno its is giving error .

      On Board - Generic ESP Module, when I try to upload the sketch, below error is coming.

      warning: espcomm_sync failed
      error: espcomm_open failed
      error: espcomm_upload_mem failed

      Just wanted to ask you, which Board are you using to upload the sketch?

      Thanks

      Author's profile photo Vladimir Savchenko
      Vladimir Savchenko
      Blog Post Author

      To go this route, you have to separately upload to the ESP8266 board, and then to the arduino board

      you will have two sketches

      - one that runs on the ESP8266, does all the necessary communication, ssl etc.. it would also listen for commands over the serial port (you can define your own protocol, not the AT stuff)

      - and one sketch for the arduino that would then send commands to the ESP8266 via the serial port

      You can find a rough example here:

      GitHub - vlast3k/vThingCO2 at ed5ae899ce683aab8d5ad9fe71c0f47dd06400ca

      The file vThingCO2/Menu.ino at ed5ae899ce683aab8d5ad9fe71c0f47dd06400ca · vlast3k/vThingCO2 · GitHub

      Implements the processing of the serial port and handling of the commands. And then you have

      wifi "ssid","pass"

      to configure wifi

      cfgiot1 "iotmmsi024148trial.hanatrial.ondemand.com", "deiceId", "msgId", "variableName"

      and

      cfgiot2 "oauthtoken", "___not__needed"

      And then when you send a command

      sndiot 4444

      it would send a message with he specified message id, device id, var name, oauth token to the HCP IOT Service.

      In the next weeks i will be simplifying this code, but for now it is like this, part of a bigger firmware

      REgards, Vladimir

      Author's profile photo Marcus Conrad Behrens
      Marcus Conrad Behrens

      I had issues with a factory account with above approach.

      The following changes made it work:

      instead: sprintf(url, "https://%s/com.sap.iotservices.mms/v1/api/http/data/%s/%s/sync?%s=%d",host,deviceId, messageId, variableName, analogRead(A0));
      use:     sprintf(url, "/com.sap.iotservices.mms/v1/api/http/data/%s/%s/sync?%s=%d", deviceId, messageId, variableName, analogRead(A0));
      
      instead: http.begin(url);
      use:     http.begin(host, 443, url, true, "C2 56 76 D6 07 DB 8F 8C 98 6E B2 24 63 14 13 69 AC 75 67 84");

      What's the difference?Β In a factory account the server checks if the client can provide him with the secure fingerprint to know that this client really wanted to connect to this server and not another one.

       

      Author's profile photo Joe Bhullar
      Joe Bhullar

      Thank you for posting that code Marcus! It helped me a lot.

      Also, if you code is taking a long time to upload the sketch -- try turning off your antivirus/firewall while uploading your sketch in the Arduino IDE. I used Arduino 1.8.5