how to get AT response from ESP8266 connected to arduino - arduino

I am fighting with ESP8266 wifi module and connecting arduino. After updating firmware to newest version i started to programm arduino to get data incoming from wifi. I saw many examples about maiking webserver via ESP8266 but none of them works for me.
ESP is connected to my Arduino Leonardo:
>
Arduino -> ESP8266
power 3.3V -> vcc
ground -> ground
tx -> rx (via logic level converter 5->3.3V)
rx -> tx (via logix level converter
power 3.3V ->gpio0 (without any resistors)
I made simple sketch:
void setup(void){
Serial.begin(9600);
Serial1.begin(115200);
}
void loop() {
if(Serial1.available())
{
Serial.println("WIFI IS AVAILABLE");
Serial1.println("AT");
delay(1000);
} else {
Serial.println("WIFI not available.");
delay(1000);
}
}
After executing it ESP8266 is powered (red led is on) and also every second blue led (blinks). That makes me sure that in fakt "AT" command is transmited to module. But there are also two issues:
i want to get response from esp - in this case word "OK". I tried Serial1.read() but it only reads one byte. Serial1.readString() makes my messages "wifi not available" and sametimes "wifi is available" as if for a while the connection would be unavailable
after uploading sketch to arduino and having powered esp8266 wifi module is always unavailable - i need to power the module off and on again to have it working.
Anybody please can help me?

What you need to do is change your approach a bit. Do not check if data is available. The trick is to send the module something and then check for data.
Do something like:
while (Serial.available() > 0)
Serial.read();
to clear the buffer before any command you want to send. Then send the command. Then check for data as a response.
Do not rely on that Blue LED as any indication. It is only an indication that the ESP8266 is busy using the WiFi in some sort of way, whether it is doing keepalives, initializing WiFi or whatever. It can be totally unrelated to whatever you are sending. If you do not receive a valid response then you must assume that there is comms issues between you and the module. One thing though is that if that Blue LED never goes off then either the module has frozen or the firmware was corrupted. I have had that many times. I then reload the firmware and usually that fixes it. It usually only happens during development times where I reset, upload code or change wires.
I use mine with an atmega328 on a separate slef-built board and not the one on the Uno and run that board on 3.3v itself and then use a logic level converter between that atmega board and my Uno so that I can program it. But I have had sporadic issues with non-comms but I suspect it might be power related. Be aware that running your Serial via the logic level converter might also be causing comms issues.
Proposed wiring: All pins except RX,TX,VCC and GND goes to VCC via 10K pullup resistors. RX goes to the arduino's TX and TX goes to the arduino's RX. Of course you know where VCC and GND goes.

Related

Arduino: Having trouble connecting/writing AT commands to Bluetooth HC05 module via USB serial

As an introduction, I bought myself an arduino and a few modules to learn some software stuff. The project is to eventually connect to a bluetooth OBD2 reader on my car to display real time data on a small LCD.
The problem
I am either not able to connect to, or not write to, my HC05 module via software serial. I think I have narrowed this down to a couple possibilities.
I am unable to connect to the module in the first place.
I have a Mega 2560 and HC05.
5V <-> VCC
GND <-> GND
D2 <-> RXD
D3 <-> TXD
Note that I have seen 9600 and 38400 baud rates for connecting but neither worked, so I made this function to try them all for me...
//set up serial relay into HC05.
SoftwareSerial hc05(2,3);
//computer serial baud rate 115200
bool hc05_connect() {
long baud_list[] = {300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200, 230400};
Serial.println("Attempting to connect to HC05 bluetooth module...");
bool success = 0;
for (int i=0; i<(sizeof(baud_list) / sizeof(baud_list[0])); i++) {
Serial.print("Baud rate ");
Serial.print(baud_list[i]);
Serial.print("...");
hc05.begin(baud_list[i]);
hc05.write("AT");
delay(1000);
if (hc05.available()) {
Serial.println(" successful!");
success = 1;
return success;
} else {
Serial.println(" failed");
}
}
return success;
}
Notes:
This has always returned failed for every baud rate.
I have the bluetooth module in command mode, initiated by pressing the button as I supply power.
I have tried unplugging the TX/RX pins while uploading the sketch. No difference noted.
My attempts to send commands to the HC05 are failing.
Below is my function for sending commands to the module.
void loop() {
// listen for communication from the ESP8266 and then write it to the serial monitor
if (hc05.available()) {
Serial.write(hc05.read());
}
// listen for user input and send it to the ESP8266
if (Serial.available() > 0) {
Serial.println("Writing to hc05...");
Serial.println(Serial.available());
Serial.println(Serial.read());
hc05.write(Serial.read());
}
}
I have added in a few lines which write back to Serial so I can see what's being sent, and the monitor returns weird stuff. For example, if I send "AT", this is what the monitor reads:
Writing to hc05...
3
65
Writing to hc05...
1
10
Notes:
Why is it sending 2 different items?
Why is it sending integers rather than the characters I said?
Does this indicate I'm just sending it nonsense commands so it's not responding?
I can provide full code if you want, this is already a huge textwall though. Please help me!
Edit
So I have been able to get communication two ways via the bluetooth module using a modified version of the code in this instructable: https://www.instructables.com/How-to-Set-Up-and-Test-Arduino-Bluetooth-Connectio/
I was able to send from PC only and not receive to an android bluetooth terminal using SoftwareSerial with HC05's RX - TX0 / TX - RX0.
And I was able to receive to PC and not send using hardware serial / Serial1 with HC05's RX - TX1 / TX - RX1.
So now I have RX - TX0 / TX - RX1. It seems to communicate through terminal like this.
void setup() {
Serial.begin(9600); //open the serial port
Serial1.begin(9600);
}
void loop() {
if (Serial1.available()) {
Serial.print("(Received)");
Serial.println(Serial1.readString()); // send from serial to bluetooth
}
if (Serial.available()) {
Serial.print("(Sent)");
Serial.println(Serial.readString());
Serial1.println(Serial.readString()); // send from bluetooth to serial
}
}
But if I apply this to my code, I still can't get it to work.
Before I try to hack this together, why am I getting serial to work across 2 different serial channels? Weird...
Okay, so I figured it out. (I can't say I fully understand, but maybe this will help people in future.)
1. Unable to connect to module
Thanks #ukBaz for suggesting I connect with the terminal app on my phone, this allowed me to debug the connection to the module in the first place. and #Juraj for suggesting that the Mega uses hardware serial.
Serial1 apparently is broken on my board, so I am using Serial3. I bluetoothed to the device with my phone, and was able to send commands back and forth between Serial and Serial3 both on 9600 baud rate. Here is the code I used:
void setup() {
Serial.begin(9600); //open the serial port to PC
Serial3.begin(9600); //open serial port to HC05. TX -> 15, RX -> 14
}
void loop() {
if(Serial3.available()){
Serial.print(Serial3.readString()); // send from serial to bluetooth
}
if(Serial.available()){
Serial3.print(Serial.readString()); // send from bluetooth to serial
}
}
I suspect I was using the wrong read/readString and write/print/println for my purpose initially.
2. Unable to issue commands to the module
Once I got that working, I changed the baud rate to 38400, and tied the STATE pin of the module to VCC (rather than using the button). Uploaded code, disconnected 5V, reconnected 5V, reset arduino.
At that point, I could issue "AT" to the module via Serial Monitor, and receive "OK" back. Woohoo!
I think I understand now that #hlovdal was suggesting that I was issuing a command to the module and never parsing a response I got, so it was.. clogged parhaps? In any case. I can now successfully issue commands and receive responses from the module.
Thanks everyone for your help.
There are some problems with how you are communicating AT command lines to your device. For instance:
hc05.write("AT");
delay(1000);
You do not send an AT command to a modem, you send an AT command line that contains zero or more AT commands, followed by a command line terminating character (that always should be '\r', aka carriage return (or <CR>)).
You are missing that terminating character here, so the modem will never send you a reply, because you have not sent it a command line.
And also, you should never, ever use delay as a substitute for reading and parsing the responses that the modem sends back. See this answer for some more details.

Use the Arduino Nano's serial interface to communicate with ESP8266 -- currently hangs

I have designed a ledstrip driver capable of receiving commands over UDP-IP. I initially worked with an Arduino MEGA, and currently I'm in the process of deploying the code in an Arduino NANO.
The Arduino NANO only has one hardware serial interface, unlike the MEGA, which has several. This forces me to disable the usual debugging through one of the Serial ports (by sending strings to the computer) and to reserve the one and only serial interface for the ESP8266. In short, I am connecting the ESP8266 to the TX and RX pins in the NANO.
I am aware that I could use the softwareserial.h library, but I'd like to avoid it if possible.
The following function sets up the Wifi object:
void wifi_setup(){
// Initialize serial for ESP module
Serial.begin(9600);
// Initialize ESP module
WiFi.init(&Serial); /* GETS STUCK HERE */
...
}
The problem is: the microcontroller gets stuck in the Wifi.init() function and never abandons it.
I am aware that the serial interface is connected to the USB port, and am suspicious this might be a problem. However, I have tried giving power to the NANO through the VIN pin instead of through the USB port, and it hasn't worked.
What am I doing wrong?
The best solution will be to write separate code for ESP8266 and Arduino Nano - or even only for ESP8266 (NodeMCU to make it easy). It will be much easier. But if you really want to do it in your way, i think ESP uses 115200 baud, and you've set it to 9600.

SoftwareSerial example not working as expected

I recently bought an Arduino UNO to read the data outputted by my Smart Meter. The meter uses serial communication and I would like to see the values being outputted on my laptop screen. I figured I would need to use the SoftwareSerial library to read the incoming data and print that data on my screen using the hardware serial and the Serial Monitor in the Arduino IDE. To become familiar with (software) serial communication on the Arduino, I reviewed the documentation of the SoftwareSerial library. Problem is, I can't get the most basic example to work and I have been stuck on this for quite a while now. The example code is below, the example can be found here
#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(57600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.println("Goodnight moon!");
// set the data rate for the SoftwareSerial port
mySerial.begin(4800);
mySerial.println("Hello, world?");
}
void loop() { // run over and over
if (mySerial.available()) {
Serial.write(mySerial.read());
}
if (Serial.available()) {
mySerial.write(Serial.read());
}
}
As far as I understand this, the following should happen:
- Type text in Serial Monitor window.
- Serial.read() reads this data and writes it to the Software Serial.
- The Software Serial reads this data and writes it back to Serial.
- That which was written appears on the screen.
But whatever I try, nothing happens. Among things I tried to following:
- Change the baud rate for both software and hardware serial (9600 for instance).
- Tried a different SoftwareSerial library (AltSoftSerial).
- Tried different RX and TX pins for SoftwareSerial.
- Instead of Serial.write(mySerial.read());, store the result in a char first.
I'm probably missing something obvious. I would be grateful to anyone who could shed some light on this or offer an alternative way for me to read the data from my Smart Meter.
Edit
I had no wiring, because the example specified "There is no circuit for this example". I tried all three options suggested by #slash-dev, but none had the expected behaviour:
SoftwareSerial with wires connecting pin 1 to pin 10 and pin 0 to pin 11. It prints strange characters:
Goodnight moon!
Ùniÿhtÿmoÿn!ÿ
nihtmoÿttt
AltSoftSerial with wires connecting 1-8 and 0-9. First prints Goodnight moon! and then it keeps printing Ô당¥�¡Ñ�moon!.
NeoSWSerial with wires connecting 1-10 and 0-11. Same as AltSoftSerial but keeps printing Ôë‹–+ë¡Ñ�j½½¹…j.
The baud rates must be the same on Serial and mySerial.
And you don't describe the connections, so I have to ask: Did you connect a wire from pin 1 (Serial transmit) to pin 10 (mySerial receive), and another wire from pin 0 (Serial receive) to pin 11 (mySerial transmit)? Note how they are crossed.
AltSoftSerial is really the best choice, but it only works on pin 8 (RX) and pin 9 (TX), which would require connecting 8 to 1 and 9 to 0. SoftwareSerial is very inefficient, because it disables interrupts for long periods of time. This can interfere with other parts of your sketch or other libraries.
My NeoSWSerial library is another alternative. It's almost as efficient as AltSoftSerial, but it works on any two pins. It can transmit and receive at the same time (unlike SoftwareSerial), but it only works at bauds 9600, 19200 and 38400.
EDIT:
I think what you've tried is probably working ok. All the software serial libraries use interrupts for processing individual bits instead of one interrupt per character. When there are other interrupts in the system (millis() TIMER0 or Serial), the bit "calculations" can be affected. This manifests as receiving the wrong byte. Your loopback test makes it especially susceptible because the sending and receiving are synchronized (the initial receive interrupt occurs while the transmit interrupt is starting the next char).
If you just hook 0 to 1, I think it will work, because the UART is able to send and receive at the same time, and it deals with complete characters, not bits. The character interrupts do not disturb the sending or receiving of the bits.
In developing the NeoSWSerial library, I have seen this manifest the same way. I had to use two Arduinos to fully test asynchronously (i.e., not synchronized). In your case, using AltSoftSerial for the SmartMeter should work fine, and you can choose different baud rates. If you are echoing the SmartMeter characters to Serial, be sure you have a higher baud rate on Serial.
This is most likely not related to the issues now 5 years ago, but in my case I was using the Arduino IDE 2.0.0-rc5 which was not writing to the soft serial for unknown reasons. I downgraded to Arduino IDE 1.8.19 and the same serial sketch worked.

Cannot connect to ESP8266 after serial speed change

After some trial and error, tonight my Arduino Uno began talking to an ESP8266 module, with the most common wiring, 3.3V power to the module from a well-sized external supply, direct connection of the 3.3V TX line, and a voltage divider to read from the 5V RX.
SoftwareSerial esp8266(2,3);
void setup()
{
Serial.begin(9600);
esp8266.begin(115200);
char buffer[50];
esp8266.write("AT\r\n");
esp8266.readBytes(buffer, sizeof(buffer));
Serial.println(buffer);
}
After setting the 115200 speed for the ESP8266<->Arduino serial communication, some clear boot messages and command responses appeared on the serial monitor.
Since these messages were interleaved by some garbage characters, I tried reducing the communication speed.
For this purpose I issued the command AT+IPR=9600 to the module, which immediately showed some action on the blue LED, an OK response on the console and finally resulted in the same LED being fixed on.
I consequently adjusted the serial speed on the Arduino side, with esp8266.begin(9600);, but could never obtain any further communication with the module.
I can now see garbage only at any speed.
Could the module have escalated to a different speed? I tried many of them (4800, 57600, 19200, back to 115200 etc.) but no clear response appeared on the monitor.
May you suggest any attempt to reestablish the connection? Any way to reset the last command result?
I'd rather avoid setting up for firmware update, if any simpler solution can be tried.
Here is the solution!
The AT+IPR command was known to break the firmware and make the module unresponsive until a complete reflash.
I found the solution in this forum discussion.

Arduino: Incoming USB serial data when USB is disabled hoses the connection

I'm writing a sketch for an Arduino Leonardo that occasionally needs to communicate bidirectionally via USB serial, and also needs to be power efficient. To save power I'd like to disable the USB when it's not needed. I can successfully use power_usb_disable() and power_usb_enable() to do this, BUT only if no data is sent to the Arduino when USB is disabled.
Here's how to reproduce the problem: I run the following sketch on the Leonardo while it's connected to a serial comms program on my computer (I've tried the Arduino serial monitor and Minicom in Linux and PuTTY in Windows). It works as expected, printing out the messages, until I type something right after the "Disabling USB..." message. Once I do that, I will receive no further data from the Leo. The funny thing is, the TX and RX LEDs continue to blink as if everything is fine. The only way to get the connection working again is to reset the board.
Now, I don't really care about dropping the incoming data when USB is disabled, that's to be expected...but I would like the serial connection to continue to work correctly once USB is enabled again.
I don't know enough about how USB serial works to know how to troubleshoot this.
#include <avr/power.h>
void setup() {
Serial.begin(9600);
delay(3000);
}
void loop() {
Serial.println("USB is enabled!");
delay(1000);
// If I send characters here, everything is fine.
Serial.println("Disabling USB...");
delay(25);
power_usb_disable();
delay(1000);
// If I send characters here, it hoses the USB connection somehow.
power_usb_enable();
delay(25);
}
I guess for now the best answer to this problem is "don't do that." I can arrange not to disable the USB if the connection is open, using the "if (Serial)" thing. So if somebody has a serial monitor open and looks as if they're about to type something, I leave USB enabled. Seems to work OK, although it doesn't address the underlying general question of how to robustly disable and re-enable USB from any state it might be in. I would still love to hear expert advice on that.

Resources