Problem: Factory resetting esp8266 - 01S to work with AT commands

What is the CPU in this case? the arduino or the esp? So SoftwareSerial would work rather reliably with lower baudrates?

The Arduino which is based on Atmega328 with a single hardware serial. SoftwareSerial works best, in my opinion, only for transmitting data, at lower baud, hence it's okay for debugging output

I don't know if your issue has been resolved yet, but let me but in.
First of all the connections if you are using an UNO to flash the ESP.
I find that My Uno's 3.3v provides enough current for the ESP even for it to connect to WiFi, but not all do.
First load an empty sketch onto the UNO (or blink anything that doesn't use Serial)
As i saw also in this thread, people tend to forget you need to pull RST on the ESP HIGH.
anyway, the list.
ESP ---------- UNO
VCC 3.3v
CH_PD-------- 3.3v
RST --------- 3.3v
TX ------------- TX
RX --- DIV --- RX (always use a voltage divider, i use 3 x 1K and it has worked without issue)
GND --------- GND
GPIO0 ------ GND (for flashing) 3.3v or free-floating for normal operation
GPIO2 ------ 3.3v or free-floating
For both GPIO0 & 2 (as well as GPIO1 which is the TX pin) goes that if they are pulled 'LOW' at boot the boot mode is modified. For GPIO 0 it selects flash mode, apparently something is possible with the others but i never use that.
When i used AT commands (briefly) i found a flashing tool that actually worked, and i managed to find firmware of different types and versions. I kept those files and instructions, but they have probably been superseded and i doubt if i can still find those links.

In general an ESP-01 with 1MB flash is black PCB and with .5MB flash is blue PCB, but there are some where i found that with black PCB they only really had .5MB of flash. There is not harm in selecting .5MB as the size for a 1MB board. There are also some (actually the ones i use most) that are not 8266 but are referred to as ESP8285, they have a different flash chip, which is controlled differently, It might be rather complex to flash AT-firmware onto one of those.
As stated before i never use AT-commands, since it is so much easier to program the an ESP directly to perform the tasks that i want it to do.
check this tutorial (it is the best i've found)

Thank you Deva_Rishi for your input!

is it the same circuit for flashing and programming via the arduino IDE? Should i have the RESET-pin on arduino connected to ground?

And what do you mean when you say that "the boot mode is modified"? I have made the circuit so that GPIO2 is free floating and GPIO0 is connected to ground. Would that work for uploading a program to it via arduino IDE?

Also I tried following the guide you sent but i used an external 3.3V power source instead of the arduinos 5V with voltage regulator, however, I get different errors each time i try to upload the blink sketch to the esp. Sometimes i just get:

warning: espcomm_sync failed
error: espcomm_open failed
error: espcomm_upload_mem failed

But sometimes i get this long error:

Arduino:1.8.13 (Windows Store 1.8.42.0) (Windows 10), Kort:"Generic ESP8266 Module, 80 MHz, ck, 26 MHz, 40MHz, QIO, 512K (no SPIFFS), v2 Prebuilt (MSS=536), Disabled, None, 115200"

Sketch uses 247043 bytes (49%) of program storage space. Maximum is 499696 bytes.

Global variables use 32848 bytes (40%) of dynamic memory, leaving 49072 bytes for local variables. Maximum is 81920 bytes.

warning: espcomm_send_command: wrong direction/command: 0x00 0x08, expected 0x01 0x08

warning: espcomm_send_command: wrong direction/command: 0x00 0x08, expected 0x01 0x08

warning: espcomm_send_command: wrong direction/command: 0x00 0x08, expected 0x01 0x08

warning: espcomm_send_command: wrong direction/command: 0x00 0x08, expected 0x01 0x08

warning: espcomm_send_command: wrong direction/command: 0x00 0x08, expected 0x01 0x08

warning: espcomm_send_command: wrong direction/command: 0x00 0x08, expected 0x01 0x08

warning: espcomm_send_command: wrong direction/command: 0x00 0x08, expected 0x01 0x08

Ett fel inträffade under uppladdning av sketchen

warning: espcomm_send_command: wrong direction/command: 0x00 0x08, expected 0x01 0x08

warning: espcomm_send_command: wrong direction/command: 0x00 0x08, expected 0x01 0x08

warning: espcomm_sync failed

error: espcomm_open failed

error: espcomm_upload_mem failed


This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Yes that should work.

Yes it is. There is no real need for the arduino RST pin to be connected to GND, all that is needed is either loading the arduino with an empty sketch or loading it with a sketch that doesn't use Serial (or pin 0 & 1)

Do you have ESP RX (GPIO3) via a voltage divider to UNO RX (pin 0) and
ESP TX (GPIO1) to UNO TX (pin 1) ?
and are both CH_PD and RST on the ESP connected to 3.3v ?
and make sure you have GND on the ESP connected to GND on the UNO

If you do that and select show verbose output during upload, what message do you get ?

Make sure this is the state when you power up the ESP.

I tried again but this time i didnt get the long error as before but I edited the preferences so that i get more info from the upload. I made sure that the things you pointed out was as they should. This is what i got now:

Arduino:1.8.13 (Windows Store 1.8.42.0) (Windows 10), Kort:"Generic ESP8266 Module, 80 MHz, ck, 26 MHz, 40MHz, QIO, 512K (no SPIFFS), v2 Prebuilt (MSS=536), Disabled, None, 115200"

Sketch uses 247043 bytes (49%) of program storage space. Maximum is 499696 bytes.

Global variables use 32848 bytes (40%) of dynamic memory, leaving 49072 bytes for local variables. Maximum is 81920 bytes.

C:\Users\Max\Documents\ArduinoData\packages\esp8266\tools\esptool\0.4.12/esptool.exe -vv -cd ck -cb 115200 -cp COM5 -ca 0x00000 -cf C:\Users\Max\AppData\Local\Temp\arduino_build_438451/Blink.ino.bin 

esptool v0.4.12 - (c) 2014 Ch. Klippel <[email protected]>

	setting board to ck

	setting baudrate from 115200 to 115200

	setting port from  to COM5

	setting address from 0x00000000 to 0x00000000

	espcomm_upload_file

	espcomm_upload_mem

	setting serial port timeouts to 1000 ms

An error occurd during the upload of the sketch

opening bootloader

resetting board

trying to connect

	flush start

	setting serial port timeouts to 1 ms

	setting serial port timeouts to 1000 ms

	flush complete

	espcomm_send_command: sending command header

	espcomm_send_command: sending command payload

	read 0, requested 1

warning: espcomm_sync failed

error: espcomm_open failed

error: espcomm_upload_mem failed

Further details: This is a picture of the circuit i have. The breadboard + and - slots get 3.3V from external power supply through the aligator-clamps and the arduino uno is connected to my pc. The RX pin is connected through 3x 1k ohm resistors.

I updated the esp8266 board in the boards manager so that i have the latest one, then it provided me with some new errors. I still have the same circuit as previous post. I dont know if these settings i have in arduino IDE for the esp is correct because I dont know what they are basically.

This is the error i got with the update in arduino IDE:

Arduino:1.8.13 (Windows Store 1.8.42.0) (Windows 10), Kort:"Generic ESP8266 Module, 80 MHz, Flash, Legacy (new can return nullptr), All SSL ciphers (most compatible), no dtr (aka ck), 26 MHz, 40MHz, QIO (fast), 1MB (FS:64KB OTA:~470KB), 2, nonos-sdk 2.2.1+100 (190703), v2 Lower Memory, Disabled, None, Only Sketch, 115200"

Executable segment sizes:

IROM   : 228624          - code in flash         (default or ICACHE_FLASH_ATTR) 

IRAM   : 26756   / 32768 - code in IRAM          (ICACHE_RAM_ATTR, ISRs...) 

DATA   : 1248  )         - initialized variables (global, static) in RAM/HEAP 

RODATA : 688   ) / 81920 - constants             (global, static) in RAM/HEAP 

