ESP32 trying to write data to thinkspeak

I know I could use the thingspeek library but it is quite large in size and as this is part of a much larger programme and concerned about the room.

#include <Arduino.h>
#include <WiFi.h>                      // Built-in
#include <ESPmDNS.h>                   // Built-in
#include <SPIFFS.h>                    // Built-in
#include <ESPAsyncWebServer.h> 
#include <TaskScheduler.h>


AsyncWebServer server(80);
WiFiClient (client);
Scheduler ts; 
auto myChannelNumber8 = 684***;
const char* myWriteAPIKey8 = "CFEMMCHI9QQ****";

const char* ssid       = "BTHub6-3CXG"; 
const char* password   = "JL4qtNuD******";
const char* ServerName = "thingspeak.com/update";
#define Thingspeak1 "184.106.153.149"
String UploadData;
String myStatus = "";
float Temperature=22.2;
float Humidity=57.7;

void SendData();

Task SendData1(5* TASK_MINUTE, TASK_FOREVER,&SendData,&ts,true); 

//############################################################################################
void setup() {
  Serial.begin(115200);                                           // Initialise serial communications
  delay(200);
  Serial.println(__FILE__);
  Serial.println("Starting...");
  Serial.print("\r\nConnecting to: "); Serial.println(String(ssid));
  IPAddress dns(8, 8, 8, 8); // Use Google as DNS
  WiFi.disconnect();
  WiFi.mode(WIFI_STA );       // switch off AP
  WiFi.setAutoConnect(true);
  WiFi.setAutoReconnect(true);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(150);
  }
  Serial.println("\nWiFi connected at: " + WiFi.localIP().toString());
}
//###############################################################################################
void loop() {
  ts.execute();
}
//###############################################################################################
void SendData(){
  if (!client.connect(Thingspeak1,80, 2000)) {  // 2000= 2 Second Time out
    Serial.println("");
    Serial.println("Server Host not open");
    Serial.println("");
    return;
  }
  Serial.println("...Submitting Upload request");
  UploadData  = "?key="+String(myWriteAPIKey8);
  UploadData += "&field1="+String(Temperature);
  UploadData += "&field2="+String("22.22");
  UploadData += "&field3="+String(Humidity);

  
  client.println("GET /"+UploadData+" HTTP/1.1\r\nConnection: close\r\n\r\n");
  client.println("Host: "+String(Thingspeak1));
  delay(250); // Essential delay for ESP32 500
  Serial.print("...Information to be uploaded: "+String(Thingspeak1));
  Serial.println(UploadData);
  Serial.println("");
  client.println("Connection: close"); 
  Serial.println("");
  client.stop();

}

And Platformio .ini

; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
upload_speed=921600
monitor_speed = 115200
;upload_protocol = espota
;upload_port=192.168.1.206
lib_deps = 
  ottowinter/AsyncTCP-esphome @ ^1.1.1
  TaskScheduler
  me-no-dev/AsyncTCP @ ^1.1.1

I dont get any errors when compiling but no data arrives at Thingspeek
so I must be doing something obviously wrong, but as try as I might I cannot see it.

If you have any thoughts please shout back as it will be much appreciated.

Your header is malformed. You’re already doing the double-\r\n before writing the host data. And then you write Connection: close again.

Also you have to write to the /update URL per this don’t you? Your URL is starting directly with ?key=... The “Write Data with GET” example should be what you need. See also here with general HTTP request formatting.

Also, you should try reading the response from the HTTP server, as it can give you clues on what was wrong in the request.

So you should try something like

void SendData(){
	if (!client.connect(Thingspeak1,80, 2000)) {  // 2000= 2 Second Time out
		Serial.println("");
		Serial.println("Server Host not open");
		Serial.println("");
		return;
	}
	Serial.println("...Submitting Upload request");
	UploadData  = "?key="+String(myWriteAPIKey8);
	UploadData += "&field1="+String(Temperature);
	UploadData += "&field2="+String("22.22");
	UploadData += "&field3="+String(Humidity);

	String httpRequest = "GET /update" + UploadData + " HTTP/1.1\r\n";
	httpRequest += "Host: " + String(Thingspeak1) + "\r\n";
	httpRequest += "Connection: close\r\n"; 
	httpRequest += "\r\n"; 

	Serial.println("HTTP GET request is");
	Serial.println(httpRequest);

	client.print(httpRequest); /* just print() because we already have final newline */
	client.flush(); /* flush data to the other end. we don't need to wait. */

	//wait for data to arrive back (max 5 seconds), then print arrived data if any
	unsigned long timeout = millis();
	while (client.available() == 0) {
		if (millis() - timeout > 5000) {
			Serial.println(">>> Client Timeout !");
			client.stop();
			return;
		}
	}

	// 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");
	client.stop();
}

Uhm if Thingspeak1 is not define where is the variable or define so that the line compiles? The connection host should be api.thingspeak.com and the /update should just be in the GET request.

Maxgerhardt
so near but so far, thank you for your suggestions and I’m very pleased to report that it works perfectly. Sometimes I get totally confused like why you use a get command when you’re trying to put something?
But may I say thank you once more for your time and effort and very prompt reply.
Thanks

That is just a style choice by developers. A webserver can abitrarily choose how it wants to react to a GET request like http://mysite.com/data=xyz.

But if this confuses you, that’s actually very good, because it shows that it goes against your gut instincts to upload / create a new data point with a GET request and not using one of the other HTTP methods / verbs, like POST and PUT. The RESTful design philosophy for creating Web APIs states how the verbs should be used – GET to retrieve a resources/ information, POST to create a new one, PUT to update, etc.

And in fact the above first link says that the URL supports both GET and POST methods.

HTTP Method

POST or GET

Content-Type

Content-Type is required only for the POST method, not for the GET method.

application/x-www-form-urlencoded for most updates.

application/json for updates in JSON format.

…So, they kinda follow the RESTful design philosophy, by accepting both POST and GET requests.

Wow all I can say is I have got a long way to go, thank you so much for the additional research, certainly something to sit down and have a thorough read. Should certainly keep me quiet for a couple of days.
Super job and thank you very much again.

Hello Maxgerhardt
I do not know if you will receive this message?
I was just using your program and trying to decode whether it is a pass or fail
I was trying to use this simple program:

	unsigned long timeout = millis();
	while (client.available() == 0) {
		if (millis() - timeout > 5000) {
			Serial.println(">>> Client Timeout !");
			client.stop();
			return;
		}
	}
  std::string str;
	// Read all the lines of the reply from server and print them to Serial
	while(client.available()) {
		line = line + client.readStringUntil('\r');
		
	}
  Serial.print(line);
  int i=line.length();
  Serial.println(i);
  Serial.println("");
  if(line.substring(i)== "Status: 200 OK"){
    Serial.println("IT IS OK");
  }
  else
  {
    Serial.println("BAD TRY AGAIN");
  }
  
	Serial.println();
	Serial.println("closing connection");
	client.stop();
}

but unfortunately I can’t seem to make it work, looking about this seems to be the easiest way to do it but obviously not, or I’m doing something wrong again.

If you have time could you please offer a suggestion?.
Sorry to disturb your Sunday afternoon
Thank you once more