ESP - HCSR-04 ultrasonic sensor data upload to thingspeak

I'm trying to upload distance data to thingspeak web platform. Have a look this video.(highly recommend to watch it)

As you can see through video, I can only update FW (forward) Field 1 chart, other 4 fields remain same.

Could you analyze my code and tell me where is the part I coded wrong or which idea I'm trying to imply to arduino is totally logical fault !

BW sensor is damaged and it's sensing nothing (0,null) instead of right value. Do not mind it.

I tried to build up for loop to receive data from 4 sensor then send it to 4 field but didn't succeed in it.So I made each sensor get it's own value and send it to thingspeak separately .

It may seem too long, however I'm repeating same things again and again for 4 sensors after each comment statement // TCP connection FW

Here is the my code:

#include <SoftwareSerial.h>
#include <stdlib.h>

int ledPin = 13;



String apiKey = "2TNSKZAUY0FUD7QY";

SoftwareSerial ser(2,3); // RX, TX

void setup() {                
  
  pinMode(ledPin, OUTPUT);    
  
  Serial.begin(9600); 
  ser.begin(9600);

  pinMode(11,OUTPUT);  //Trigger    FW
  pinMode(10,INPUT);   //Echo

  pinMode(5,OUTPUT);  //Trigger     R
  pinMode(4,INPUT);   //Echo

  pinMode(A1,OUTPUT);  //Trigger    L
  pinMode(A0,INPUT);   //Echo

  pinMode(A2,OUTPUT);  //Trigger    BW
  pinMode(A3,INPUT);   //Echo
  
  // reset ESP8266
  ser.println("AT+RST");
}

void loop() {

   long duration1, distance1;
   long duration2, distance2;
   long duration3, distance3;
   long duration4, distance4;
  
  digitalWrite(ledPin, HIGH);   
   delay(200);               
  digitalWrite(ledPin, LOW);

  // FW 1 pin distance calculation
    digitalWrite(11,LOW);
    delayMicroseconds(2);
    digitalWrite(11,HIGH);
    delayMicroseconds(10);
    digitalWrite(11,LOW);
    
    duration1 = pulseIn(10,HIGH);
    distance1 = (duration1/2)/29.1;
    Serial.print(distance1);
    Serial.println("cm//");
    delay(500); 
  
  // R 2 pin distance calculation
    digitalWrite(5,LOW);
    delayMicroseconds(2);
    digitalWrite(5,HIGH);
    delayMicroseconds(10);
    digitalWrite(5,LOW);
    
    duration2 = pulseIn(4,HIGH);
    distance2 = (duration2/2)/29.1;
    Serial.print(distance2);
    Serial.println("cm//");
    delay(500); 

   // L 3 pin distance calculation
    digitalWrite(A5,LOW);
    delayMicroseconds(2);
    digitalWrite(A5,HIGH);
    delayMicroseconds(10);
    digitalWrite(A5,LOW);
    
    duration3 = pulseIn(A0,HIGH);
    distance3 = (duration3/2)/29.1;
    Serial.print(distance3);
    Serial.println("cm//");
    delay(500); 
   
  // BW 4 pin distance calculation
    digitalWrite(A2,LOW);
    delayMicroseconds(2);
    digitalWrite(A2,HIGH);
    delayMicroseconds(10);
    digitalWrite(A2,LOW);
    
    duration4 = pulseIn(A3,HIGH);
    distance4 = (duration4/2)/29.1;
    Serial.print(distance4);
    Serial.println("cm//");
    delay(500); 
  
  Serial.println("distanceFW");
  Serial.println(distance1);
  Serial.println("distanceR");
  Serial.println(distance2);
  Serial.println("distanceL");
  Serial.println(distance3);
  Serial.println("distanceBW");
  Serial.println(distance4);
 
  // TCP connection FW
  String cmd1 = "AT+CIPSTART=\"TCP\",\"";
  cmd1 += "184.106.153.149"; // api.thingspeak.com
  cmd1 += "\",80";
  ser.println(cmd1);
   
  if(ser.find("Error")){
    Serial.println("AT+CIPSTART error");
    return;
  }

  // FW prepare GET string 
  String getStr1 = "GET /update?api_key=";
  getStr1 += apiKey;
  getStr1 +="&field1=";
  getStr1 += String(distance1);
  getStr1 += "\r\n\r\n";

  // send data length FW
  cmd1 = "AT+CIPSEND=";
  cmd1 += String(getStr1.length());
  ser.println(cmd1);

  if(ser.find(">")){
    ser.print(getStr1);
  }
  else{
    ser.println("AT+CIPCLOSE1");
    // alert user
    Serial.println("AT+CIPCLOSE1");
  }

  // TCP connection R
  String cmd2 = "AT+CIPSTART=\"TCP\",\"";
  cmd2 += "184.106.153.149"; // api.thingspeak.com
  cmd2 += "\",80";
  ser.println(cmd2);
   
  if(ser.find("Error")){
    Serial.println("AT+CIPSTART error");
    return;
  }

// R prepare GET string 
  String getStr2 = "GET /update?api_key=";
  getStr2 += apiKey;
  getStr2 +="&field2=";
  getStr2 += String(distance2);
  getStr2 += "\r\n\r\n";

  // R send data length
  cmd2 = "AT+CIPSEND=";
  cmd2 += String(getStr2.length());
  ser.println(cmd2);

  if(ser.find(">")){
    ser.print(getStr2);
  }
  else{
    ser.println("AT+CIPCLOSE2");
    // alert user
    Serial.println("AT+CIPCLOSE2");
  }

 // TCP connection L
  String cmd3 = "AT+CIPSTART=\"TCP\",\"";
  cmd3 += "184.106.153.149"; // api.thingspeak.com
  cmd3 += "\",80";
  ser.println(cmd3);
   
  if(ser.find("Error")){
    Serial.println("AT+CIPSTART error");
    return;
  }

  
  // L prepare GET string 
  String getStr3 = "GET /update?api_key=";
  getStr3 += apiKey;
  getStr3 +="&field3=";
  getStr3 += String(distance3);
  getStr3 += "\r\n\r\n";

  // L send data length
  cmd3 = "AT+CIPSEND=";
  cmd3 += String(getStr3.length());
  ser.println(cmd3);

  if(ser.find(">")){
    ser.print(getStr3);
  }
  else{
    ser.println("AT+CIPCLOSE3");
    // alert user
    Serial.println("AT+CIPCLOSE3");
  }

  // TCP connection BW
  String cmd4 = "AT+CIPSTART=\"TCP\",\"";
  cmd4 += "184.106.153.149"; // api.thingspeak.com
  cmd4 += "\",80";
  ser.println(cmd4);
   
  if(ser.find("Error")){
    Serial.println("AT+CIPSTART error");
    return;
  }

  
  // BW prepare GET string 
  String getStr4 = "GET /update?api_key=";
  getStr4 += apiKey;
  getStr4 +="&field4=";
  getStr4 += String(distance4);
  getStr4 += "\r\n\r\n";

  // BW send data length
  cmd4 = "AT+CIPSEND=";
  cmd4 += String(getStr4.length());
  ser.println(cmd4);


    if(ser.find(">")){
    ser.print(getStr4);
  }
  else{
    ser.println("AT+CIPCLOSE4");
    // alert user
    Serial.println("AT+CIPCLOSE4");
  }
    
  // thingspeak needs 15 sec delay between updates
  delay(8000);  
}