BSS    : 24880 )         - zeroed variables      (global, static) in RAM/HEAP 

Sketch uses 257316 bytes (26%) of program storage space. Maximum is 958448 bytes.

Global variables use 26816 bytes (32%) of dynamic memory, leaving 55104 bytes for local variables. Maximum is 81920 bytes.

myFilepath\Documents\ArduinoData\packages\esp8266\tools\python3\3.7.2-post1/python3 myFilepath\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4/tools/upload.py --chip esp8266 --port COM5 --baud 115200 --before no_reset --after soft_reset write_flash 0x0 C:\Users\Max\AppData\Local\Temp\arduino_build_438451/Blink.ino.bin 

esptool.py v2.8

Serial port COM5

Connecting........_____....._____....._____....._____....._____....._____.....____Traceback (most recent call last):

  File "myFilepath\ArduinoData\packages\esp8266\hardware\esp8266\2.7.4/tools/upload.py", line 65, in <module>

    esptool.main(cmdline)

  File "myFilepath/ArduinoData/packages/esp8266/hardware/esp8266/2.7.4/tools/esptool\esptool.py", line 2890, in main

    esp.connect(args.before)

  File "myFilepath/ArduinoData/packages/esp8266/hardware/esp8266/2.7.4/tools/esptool\esptool.py", line 483, in connect

    raise FatalError('Failed to connect to %s: %s' % (self.CHIP_NAME, last_error))

