Hardware or software?

I followed a project on Instructables to build a Salt Level Monitor for my Water Softening System.

I attempted building two versions of this. I could neither to connect to my WiFi network. The first is based on the ESP8266, the second is based on the ESP8266 12-E NodeMCU.

Code seemed to compile clean and upload fine.

Can anyone spot something in the code That would prevent or not even initiate a WiFi connection?

I've doublechecked the wiring, is there a way to trouble shoot the hardware using the Arduino tools?

I realize it's a lot getting others to look at this code but I'm a novice here. Thanks!

// #include <AVision_ESP8266.h>

// Water Softener Salt Level Monitor

#include "Adafruit_VL53L0X.h"
Adafruit_VL53L0X lox = Adafruit_VL53L0X();
#include <ESP8266WiFi.h>

// Network information.
#define WIFI_NAME "Getsome"
#define PASSWORD "123XXXX"

IPAddress ip(192,168,1,110);          // Choose your ip address
IPAddress gateway(192,168,1,1);       // Your gateway
IPAddress subnet(255,255,255,0);
IPAddress dns(192,168,1,1);           // Same as your gateway

// Hardware information.
#define TIMEOUT  5000                 // Timeout for server response.

// ThingSpeak information.

#define THING_SPEAK_ADDRESS "api.thingspeak.com"
String writeAPIKey="15GROHOPXYJKR0L5";             // Change this to the write API key for your channel.
                         
WiFiClient client;

// Put your setup code here, to run once:
void setup()
{  
    Serial.begin( 74880 ); // You may need to adjust the speed depending on your hardware.
    lox.begin();

    connectWifi();
}
void loop() {
      
          HTTPPost();
    
    delay( 1000 );
    Serial.println( "Goodnight for an hour ");
   ESP.deepSleep( 4200000000ULL );        // unsigned 32 bit integer in microseconds

delay(100);
    
    // If you disable sleep mode, add delay so you don't post to ThingSpeak too often.
    //   delay( 20000 );
}


// Connect to the local Wi-Fi network
// int connectWifi()
void connectWifi()
// connectWifi()
{
WiFi.mode(WIFI_STA);      
WiFi.persistent(false);        // Turn off confusing helful features
WiFi.setAutoConnect(false);
WiFi.setAutoReconnect(false);
WiFi.config(ip, gateway, subnet, dns);
WiFi.begin(WIFI_NAME, PASSWORD); 
  delay(1000);                    // Optimise for minimum value to connect
    // return 0;
}
    
// This function builds the data string for posting to ThingSpeak
  
int HTTPPost(){
VL53L0X_RangingMeasurementData_t measure; 
   lox.rangingTest(&measure, false);
  
    if (client.connect( THING_SPEAK_ADDRESS , 80 )){

       // Build the postData string.  
       String postData= "api_key=" + writeAPIKey ;

   postData += "&field1=";
    postData += String(measure.RangeMilliMeter);
    postData += "&field2=";
    postData += String(WiFi.RSSI());

        // POST data via HTTP.
        Serial.println( "Connecting to ThingSpeak for update..." );
        Serial.println();
        
        client.println( "POST /update HTTP/1.1" );
        client.println( "Host: api.thingspeak.com" );
        client.println( "Connection: close" );
        client.println( "Content-Type: application/x-www-form-urlencoded" );
        client.println( "Content-Length: " + String( postData.length() ) );
        client.println();
        client.println( postData );
        
        Serial.println( postData );
        
        String answer=getResponse();
        Serial.println( answer );

        Serial.println(WiFi.RSSI());
Serial.println(measure.RangeMilliMeter);
         
    }
    else
    {
      Serial.println ( "Connection Failed" );
    } 
  return 0;
}
// Collect the response and build it into a string.
String getResponse(){
  String response;

  long startTime = millis();

  delay( 200 );
  while ( client.available() < 1 && (( millis() - startTime ) < TIMEOUT ) ){
        delay( 5 );
  }
  if( client.available() > 0 ){ // Get response from server.
     char charIn;
     do {
         charIn = client.read(); // Read a char from the buffer.
         response += charIn;     // Append the char to the string response.
        } while ( client.available() > 0 );
    }
  client.stop();
          return response;
}

