I wrote this instructable because Thingspeak -nevermind how easy to set up- has a few hurdles that I ran into and that, judging from reactions, other people are struggling withas well. Things you need: I wanted to collect some weather-data with my Arduino and have that available as nice graphs, on a webpage, so I could also monitor it from afar There're few alternatives for Xively: I picked 'Thingspeak' I describe a simpel connection with an ethernet cable and a connection via WiFi Step 1: Hurdles and SolutionsHurdle 1 "Using an Arduino + Ethernet Shield to Update a ThingSpeak Channel" https://github.com/iobridge/ThingSpeak-Arduino-Exa... That program takes a reading from the A0 port and sends that to "Field1" in your datastream Ok so you try that, you hang a variable resistor like an LDR or NTC on port A0, add your API in the program and run it. Hurdle 2 Trying to find info on that function on internet quickly led me to endless discussions on 'how stupid' it was and people asking questions were often told "why would you need that, Serial.print will do that for you" Yeah, true, but I don't want to print, I need it because Thingspeak wants it. Solution char t_buffer[10]; t=(ReadSensor); String temp=dtostrf(t,0,5,t_buffer); That bufferspace is important. I had it working with '7' or even '5', but when I added a second sensor that needs this function, my datastream would crash and or I got the weirdest results. I also figured that I could use the same bufferspace alternating for each sensor, but that also didnt really work, so now i have a bufferspace for each sensor. Hurdle3 Solution updateThingSpeak("field1="+temp+"&field2="+humid+"&field3="+pres+"&field4="+temp2); AdvertisementStep 2: The ProgramBelow you will find the full code. /* Arduino --> ThingSpeak Channel via Ethernet The ThingSpeak Client sketch is designed for the Arduino and Ethernet. This sketch updates a channel feed with an analog input reading via the ThingSpeak API (http://community.thingspeak.com/documentation/) using HTTP POST. The Arduino uses DHCP and DNS for a simpler network setup. The sketch also includes a Watchdog / Reset function to make sure the Arduino stays connected and/or regains connectivity after a network outage. Use the Serial Monitor on the Arduino IDE to see verbose network feedback and ThingSpeak connectivity status. Getting Started with ThingSpeak: * Sign Up for New User Account - <a href="https://www.thingspeak.com/users/new" rel="nofollow"> https://www.thingspeak.com/users/new </a> * Enter a MAC Address in this sketch under "Local Network Settings" * Create a new Channel by selecting Channels and then Create New Channel * Enter the Write API Key in this sketch under "ThingSpeak Settings" Arduino Requirements: * Arduino with Ethernet Shield or Arduino Ethernet * Arduino 1.0 IDE Network Requirements: * Ethernet port on Router * DHCP enabled on Router * Unique MAC Address for Arduino Created: October 17, 2011 by Hans Scharler (http://www.iamshadowlord.com) Additional Credits: Example sketches from Arduino team, Ethernet by Adrian McEwen Added dht11/BMP180 showed dtostrf function by diy_bloke 22/11/2014 */ #include <SPI.h> #include <Ethernet.h> #include <dht11.h> #include <Wire.h> #include <Adafruit_BMP085.h> // This is the version 1 library #define DHT11PIN 4 // The Temperature/Humidity sensor Adafruit_BMP085 bmp; dht11 DHT11; // Local Network Settings byte mac[] = { 0xD4, 0x28, 0xB2, 0xFF, 0xA0, 0xA1 }; // Must be unique on local network // ThingSpeak Settings char thingSpeakAddress[] = "api.thingspeak.com"; String writeAPIKey = "REPLACE_THIS_BY_YOUR_API_BUT_KEEP_THE_QUOTES"; const int updateThingSpeakInterval = 16 * 1000; // Time interval in milliseconds to update ThingSpeak (number of seconds * 1000 = interval) // Variable Setup long lastConnectionTime = 0; boolean lastConnected = false; int failedCounter = 0; // Initialize Arduino Ethernet Client EthernetClient client; void setup() { // Start Serial for debugging on the Serial Monitor Serial.begin(9600); // Start Ethernet on Arduino startEthernet(); } void loop() { // Read value from Analog Input Pin 0 String analogPin0 = String(analogRead(A0), DEC); // Print Update Response to Serial Monitor if (client.available()) { char c = client.read(); Serial.print(c); } //------DHT11-------- int chk = DHT11.read(DHT11PIN); char t_buffer[10]; char h_buffer[10]; float t=(DHT11.temperature); String temp=dtostrf(t,0,5,t_buffer); //Serial.print(temp); //Serial.print(" "); float h=(DHT11.humidity); String humid=dtostrf(h,0,5,h_buffer); //Serial.println(humid); //-----BMP180----------- bmp.begin(); float p=(bmp.readPressure()/100.0);//this is for pressure in hectoPascal float m=(bmp.readPressure()/133.3);// this is for pressure in mmHG float t2=(bmp.readTemperature()); char p_buffer[15]; char t2_buffer[10]; String pres=dtostrf(p,0,5,p_buffer); String temp2=dtostrf(t2,0,5,t2_buffer); Serial.println(pres); // } //---------------- // Disconnect from ThingSpeak if (!client.connected() && lastConnected) { Serial.println("...disconnected"); Serial.println(); client.stop(); } // Update ThingSpeak if(!client.connected() && (millis() - lastConnectionTime > updateThingSpeakInterval)) { updateThingSpeak("field1="+temp+"&field2="+humid+"&field3="+pres+"&field4="+temp2); } // Check if Arduino Ethernet needs to be restarted if (failedCounter > 3 ) {startEthernet();} lastConnected = client.connected(); } void updateThingSpeak(String tsData) { if (client.connect(thingSpeakAddress, 80)) { client.print("POST /update HTTP/1.1\n"); client.print("Host: api.thingspeak.com\n"); client.print("Connection: close\n"); client.print("X-THINGSPEAKAPIKEY: "+writeAPIKey+"\n"); client.print("Content-Type: application/x-www-form-urlencoded\n"); client.print("Content-Length: "); client.print(tsData.length()); client.print("\n\n"); client.print(tsData); lastConnectionTime = millis(); if (client.connected()) { Serial.println("Connecting to ThingSpeak..."); Serial.println(); failedCounter = 0; } else { failedCounter++; Serial.println("Connection to ThingSpeak failed ("+String(failedCounter, DEC)+")"); Serial.println(); } } else { failedCounter++; Serial.println("Connection to ThingSpeak Failed ("+String(failedCounter, DEC)+")"); Serial.println(); lastConnectionTime = millis(); } } void startEthernet() { client.stop(); Serial.println("Connecting Arduino to network..."); Serial.println(); delay(1000); // Connect to network amd obtain an IP address using DHCP if (Ethernet.begin(mac) == 0) { Serial.println("DHCP Failed, reset Arduino to try again"); Serial.println(); } else { Serial.println("Arduino connected to network using DHCP"); Serial.println(); } delay(1000); } Step 3: Connect to Thingspeak using an ESP8266 WiFi ModuleThe previous presented internet connection was made via a cable. However, there is a cheap WiFi module that is available to attach to the Arduino: The ESP 8266. // <a href="https://nurdspace.nl/ESP8266" rel="nofollow"> https://nurdspace.nl/ESP8266 </a> //http://www.instructables.com/id/Using-the-ESP8266-module/ //https://www.zybuluo.com/kfihihc/note/31135 //http://tminusarduino.blogspot.nl/2014/09/experimenting-with-esp8266-5-wifi-module.html //http://www.cse.dmu.ac.uk/~sexton/ESP8266/ //https://github.com/aabella/ESP8266-Arduino-library/blob/master/ESP8266abella/ESP8266aabella.h //http://contractorwolf.com/esp8266-wifi-arduino-micro/ //********************************************************** #include <SoftwareSerial.h> int sensor_temp = A0; int value_temp; int sensor_light = A1; int value_light; int sensor_humid = A2; int value_humid; #define DEBUG FALSE //comment out to remove debug msgs //*-- Hardware Serial #define _baudrate 9600 //*-- Software Serial // #define _rxpin 2 #define _txpin 3 SoftwareSerial debug( _rxpin, _txpin ); // RX, TX //*-- IoT Information #define SSID "[YOURSSID]" #define PASS "[YOURPASSWORD]" #define IP "184.106.153.149" // ThingSpeak IP Address: 184.106.153.149 // GET /update?key=[THINGSPEAK_KEY]&field1=[data 1]&field2=[data 2]...; String GET = "GET /update?key=[ThingSpeak_(Write)API_KEY]"; void setup() { Serial.begin( _baudrate ); debug.begin( _baudrate ); sendDebug("AT"); delay(5000); if(Serial.find("OK")) { debug.println("RECEIVED: OK\nData ready to sent!"); connectWiFi(); } } void loop() { value_temp = analogRead(sensor_temp); value_light = analogRead(sensor_light); value_humid = analogRead(sensor_humid); String temp =String(value_temp);// turn integer to string String light= String(value_light);// turn integer to string String humid=String(value_humid);// turn integer to string updateTS(temp,light, humid); delay(3000); // } //----- update the Thingspeak string with 3 values void updateTS( String T, String L , String H) { // ESP8266 Client String cmd = "AT+CIPSTART=\"TCP\",\"";// Setup TCP connection cmd += IP; cmd += "\",80"; sendDebug(cmd); delay(2000); if( Serial.find( "Error" ) ) { debug.print( "RECEIVED: Error\nExit1" ); return; } cmd = GET + "&field1=" + T +"&field2="+ L + "&field3=" + H +"\r\n"; Serial.print( "AT+CIPSEND=" ); Serial.println( cmd.length() ); if(Serial.find( ">" ) ) { debug.print(">"); debug.print(cmd); Serial.print(cmd); } else { sendDebug( "AT+CIPCLOSE" );//close TCP connection } if( Serial.find("OK") ) { debug.println( "RECEIVED: OK" ); } else { debug.println( "RECEIVED: Error\nExit2" ); } } void sendDebug(String cmd) { debug.print("SEND: "); debug.println(cmd); Serial.println(cmd); } boolean connectWiFi() { Serial.println("AT+CWMODE=1");//WiFi STA mode - if '3' it is both client and AP delay(2000); //Connect to Router with AT+CWJAP="SSID","Password"; // Check if connected with AT+CWJAP? String cmd="AT+CWJAP=\""; // Join accespoint cmd+=SSID; cmd+="\",\""; cmd+=PASS; cmd+="\""; sendDebug(cmd); delay(5000); if(Serial.find("OK")) { debug.println("RECEIVED: OK"); return true; } else { debug.println("RECEIVED: Error"); return false; } cmd = "AT+CIPMUX=0";// Set Single connection sendDebug( cmd ); if( Serial.find( "Error") ) { debug.print( "RECEIVED: Error" ); return false; } } NOTE In the latest version of the ESP8266 firmware AT+CIOBAUD is no longer supported and returns ERROR. More note Step 4: Using just the ESP8266if you come upon this page and see gibberish... there was a full step here, but somehow Instructables decided it would be better to replace it with gibberish...after i already saved it. I will give it another go In the previous step I used an ESP8266 to send the sensorvalues that were read by an Arduino to Thingspeak. However, it is also possible to do it without an Arduino at all. I connected a DHT11 to pin 2 of my ESP8266-01 and used the following program. I can't take full credit for the program, I think the original is from Jeroen Beemster #include <DHT.h> // DHT.h library #include <ESP8266WiFi.h> // ESP8266WiFi.h library #define DHTPIN 2 #define DHTTYPE DHT11 const char* ssid = "YourNetworkSSID"; const char* password = "YourPassword"; const char* host = "api.thingspeak.com"; const char* writeAPIKey = "YourWriteAPI"; DHT dht(DHTPIN, DHTTYPE, 15); void setup() { // Initialize sensor dht.begin(); delay(1000); // Connect to WiFi network WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); } } void loop() { float humidity = dht.readHumidity(); float temperature = dht.readTemperature(); if (isnan(humidity) || isnan(temperature)) { return; } // make TCP connections WiFiClient client; const int httpPort = 80; if (!client.connect(host, httpPort)) { return; } String url = "/update?key="; url+=writeAPIKey; url+="&field1="; url+=String(temperature); url+="&field2="; url+=String(humidity); url+="\r\n"; // Request to the server client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n"); delay(1000); } It is not the goal of this instructable to explain how to program the ESP8266, there are plenty of sources for that. A good one is here. If you already have an USB-TTL module at 3.3 Volt, you dont need to worry about voltages. If you only have a 5Volt USB-TTL module you still can use it but have to use a voltage divider between the Tx of the module and the Rx of the ESP8266. Never ever put 5 volt on the ESP8266 Step 5: A BonusIn case you do not want to use Thingspeak but just want your own webserver: use this program: /* * DHT11 Sensor connected to Pin 2 <a href="http://arduino-info.wikispaces.com/ethernet-temp-humidity" rel="nofollow"> http://arduino-info.wikispaces.com/ethernet-temp-...> Based on code by David A. Mellis & Tom Igoe Adapted by diy_bloke * bmp180sensor on a4/a5 */ /*-----( Import needed libraries )-----*/ #include <SPI.h> #include <Ethernet.h> #include <dht11.h> #include <Wire.h> //#include <Adafruit_Sensor.h> //#include <Adafruit_BMP085_U.h> #include <Adafruit_BMP085.h> /*-----( Declare Constants and Pin Numbers )-----*/ #define DHT11PIN 2 // The Temperature/Humidity sensor // Enter a MAC address and IP address for your controller below. // The IP address will be dependent on your local network: byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; /*-----( Declare objects )-----*/ |