Connecting the ESP8266 chip to your network
I’m working on a project to automate our chicken coop (see my article Getting over myself and doing things the easy way for more details on the project). Right now, the lights open and close by themselves: it needed to be done now since the chickens had trouble laying eggs with our short Fall days. The current system uses an Arduino Uno, a real-time clock module with the DS1307 chip and an analog dimmer. You can see the code for this version on GitHub :
https://github.com/CindyPotvin/Chickmatic/tree/master/Phase1-ScheduleTime
I’m working on the second phase: being able to change the schedule directly from our phones and gather weather data from inside and outside the coop. My plan is to use the Arduino I already have to gather data and control the dimmer, and add a ESP8266 chip to connect this system to our home network.
Another server inside the house, probably a Raspberry Pi, will be used to host a small web application in NodeJS that will save the schedule and weather data. This is also in progress on GitHub at :
https://github.com/CindyPotvin/Chickmatic/tree/master/WebServer
To get started, I had to figure out how to connect to the network using the ESP8266. I purchased a cheap, poorly-documented board (the ESP13 by doit.am) that mounts the chip as an Arduino shield so they can be stacked:
Here are where the problems started. Because of the form factor, I thought I could make HTTP requests from the Arduino, and the ESP8266 would be a dumb chip that transmitted the request.
That’s far from the truth: the ESP8266 is also a microcontroller and it has to also be programmed. It comes preloaded with some strange chinese firmware that I could use to see if the board works, but not much else. Fortunately, it can also be programmed using the Arduino IDE and there are some nice examples, so I could start from there.
Unfortunately, it’s not that easy to program the chip directly since it doesn’t have its own USB port. There are all kinds of suggestions online on how to bypass the Arduino and use its USB port to program the chip, but it never worked and I would always get the following errors:
warning: espcomm_sync failed
error: espcomm_open failed
TL;DR The only way I found to program the ESP8266 easily was to use a 3.3V FTDI cable I bought on eBay for a few dollars, pull the digital pin 0 to ground (as stated in the documentation for the ESP8266), reboot and then I was good to go. Don’t waste time like it did.
Good to go for a few minutes, that is. After connecting just fine to the network for the first time and congratulating myself on my success, I never could connect a second time using the same code. After much experimentation, I found that the best way to make sure it always worked was to disconnect from the network and then reconnect while the chip is booting. Here is what my setup looks like for the ESP8266:
void setup() { Serial.begin(115200); // WiFi.disconnect(); // Made things work because memory was corrupted but is not needed, see EDIT below WiFi.persistent(false); Serial.print("Connecting"); WiFi.begin(/*username*/,/*password*/); // Username/password not required after the first time, saved to flash while (WiFi.status() != WL_CONNECTED) { delay(5500); Serial.print("status"); Serial.println(WiFi.status()); } Serial.println(" connected"); Serial.println(WiFi.localIP()); }
So, I’m finally ready to get started coding now that I’ve proved that I can connect to my network. To be more precise, I want to use the I2C bus to connect the Arduino and the ESP8266 together using the Wire library. The ESP8266 will send all the HTTP requests and parse the responses. This will leave the standard serial ports free so I can debug and program both chips without unplugging everything each time.
Seems logical to me, but the shield doesn’t wire the I2C bus for the Arduino and the ESP8266 together, only the serial port. I can’t just wire them myself since the ESP8266 works with 3.3V logic levels while the Arduino works with 5V. I need to have a logic level shifter, like what they did on the shield with the serial ports (the blue dip switches are used to toggle between programming the chip and linking the chips together). It can work for a little while if I cheat and connect them anyway, but it will eventually fry the ESP8266.
Since I really want to keep the serial ports for debugging and because the shield doesn’t really add much to the project after all, I ordered a new ESP8266 off eBay that’s only the chip mounted on a board with the I2C port exposed, along with an order for a few level shifters. It took a while to find a good board: many of the cheap models only expose the serial ports while I wanted a bit more. I’m still wanting for the new chips to show up in the mail, so stay tuned!
EDIT: following Ken’s comment, I tried to clear the ESP8266 memory using his sketch at https://github.com/kentaylor/EraseEsp8266Flash, and indeed it now works property.
It makes a lot of sense: I tried the disconnect() because I read somewhere that the connection was persistent, so I figured it couldn’t hurt to try disconnecting, but I did not realize I could clear the flash instead. I can’t tell when the memory got corrupted: I tried many examples I found lying around on the Internet before reaching this point.
He also made me realize I won’t need the Arduino anymore. I was stuck with the idea that it would be a hassle to plug the dimmer (controlled by a digital signal) and the real-time clock to the ESP8266, but it shouldn’t be too hard. I’ll need to use the I2C for the clock, but the library handles everything.
Don’t hesitate to tell me if I do something else that’s wrong: I’m an amateur at best when it comes to electronics. I occasionally write about my experiments, but the results are far from production-ready.
Ken Taylor
November 16, 2016 @ 19:47
There is more misinformation on the ESP8226 than good and this article just makes things that little bit worse. So looking at the code sample:-
WiFi.disconnect(); // Required or it won’t always reconnect to wifi
Comment: WiFiDisconnect() is not useful unless you really want to disconnect.
WiFi.persistent(false);
Comment: Means do not save the WiFi credentials for automatic connection on subsequent reboots.
WiFi.begin(/*username*/,/*password*/);
Comment: You only need to call this once, ever, but calling after every boot does no harm. WiFi credentials are saved in flash and are not overwritten by uploading a new sketch. On subsequent reboots the WiFi connectivity process starts before user code is started and this function call does nothing unless the parameters are different to those already stored.
Being unable to connect normally can occur if you have corrupted the flash. The corruption is persistent across reprogramming and if this occurs the flash needs to be flushed. A sketch that will do that is at https://github.com/kentaylor/EraseEsp8266Flash
I would implement your whole project on the ESP but if you don’t intend to do that then from the original modules Tindie page at https://www.tindie.com/products/doit/esp8266-esp-13-wifi-web-sever-shield-for-arduino/ “The module shield can be used as an independent ESP8266 development board. for instance, downloading the official AT commands firmware” and this would probably work best for you.
Using an I2C bus to link modules seems like hard work to me , you say without level shifters “it will eventually fry the ESP8266” but that is not the case.
fernando
January 5, 2017 @ 18:49
Ken, thanks. I have open a issue in WifiManager library. Please, tell us what do you think about using persistent(false) in WifiManager, I have read this:
“Setting persistent to false will get SSID / password written to flash only if currently used values do not match what is already stored in flash.”
So I think it will be better to have over “not to have”; won’t it ???
issue: https://github.com/tzapu/WiFiManager/issues/242#issuecomment-270690584