Thanks for letting us know your knowledge level. I am sorry to say as I understand your code has several areas that could be causing issues, ranging from logical errors to potential misconfigurations. Below, I’ll highlight some potential problems and suggest improvements:

Issues and Improvements:

  1. Serial Baud Rate:
  • You are using Serial.begin(74880);, which is an unusual baud rate. Ensure that your Serial Monitor matches this baud rate, as it's specific to some ESP8266 boot messages but not standard for general debugging.
  1. Deep Sleep Timing:
  • The ESP.deepSleep(4200000000ULL); command sets the ESP8266 to sleep for approximately 4,200 seconds (about 70 minutes). If you intended it to be 1 hour, ensure the value aligns with your timing needs. This command also puts the device to sleep immediately, which might skip some Serial print messages unless executed just before sleep.
  1. WiFi Configuration:
  • The WiFi.config(ip, gateway, subnet, dns); command may fail if static IP settings are not correctly matched with your network settings. Ensure the IP address does not conflict with other devices on your network.
  1. WiFi Connection Delay:
  • In connectWifi(), after calling WiFi.begin(WIFI_NAME, PASSWORD);, you only have a delay(1000);. You should wait until the WiFi is connected before proceeding. Add code to verify the connection:
while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
}
Serial.println("Connected to WiFi.");
  1. Reading the I2C Sensor (Adafruit_VL53L0X):
  • The lox.begin() function should be checked for success. The begin() function returns true if the sensor initializes correctly. Modify the initialization to:
if (!lox.begin()) {
    Serial.println("Failed to boot VL53L0X sensor!");
    while (1); // Halt the program or handle the error
}
  1. Incorrect Serial.read() Usage:
  • In Get_Number(), you call Serial.read() inside a while loop checking for availability. This would cause an infinite loop because Serial.read() always reads the next byte (which could be -1 if nothing is available), creating logic problems.
  1. Connection Handling in HTTPPost():
  • Ensure client.connect() is successful. The if (client.connect(...)) block may execute before the connection is fully established, leading to failed posts.
  1. Resource Management:
  • client.stop() should be called after reading the response. It is there, but ensure no other use of client before proper closure, which could leave resources open.
  1. General Exception Handling:
  • There is little exception handling for common failures (e.g., failed WiFi connections, ThingSpeak communication failures). Implement checks to gracefully handle such scenarios.

Revised Code Snippet for Key Sections:

Here are some improvements integrated into your code:

void setup() {
    Serial.begin(74880); // Adjust as needed to match your Serial Monitor
    if (!lox.begin()) {
        Serial.println("Failed to boot VL53L0X sensor!");
        while (1); // Halt program execution if the sensor fails to initialize
    }
    connectWifi();
}

void connectWifi() {
    WiFi.mode(WIFI_STA);
    WiFi.persistent(false);
    WiFi.setAutoConnect(false);
    WiFi.setAutoReconnect(false);
    WiFi.config(ip, gateway, subnet, dns);
    WiFi.begin(WIFI_NAME, PASSWORD);

    // Wait until the WiFi is connected
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.println("\nConnected to WiFi.");
}

int HTTPPost() {
    VL53L0X_RangingMeasurementData_t measure;
    lox.rangingTest(&measure, false);

    if (client.connect(THING_SPEAK_ADDRESS, 80)) {
        String postData = "api_key=" + writeAPIKey;
        postData += "&field1=" + String(measure.RangeMilliMeter);
        postData += "&field2=" + String(WiFi.RSSI());

        Serial.println("Connecting to ThingSpeak for update...");
        client.println("POST /update HTTP/1.1");
        client.println("Host: api.thingspeak.com");
        client.println("Connection: close");
        client.println("Content-Type: application/x-www-form-urlencoded");
        client.println("Content-Length: " + String(postData.length()));
        client.println();
        client.println(postData);

        String answer = getResponse();
        Serial.println(answer);
    } else {
        Serial.println("Connection Failed");
    }

    client.stop(); // Ensure client resources are released
    return 0;
}

What I did:

  • Added error checks for sensor initialization.
  • Modified WiFi connection handling to wait until connected.
  • Added proper client connection verification and cleanup.
  • Adjusted delays and serial output to ensure they are executed correctly.

I did not test this but I think it should work. Let us know.

1 Like

Thanks so much! This is very helpful.

When it prints the messages such as "Connection Failed" where do those show up? I assume the serial monitor is the output window at the bottom of the screen. After the code was uploaded, I never got any out put in this window. Perhaps due the problems you outlined.

No, the Serial Monitor is a separate tool from your main code editor. In the Arduino IDE, you can open it by clicking the square icon in the top right corner. At the bottom of the Serial Monitor, the window that opened, you’ll see the baud rate setting, which needs to match the value you set in your code with Serial.begin(115200).

I see, found that.

Made the changes and compiled the code. Got this;

error: 'getResponse' was not declared in this scope
72 | String answer = getResponse();
| ^~~~~~~~~~~
Multiple libraries were found for "ESP8266WiFi.h"
Used: C:\Users\JayCarlson\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\libraries\ESP8266WiFi
Not used: C:\Users\JayCarlson\OneDrive\Work Documents\Arduino\libraries\ESP8266WiFi
exit status 1

Compilation error: 'getResponse' was not declared in this scope

This message indicates that you have more than one copy of the library installed. Did you install the library, delete it, and then reinstall the IDE or any libraries afterward?

I may have, but that's a warning. Right? I think the critical error is below;

Compilation error: 'getResponse' was not declared in this scope

Is getResponse a variable or a subroutine, and wouldn't I want wifi persistent, setautoconnect, and setautoreconnect all to true?

It is a response from your server:

String getResponse() {    // Define the function returning a string
  // Simulated response generation
  return "This is the response";
}

I apologize, I don't get it. What is the remedy?

String answer = getResponse();
Serial.println(answer);
} else {
Serial.println("Connection Failed");
}

It seems in this context that GetResponse is passing a value to a variable (answer). Is GetResponse a system function, a subroutine or a variable? There is nowhere else in the code where this function is used or defined.

String getResponse() {    // Define the function returning a string
  // Simulated response generation
  return "This is the response";
}

Does this code set GetResponse as a string value?

What is the first word? That is what is returned from the function 'getResponse()'.

It seems you might not be fully ready to start the project just yet, but that’s perfectly okay! We don't know your skill set or what resources you have at your disposal, so I recommend starting with some online tutorials. While the quality varies, many tutorials are excellent and will help you build a solid foundation.

Here’s How to Get Started:

  1. Learn the Basics: Begin with the fundamentals, such as controlling outputs (like LEDs) and interpreting inputs (such as reading a switch or receiving a message). LEDs are a great starting point since they’re inexpensive and most Arduino boards come with a built-in LED.
  2. Explore Basic Electronics Tutorials: Look for beginner-friendly tutorials on electronics concepts. These will help you understand key principles that you’ll need as you progress.
  3. Recommended Resources:
  • Arduino Cookbook: Consider going through the Arduino Cookbook, which is a comprehensive guide filled with practical projects and step-by-step instructions.
  • Online Tutorials: Check out YouTube channels like CodeBeauty for easy-to-understand lessons presented in small, digestible parts.
  1. Learning the IDE: During this process, you will also learn what an IDE (Integrated Development Environment) is and how to use it to write, generate, and upload your code to the Arduino.
  2. Practice and Learn at Your Own Pace: Everyone learns at different speeds, and that’s completely normal. It may take a few months to grasp the basics, but with consistent practice, you’ll see progress.

Additional Help:

Please keep us updated on your journey, and don’t hesitate to ask questions as you learn. We’re here and willilng to help and guide you along the way!

I'm not sure I'm communicating my question properly. Is there somewhere I need to define GetResponse or is it a function of the language? Do I need to integrate your sample code form your previous message to define GetResponse? It isn't defined anywhere in the code and it seems more complicated to define GetResponse as a specific string and then pass that value to the variable answer.

You've been very helpful thus far, I think my confusion is that your code called GetResponse but did not define it.

It is a function you need to define. Have you read the Arduino Cookbook and followed several Online Tutorials: For C++ Check out YouTube channels like CodeBeauty for easy-to-understand lessons presented in small, digestible parts. She has a section on functions.

I added the snippet of code to define getResponse and got beyond that error, then got an undefined loop error so I added;

void loop(){}

Now I am troubleshooting an " rf[112] : 0�Failed to boot VL53L0X sensor!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.