Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for hard reset through dedicated pin. #125

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

phrxmd
Copy link

@phrxmd phrxmd commented Jan 3, 2018

A hard reset (as opposed to a soft reset through the AT+RST command) has the advantage that it works even when the ESP8266 is hung for some reason. This can be used for auto-resetting the ESP8266 by a watchdog, more reliably than through the AT interface.

To use this, you need to wire a dedicated pin of the Arduino to the ESP8266's ̀CH_PD line and #define WL_HARD_RESET_PIN in your code. Take the usual precautions regarding voltage (5V -> 3.3V), just as for the ESP8266's RX pin. If you use the ESP8266 Wifi Shield, that means one extra 1K and 2.2K resistor each, and wiring up CH_PD to an Arduino pin instead of 3.3V.

The rationale for choosing the CH_PD instead of the RST line is explained by the analysis at https://hallard.me/esp8266-autoreset/. The author recommends CH_PD over RST for auto reset because of problems with how the RST line is apparently wired up internally.

Pin 10 is suggested in the code because it works nicely with AltSoftSerial - the library uses pins 8/9 for RX/TX and disables the PWM functionality of pin 10, leaving it usable only for digital I/O - but the specific pin does not really matter.

A hard reset (as opposed to a soft reset through AT+RST) has the advantage that it works even when the ESP8266's AT interface is hung for some reason. This can be used for reliably auto-resetting the ESP8266 by a watchdog.

To use this, wire a dedicated pin of the Arduino to the ESP8266's CH_PD line, and #defining WL_HARD_RESET_PIN somewhere in your code. Take the usual precautions regarding voltage (5V -> 3.3V), just as for the ESP8266's RX pin. The rationale for choosing the CH_PD instead of the RST line is explained by the analysis at https://hallard.me/esp8266-autoreset/. Basically he recommends CH_PD over RST for auto reset, because of problems with how the RST line is wired up internally.
@phrxmd
Copy link
Author

phrxmd commented Jan 3, 2018

Here's a basic wiring diagram for a prototype shield, with a voltage divider on the CH_PD pin.
esp8266-ch-pd_steckplatine

(In the real world one would want to add 10K pull-ups on the CPIO0, CPIO2 and RST pins as well.)

@JAndrassy
Copy link

it would be better to have the option to tell the library to not to do the software reset and handle the hardware rest outside the library. because for example on Uno WiFi the esp2866 CH_EN pin is connected to GPIO pin on I2C UART bridge not to Atmega pin

@phrxmd
Copy link
Author

phrxmd commented Jan 3, 2018

Interesting point about Uno Wifi, but that comes with its own software stack and makes highly specific use of I2C also for a lot of other things. I'm not sure if it makes a good target for a low-level library for the AT command interface. It's also a bit of a niche board.

I guess you could abstract out the reset completely, either by using virtual methods and deriving from the EspDrv class, or by keeping function pointers around:

// Default reset function: soft reset
bool issueSoftReset() {
    issueResetCommand(); // send AT+RST to ESP8266
    cleanUp();
    return true;
}

// Constructors with function parameters
WiFi.init(Stream esp_serial, bool (*resetFunction)() = issueSoftReset) {
    [...] 
    EspDrv::wifiDriverInit(espSerial, resetFunction);
    [...]
}

void EspDrv::wifiDriverInit(Stream *espSerial, bool (*resetFunction)() ) {
    [...]
    _myResetFunction = resetFunction;
}

// Reset method in driver object dynamically calls reset function 
void EspDrv::reset() {
    // call whatever reset function the user specified
    if ((*_myResetFunction)()) {
        doOtherInitializationStuff();
    } else {
        handleError();
    }
}

That way you could reset the ESP8266 any way you like without changing the library at all, but realistically, it looks a bit like overkill... in comparison to a few #ifdef's and like 5 lines of code ;)

I was rather thinking of people like me, who hook up a bunch of $3 ESP-01 boards with stock AT firmares to Arduinos as low-cost Wifi modules. Optional hardware reset through an Arduino pin is a simple way to get a bit more reliability, that's all. I switched to WifiEsp from Jonas Ekstrand's SerialESP8266wifi library and found hardware reset the one feature I was missing.

@JAndrassy
Copy link

off topic: Nothing very special with Uno WiFi. Where you with Uno and esp module use SoftwareSerial, Uno WiFi uses an I2C UART to connect to RX/TX of esp. And CH_EN and GPIO0 are connected to GPIO pins of the I2C UART for reset and reset to bootloader of esp.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants