Can't update fields to thing speak

Desmond Hanan on 15 Dec 2021 (Edited on 16 Dec 2021)
Latest activity Reply by Armen Abroyan on 26 Jul 2023

I was testing some sensors using code that I've run before successfully on an Arduino device to update to thingspeak, but I keep getting the http error code -302.

if true
  % code
#include <SPI.h>
#include <WiFi101.h>
#include <Wire.h>
#include <secrets_new.h>
#include <ThingSpeak.h>
#include <SD.h>
char ssid[] = SECRET_SSID;   // your network SSID (name) 
WiFiClient  client;
unsigned long myChannelNumber = SECRET_CH_ID;
const char * myWriteAPIKey = SECRET_WRITE_APIKEY;
int soil_moisture_2cm = 0;
int soil_moisture_5cm = 0;
int soil_temperature_2cm = 0;
int soil_temperature_5cm = 0;
void setup() {
// put your setup code here, to run once:
WiFi.setPins(8,7,4,2);
Wire.begin();
delay(1000);
Serial.begin(9600);
 if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }
String fv = WiFi.firmwareVersion();
if (fv != "1.0.0") {
  Serial.println("Please upgrade the firmware");
}
ThingSpeak.begin(client);
}
void loop() {
if(WiFi.status() != WL_CONNECTED){
  Serial.print("Attempting to connect to SSID: ");
  Serial.println(SECRET_SSID);
  while(WiFi.status() != WL_CONNECTED){
    WiFi.begin(ssid); // Connect to WPA/WPA2 network. Change this line if using open or WEP network
    Serial.print(".");
    delay(5000);     
  } 
  Serial.println("\nConnected.");
      }
soil_moisture_2cm = analogRead(A0);
soil_moisture_5cm = analogRead(A1);
soil_temperature_2cm = analogRead(A2);
soil_temperature_5cm = analogRead(A3);
 ThingSpeak.setField(1, soil_moisture_2cm);
 ThingSpeak.setField(2, soil_moisture_5cm);
   ThingSpeak.setField(3, soil_temperature_2cm);
   ThingSpeak.setField(4, soil_temperature_5cm);
    int y = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
  if(y == 200){
    Serial.println("Channel 2 update successful.");
  }
else{
  Serial.println("Problem updating channel 2. HTTP error code " + String(y));
}
delay(30000);
}
end
Christopher Stapels
Christopher Stapels on 16 Dec 2021 (Edited on 16 Dec 2021)

Did you start experiencing this problem recently? Can you tell us more about the wifi shield you are using? We have recently upgraded our system requirements to require TLS 1.2. See the system requirements for additional details.

Can you also try updating your channel in a browser address bar, just to make sure that works? Its a good basic step to limit out other problems.

Armen Abroyan
Armen Abroyan on 19 Dec 2021

Hi Christopher, I am having similar problem my channel stopped recieving data from my devices starting from Dec 14th, before that it was working for years. I can update my channel through the browser though.

Ghaith Alshishani
Ghaith Alshishani on 22 Dec 2021

WOW thank god, I'm not the only one here!!! I've been struggling for more than a week now, banging my head for answers in hope for finding someone with the same problem as me! Yesss indeed the last msg I got from my sensors on the field was on the 13th of December. I tried everything I even opened a complaint ticket with my M2M GSM provider hoping the problem is from their end.

On a separate test device, I managed to get the problem fixed by removing the SSL from the HTTP request I send from the GSM module (sim800L) then it worked fine ... I'm not that concerned about security since this is a research project for the University, however, I would really not prefer to drive all across Jordan (it's a big desert in case you don't know) to update the code on every device I have on the field.

Please help us fix this!!!

I was hesitant to open a new discussion regarding this topic but since I'm not the only one facing the problem ill open a new discussion and post a sample code

thanks armen for sharing your experience, i hope changing the SSL works for you as well

Armen Abroyan
Armen Abroyan on 4 Jan 2022

Ditto Galiath, thanks for sharing. I am also glad to hear I am not the only one with the problem :). Was you able to solve the issue rather than removeing the SSL? Secure channel is not crucial in my case either. I am just curious to know whether there is a final solution for this. My code stnippet sending and recieveing data from Thingspeak is following:

bool sendDataToThingspeak(int fieldID, int workingTimeRemaining)
{
    if(WiFi.status() == WL_CONNECTED)
    {
        // Use WiFiClient class to create TCP connections
        WiFiClientSecure client;
          if (!client.connect(host, httpsPort))
          {
              SERIAL_PRINTLN("connection failed");
              return false;
          }
          // We now create a URI for the request
          String url = "/update?api_key=";
          url += writeAPIKey;
          url += String("&field") + fieldID + "=";
          url += workingTimeRemaining;
          SERIAL_PRINT("Requesting URL: ");
          SERIAL_PRINTLN(url);
          // This will send the 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);
          // Read all the lines of the reply from server and print them to Serial
          while(client.available()){
          String line = client.readStringUntil('\r');
          SERIAL_PRINT(line);
          }
          SERIAL_PRINTLN();
          SERIAL_PRINTLN("closing connection");
          return true;
      }
      return false;
  }
bool getIntFromThingspeak(int fieldID, int & value)
{
    if(WiFi.status() == WL_CONNECTED)
    {
        // Use WiFiClient class to create TCP connections
        WiFiClientSecure client;
        if (!client.connect(host, httpsPort))
        {
            SERIAL_PRINTLN("connection failed");
            return false;
        }
          // We now create a URI for the request
          String url = "/channels/79666/fields/";
          url += fieldID;
          url += "/last.json?api_key=";
          url += readAPIKey;
          SERIAL_PRINT("Requesting URL: ");
          SERIAL_PRINTLN(url);
          // This will send the 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(100);
          value = 0;
          // Read all the lines of the reply from server and print them to Serial
          String findString = String("\"field") + fieldID + "\":\"";
          if(client.find(findString.c_str()))
          {
              String line = client.readStringUntil('\"');
              value = line.toInt();
              SERIAL_PRINT(line);
          }
          SERIAL_PRINTLN();
          SERIAL_PRINTLN("closing connection");
          return true;
      }
      return false;
  }
Vinod
Vinod on 22 Dec 2021

To be clear, Armen's code does not appear to be using WiFiClientSecure and HTTPS with SSL/TLS. This is unlikely to be related to any changes we made on ThingSpeak.

Ghaith, can you share the code on your device? Is the SIM800L module doing the SSL/TLS handshakes? What versions of SSL/TLS do those modules support?

Ghaith Alshishani
Ghaith Alshishani on 23 Dec 2021

Ahaa I didn't check armens code actually, but i was so happy to see someone with the same problem date as me.

To give you a clear picture: Im using arduino pro mini with SIM800L and Im collecting weather data remotely using GPRS HTTPS posts to Thingspeak's API (writing bulk csv data). tens of these devices were functioning seamlessly for the past 3 years until the 14th of December, when they all went silent.

This is a simple code that had been working before the 14th (or the release i read about here )

#include <SoftwareSerial.h>
SoftwareSerial mySerial(8, 7);            // RX, TX Pins
#define GSMswitch  9    // select the pin for the switch to turn the GSM on/off
void setup() {
    pinMode(GSMswitch, OUTPUT);
    digitalWrite(GSMswitch, HIGH);
    Serial.begin(9600);
    Serial.println("Salamzzz");
    mySerial.begin(9600);
    delay(8000);  
  }