thanks for your interest

I can't follow your video. I can't make sense of your code. It may help if you simplified the code so it just works with one sensor - get that working, and then extend it.

I think it would be a lot easier if you structure your program as a series of single-purpose functions - each of which can be tested and proved on its own. Have a look at Planning and Implementing a Program

Your code in loop() could, perhaps, be simplified to

void loop() {
    readSensors();
    sendData();
{

...R

I can't make sense of your code

OK. I started the coding as you suggest it. I want to be sure if I'm doing it right.

this is the first setup part :

#include <SoftwareSerial.h>
#include <stdlib.h>

String apiKey = "2TNSKZAUY0FUD7QY";
SoftwareSerial ser(2,3); // RX, TX

void setup() {                
  
  Serial.begin(9600); 
  ser.begin(9600);

  pinMode(11,OUTPUT);  //Trigger    FW
  pinMode(10,INPUT);   //Echo
  
  ser.println("AT+RST"); // reset ESP8266
}

here is the main loop which is like your desire:

void loop() {

   readSensors();
   
   sendData();
}

Then, one of the functions (reading only FW sensor) :

void readSensors() {
  
  long duration, distance;

    digitalWrite(11,LOW);
    delayMicroseconds(2);
    digitalWrite(11,HIGH);
    delayMicroseconds(10);
    digitalWrite(11,LOW);

    duration = pulseIn(10,HIGH);
    distance = (duration/2)/29.1;
    Serial.print(distance);
    Serial.println("cm//");
    delay(500); 
  
Serial.println("distanceFW");
Serial.println(distance);

}

Other function (preparing and sending only FW distance) :

// TCP connection and send Data to FW field 1

void sendData() {

  distance = readSensors();
  String cmd = "AT+CIPSTART=\"TCP\",\"";
  cmd += "184.106.153.149"; // api.thingspeak.com
  cmd += "\",80";
  ser.println(cmd);
   
  // FW prepare GET string 
  
  String getStr = "GET /update?api_key=";
  getStr += apiKey;
  getStr +="&field1=";
  getStr += String(distance);
  getStr += "\r\n\r\n";

  // send data length FW
 
  cmd = "AT+CIPSEND=";
  cmd += String(getStr.length());
  ser.println(cmd);

  if(ser.find(">")){
    ser.print(getStr);
  }
  else{
    ser.println("AT+CIPCLOSE1");
    // alert user
    Serial.println("AT+CIPCLOSE1");
  }

In this part I m getting compile error, I'm noob in coding and I'll look for it :

'distance' was not declared in this scope

is this what you want to me about simplifying the code? If yes, I'll keep looking for find a way the implement this two functions for other 4 sensors again.

void readSensors() {

That is a poor name for the function. Suppose that you used a name that reflected what you are really doing, like getDistance(). Doesn't it seem reasonable that such a function, like digitalRead(), would return a value?

Make your function return a value. Store that value somewhere when you call the function, like, maybe:

   long distance = getDistance();

It looked like it might have been going well until this bit

void sendData() {

  distance = readSensors();

Why are you reading the sensors in the sendData() function. You already got the sensor values in loop() before you called sendData().

I just used the name "readSensors()" because I was lazy. @PaulS's suggestion to call it "getDistances()" might be better.

...R