ESP8266: "It don't come easy!"

Posted by: Dave Vandenbout 2 years, 6 months ago


Nobody ever accused Ringo of being the smartest Beatle, but he sure nailed that particular bit of philosophy: It don't come easy! Not only when singing the blues, but for pretty much everything else as well. I found that out first-hand.

After building my ESP8266 protoboard, my next task was to recompile the VHDL of the ZPUino to add another serial port for communicating with the Wifi module. The microcontroller core in the ZPUino can be augmented with Wishbone-compatible peripherals that communicate with the core through a set of sixteen slots. One slot is already occupied by a UART that's used to talk to the ZPUino IDE running on the PC, so it was just a matter of instantiating another UART in an empty slot. Easy enough.

Once the ZPUino VHDL was recompiled and downloaded to the XuLA board, it was all down to the programming. Getting access to the second serial port requires a single declaration:

HardwareSerial esp8266(2);  // Find the second UART attached to the ESP8266 module.

This causes the ZPUino to scan through the sixteen slots and query the identifier of every device it finds. Once it finds the second UART, it maps the register address space of the device to the esp8266 object.

The ZPUino also supports a feature called Peripheral Pin Select (PPS). This allows the assignment in software of a peripheral's I/O signals to any of the physical I/O pins of the ZPUino. Connecting the transmit and receive pins of the UART to the receive and transmit pins of the ESP8266 module is done like this:

esp8266.begin(115200, TX(3), RX(17)); // Set bit-rate and assign transmit and receive pins.

(I had previously mapped-out that I/O pins 3 and 17 of the ZPUino exited the XuLA board, traversed the StickIt! board, exited through the PM2 connector, entered my protoboard, and terminated on the serial receive and transmit pins of the ESP8266 module.)

I made these small changes to an existing program that uses the ESP8266 module to load a version of the hackaday website. I compiled and downloaded the program to my ZPUino and ...


OK, it was unreasonable to expect that was going to work. So I started tracing out the problems. First, I needed to make sure the PPS mapping was OK. I attached an LED to the FPGA pin that outputs the serial datastream to the ESP8266 module. It came on, which is good because that shows the output is active. (If I had messed up the PPS assignment, the pin would have been in a high-impedance mode and the LED would have been off.)

Next, I slowed the tranmission rate from 115200 down to 300 bits per second. That would allow me to see the LED flickering as the serial data was transmitted. Unfortunately, the LED stayed on solidly when I executed the program. So the program wasn't accessing the second serial port.

With the help of some ZPUino library routines that check the status of devices, I found the second serial port wasn't getting assigned and its register space wasn't mapped. Poking through the library code, I found an error that skipped any duplicate device after the first had been mapped. Since the ESP8266 serial port was the second UART, it was just ignored.

After correcting my copy of the library (and filing a bug report with the ZPUino's author), I recompiled the program and ...

Success! The LED flickered, showing that serial data was getting to the ESP8266 module.

Restoring the transmission rate back to 115200 bps and executing the program again brought some results that resembled my initial tests of the ESP8266 module using the C232HM cable. The module reset and firmware version commands were eliciting the correct responses, but the connection to the website was still failing.

By echoing the commands back to the terminal on the PC, I could see the connection wasn't being made because the IP address and other pieces of information weren't getting inserted into the command strings. After running a few simple tests, I found the String class wasn't operating as it should: creation and concatenation operations were just returning empty strings. Looking through the library code again, I found the realloc subroutine was just a stub that always returned a NULL pointer. (This was probably a placeholder and the originator never got around to replacing it with something that functioned.) I wrote a naive implementation and sent another bug report.

Now when I recompiled and ran my code, the correct command strings were generated but it still wasn't connecting and was sometimes responding Busy... when commands were sent. At this point, I went to the ESP8266 forum to see if more experienced users had some wisdom. There I found mention of the Busy... prompt coming from the ESP8266, indicating it was still working on a previous operation and could not accept a new command string. I also saw that tying the reset, chip-select, and general-purpose I/O pins to 3.3V was thought to make the chip act more reliably.

So I went back and modified my protoboard to tie those pins high and then re-ran the program ...

No change. The same errors occurred.

At this point I couldn't figure out why some commands worked when I typed them in manually through the C232HM cable, but wouldn't work when the ZPUino sent the same commands (e.g., the AT+CWLAP for listing any in-range access points). The only difference was that I entered the commands much more slowly. So I modified my program to put a five-second delay between each command transmission and ran it ...

Success! It connected to the website and retrieved the HTML for the page. You can see a trace of the commands and responses here.

Now it was just a matter of reducing the delays to their minimum values and removing any unneeded delays between commands. In the end, only three delays remained: a two-second delay before the access points were listed, a four-second delay after the Wifi connection was made, and a final two-second delay after establishing the TCP link to the website. The finished program can be seen here.

I hope this helps some others get their ESP8266 modules working. Most of my problems were caused by the ZPUino libraries, but the ESP8266 is still finicky about how you talk to it. However, I was still able to get it to work with the stock firmware that came loaded on it. My next job is to update the firmware and see what effect that has.

Until then, take us out, Ringo!

Current rating: 5


  • Francois Charbonneau 2 years, 3 months ago

    Hello Dave,

    Great post, as usual! I am trying to replicate some of your steps for a different purpose but I still need to get the UART to work and it seems I'm running into very similar issues. Would you care to elaborate on the bugs you found inside the ZPUino libraries. I'm digging through it at this very moment and I have a feeling it might be the same exact problem, I just haven't found it yet.


    Link / Reply
  • Dave Vandenbout 2 years, 3 months ago

    I found an error when I ran the following code. The second serial port never registers:

    HardwareSerial Serial(1);
    HardwareSerial Serial1(2);

    The only way to register both serial ports is:

    HardwareSerial Serial(1);
    HardwareSerial Serial1(1); // or HardwareSerial Serial1(0xff) also works.

    I had another problem with creating strings. There was a problem with the memory allocation code.

    I sent some potential fixes for these problems. You can look at them here:

    Link / Reply

New Comment

required (not published)

Recent Posts






RSS / Atom