In my earlier post “Tutorial: Web Server with the ESP8266 WiFi Module” I used the ESP8266 WiFi module to run a local web server. This is a cool way to control devices inside my network. But to use that web page from the internet, I would need to open up my router which I don’t want to do for obvious reasons. Why not going the other way: host the web page in the internet, and have my board communicating with that internet page? This is exactly what this hype around IoT (Internet of Things) is all about :-).
Outline
In this article I continue to use the foundation I have made in my earlier “Tutorial: Web Server with the ESP8266 WiFi Module“: The FRDM-KL25Z board with the ESP8266 WiFi module.
ThingSpeak
I stumbled over ThingSpeak (https://thingspeak.com/) while searching for an IoT cloud platform where I could store my data. There are many ones available, but the this one really stand out in my view: open, free and good infrastructure, including visualization tools.
💡 There is another IoT data server which I recommend to look at: https://data.sparkfun.com/. This one is simple and easy to use, but does not come with visualization out of the box.
Before using ThingSpeak, you need to set up an account:
- Sign up for a free account at https://thingspeak.com/
- Go to Channels and create New Channel. It will assign a Channel ID (we will use later). Provide a name and description. You can leave the other fields with the defaults for now. Press Save at the bottom of the Channel Settings page.
- Go to API Keys: it has generated an API key we will use in the communication.
- Now I can test the connection by putting this in my browser
http://api.thingspeak.com/update?key=API_KEY&field1=0
after replacing API_KEY with the API key from above:
http://api.thingspeak.com/update?key=J4P1LICZI6ZF0YWG
&field1=0
This will add the data ‘0’ to ‘field1’. The browser responds with the number of data points: - I can check the result with
http://api.thingspeak.com/channels/CHANNEL_ID/feed.json?key=API_KEY
where now again use my API key plus the channel ID I have been assigned from above:
http://api.thingspeak.com/channels/20696/feed.json?key=J4P1LICZI6ZF0YWG
- This way I can add multiple data points, and I can view the data in a graphical view:
Now all what is needed to get the ESP8266 to connect to the ThingSpeak server and send the data :-).
Manual ESP8266 Command Sequence
First, let me show the command sequence using the command line shell.
At this point, I assume the ESP8266 module is connected to the access point. Then I set it up to allow multiple connections with CIPMUX:
AT+CIPMUX=1
Then, start a TCP connection to the ThingSpeak server (184.106.153.149), using http port 80. Because I’m allowing multiple connections with CIPMUX, I pass a channel (4):
AT+CIPSTART=4,"TCP","184.106.153.149",80
The ESP8286 should respond with:
OK Linked
Next, I’m using the CIPSEND to send my data. The first value is the channel id from above (4), followed by the size of the string I’m going to send (44 characters in my case):
AT+CIPSEND=4,44
❗ The size needs to include/count the “\r\n” at the end of the string!
Then the module should respond with
>
to show it is ready to receive the data. The data is sent directly, in my case with
GET /update?key=J4P1LICZI6ZF0YWG&field1=60
The GET command sends the data. ‘/update’ is the command to the data site to update the data points, followed by the API key, the field name and the value (60 in my case).
Finally, I close the TCP connection at the end with
AT+CIPCLOSE
And the new data point shows up in ThingSpeak 🙂 :
And here the full command line log:
Sending Data from Program
Because sending the data with the command line shell takes time, it makes sense to automate it in a function.
#define THING_SPEAK_IP_STR "184.106.153.149" /* thingspeak.com IP Address */ #define THINK_SPEAK_IP_PORT 80 /* port number */ #define THING_SPEAK_KEY_STR "J4P1LICZI6ZF0YWG" /* API key */ #define THING_SPEAK_CHANNEL 20696 /* channel ID */ #define THING_SPEAK_LABEL_STR "field1" /*! * \brief Sends a value to the ThingSpeak server * \param value Value to be sent * \param io Shell I/O handler or NULL if not used * \return Error code, ERR_OK for no failure */ uint8_t THINK_SendValue(int32_t value, const CLS1_StdIOType *io) { /* Does the same as the following shell commands: ESP send AT+CIPMUX=1 ESP send AT+CIPSTART=4,"TCP","184.106.153.149",80 // 4 is the channel ID ESP send AT+CIPSEND=4,44 // size with \r\n! ESP send GET /update?key=J4P1LICZI6ZF0YWG&field1=60 ESP send AT+CIPCLOSE */ uint8_t res = ERR_OK; uint8_t buf[64]; uint8_t ch_id = 4; res = ESP_SetNumberOfConnections(1, io, ESP_DEFAULT_TIMEOUT_MS); if (res==ERR_OK) { res = ESP_OpenConnection(ch_id, TRUE, THING_SPEAK_IP_STR, THINK_SPEAK_IP_PORT, 5000, io); if (res==ERR_OK) { UTIL1_strcpy(buf, sizeof(buf), "GET /update?key="); UTIL1_strcat(buf, sizeof(buf), THING_SPEAK_KEY_STR); UTIL1_chcat(buf, sizeof(buf), '&'); UTIL1_strcat(buf, sizeof(buf), THING_SPEAK_LABEL_STR); UTIL1_chcat(buf, sizeof(buf), '='); UTIL1_strcatNum32s(buf, sizeof(buf), value); UTIL1_strcat(buf, sizeof(buf), "\r\n"); res = ESP_PrepareMsgSend(ch_id, UTIL1_strlen(buf), 3000, io); if (res==ERR_OK) { /* sending data */ res = ESP_SendATCommand(buf, NULL, 0, NULL, ESP_DEFAULT_TIMEOUT_MS, io); if (res!=ERR_OK) { CLS1_SendStr("Sending page failed!\r\n", io->stdErr); /* copy on console */ } else { for(;;) { /* breaks */ res = ESP_ReadCharsUntil(buf, sizeof(buf), '\n', 1000); if (res==ERR_OK) { /* line read */ if (io!=NULL) { CLS1_SendStr(buf, io->stdOut); /* copy on console */ } } if (UTIL1_strncmp(buf, "SEND OK\r\n", sizeof("SEND OK\r\n")-1)==0) { /* ok from module */ break; } } } } } (void)ESP_CloseConnection(ch_id, io, ESP_DEFAULT_TIMEOUT_MS); } return res; }
All the other ESP8266 functions are in the ESP8266.c driver file. And a ‘send’ command have been implemented to automate sending data:
With this, I can send data interactively or automatically in given interval:
Summary
With the right steps and know-how, it is really easy to send data to the internet and host it on an IoT server. I this example I used ThingSpeak to post data points and visualize them, but any other IoT host can be used. ThingSpeak has other API’s, plugins and apps which can be used for different applications, e.g. tweeting messages to Twitter, line up requests at predetermined times or execute queued commands. I guess I have to explore all this in the next days and weeks :-).
The project and sources for this tutorial are available on GitHub: https://github.com/ErichStyger/mcuoneclipse/tree/master/Examples/KDS/FRDM-KL25Z/FRDM-KL25Z_ESP8266_ThingSpeak.
Happy Logging 🙂
Links:
- Freescale FRDM-KL25Z Board: http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=FRDM-KL25Z
- Espressif ESP8266 WiFi Module: https://espressif.com/en/products/esp8266/
- Electrodragon ESP8266 Module: http://www.electrodragon.com/w/Wi07c
- SparkFun: https://data.sparkfun.com/
- Steps how to connect to ThingSpeak: http://www.instructables.com/id/ESP8266-Wifi-Temperature-Logger/?ALLSTEPS
Very nice and useful post Erich ( as usual ) !!!
Just a little point to add : the thingspeak server ip address address ( today it is 184.106.153.149 ) could change in future , so it would be great to add dsn client capability to the project in order to automatically resolve the “thingspeak.com” address to the correct ip address ( whatever it will become ).
LikeLike
Yes, I had that thought about DNS client too. For now, it was easier to use the IP address directly.
LikeLike
Hello Erich,
I am trying to send 3-axis data from the FRDM accelerometer to 3 fields in my ThingSpeak channel. For a start, I am sending only X axis to one field. It seems to be necessary to close TCP connection after every GET command, is that true? Also, if I want to send data to multiple fields, do I need to use multiple channels, with multiple CIPSTART commands to different channels, and also several CIPSEND commands?
LikeLike
Yes, I had to close the connections with my hardware/firmware too. I believe this is a bug in the firmware, so this might change we newer firmware (I have not tried that yet). I have not tried multiple channels yet, but if you do, you will need a CIPSEND for each channel.
LikeLike
Hello,
Instead of using multiple channels, I found out that I can use a single GET command to send multiple data fields. I just need to add “&field2=xx&field3=yy” after the original GET command. Now I can send all accelerometer axes for my 3 channel fields in one command. Anyway, it is a pain in the neck to have to close and re-open TCP connection every time I want to send new data. It would be interesting to make a programmer for the module using the FRDM board, so when new firmware versions come, we can be able to update the module with the hardware we have at hand.
LikeLike
Ah, I thought you wanted to use multiple channels. But yes, you can use a single GET for multiple fields too 🙂
As for updating the firmware on the ESP8266: I was considering as well to setup a FRDM board to do that job too, but had no time to work on that yet.
LikeLike
Pingback: Hello Internet! I have a Thing! | MWH Projects Blog
The major problem now in using ESP8266 for WiFi router routed application, is the IP address that is got to be written in the program ( say for Arduino) so it cannot be changed by a lame user.We have successfully overcome this by writing the vales of SSID & Password every time it faces a new wifi router on a serial terminal like (most user friendly is from Hackaday.–http://hackaday.io/project/3568-esp8266-test-program) .Run all the AT commands till you complete the SSID & Password and then remove the ESP and use it with any Arduino interface with program running from thereafter..
LikeLike
Hello. Can you help me? I cant find any way to get data from thingspeak.com. i try many way but it not work. (sory because my english)
LikeLike
can you check if you have any firewalls or other things in between?
LikeLike
Watch it– https://www.youtube.com/watch?v=Wzhj0lgf7wU
LikeLike
Hello.
I tried your esp8266 tutorial on sending data to thinkspeak. I get all the way to the end but after I post the data following the CIPSEND I get an error and the data never shows up? I can’t get past the 400 error. Obvioulsy a bad GET request.
at+CIPSTART=4,”TCP”,”184.106.153.149″,80
4,CONNECT
OK
at+CIPSEND=4,37
> /update?key=80TH1Y8SLZ3XXXXX&field1=1
SEND OK
+IPD,4,323:HTTP/1.1 400 Bad Request
Server: nginx/1.7.5
Date: Mon, 26 Jan 2015 00:16:38 GMT
Content-Type: text/html
Content-Length: 172
Connection: close
OK
4,CLOSED
Thank you,
Rich
LikeLike
I don’t have the module/hardware with me. Is the connection working with the Http/web interface in your browser?
LikeLike
Yes. I can directly query Thingspeak via a browser and get data to populate.
LikeLike
Yes we also faced the same problem. write like this Tx_String(“AT+CIPSEND=50”);
Tx_String(“GET /update?key=****************&field1=”);
As you see the above characters inside the bracket, are 40 But write little more as seen above for AT+CIPSEND = 50 (and not 40)
On Mon, Jan 26, 2015 at 12:55 PM, MCU on Eclipse wrote:
> Rich commented: “Hello. I tried your esp8266 tutorial on sending data > to thinkspeak. I get all the way to the end but after I post the data > following the CIPSEND I get an error and the data never shows up? I can’t > get past the 400 error. Obvioulsy a bad GET request.” Respond to this > comment by replying above this line > New comment on *MCU on Eclipse * > > > *Rich* commented > > on Tutorial: IoT Datalogger with ESP8266 WiFi Module and FRDM-KL25Z > . > > > in response to *Erich Styger*: > > In my earlier post “Tutorial: Web Server with the ESP8266 WiFi Module” I > used the ESP8266 WiFi module to run a local web server. This is a cool way > to control devices inside my network. But to use that web page from the > internet, I would need to open up my router which I don’t […] > > Hello. > > I tried your esp8266 tutorial on sending data to thinkspeak. I get all the > way to the end but after I post the data following the CIPSEND I get an > error and the data never shows up? I can’t get past the 400 error. > Obvioulsy a bad GET request. > > at+CIPSTART=4,”TCP”,”184.106.153.149″,80 > 4,CONNECT > > OK > at+CIPSEND=4,37 > > /update?key=80TH1Y8SLZ3XXXXX&field1=1 > SEND OK > > +IPD,4,323:HTTP/1.1 400 Bad Request > Server: nginx/1.7.5
LikeLike
Thanks for the post – it was helpful.
I’m getting an “ERROR” response from thingspeak after issuing my GET command.
My AT commands are almost exactly like yours, except for the API Key of course.
The command works from the terminal (updates my thingspeak graph), but when it’s run from my Arduino sketch, I get the error and my data is not sent.
Any clues?
LikeLike
Hi James,
is there a special reason why you have to run an Arduino sketch? Can you not use normal C/C++ instead? My guess is that there is a bug in that sketch, so you would have to debug it to find out what is going wrong.
The other thing is: check if doing things slower (with a delay) is helping. That might be a synchronization issue. I assume you are using interrupts?
LikeLike
Erich, Thanks for your prompt reply. I’m using Arduino because that is my preferred platform for this project, and I have other elements already implemented in Aduino sketch. In other words, C/C++ is not “normal” for me. In any event, I agree that there is probably an error in the sketch, and when I insert 2s delays between the important bits, but I still get the “ERROR” response on the GET command. Do you know of any additional details behind the “ERROR” message that I can use to troubleshoot my sketch?
LikeLike
Hi James,
I don’t know what is behind this error. The inability of really debugging Arduino sketches other then with printf() messages was the major reason why I stopped using ‘the Arduino way’ years back. So I recommend that you start adding printing information in your program flow to find out what is going on. Good luck!
LikeLike
hello,
I have send my data to thingspeak. can i go for sending data from one esp8266 to another one.?
If yes then how it would be??
Please leave reply.
LikeLike
I have not done that, but I believe this should be possible? Are you able to read data from ThingSpeak?
LikeLike
yes
LikeLike
Hello every body
I have a question that I want to ask
It is that i want to send a sensor data with ESP
the sensor output is serial with RX and TX pins
so I have decided to connect it directly to ESP
the question is how to read this data with the simulinkUDP receive?
thank you so much
LikeLike
Hello,
I’m not familiar with the simulinkUDP connection. My understanding is that you want to read that data over the wire? You could use the FRDM board translating the data over UART/USB CDC to the host, if this is your use case.
LikeLike
Thank you so much…(y)
LikeLike
Hi, could you help me out a bit? My Esp seem to be sending out data perfectly while connected to my home router. However, the connection closes most of the time when I use a wifi hotspot instead, and most of the values dont send. This is really weird because it works beautifully with my home wifi. My wifi hotspot works fine by the way
LikeLike
Have you tried with different hotspots? I admit that I have it used with access points/routers only. Maybe your hotspot disconnects the module in some ways?
LikeLike
I have tried using my phone as a hotspot as well to no avail. Some values do get sent out but these are far and few. The connection closes after every attempt at sending a value, and I think its because of an error after the At+CIPSEND command.
LikeLike
I’m not clear what the problem could be, but I suspect it might be a problem that the hotspot too frequently closes the connection?
LikeLike
Hello, i am working on ESP8266 access point and i want to have internet on my phone when i connect to my ESP8266 but it said that don’t have internet connection, but i have i don’t know what is wrong? can someone help me with that please.
LikeLike
Hi Jan, you would need to use the ESP8266 as access point.
LikeLike
i have on MODE=2 and i connect computer on my ESP8266 and showing me yellow triangle what i need to do then?
LikeLike
I have not used it in access point mode yet. But for sure it would need to provide some IP address to the client, and I think this is what you are missing?
LikeLike
Do i need to have in MODE=1 for STA to have access point?
LikeLike
AT+CWMODE=1 is for device, AT+CWMODE=2 is for access point. See https://mcuoneclipse.com/2014/11/30/tutorial-web-server-with-the-esp8266-wifi-module/
LikeLike
hi i’m using esp8266 module.i have already uploaded lua firmware by nodemcu. now i want to send adc value from one esp module to another esp module they are connected through UART.now plz help how i can send adc value. plz give the two programmes code.
LikeLike
I’m affraid that I cannot do the work for you, but I can give you some hints what you have to do: I recommend that you either configure one ESP module as AP the other in Device mode. Then connect from the Device node to the AP node. The other (easier) way is that you configure both in Device mode, then connect to a third node (e.g. HTTP/FTP server) and store the values there. So one node sends the ADC value to the server, while the other module is retrieving the values from there.
LikeLike
Hi Erich,
I have a system where I am using HiFly HF-LPB100 wifi module. It supports HTTP protocol but it does not have FTP implemented on it.
My system has 2 components.
1. SD card (where i store the csv files).
2. wifi module.
I am using FRDM-K22F board.
I want to send files from SDCard to the server. I am thinking of 2 options.
1. Use HTTP POST command to attach the file.
2. Use FTP for file transfers.
Which is better among these two.
Also I know HTTP POST with file attachment works on my laptop. But I have no clue how to attach a file from my MCU. On my laptop, I give the path of file. How do I do it on my embedded device?
Thanks in advance.
LikeLike
Hi Vishal,
my preference would be to use ftp as this is designed for file transfer. But for short text/information of course you could use HTTP too.
But I don’t have an example of that to share.
LikeLike
Is u successful in transferring data to FTP/ HTTP?
LikeLike
I have not used FTP with the ESP8266.
LikeLike
Hi,
I’m looking to transmit short bursts of data as fast as possible. My adc is capturing at 10M Samples per second, so the bottleneck will most likely be on the networking side.
Do you know what kind of data rates are generally achievable with the esp8266 (or cc3100, etc)? For example, a host using a spi clock of 5mhz, doing nothing but transmitting the alphabet, how many characters per second before characters start dropping (udp or tcp)?
What type of application layer is best suited for high bandwidth bursts?
Thanks!
Ben
LikeLike
Hi Ben,
I have no idea, I have not used that module that way. One limitation factor will be as well the serial interface to the module. So 10M (Mega?) samples per second are a *lot*.
Using SPI with 5 MHz clock will require at least 8 clocks to transmit one byte (8 bits), plus overhead. So with a 5 MHz clock you will not be able to send more than 5/8 MBytes. Realistically you need to count in an overhead (idle time, communication overhead) of 10-20%.
I hope this helps,
Erich
LikeLike
Pingback: PIC na IoT com ESP8266 e ThingSpeak - Embarcados
Could I send the X axes value too?
LikeLike
Thank you very mush.
There is a slight problem which is occuring before the final execution.ON giving the GET command to fetch the page details a ‘busys….’ is returned. Can please let me know how to overcome this problem?
LikeLike
I have not seen that problem. Maybe it is a problem with your firmware on the ESP8266?
LikeLike
how to mysql to php databases send the thingspeak ?
i am using gas sensor mq135 to data send the Node MCU .the node mcu Crete the esp8266 host post to send data bases storage of MYSQL php ..
mysql tohow to post the data on web server thinkspeak.how?
LikeLike
I have not used it in that way, but this is certainly possible. Search the internet for tutorials which guide you how to send data to a mysql server using http or any other TCP/IP based protocol. The ESP8266 is not any differnt from that.
LikeLike
Hi, Erich!
I am trying to create a project that is using 2 Serial_LDD components: one for sending debug messages on UART0 and the second one to communicate with an ESP8266-12F WiFi module on UART2. I am trying to set the baud for UART2 to 115200 bps, but I get an error saying that is impossible to set the selected value. I tried to set the baud to 38400, but this doesn’t help because the module is communicating on 115200. Is it impossible to use UART2 with 115200 as a baud value?
Thank you,
Elena
LikeLike
Hi Elena,
if you want to achieve a higher baud, then you have to increase the CPU clock. Have you already set the clock to the maximum?
Erich
LikeLike
So far, I’ve only used the default CPU clock. How can I set it to the maximum value?
Thank a lot,
Elena
LikeLike
Hi Elena,
if you are using the KL25Z, then the default would be only around 20 MHz which is too slow for high baud rates. So yes, you can (and should) set it to the maximum value which is 48 MHz.
Erich
LikeLike
Pingback: WiFi OLED Mini Weather Station with ESP8266 | MCU on Eclipse
This is a post from 4 years ago, but am using esp8266 in a project, I figured it would be super simple to hook it up to a FRDM-K64F board and get it working. Sure enough even without a webserver implementation, I have written a simple firmware that connects to the esp8266 board in AP mode and sends a value to thingspeak.com. My issue is that it is not consistent in sending values. First of all I have to use longer timeout values than yours (typically 10 to 12 seconds) in order to read the entire response and even then is not always consistent. In your testing I see you were uploading a value to thingspeak every 30 seconds. That is what I am trying to achieve here, too often it fails. Sometimes it reports failed to send and the value appears on the chart. How comes you were able to get consistent results? I am using some 4G wifi dongle for internet and it works pretty well.
LikeLike
It is amazing to realize how fast time goes by, 4 years already!
I would have to dig out that project hardware (not sure if I still have a esp8266 around), but it was working very well that way for several months. I used an normal wireless access point, so no 4G. Maybe the issue is on thingspeak that they slow down things now? I pretty much moved over to use MQTT instead for such kind of things.
LikeLike
Thanks man. I will check out MQTT. I figured out that the 4g network is troublesome over here, I am in Lahore Pakistan. I however figured out how to update the firmware to the latest version using esptools, in Linux. I am writing a blog post about that. I will test again the performance tomorrow before ruling it out.
LikeLike
Pingback: Eclipse JTAG Debugging the ESP32 with a SEGGER J-Link | MCU on Eclipse