Hello Arduino Community,
I'm a newbie and I'm working on a project using an Arduino with an ESP8266 module to send ultrasonic sensor data to ThingSpeak. I have been facing an issue with DNS resolution when trying to connect to ThingSpeak. The connection fails with a "DNS Fail" error. Below are the details of my setup and the code I'm using.
Project Details:
- Microcontroller: Arduino
- WiFi Module: ESP8266
- Sensor: Ultrasonic Sensor (HC-SR04)
- Goal: Send distance data to ThingSpeak
Problem Description:
I can connect the ESP8266 to my WiFi network, but when attempting to resolve the DNS for api.thingspeak.com
, it fails with a "DNS Fail" error. Below is the serial output I get:
rust
Copy code
00:36:09.298 -> Connecting to WiFi...
00:36:09.298 -> AT+CWJAP="wifi","12345678"
00:36:11.447 -> WIFI DISCONNECT
00:36:16.905 -> WIFI CONNECTED
00:36:16.948 -> WIFI GOT IP
00:36:18.301 ->
00:36:18.301 -> OK
00:36:29.307 ->
00:36:29.340 -> Response: AT+CWJAP="vivo1901","12345678"
00:36:29.372 -> WIFI DISCONNECT
00:36:29.372 -> WIFI CONNECTED
00:36:29.404 -> WIFI GOT IP
00:36:29.404 ->
00:36:29.438 -> OK
00:37:32.598 ->
00:37:32.598 -> ERROR
00:37:35.776 ->
00:37:35.776 -> Response: AT+CIPSTART="TCP","AT+CIPDOMAIN="api.thingspeak.com"",80
00:37:35.844 -> busy p...
00:37:35.844 -> DNS Fail
00:37:35.877 ->
00:37:35.877 -> ERROR
00:37:35.877 ->
00:37:35.877 -> Connection to ThingSpeak failed.
Code:
cpp
Copy code
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX, TX for ESP8266
const int Trig = 8;
const int Echo = 9;
const long MEASURE_INTERVAL = 5000; // Measure interval
const long THINGSPEAK_INTERVAL = 15000; // ThingSpeak update interval
const int DipSwitch1 = 10; // First switch
const int DipSwitch2 = 11; // Second switch
const int DipSwitch3 = 12; // Third switch
const int DipSwitch4 = 13; // Fourth switch
const int RED_LED = 7; // Red LED
const int GREEN_LED = 6; // Green LED
unsigned long lastThingSpeakUpdate = 0;
bool printData = true; // Variable to control printing
const char* ssid = "wifi"; // Replace with your WiFi SSID
const char* password = "12345678"; // Replace with your WiFi password
const char* apiKey = "AAAAAA"; // Your ThingSpeak API key
void setup() {
Serial.begin(9600);
mySerial.begin(9600);
Serial.println("Starting setup...");
// Initialize pins
pinMode(Trig, OUTPUT);
pinMode(Echo, INPUT);
pinMode(RED_LED, OUTPUT);
pinMode(GREEN_LED, OUTPUT);
pinMode(DipSwitch1, INPUT_PULLUP);
pinMode(DipSwitch2, INPUT_PULLUP);
pinMode(DipSwitch3, INPUT_PULLUP);
pinMode(DipSwitch4, INPUT_PULLUP);
Serial.println("Pins initialized.");
// Connect to WiFi
connectToWiFi();
}
void loop() {
long distance = measureDistance();
int waterLevelThreshold = getWaterLevelThreshold();
if (printData) {
Serial.print("Ultrasonic Distance: ");
Serial.print(distance);
Serial.println(" cm");
Serial.print("Current Water Level Threshold: ");
Serial.print(waterLevelThreshold);
Serial.println(" cm");
}
delay(MEASURE_INTERVAL);
// Control LEDs based on distance
if (distance <= 30) {
digitalWrite(GREEN_LED, HIGH);
digitalWrite(RED_LED, LOW);
} else if (distance <= 80) {
digitalWrite(GREEN_LED, HIGH);
digitalWrite(RED_LED, LOW);
delay(150); // Blink delay
digitalWrite(GREEN_LED, LOW);
delay(50); // Blink delay
} else if (distance > waterLevelThreshold) {
digitalWrite(GREEN_LED, LOW);
digitalWrite(RED_LED, HIGH);
} else {
digitalWrite(GREEN_LED, LOW);
digitalWrite(RED_LED, LOW);
}
// Update ThingSpeak at regular intervals
if (millis() - lastThingSpeakUpdate > THINGSPEAK_INTERVAL) {
updateThingSpeak(distance);
lastThingSpeakUpdate = millis();
}
}
// Measure distance using ultrasonic sensor
long measureDistance() {
digitalWrite(Trig, LOW);
delayMicroseconds(2);
digitalWrite(Trig, HIGH);
delayMicroseconds(10);
digitalWrite(Trig, LOW);
long duration = pulseIn(Echo, HIGH);
long distanceCm = duration / 29 / 2;
return distanceCm;
}
// Get water level threshold based on DIP switch settings
int getWaterLevelThreshold() {
int threshold = 40; // Default threshold
bool switch1 = (digitalRead(DipSwitch1) == LOW);
bool switch2 = (digitalRead(DipSwitch2) == LOW);
bool switch3 = (digitalRead(DipSwitch3) == LOW);
bool switch4 = (digitalRead(DipSwitch4) == LOW);
if (switch1) threshold = 50;
if (switch2) threshold = 60;
if (switch3) threshold = 70;
if (switch4) threshold = 80;
if (printData) {
Serial.print("DIP Switch 1: ");
Serial.println(switch1 ? "ON" : "OFF");
Serial.print("DIP Switch 2: ");
Serial.println(switch2 ? "ON" : "OFF");
Serial.print("DIP Switch 3: ");
Serial.println(switch3 ? "ON" : "OFF");
Serial.print("DIP Switch 4: ");
Serial.println(switch4 ? "ON" : "OFF");
}
return threshold;
}
// Send AT commands to the ESP8266
bool sendCommand(const char* command, unsigned long timeout) {
mySerial.println(command);
unsigned long time = millis();
String response = "";
while (millis() - time < timeout) {
while (mySerial.available()) {
char c = mySerial.read();
response += c;
Serial.write(c); // Echo the response to Serial Monitor
}
}
Serial.println(); // Print a new line after the response
Serial.println("Response: " + response); // Debugging line
return response.indexOf("OK") != -1 || response.indexOf("WIFI CONNECTED") != -1;
}
bool sendCommand(String command, unsigned long timeout) {
return sendCommand(command.c_str(), timeout);
}
// Connect to WiFi
void connectToWiFi() {
Serial.println("Resetting module...");
sendCommand("AT+RST", 10000);
delay(10000); // Additional delay to ensure reset
Serial.println("Setting WiFi mode...");
sendCommand("AT+CWMODE=1", 5000);
delay(2000); // Ensure command is processed
Serial.println("Connecting to WiFi...");
if (sendCommand("AT+CWJAP=\"" + String(ssid) + "\",\"" + String(password) + "\"", 20000)) {
Serial.println("Connected to WiFi");
} else {
Serial.println("Failed to connect to WiFi");
}
}
// Perform DNS lookup to resolve the IP address of ThingSpeak
String resolveDNS(String host) {
String cmd = "AT+CIPDOMAIN=\"" + host + "\"";
mySerial.println(cmd);
unsigned long time = millis();
String response = "";
while (millis() - time < 5000) {
while (mySerial.available()) {
char c = mySerial.read();
response += c;
Serial.write(c); // Echo the response to Serial Monitor
}
}
Serial.println(); // Print a new line after the response
Serial.println("Response: " + response); // Debugging line
int startIndex = response.indexOf(":") + 1;
int endIndex = response.indexOf("\r", startIndex);
return response.substring(startIndex, endIndex);
}
// Update ThingSpeak with distance data
void updateThingSpeak(long distance) {
String ipAddress = resolveDNS("api.thingspeak.com");
Serial.println("Resolved IP: " + ipAddress);
if (ipAddress.length() == 0) {
Serial.println("Failed to resolve IP address.");
return;
}
String cmd = "AT+CIPSTART=\"TCP\",\"" + ipAddress + "\",80";
if (sendCommand(cmd.c_str(), 5000)) {
Serial.println("Connected to ThingSpeak.");
} else {
Serial.println("Connection to ThingSpeak failed.");
return;
}
String httpRequest = "GET /update?api_key=" + String(apiKey) + "&field1=" + String(distance) + " HTTP/1.1\r\n" +
"Host: api.thingspeak.com\r\n" +
"Connection: close\r\n\r\n";
cmd = "AT+CIPSEND=" + String(httpRequest.length());
if (sendCommand(cmd.c_str(), 5000)) {
Serial.println("Sending data to ThingSpeak...");
mySerial.print(httpRequest);
// Wait for the response
unsigned long time = millis();
String response = "";
while (millis() - time < 5000) {
while (mySerial.available()) {
char c = mySerial.read();
response += c;
Serial.write(c);
}
}
Serial.println("Response: " + response);
// Check if the response indicates success
if (response.indexOf("OK") != -1 || response.indexOf("SEND OK") != -1) {
Serial.println("ThingSpeak update sent successfully.");
} else {
Serial.println("Failed to send data to ThingSpeak, retrying...");
}
// Close the connection
if (sendCommand("AT+CIPCLOSE", 5000)) {
Serial.println("Connection closed successfully.");
} else {
Serial.println("Failed to close connection, retrying...");
}
} else {
Serial.println("Failed to initiate data send.");
}
}