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

[ESP32-S3] Battery ADC with wi-fi? #87

Closed
nickolay opened this issue Nov 29, 2022 · 8 comments
Closed

[ESP32-S3] Battery ADC with wi-fi? #87

nickolay opened this issue Nov 29, 2022 · 8 comments
Labels
invalid This doesn't seem right

Comments

@nickolay
Copy link

The ESP32-S3 based "T5-4.7 Plus" provides IO14 for reading the battery voltage. In terms of ADC, it is known as ADC2_CH3, and ADC2 is said to be conflicting with wifi operation. Common wisdom on the Internet is to avoid attempting to use channel 2 ADC together with Wi-fi -- I couldn't even find any success reports. The battery examples in this repo are, suspiciously, running with wifi off, and the wifi example doesn't monitor the battery.

Before I spend too much time on this... Did anyone get this working? Could you provide an example?

@lbuque lbuque added the invalid This doesn't seem right label Dec 7, 2022
@lbuque
Copy link
Contributor

lbuque commented Dec 12, 2022

Yes, ADC2 and wifi cannot work at the same time. This is our mistake.

@nickolay
Copy link
Author

Thanks for confirming my findings! Do you know if there's any workaround worth pursuing? Or is it only possible to read battery level after booting the device and before the wi-fi is turned on for the first time?

@lbuque
Copy link
Contributor

lbuque commented Dec 12, 2022

You can turn off the wifi (esp_wifi_stop) before reading the adc value.

@nickolay
Copy link
Author

Good, I'll try that sometime -- thanks again!

@lbuque
Copy link
Contributor

lbuque commented Dec 13, 2022

You can try this code, I found that both wifi and adc2 work fine!

#include <Arduino.h>
#include <WiFi.h>
#include <esp_adc_cal.h>

String sta_ssid = "GL-MT1300-44e";
String sta_pwd = "88888888";
int vref = 1100;
void WiFiEvent(WiFiEvent_t event);
void wifi_init_sta(void);
void getBatteryPercentage();

void setup() {
    Serial.begin(115200);
    delay(10);
    // put your setup code here, to run once:
    wifi_init_sta();
}

void loop() {
    // put your main code here, to run repeatedly:
    getBatteryPercentage();
    delay(1000);
}


void getBatteryPercentage() {
    esp_adc_cal_characteristics_t adc_chars;
    esp_adc_cal_value_t val_type = esp_adc_cal_characterize(ADC_UNIT_2, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_12, 1100, &adc_chars);
    uint32_t v = esp_adc_cal_raw_to_voltage(analogRead(14), &adc_chars);
    float battery_voltage = ((float)v / 1000) * 2;
    Serial.print("ADC RAW: ");
    Serial.println(v);
    Serial.print("Battery voltage: ");
    Serial.println(battery_voltage);
}

void wifi_init_sta(void)
{
    uint8_t mac[6];
    char ssid[32];

    WiFi.disconnect(true);
    delay(1000);

    WiFi.mode(WIFI_AP_STA);
    // WiFi.mode(WIFI_AP);
    Serial.printf("WiFi: Set mode to WIFI_AP_STA\n");

    WiFi.onEvent(WiFiEvent);

    WiFi.begin(sta_ssid.c_str(), sta_pwd.c_str());
}