void loop() {
    gsm_sendhttp();
}
void gsm_sendhttp() {
    mySerial.println("AT");
    delay(500);
    ShowResponse();
    Serial.println("");
    mySerial.println(F("AT+SAPBR=3,1,Contype,GPRS"));
    delay(100);
    ShowResponse();
    Serial.println("");
    mySerial.println(F("AT+SAPBR=3,1,APN,m2ms.orange.jo"));         //change according to network - Umniah "mySerial.println(F("AT+SAPBR=3,1,APN,net"));" - Zain "mySerial.println(F("AT+SAPBR=3,1,APN,zain"));"
    delay(100);
    ShowResponse();
    Serial.println("");
    mySerial.println(F("AT+SAPBR =1,1"));
    delay(100);
    ShowResponse();
    Serial.println("");
    mySerial.println(F("AT+SAPBR=2,1"));
    delay(5000);//absolute minumum 1000ms
    ShowResponse();
    Serial.println("");
  //  wdt_reset();
    mySerial.println(F("AT+HTTPINIT"));
    delay(100);
    ShowResponse();
    Serial.println("");
    mySerial.println("AT+HTTPSSL=1");
    delay(100);
    ShowResponse();
    Serial.println("");
    mySerial.println(F("AT+HTTPPARA=CID,1"));
    delay(100);
    ShowResponse();
    Serial.println("");
    mySerial.println(F("AT+HTTPPARA=URL,https://api.thingspeak.com/channels/******/bulk_update.csv")); //to change channel simply replace the 6-digit number between "channels/" and "/bulk_update.csv"
    delay(200);
    while(mySerial.available()>0){ Serial.write(mySerial.read());delay(1);}
    Serial.println("");
    mySerial.println(F("AT+HTTPPARA=CONTENT,application/x-www-form-urlencoded"));
    delay(200);
    ShowResponse();
    Serial.println("");
    ShowResponse();
    Serial.println("");
    mySerial.println(F("AT+HTTPDATA=400,2000")); //absolute minumum 1000ms
    delay(200);
    ShowResponse();
    Serial.println("");
    mySerial.print(F("write_api_key=******************&time_format=relative&updates=1,1,2,3"));
    delay(2000); //absolute minumum 1000ms
    ShowResponse();
    Serial.println("");
    mySerial.println(F("AT+HTTPACTION=1"));
    delay(500); //absolute minumu 5000ms
    mySerial.println(F("AT+HTTPREAD"));
    delay(100); //absolute minumu 5000ms
    ShowResponse();
    Serial.println("");
  }
void ShowResponse(){
  while(mySerial.available()>0){ 
    Serial.write(mySerial.read());
    delay(20);
  }  
}

for this same code to work again now i have to omit the AT+HTTPSSL=1 part and use HTTP instead of HTTPS

I will check the Product Identification (ATI command) for the SIM800L modules I have, and check what firmware is installed then get back to you on that. I guess I should update the firmware. is that right?

thanks Vinod

Vinod
Vinod on 23 Dec 2021 (Edited on 23 Dec 2021)

Based on Google searches and the app note here, I think you need to add this AT command to enable TLS 1.2 on the SIM800 module: +SSLOPT=1,1.

I believe you may also need to update the firmware on the SIM800L module so it can do HTTPS over TLS1.2. Earlier versions of TLS are vulnerable to attacks and are no longer supported when making secure connections to ThingSpeak.

Christopher Stapels
Christopher Stapels on 21 Dec 2021

Do you have information about the WiFi shield? Is it possible to upgrade its firmware?

Armen Abroyan
Armen Abroyan on 21 Dec 2021

No idea, I use ESP8266 ESP12 module with WIFI embedded. It is from 6 years ago it worked as it is during this period.

Christopher Stapels
Christopher Stapels on 17 Dec 2021

Many of the errors in the library have to do with connectivity. Can you restart your router and your Adruino device and try again?

Armen Abroyan
Armen Abroyan on 4 Jan 2022 (Edited on 4 Jan 2022)

Hi @Christopher I tried restarting all of the devices including wifi router, no luck. Should I update firmware of my ESP8266?

Here is my code sending and recieving data to Thingspeak:

if true
  % code
