I want to let my ESP32 get information from my homepage. But I get an error code -5 in the serial monitor output.
I can't figure out what is wrong?
Is there something wrong with the code?
Does the server not allow ESP32 to receive data and how do I find out of this?
You can see the output further down.
Code:
#include <WiFi.h> // Replace with WiFi.h for ESP32
#include <WebServer.h> // Replace with WebServer.h for ESP32
#include <AutoConnect.h> // For AutoConnect Wifi
#include <time.h> // For NTP time
//for display
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//DISPLAY
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library.
// On an arduino UNO: A4(SDA), A5(SCL)
// On an arduino MEGA 2560: 20(SDA), 21(SCL)
// On an arduino LEONARDO: 2(SDA), 3(SCL), ...
#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
int x,minX;
IPAddress ip;
//AUTOCONNECT
WebServer Server; // Replace with WebServer for ESP32
AutoConnect Portal(Server);
AutoConnectConfig Config;
//Webside fra ESP
void rootPage() {
char content[] = "Kapsejlads.nu - HORN";
Server.send(200, "text/plain", content);
}
//SKRIV NTP TID
void printLocalTime(){
struct tm timeinfo; //skriv tiden til timeinfo som tidskode
if(!getLocalTime(&timeinfo)){ //kontroller om tid er modtaget
Serial.println("Failed to obtain time");
return;
}
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S"); //skriv tid til monitor
}
//SÆT TIDSZONE
void setTimezone(String timezone){
Serial.printf(" Setting Timezone to %s\n",timezone.c_str()); //skriv til monitor
setenv("TZ",timezone.c_str(),1); // Now adjust the TZ. Clock settings are adjusted to show the new local time. Indstil til CPH
tzset(); //indstil tidszonen
}
//HENT NTP TID
void initTime(String timezone){
struct tm timeinfo; //skriv tiden til timeinfo
Serial.println("Setting up time");
configTime(0, 0, "europe.pool.ntp.org"); // First connect to NTP server, with 0 TZ offset. Ingen tidszone eller sommertidskorrektion
if(!getLocalTime(&timeinfo)){ //hvis NTP ikke kan hentes
Serial.println(" Failed to obtain time");
return;
}
Serial.println(" Got the time from NTP"); //NTP tid er hentet
// Now we can set the real timezone
setTimezone(timezone); //sæt tidszonen og dermed evt. sommertid
}
void setup() {
//DISPLAY
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);
//delay(2000); // Pause for 2 seconds
display.setTextSize(1); //font størrelse
display.setTextColor(WHITE); //skrift farve
display.setTextWrap(false); //skift ikke linje
display.clearDisplay(); //ryd display
display.setCursor(0, 10); //start position
display.print("Kapsejlads.nu"); //sæt tekst
display.setCursor(0, 20); //ny position
display.print("by Frank Larsen"); //sæt tekst
display.display(); //skriv til display
x=display.width(); //sæt x = display bredde.
//AUTOCONNECT
Serial.begin(115200);
Serial.println();
Config.apid = "Kapsejlads-horn";
Config.psk = "Kapsejlads.nu";
Portal.config(Config);
//FORBIND WIFI
Server.on("/", rootPage);
if (Portal.begin()) {
Serial.println("WiFi connected: " + WiFi.localIP().toString());
}
//hent NTP tid
delay(500); //vent 0,5 s, så wifi er klar
initTime("CET-1CEST,M3.5.0,M10.5.0/3"); //hent tid for københavn, https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
//hent klub navn
String serverName = "https://kapsejlads.nu/hide-horn-esp.php";
if(WiFi.status()== WL_CONNECTED){
WiFiClient client;
HTTPClient http;
String serverPath = serverName + "?klubid=13";
Serial.println(serverPath);
// Your Domain name with URL path or IP address with path
http.begin(client, serverPath.c_str());
// If you need Node-RED/server authentication, insert user and password below
//http.setAuthorization("REPLACE_WITH_SERVER_USERNAME", "REPLACE_WITH_SERVER_PASSWORD");
// Send HTTP GET request
int httpResponseCode = http.GET();
if (httpResponseCode>0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
String payload = http.getString();
Serial.println(payload);
}
else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
}
// Free resources
http.end();
}
else {
Serial.println("WiFi Disconnected");
}
}
void loop() {
Portal.handleClient();
//Hent lokal NTP fra ESP
struct tm timeinfo;
getLocalTime(&timeinfo);
//vis rulletekst
char message[]="Dette er min tekst";
//minX=-12*strlen(message);
minX=-12*25; //12 karakter i disp med denne font, 25 karakter tekst at vise
display.setTextSize(2);
display.clearDisplay();
display.setCursor(x,10);
display.print(WiFi.localIP().toString()+" - "); //viser IP i display
display.print(&timeinfo, "%H:%M:%S"); //viser tiden bagefter i display
//display.print(message); //viser tekst i display
display.display(); //skriv til display
x=x-1;
if(x<minX)x=display.width();
//Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S"); //skriv tid til monitor
}
Output:
WiFi connected: 192.168.1.118
Setting up time
Got the time from NTP
Setting Timezone to CET-1CEST,M3.5.0,M10.5.0/3
https://kapsejlads.nu/hide-horn-esp.php?klubid=13
Error code: -5
I have tried to move the http code to the loop part without results.
When I run the homepage link I get "Demo klub" as result. This is just simple text. I expected the ESP32 to put this output to the Serial Monitor. But no.
I have also tried to format the output from the homepage as html, but it gives me same result:
echo '<html>';
echo '<head></head>';
echo '<body>';
echo $klub[0]['klub'];
echo '</body></html>';
HTTPClient is open source, so you can read the code to find out what a -5 on return means - "Connection Lost".
In this case the connection is lost because you're trying to perform a GET from an HTTPS URL. Unfortunately, your code is using WiFiClient as the client object, which does not support SSL and HTTPS. You need to use WiFiClientSecure for HTTPS.
When you use WiFiClientSecure you need to either provide information about the certificates that the server is using or to set the connection as insecure. An insecure connection will still perform all the encryption associated with HTTPS, it just won't attempt to verify the identity of the web server. While you really should properly secure the connection, insecure may be acceptable for testing or very limited use projects.
So your code could look like this:
if(WiFi.status()== WL_CONNECTED){
WiFiClientSecure client;
HTTPClient http;
client.setInsecure();
You can learn more about how to do this in the examples that come with the HTTPClient library. You can learn more about how to configure WiFiClientSecure in its README and examples.
Related
Goal
I am trying to send temperature data between two Esp8266 modules.
The Server reads a temperature value from the analog pin and is supposed to host this data on a website (I don´t know the correct term for that) over a wifi access point that also runs on the Esp. The Client is supposed to receive the temperature value and output it via serial.
What works
I can connect my phone to the access point and access the data on the IP of the access point. I also can connect the client Esp to my home wifi and it outputs code from different websites.
Problem
But when I try to connect it to the Esp wifi, the wifi login/connection works, but the http.GET function outputs -1 which corresponds to the error message "HTTPC_ERROR_CONNECTION_FAILED".
While the client is connected to the wifi of the Esp my phone displays a similar error message.
I also had the problem that the esp could not continually read A0 while using the Wifi, so I had to build in a delay.
Server Code
// Import required libraries
#include "ESPAsyncWebServer.h"
#include "WiFi.h"
#include <math.h>
#include <ESP8266WiFi.h>
//Constants for temperature calculation
double T;
float V_0 = 5.02;
float R_1 = 99700.0;
float a = 283786.2;
float b = 0.06593;
float c = 49886.0;
float set = 30;
int sensorValue;
float voltage;
// Set your access point network credentials
const char* ssid = "ESP32-Access-Point";
const char* password = "123456789";
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
String readTemp() {
return String((-1.0/b)*(log(((R_1*voltage)/(a*(V_0-voltage)))-(c/a)))); //Function to calculate temperature from Voltage
}
void setup(){
Serial.begin(115200);
Serial.println();
// Setting the ESP as an access point
Serial.print("Setting AP (Access Point)…");
// Remove the password parameter, if you want the AP (Access Point) to be open
WiFi.softAP(ssid, password);
IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(IP);
server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/plain", readTemp().c_str());
});
// Start server
server.begin();
}
void loop()
{
//reading of A0
Serial.println(voltage);
Serial.println(readTemp().c_str());
sensorValue = analogRead(0); //?Wifi not working, when reading A0?
delay(10);
voltage = sensorValue * (3.3 / 1023.0);
}
Client Code
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <ESP8266WiFiMulti.h>
ESP8266WiFiMulti WiFiMulti;
const char* ssid = "ESP32-Access-Point";
const char* password = "123456789";
void setup () {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting..");
}
Serial.print("Connected to ");
Serial.println(ssid);
}
void loop() {
if (WiFi.status() == WL_CONNECTED) { //Check WiFi connection status
HTTPClient http; //Declare an object of class HTTPClient
http.begin("http://192.168.4.1/temperature"); //Specify request destination
int httpCode = http.GET(); //Send the request
if (httpCode > 0) { //Check the returning code
String payload = http.getString(); //Get the request response payload
Serial.println("/////////////////////////////////////////////////////////////");
Serial.println(payload); //Print the response payload
}
else{Serial.println("Error");}
http.end(); //Close connection
}
delay(30000); //Send a request every 30 seconds
}
I would really appreciate it if anybody could help me with this because I have been tearing my hair out for weeks over this. Thanks in advance and sorry for any grammatical or spelling mistakes in advance.
I have a project in which I use an Arduino UNO and an esp8266-01.
The Arduino is used to gather water high and water low sensor information and then transmit that information over to turn on/off a latching relay for a water valve to fill my pool. It also turns off and on a solar panel to charge my batteries and also turns off and on the esp8266.
I want to be able to connect to the wifi every time the esp8266 comes on and then send water level sensor information and battery level sensor information up to thingSpeak.
In the following code I have made it so that the first time the esp8266 is powered up it tries to connect to the local wifi but since no ip and password is provided it go to access point mode and opens a sign in page. I also provide the user to input their thingSpeak write api. This data is saved to the esp8266's eeprom so that in the future it will auto connect and send information to thingSpeak. This works fine.
My problem is getting the information from the water level sensor and the battery level into the esp8266. I was first gathering the data on the Arduino and then having the esp8266 connect and upload the information using AT commands using SerialSoftware. However to get the AUTOCONNECT to work I had to reprogram the esp8266 and now it doesn't respond to AT commands. I have tried to reprogram the RX and TX pins on the ESP but it only has two reading when there is water present it reads 1024 and no water is 0. Nothing in between. The battery level doesn't register anything. Can I do this using the TX and RX pins somehow as an analog input or can I take the information (numbers) gathered on the Arduino and had them off to the ESP8266 using the TX (arduino) and RX (ESP)to send them to ThingSpeak. I am at a loss and need help.
Here is the code on the ESP8266
#include <FS.h>
#include <ESP8266WiFi.h> //https://github.com/esp8266/Arduino
#include <EEPROM.h>
//needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager
#include <ArduinoJson.h>
//NEW STUFF START
char Password[36]="";
char apiKey[16]="";
WiFiClient client;
//eeprom new end
char defaultHost[100] = ""; //Thing Speak IP address (sometime the web address causes issues with ESP's :/
long itt = 500;
long itt2 = 500;
const byte wifiResetPin = 13;
int interruptPinDebounce = 0;
long debouncing_time = 1000;
volatile unsigned long wifiResetLastMillis = 0;
bool shouldSaveConfig = false;
void saveConfigCallback () {
Serial.println("Should save config");
shouldSaveConfig = true;}
void handleWifiReset(){
if(millis()<wifiResetLastMillis){
wifiResetLastMillis = millis();
}
if((millis() - wifiResetLastMillis)>= debouncing_time){
Serial.println("Clearing WiFi data resetting");
WiFiManager wifiManager;
wifiManager.resetSettings();
SPIFFS.format();
ESP.reset();
delay(1000);
}
wifiResetLastMillis = millis();
}
int addr = 0;
void setup() {
//EEPROM.begin(512); //Initialize EEPROM
WiFiManager wifiManager;
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(wifiResetPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(wifiResetPin), handleWifiReset,FALLING);
WiFiManagerParameter customAPIKey("apiKey", "ThingSpeakWriteAPI", apiKey, 16);
//END NEW STUFF
//WiFiManager
//Local intialization. Once its business is done, there is no need to keep it around
//WiFiManager wifiManager;
//NEW STUFF START
//wifiManager.setSaveConfigCallback(saveConfigCallback);
wifiManager.addParameter(&customAPIKey);
//END NEW STUFF
//reset saved settings
//wifiManager.resetSettings();
//set custom ip for portal
//wifiManager.setAPStaticIPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0));
//fetches ssid and pass from eeprom and tries to connect
//if it does not connect it starts an access point with the specified name
//here "AutoConnectAP"
//and goes into a blocking loop awaiting configuration
wifiManager.autoConnect("AutoConnectAP");
Serial.println("Connected");
//NEW STUFF START
strcpy(apiKey, customAPIKey.getValue());
if (shouldSaveConfig) {
Serial.println("saving config");
DynamicJsonBuffer jsonBuffer;
JsonObject& json = jsonBuffer.createObject();
json["defaultHost"] = defaultHost;
json["apiKey"] = apiKey;
Serial.println("API");
Serial.print(apiKey);
String apiKey2 = String(apiKey);
File configFile = SPIFFS.open("/config.json", "w");
if (!configFile) {
Serial.println("failed to open config file for writing");
}
json.printTo(configFile);
json.printTo(Serial);
delay(1000);
configFile.close();
//end save
}
Serial.println("local ip");
Serial.println(WiFi.localIP());
//END NEW STUFF
//or use this for auto generated name ESP + ChipID
//wifiManager.autoConnect();
//Serial.println("WriteApi");
//Serial.println(apiKey);
//if you get here you have connected to the WiFi
//Serial.println("K)");
//save the custom parameters to FS
strcpy(apiKey,customAPIKey.getValue());
EEPROM.begin(512); //Initialize EEPROM
// write appropriate byte of the EEPROM.
// these values will remain there when the board is
// turned off.
EEPROM.write(addr, 'A'); //Write character A
addr++; //Increment address
EEPROM.write(addr, 'B'); //Write character A
addr++; //Increment address
EEPROM.write(addr, 'C'); //Write character A
//Write string to eeprom
String www = apiKey;
for(int i=0;i<www.length();i++) //loop upto string lenght www.length() returns length of string
{
EEPROM.write(0x0F+i,www[i]); //Write one by one with starting address of 0x0F
}
EEPROM.commit(); //Store data to EEPROM
//Read string from eeprom
}
//callback notifying us of the need to save config
void loop() {
Serial.begin(115200);
WiFiManager wifiManager;
if (WiFi.status() == WL_DISCONNECTED) {
wifiManager.autoConnect("AutoConnectAP");}
delay(5000);
if (WiFi.status() == WL_CONNECTED) { Serial.println("Connected");
WiFiClient client;
long itt = 500;
long itt2 = 500;
char defaultHost[100] = "api.thingspeak.com";
//HERE IS WHERE I CHANGE THE TX AND RX PIN FUNCTION
pinMode(1, FUNCTION_3);
pinMode(3, FUNCTION_3);
//THEN I ASSIGN THEM AS INPUT PINS
pinMode(1,INPUT);
pinMode(3,INPUT);
//ASSIGN EACH PIN TO AN INTERGER
const int waterInPin = 3; // Analog input pin that the potentiometer is attached to
const int BatteryInPin = 1; // Analog input pin that the battery is attached to
int waterSensorInValue;//reading our water lever sensor
int waterSensorOutValue;//conversion of water sensor value
int BatterySensorInValue;//reading our water lever sensor
int BatterySensorOutValue;//conversion of water sensor value
// put your main code here, to run repeatedly:
waterSensorInValue = analogRead(waterInPin);
BatterySensorInValue = analogRead(BatteryInPin);
waterSensorOutValue = map(waterSensorInValue,0,1024,0,225);
BatterySensorOutValue = map(BatterySensorInValue,0,1024,0,225);
Serial.println("WaterOutValue = ");
Serial.println(waterSensorOutValue );
Serial.println("WaterInValue = ");
Serial.println(waterSensorInValue );
Serial.println("BatteryOutValue = ");
Serial.println(BatterySensorOutValue );
Serial.println("BatteryInValue = ");
Serial.println(BatterySensorInValue);
//ASSIGN THE INPUT VALUES TO UPLOAD LONGS
itt = waterSensorInValue;
itt2 = BatterySensorInValue;
EEPROM.begin(512);
Serial.println(""); //Goto next line, as ESP sends some garbage when you reset it
Serial.print(char(EEPROM.read(addr))); //Read from address 0x00
addr++; //Increment address
Serial.print(char(EEPROM.read(addr))); //Read from address 0x01
addr++; //Increment address
Serial.println(char(EEPROM.read(addr))); //Read from address 0x02
//Read string from eeprom
String www;
//Here we dont know how many bytes to read it is better practice to use some terminating character
//Lets do it manually www.circuits4you.com total length is 20 characters
for(int i=0;i<16;i++)
{
www = www + char(EEPROM.read(0x0F+i)); //Read one by one with starting address of 0x0F
}
Serial.print(www); //Print the text on serial monitor
if (client.connect(defaultHost,80))
{ // "184.106.153.149" or api.thingspeak.com
itt++; //Replace with a sensor reading or something useful
//UPLOAD TO THINGSPEAK
String postStr = www;
postStr +="&field1=";
postStr += String(itt);
postStr +="&field2=";
postStr += String(itt2);
postStr += "\r\n\r\n\r\n";
client.print("POST /update HTTP/1.1\n");
client.print("Host: api.thingspeak.com\n");
client.print("Connection: close\n");
client.print("X-THINGSPEAKAPIKEY: "+String (www)+"\n");
client.print("Content-Type: application/x-www-form-urlencoded\n");
client.print("Content-Length: ");
client.print(postStr.length());
client.print("\n\n\n");
client.print(postStr);
Serial.println("% send to Thingspeak");
}
client.stop();
Serial.println("Waiting…");
}
delay(55000);
}
As I said almost everything works ok. The ESP8266 comes on when the Arduino turns it on. The sensor comes on and gets the value. A value is uploaded to ThingSpeak (just not a useful one.
Any Ideas, suggestions, examples, tutorials will be greatly appreciated. Thanks.
My suggestion is use only one ESP32 to do all this work.
It´s much simpler and easier than using two micro-controllers.
You can use the ESP32 to read and send the sensor data and save the trouble of communicating two different micros.
I have a project about the automated gate. I'm using Cytron ESP8266 Wifi Shield. I'm using it to transmit and store the ultrasonic data to my xampp localhost port 80.
But there is an error in my code on the client side.
Here is my code:
#include <CytronWiFiShield.h>
#include <CytronWiFiClient.h>
#include <CytronWiFiServer.h>
#include <SoftwareSerial.h>
const int trigPin = 5;
const int echoPin = 4;
long duration;
int distance;
ESP8266Client client;
const char *ssid = "HRHS";
const char *pass = "06031960";
IPAddress ip(192, 168, 100, 9); //The IP address i got from cmd
ESP8266Server server(80);
const char htmlHeader[] = "HTTP/1.1 200 OK\r\n"
"Content-Type: text/html\r\n"
"Connection: close\r\n\r\n"
"<!DOCTYPE HTML>\r\n"
"<html>\r\n";
void setup()
{
// put your setup code here, to run once:
Serial.begin(9600);
while (!Serial)
{
; // wait for serial port to connect. Needed for Leonardo only
}
if (!wifi.begin(2, 3))
{
Serial.println(F("Error talking to shield"));
while (1)
;
}
Serial.println(wifi.firmwareVersion());
Serial.print(F("Mode: "));
Serial.println(wifi.getMode()); // 1- station mode, 2- softap mode, 3- both
Serial.println(F("Start wifi connection"));
if (!wifi.connectAP(ssid, pass))
{
Serial.println(F("Error connecting to WiFi"));
while (1)
;
}
Serial.print(F("Connected to "));
Serial.println(wifi.SSID());
Serial.println(F("IP address: "));
Serial.println(wifi.localIP());
wifi.updateStatus();
Serial.println(wifi.status()); //2- wifi connected with ip, 3- got connection with servers or clients, 4- disconnect with clients or servers, 5- no wifi
//clientTest();
espblink(100);
server.begin();
}
void loop()
{
//Start of Program
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Calculating the distance
distance = duration * 0.034 / 2;
// Prints the distance on the Serial Monitor
delay(1000);
// Connect to the server (your computer or web page)
if (client.connect("192.168.100.9", 80)) //Same local ip address from cmd
{
client.print("GET /write_data.php?"); // This
client.print("value="); // This
client.print(distance); // And this is what we did in the testing section above. We are making a GET request just like we would from our browser but now with live data from the sensor
client.println(" HTTP/1.1"); // Part of the GET request
client.println("Host: "); // IMPORTANT: If you are using XAMPP you will have to find out the IP address of your computer and put it here (it is explained in previous article). If you have a web page, enter its address (ie.Host: "www.yourwebpage.com")
client.println("Connection: close"); // Part of the GET request telling the server that we are over transmitting the message
client.println(); // Empty line
client.println(); // Empty line
client.stop(); // Closing connection to server
}
else
{
// If Arduino can't connect to the server (your computer or web page)
Serial.println("--> connection failed\n");
}
// Give the server some time to receive the data and store it. I used 10 seconds here. Be advised when delaying. If u use a short delay, the server might not capture data because of Arduino transmitting new data too soon.
delay(10000);
}
void espblink(int time)
{
for (int i = 0; i < 12; i++)
{
wifi.digitalWrite(2, wifi.digitalRead(2) ^ 1);
delay(time);
}
}
}
Hello sorry again. I'm going to update the progress here can?
I have updated the code. Please correct me if I'm able or not to do this
Okay, the shield is connected to wifi. However, still cannot connect to database xampp localhost.
I have searched many on Google but most os the solutions are using ethernet shield and to webpage, not localhost.
Im stuck here. Any help is really appreciated.
You didn't declare a (global) variable server, like
const char server[] = "www.adafruit.com";
(Like you did in void clientTest() )
But I did something else. I made my wifiShield a server itself. I am able to control led from there and monitor the data from there. Unfortunately no data storage but as long as I can monitor it from distance I am happy lol
I was trying to upload a Xively feed with an Arduino connected via an Arduino GSM shield.
Xively does not publish any specific example for an Arduino GSM shield. I tried to use the Arduino GSM Pachube Client library changing "pachube.com" in "xively.com", but it did not work. It seems that my GSM shield is able to connect but cannot put the data to the server.
In my example I created a device called "Arduino GSM" with just one channel called "sensor1". In the request log I cannot read any request incoming, although the serial monitor shows that a connection with the server occurs.
This is the code I tried:
// Original GSM Pachube client modified for Xively
// Changes: pachube.com -> xively.com
// inserted APIKEY, FEEDID, USERAGENT
// inserted GPRS_APN, login, password
/*GSM Pachube client
This sketch connects an analog sensor to Pachube (http://www.pachube.com)
using a Telefonica GSM/GPRS shield.
This example has been updated to use version 2.0 of the Pachube.com API.
To make it work, create a feed with a datastream, and give it the ID
sensor1. Or change the code below to match your feed.
Circuit:
* Analog sensor attached to analog in 0
* GSM shield attached to an Arduino
* SIM card with a data plan
created 4 March 2012
by Tom Igoe
and adapted for GSM shield by David Del Peral
This code is in the public domain.
http://arduino.cc/en/Tutorial/GSMExamplesPachubeClient
*/
// libraries
#include <GSM.h>
// Pachube Client data -> changed in Xively Data
#define APIKEY "myapikey" // replace your pachube api key here
#define FEEDID 111111111 // replace your feed ID
#define USERAGENT "Arduino GSM" // user agent is the project name
// PIN Number
#define PINNUMBER ""
// APN data
#define GPRS_APN "WINDBIZ WEB" // replace your GPRS APN
#define GPRS_LOGIN "" // replace with your GPRS login
#define GPRS_PASSWORD "" // replace with your GPRS password
// initialize the library instance:
GSMClient client;
GPRS gprs;
GSM gsmAccess;
// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
// IPAddress server(216,52,233,121); // numeric IP for api.pachube.com
char server[] = "api.xively.com"; // name address for pachube API
unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds
boolean lastConnected = false; // state of the connection last time through the main loop
const unsigned long postingInterval = 10*1000; //delay between updates to Pachube.com
void setup()
{
// initialize serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
// connection state
boolean notConnected = true;
// After starting the modem with GSM.begin()
// attach the shield to the GPRS network with the APN, login and password
while(notConnected)
{
if((gsmAccess.begin(PINNUMBER)==GSM_READY) &
(gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD)==GPRS_READY))
notConnected = false;
else
{
Serial.println("Not connected");
delay(1000);
}
}
}
void loop()
{
// read the analog sensor:
int sensorReading = analogRead(A0);
// if there's incoming data from the net connection.
// send it out the serial port. This is for debugging
// purposes only:
if (client.available())
{
char c = client.read();
Serial.print(c);
}
// if there's no net connection, but there was one last time
// through the loop, then stop the client:
if (!client.connected() && lastConnected)
{
client.stop();
}
// if you're not connected, and ten seconds have passed since
// your last connection, then connect again and send data:
if(!client.connected() && ((millis() - lastConnectionTime) > postingInterval))
{
sendData(sensorReading);
}
// store the state of the connection for next time through
// the loop:
lastConnected = client.connected();
}
/*
This method makes a HTTP connection to the server.
*/
void sendData(int thisData)
{
// if there's a successful connection:
if (client.connect(server, 80))
{
Serial.println("connecting...");
// send the HTTP PUT request:
client.print("PUT /v2/feeds/");
client.print(FEEDID);
client.println(".csv HTTP/1.1");
client.print("Host: api.xively.com\n");
client.print("X-ApiKey: ");
client.println(APIKEY);
client.print("User-Agent: ");
client.println(USERAGENT);
client.print("Content-Length: ");
// calculate the length of the sensor reading in bytes:
// 8 bytes for "sensor1," + number of digits of the data:
int thisLength = 8 + getLength(thisData);
client.println(thisLength);
// last pieces of the HTTP PUT request:
client.print("Content-Type: text/csv\n");
client.println("Connection: close");
client.println();
// here's the actual content of the PUT request:
client.print("sensor1,");
client.println(thisData);
}
else
{
// if you couldn't make a connection:
Serial.println("connection failed");
Serial.println();
Serial.println("disconnecting.");
client.stop();
}
// note the time that the connection was made or attempted
lastConnectionTime = millis();
}
/*
This method calculates the number of digits in the
sensor reading. Since each digit of the ASCII decimal
representation is a byte, the number of digits equals
the number of bytes.
*/
int getLength(int someValue)
{
// there's at least one byte:
int digits = 1;
// continually divide the value by ten,
// adding one to the digit count for each
// time you divide, until you're at 0:
int dividend = someValue /10;
while (dividend > 0)
{
dividend = dividend /10;
digits++;
}
// return the number of digits:
return digits;
}
Added a temperature and humidity sensor (DHT11) to the standard Cosm Arduino sensor client example. Works for a short while then data streams flat line.
Any idea what could be causing the problem?
Many thanks
Staza
/**
* Cosm Arduino sensor client example.
*
`` * This sketch demonstrates connecting an Arduino to Cosm (https://cosm.com),
* using the new Arduino library to send and receive data.
/**
DHT11 temp and humidity sensor added to the COSM example code
**/
#include <SPI.h>
#include <Ethernet.h>
#include <HttpClient.h>
#include <Cosm.h>
#include <dht11.h>
//DHT11*********************************************************************
dht11 DHT11;
#define DHT11PIN 7//pin DHT11 sensor is connected to
//DHT11*********************************************************************
#define API_KEY "xxxxxx" // your Cosm API key
#define FEED_ID xxxxx // your Cosm feed ID
// MAC address for your Ethernet shield
byte mac[] = {xxxx, xxxx, xxxx, xxxx, xxxx, xxxx};
// Analog pin which we're monitoring (0 and 1 are used by the Ethernet shield)
int sensorPin = 2;
unsigned long lastConnectionTime = 0; // last time we connected to Cosm
const unsigned long connectionInterval = 15000; // delay between connecting to Cosm in milliseconds
// Initialize the Cosm library
// Define the string for our datastream ID
char sensorId[] = "sensor_reading";
char sensorId2[] = "DHT11_humidity_sensor_reading";
char sensorId3[] = "DHT11_temperature_sensor_reading";
CosmDatastream datastreams[] = {
CosmDatastream(sensorId, strlen(sensorId), DATASTREAM_FLOAT),
CosmDatastream(sensorId2, strlen(sensorId2), DATASTREAM_FLOAT),
CosmDatastream(sensorId3, strlen(sensorId3), DATASTREAM_FLOAT),
};
// Wrap the datastream into a feed
CosmFeed feed(FEED_ID, datastreams, 3 /* number of datastreams */);
EthernetClient client;
CosmClient cosmclient(client);
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial.println("Cosm Sensor Client Example");
Serial.println("==========================");
Serial.println("Initializing network");
while (Ethernet.begin(mac) != 1) {
Serial.println("Error getting IP address via DHCP, trying again...");
delay(15000);
}
Serial.println("Network initialized");
Serial.println();
}
void loop() {
// main program loop
if (millis() - lastConnectionTime > connectionInterval) {
//check DHT11 sensor is working OK
int chk = DHT11.read(DHT11PIN);
Serial.print("Read DHT11 sensor: ");
switch (chk)
{
case 0: Serial.println("OK"); break;
case -1: Serial.println("Checksum error"); break;
case -2: Serial.println("Time out error"); break;
default: Serial.println("Unknown error"); break;
}
sendData(); // send data to Cosm
getData(); // read the datastream back from Cosm
lastConnectionTime = millis(); // update connection time so we wait before connecting again
}
}
// send the supplied values to Cosm, printing some debug information as we go
void sendData() {
int sensorValue = analogRead(sensorPin);
int humidityDHT11 = ((float)DHT11.humidity);
int tempDHT11 = ((float)DHT11.temperature);
datastreams[0].setFloat(sensorValue);
datastreams[1].setFloat(humidityDHT11); //DHT11 humidity value*******
datastreams[2].setFloat(tempDHT11); //DHT11 temp value********
Serial.print("Read sensor value ");
Serial.println(datastreams[0].getFloat());
Serial.print("Read DHT11 humidity sensor value ");
Serial.println(datastreams[1].getFloat());
Serial.print("Read DHT11 temperature sensor value ");
Serial.println(datastreams[2].getFloat());
Serial.println("Uploading to Cosm");
int ret = cosmclient.put(feed, API_KEY);
Serial.print("PUT return code: ");
Serial.println(ret);
Serial.println();
}
// get the value of the datastream from Cosm, printing out the value we received
void getData() {
Serial.println("Reading data from Cosm");
int ret = cosmclient.get(feed, API_KEY);
Serial.print("GET return code: ");
Serial.println(ret);
if (ret > 0) {
Serial.print("Datastream is: ");
Serial.println(feed[0]);
Serial.print("Sensor value is: ");
Serial.println(feed[0].getFloat());
Serial.print("Datastream is: ");
Serial.println(feed[1]);
Serial.print("Sensor value is: ");
Serial.println(feed[1].getFloat());
Serial.print("Datastream is: ");
Serial.println(feed[2]);
Serial.print("Sensor value is: ");
Serial.println(feed[2].getFloat());
}
Serial.println();
}
Cosm has a debug page which might give you a clue as to what's going wrong.
This is currently located at: https://cosm.com/users/YOURUSERNAME/debug and it lists all incoming requests in real time as they come through. If your device works initially, you should see it start making requests successfully, and depending on how long it takes till it flatlines you might be able to keep this page open and hopefully see when it starts failing.
Do you see anything in the Arduino serial output when it seems to stop working, or does it seem like the Arduino is still happily sending data?
The other thing you could try is using Wireshark to inspect network traffic over the wire. Setting this up is slightly more involved however, so I'd suggest trying the other approaches first.
If none of this seems feasible I'd suggest mailing Cosm support with your feed details and have them look into it.
Seconding smulube's suggestion to monitor the serial output. Additionally, eliminate the variable of the COSM code & Ethernet: start debugging the issue with a sketch that is just taking readings from the DHT11 and monitor what's going on in the Arduino's serial output on your computer (in the Tools dropdown menu).
I just received my DHT22 (RHT03) from Sparkfun last night and tried several samples that wouldn't compile (my fault, I'm sure). The sample that worked "out of the box" for me with my Arduino Uno came from Tom Boyd's page (be sure to scroll to the bottom for the most recent code): DHT11 / Aosong AM2302 humidity and temperature sensor
I'm curious: how long did it take for your sensor to flatline? I integrated the code from Tom with the Cosm code and it's been running without interruption for me for an hour now.
Cheers,
Reeves