esptool.FatalError: Failed to connect to ESP8266: Timed out waiting for packet header

esptool.FatalError: Failed to connect to ESP8266: Timed out waiting for packet header

From what i see in your picture, you have not understood what i meant with voltage divider.
The idea of the voltage divider is that the 5v logic signal that comes from the UNO is reduced to 3.3v
For this you connect the 3x 1K like this :
UNO RX -- 1k res -- ESP RX -- 1k res -- 1K res -- GND
So that when the UNO RX pin is 5v the ESP RX pin is at 3.3(3333)v
The way you have it connected, you are not dividing the voltage at all.
Chances are you have fried the ESP-01's RX pin.
Also i can not see that you have connected the ESP GND pin at all.
Nearly all tutorial suggest you make some kind of adapter for the ESP-01 to fit into a breadboard, rather than soldering wires onto it, but this is a different matter.

Okay i see, interesting.. I changed the circuit for the RX pins and i got some results.
Ok so i get this now. I was trying to upload the blink sketch to the esp but it seems like its never resetting... The blue light on the esp was on for like 2 minutes then it went black. I dont know if the code is uploaded but it seems like it. However the code is not executed. I think i need to change the circuit. Is it the GPIO0 that i need to change to free-floating for normal operation or what is it that i need to change for the esp to run the code?

I searched the internet and finally i got the program running!! Now what i need is to establish a way for the arduino uno to send data from sensor to the esp8266 and then i need the esp to read the data. I've seen that this can be done with SoftwareSerial even though it is not perfect. I've been looking around for a good and simple demonstration for this but i havent found any. Do you know how i do to send data from arduino to the esp?

Perhaps i should start a new thread for this as it isnt really the same issue anymore?

Oh great, i was worried you fried the ESP-01, they are quite sensitive.

Yep GPIO 0 needs to be HIGH or free-floating at boot. (you can use it anyway you want after that)
Keep in mind that the LED_BUILTIN is set as 2 (referring to GPIO 2) as a default in the IDE, but usually an ESP-01 has it on GPIO 1 (the TX-pin)

Well of course i do ! First of all, on the ESP side you should be using hwSerial, you have only 4 GPIO's available, and since 2 of those are connected to the UART, it makes sense to use it. (less CPU intensive and more reliable)
On the UNO side you could also use hwSerial if you aren't using it for something else that would be the preferred choice. All you need to do for that, would be to swap the TX & RX on the UNO side.
May you decide that you want to use swSerial anyway, you should use a lower BAUD-rate for that, say 9600kbps
Sending data is generally fairly straightforward, it is the reception that is tricky, but have a look at Serial Input Basics By Robin2.

I suppose hwSerial means hardware serial, what is this and what is the difference between software serial and hardware serial?

To explain the difference between hwSerial and swSerial, let me do a short explantion of Serial. In Serial bytes are being sent one bit at a time and every byte has a few other bits that are send along like a start bit, sometimes parity, and a stop bit. These bit are send by setting an output pin either HIGH or LOW.
hwSerial makes use of hardware, with which it can read a whole byte from memory, and send it one bit at a time without the use of the main core. Also it can receive bits one at a time, and when it has received a whole byte like that, it can tell the main core that it has a byte read, which then can be read in one go into memory.
swSerial uses the main core for this process, where for transmission the timing sensitivity means that the processors undivided attention is required (interrupts also need to be turned off) and for reception timing it is high interrupt dependant. hwSerial is a lot more reliable at much higher speeds. swSerial on an AVR can run reliably at up to 57600kbps and is fine for for instance MiDi (which runs at 31250kbps) but reception at 115200kbps is not reliable (transmission still is, so if you'd use swSerial to send AT-commands to an ESP-01 which uses 115200 as default BUAD-rate, the first command should be to switch to 9600 or something.)
In most situations a lower speed is fine, at 9600kbps a byte takes just over 1ms to be transmitted and received, and in most applications 20 or 30 ms for a transfer is not a problem. hwSerial is just a lot less CPU intensive, so it is the preferred option if available.
If you are going to use swSerial, let me give you a heads up about what i've experienced. I've fried at least a dozen of ESP-01's with what i suspect was just an unfortunate choice of Pins for it. I used pins 11 & 12, and apparently one those goes HIGH momentarily during boot, and when that happens at the same time that the TX pin goes HIGH, the reverse voltage fries the pin (I think, i mean this is elaboration on things i've read combined with the experience.) The TX pin of the ESP goes HIGH during boot,a nd during TX transmission. It just when it coincides with the UNO pin going HIGH this happens, anyway i ended up using opto-couplers for protection and that worked. so stay away from pins, i think it's 10, 11 and maybe 12.
I have not had any issue using hwSerial on an UNO to connect to an ESP ever though.