endbool sendDataToThingspeak(int fieldID, int workingTimeRemaining)
{
  if(WiFi.status() == WL_CONNECTED)
  {
      // Use WiFiClient class to create TCP connections
      WiFiClientSecure client;
        if (!client.connect(host, httpsPort))
        {
            SERIAL_PRINTLN("connection failed");
            return false;
        }
        // We now create a URI for the request
        String url = "/update?api_key=";
        url += writeAPIKey;
        url += String("&field") + fieldID + "=";
        url += workingTimeRemaining;
        SERIAL_PRINT("Requesting URL: ");
        SERIAL_PRINTLN(url);
        // This will send the 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);
        // Read all the lines of the reply from server and print them to Serial
        while(client.available()){
        String line = client.readStringUntil('\r');
        SERIAL_PRINT(line);
        }
        SERIAL_PRINTLN();
        SERIAL_PRINTLN("closing connection");
        return true;
    }
    return false;
}
bool getIntFromThingspeak(int fieldID, int & value)
{
  if(WiFi.status() == WL_CONNECTED)
  {
      // Use WiFiClient class to create TCP connections
      WiFiClientSecure client;
      if (!client.connect(host, httpsPort))
      {
          SERIAL_PRINTLN("connection failed");
          return false;
      }
        // We now create a URI for the request
        String url = "/channels/79666/fields/";
        url += fieldID;
        url += "/last.json?api_key=";
        url += readAPIKey;
        SERIAL_PRINT("Requesting URL: ");
        SERIAL_PRINTLN(url);
        // This will send the 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(100);
        value = 0;
        // Read all the lines of the reply from server and print them to Serial
        String findString = String("\"field") + fieldID + "\":\"";
        if(client.find(findString.c_str()))
        {
            String line = client.readStringUntil('\"');
            value = line.toInt();
            SERIAL_PRINT(line);
        }
        SERIAL_PRINTLN();
        SERIAL_PRINTLN("closing connection");
        return true;
    }
    return false;
}
Christopher Stapels
Christopher Stapels on 4 Jan 2022 (Edited on 4 Jan 2022)

Yes, definitely upgrade the firmware when you can. Be sure you update the libraries and board files before programming as well. Since you appear to be writing directly from the ESP8266, you could probably benefit greatly from using the ThingSpeak library in your code as well.

Armen Abroyan
Armen Abroyan on 5 Jan 2022

@Christopher I have updated the code to match to the latest Tingspeak examples. Please see the code below. Also Updated NodeMCU ESP8266 module with the latest firmware.

I still get folloiwing error when it tries to read an integer filed:

>>Problem reading channel. HTTP error code -301

I have also tried with a different WIFI device (My phone's hotspot), the same result. It can connect to the router but can't send/recieve data from Thingspeak.

bool sendIntToThingspeak_T(int fieldID, int value)
{
    if(WiFi.status() == WL_CONNECTED)
    {
        // Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different
        // pieces of information in a channel.  Here, we write to field 1.
          int x = ThingSpeak.writeField(homeSweetHomeChannelNumber, fieldID, value, readAPIKey);
          if(x == 200)
          {
              Serial.println("Channel update successful.");
          }
          else
              Serial.println("Problem updating channel. HTTP error code " + String(x));
      }
      return false;
  }
bool getIntFromThingspeak_T(int fieldID, int & value)
{
    if(WiFi.status() == WL_CONNECTED)
    {
        // Use WiFiClient class to create TCP connections
          float valueOut = ThingSpeak.readLongField(homeSweetHomeChannelNumber, fieldID, readAPIKey);
          // Check the status of the read operation to see if it was successful
          int statusCode = ThingSpeak.getLastReadStatus();
          if(statusCode == 200)
          {
              value = valueOut;
              SERIAL_PRINTLN("VentBot remainting: " + String(valueOut));
              return true;
          }
          else
              SERIAL_PRINTLN("Problem reading channel. HTTP error code " + String(statusCode)); 
      }
      return false;
  }
Armen Abroyan
Armen Abroyan on 5 Jan 2022

An update: it started to work normally when I changed WiFiClientSecure to WiFiClient. I think it is the same case as Ghaith also shared, there must be something changed/broken in the secure connection.

芷仪 牟
芷仪 牟 on 26 Jul 2023
I also meet the same question. Could you tell me how to change WiFiClientSecure to WiFiClient?
Armen Abroyan
Armen Abroyan on 26 Jul 2023

Simply renaming declaration of WiFiClientSecure to WiFiClient will do the work, but I suggest to make the secure connection work if it is important for your application. @Vinod provided the instructions.

Vinod
Vinod on 7 Jan 2022 (Edited on 7 Jan 2022)

I'd recommend using secure connections. See the instructable linked here for what you need to do to update the firmware on your esp8266.