void WiFiEvent(WiFiEvent_t event)
{
    Serial.printf("[WiFi-event] event: %d\n", event);

    switch (event) {
        case ARDUINO_EVENT_WIFI_READY: 
            Serial.println("WiFi interface ready");
            break;
        case ARDUINO_EVENT_WIFI_SCAN_DONE:
            Serial.println("Completed scan for access points");
            break;
        case ARDUINO_EVENT_WIFI_STA_START:
            Serial.println("WiFi client started");
            break;
        case ARDUINO_EVENT_WIFI_STA_STOP:
            Serial.println("WiFi clients stopped");
            break;
        case ARDUINO_EVENT_WIFI_STA_CONNECTED:
            Serial.println("Connected to access point");
            break;
        case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
            Serial.println("Disconnected from WiFi access point");
            WiFi.begin(sta_ssid.c_str(), sta_pwd.c_str());
            break;
        case ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE:
            Serial.println("Authentication mode of access point has changed");
            break;
        case ARDUINO_EVENT_WIFI_STA_GOT_IP:
            Serial.print("Obtained IP address: ");
            Serial.println(WiFi.localIP());
            break;
        case ARDUINO_EVENT_WIFI_STA_LOST_IP:
            Serial.println("Lost IP address and IP address is reset to 0");
            break;
        case ARDUINO_EVENT_WPS_ER_SUCCESS:
            Serial.println("WiFi Protected Setup (WPS): succeeded in enrollee mode");
            break;
        case ARDUINO_EVENT_WPS_ER_FAILED:
            Serial.println("WiFi Protected Setup (WPS): failed in enrollee mode");
            break;
        case ARDUINO_EVENT_WPS_ER_TIMEOUT:
            Serial.println("WiFi Protected Setup (WPS): timeout in enrollee mode");
            break;
        case ARDUINO_EVENT_WPS_ER_PIN:
            Serial.println("WiFi Protected Setup (WPS): pin code in enrollee mode");
            break;
        case ARDUINO_EVENT_WIFI_AP_START:
            Serial.println("WiFi access point started");
            break;
        case ARDUINO_EVENT_WIFI_AP_STOP:
            Serial.println("WiFi access point  stopped");
            break;
        case ARDUINO_EVENT_WIFI_AP_STACONNECTED:
            Serial.println("Client connected");
            break;
        case ARDUINO_EVENT_WIFI_AP_STADISCONNECTED:
            Serial.println("Client disconnected");
            break;
        case ARDUINO_EVENT_WIFI_AP_STAIPASSIGNED:
            Serial.println("Assigned IP address to client");
            break;
        case ARDUINO_EVENT_WIFI_AP_PROBEREQRECVED:
            Serial.println("Received probe request");
            break;
        case ARDUINO_EVENT_WIFI_AP_GOT_IP6:
            Serial.println("AP IPv6 is preferred");
            break;
        case ARDUINO_EVENT_WIFI_STA_GOT_IP6:
            Serial.println("STA IPv6 is preferred");
            break;
        case ARDUINO_EVENT_ETH_GOT_IP6:
            Serial.println("Ethernet IPv6 is preferred");
            break;
        case ARDUINO_EVENT_ETH_START:
            Serial.println("Ethernet started");
            break;
        case ARDUINO_EVENT_ETH_STOP:
            Serial.println("Ethernet stopped");
            break;
        case ARDUINO_EVENT_ETH_CONNECTED:
            Serial.println("Ethernet connected");
            break;
        case ARDUINO_EVENT_ETH_DISCONNECTED:
            Serial.println("Ethernet disconnected");
            break;
        case ARDUINO_EVENT_ETH_GOT_IP:
            Serial.println("Obtained IP address");
            break;
        default: break;
    }
}

@nickolay
Copy link
Author

Your example seems to work -- in that it reports decreasing voltages (starting with ~ 4.1+V) while on battery, and 4.6V when no battery is connected. (*)

I am confused about the accuracy of these measurements though, given that:

  • I'm not sure what negative effect wi-fi was to have on ADC2 (the docs used to say the reading would "fail" -- could I be seeing results distorted by wifi operation? Should I expect occasional random values?)
  • The other demo advises to use epd_poweron(), followed by a short delay, while the code here just reads the ADC without all the ceremony
  • I don't seem to have the ADC calibration values (though, judging by this graph, the effect should be minor)

I suppose I can just see how it goes, unless you have any additional advice.

Your help so far is very much appreciated. Thank you again!

(*) I didn't know how to view Serial output while not connected via USB, so I had to add log_wifi(String(battery_voltage));, which is defined like below.

void log_wifi(String s) {
    WiFiClient client;
    const int httpPort = 8888;
    String host = "192.168.2.88";
    if (!client.connect(host.c_str(), httpPort)) {
        Serial.println("connection failed");
        return;
    }

    String url = "/?v=" + s;
    Serial.println(url);

    client.print(String("GET ") + url + " HTTP/1.1\r\n" +
                 "Host: " + host + "\r\n" +
                 "Connection: close\r\n\r\n");
    unsigned long timeout = millis();
    while (client.available() == 0) {
        if (millis() - timeout > 5000) {
            Serial.println(">>> Client Timeout !");
            client.stop();
            return;
        }
    }

    while(client.available()) {
        String line = client.readStringUntil('\r');
        Serial.print(line);
    }
}

@random-0110-dude
Copy link

@lbuque Thank you for this example. It works, but it often triggers watchdog and thus a reboot happens. Can it be solved as well?

@berry0511
Copy link

Hello everyone, I would like to ask, if I enable the WiFi function on the ESP32-S3, will it only affect the ADC function, and will the functionality of GPIO/SPI/I2C be affected?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
invalid This doesn't seem right
Projects
None yet
Development

No branches or pull requests

4 participants