Thank you for this information! I tried to do as you said: switch the RX and tx pin so that i know have the esp RX pin to the arduino TX pin through voltage divider. So im using hardware serial. And the esp TX pin is directly to the arduino RX pin. I got it working with using Serial.begin(74880) and then using a program with Serial.println("message from uno").

And in the esp program i read the serial data with this function that i got from the link you sent:

void recvWithEndMarker() {
  static byte ndx = 0;
  char endMarker = '\n';
  char rc;
  while (Serial.available() > 0 && newData == false) {
    rc = Serial.read();

    if (rc != endMarker) {
      receivedChars[ndx] = rc;
      ndx++;
      if (ndx >= numChars) {
        ndx = numChars - 1;
      }
    } else {
      receivedChars[ndx] = '\0';  // terminate the string
      ndx = 0;
    }
  }
}

I realized that I couldn't just use Serial.read() as it read just some number like "103" so I used the function above instead and it works! I have the esp send that read data to my webserver with an HTTP request. And I can see it in the server logs!!!!

Though this function to read the serial data that is coming from the arduino feels a bit unnecessary, but maybe it is the best way.

When i send a string like "Message from uno to esp" from uno to esp via serial, does it send each character individually or does it send an entire array of characters like a string?

Please read again my explanation, it sends individual bits which together form bytes which together can represent a sentence. They are just the bytes, (in ascii) You can send a sentence like that, but if the program at the other end is expecting integers, it can read them as integers, and whatever you've send will make no sense at all. They are just bytes. As long as you interpret what you send correctly it works.

You need to do error checking if you want your program to take action on what is received, things go wrong, this function takes care of quite a lot of possible mishaps, and is 'non-blocking' which means that your receiving program can keep doing what it's doing, like serving a webpage, while the message is being received.

Well you can, and chances are what you may have sent was a 'g', but you need to know in what part of the transmission you are. There are a few other options, you could send just a series of character "HERE" and once you received that, you could read the bytes that come after and do whatever you want with it. It is not quite as reliable as Robin's method, but it may be a bit quicker. In rare cases you may be forced to receive in a blocking way, which in some way is easier to program, so if that circumstance arises, well if you manage this, that'll be easier.

Check out the ESP8266Webserver library and it's examples, you will probably find more of what you may want to do. An ESP-01 is a really great UI

I looked at some the examples but i couldnt understand if this library is used for hosting a server on the arduino or communicating with another server. What I have is a server on a computer and want to send it to that server. Can i use this library for that?

Okay I guess I'll use this function for now as it is working.

I have a question, what happens if the uno sends, say 100 messages a second with Serial.println() and the esp runs the serial.read() 10 times a second, will the "inputbuffer" on the esp get filled up and cause trouble or is this not how it works? This however shouldnt be a problem for me as I will check if there is a message available from the uno and as soon as there is, the esp will immideatly send a message to my server, but im curious anyway.

Okay i see now, I understand know :slight_smile:

No this library is what you think it is for, i just thought it might interest you.

Buffer overflow is always a concern. the Serial (core) library has it's own buffer which i think is 128 bytes, but which you can increase.
Then this method has it's own buffer again, which you can also increase if your complete message wouldn't fit into that.

receivedChars[] 

The Serial object takes care of reading the byte from the UART and storing it in the input buffer. It does this in the background using an interrupt handler.
When you do read(), it reads a byte from that buffer and moves the pointer along to the next byte to be read.
The function

void recvWithEndMarker() {

reads from the input buffer and stores into receivedChars until it receives the endmarker (or receivedChars is full)
One of the possible reasons for using a 'blocking' reception method can be that either the message is so long that you may overflow the input buffer, in that case you want to read the whole thing as it comes in and wait until you've received all. Another can be that whatever else is happening in your program may take such a long time that coming back to 'recvWithEndMarker()' may take to long.
Another possible reason can be that when using swSerial, in combination with a method that disables interrupts (like sending a signal to WS281x LEDs ) you may want to wait until you have completed the reception before to continue.
None of these things apply in your case.