espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.3k stars 7.35k forks source link

ADC2 Channel cannot be used when WiFi is in use #440

Closed bestpika closed 6 years ago

bestpika commented 7 years ago

When WiFi.begin(...), I can't read all ADC2's channel. All value is incorrect.

image

prices commented 7 years ago

I was just tracking this. I set up a simple circuit with a pot from VCC to GND with the wiper connected to IO34 and IO25. IO34 is ADC1, IO25 is ADC2. I used the following code in the Arduino IDE v1.8.1:

#include "WiFi.h"

unsigned long previousMillis;        // will store last temp was read
uint32_t delayMS;

void setup() {
  Serial.begin(115200);
  // put your setup code here, to run once:
    pinMode(34, ANALOG);
    pinMode(25, ANALOG);
    delayMS = 1000;
    previousMillis = 0;
    WiFi.begin("test", "testpassword");  // Comment this line out and it works.

}

void loop() {
  // put your main code here, to run repeatedly:
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= delayMS) {
        previousMillis = currentMillis;
        Serial.print("ADC1: ");
        Serial.println(analogRead(34));
        Serial.print("ADC2: ");
        Serial.println(analogRead(25));
    }
}

Results with WiFi.begin() in the code (binary size 507808 bytes):

ADC1: 608^M$
ADC2: 4095^M$
ADC1: 610^M$
ADC2: 4095^M$
ADC1: 608^M$
ADC2: 4095^M$
ADC1: 608^M$
ADC2: 4095^M$

Results with WiFi.begin() commented out (binary size 299472 bytes):

ADC1: 609^M$
ADC2: 893^M$
ADC1: 612^M$
ADC2: 894^M$
ADC1: 612^M$
ADC2: 892^M$
ADC1: 608^M$
ADC2: 896^M$

Before testing I completely wiped the flash on the device using

esptool.py --port /dev/ttyUSB0 erase_flash

Let me know if there is any more information you need.

prices commented 7 years ago

I found some information here:

https://github.com/espressif/arduino-esp32/issues/102

The comment is from igrr saying: "This happens because ADC2 pins can not be used when WiFi is used."

I have yet to find confirmation of this in the data sheets, but I am still looking.

prices commented 7 years ago

Seems now I have confirmation that this is not a software bug. It is the chip itself. This will not get fixed in software.

prices commented 7 years ago

It seems that ADC2 is used with WiFi and maybe BlueTooth. That is why it is unavailable. So this might be fixed, but won't be fixed in this software. It will get fixed in the SDK.

https://www.esp32.com/viewtopic.php?t=1822#p10097

copercini commented 6 years ago

Let's concentrate ADC2 conflict with wifi here: https://github.com/espressif/arduino-esp32/issues/440 to keep the things organized =)

prices commented 6 years ago

I am just curious that you said we should concentrate the discussion in this bug, then closed this bug. Did you mean to point to a different bug?

copercini commented 6 years ago

Oh, I linked the wrong issue, this is the correct one (which I think is the same discussion): https://github.com/espressif/arduino-esp32/issues/102 Sorry =)

danielcolchete commented 5 years ago

For the record, resetting registers SENS_SAR_START_FORCE_REG and SENS_SAR_READ_CTRL2_REG to the old values they had before WiFi was turned seem to be a work around for this issue. And will allow you to use ADC2 again after you stop and deinitialize WiFI.

An algorithm here would be something like: old1 <- SENS_SAR_START_FORCE_REG old2 <- SENS_SAR_READ_CTRL2_REG InitWifi StartWifiAndConnect (Do your wifi thing here) StopWifiAndDisconnect DeinitWifi SENS_SAR_START_FORCE_REG <- old1 SENS_SAR_READ_CTRL2_REG <- old1

danielcolchete commented 5 years ago

I forgot to include the SENS_SAR_MEAS_START2_REG register. This one is important too.

Hetric commented 5 years ago

I forgot to include the SENS_SAR_MEAS_START2_REG register. This one is important too.

@danielcolchete, do you have the Arduino code to fix the ADC2 problem by any chance? I'm trying to use Bluetooth to send analog values from ADC2. I have no luck so far.

grasmanek94 commented 4 years ago

ADC2 cannot be used with WiFi or Bluetooth? Well this code just proves that statement wrong!

#define DR_REG_SENS_BASE 0x3ff48800
#define SENS_SAR_START_FORCE_REG (DR_REG_SENS_BASE + 0x002c)
#define SENS_SAR_READ_CTRL2_REG (DR_REG_SENS_BASE + 0x0090)
#define SENS_SAR_MEAS_START2_REG (DR_REG_SENS_BASE + 0x0094)

int pin = 27;
uint64_t reg_a;
uint64_t reg_b;
uint64_t reg_c;

void setup()
{
    reg_a = READ_PERI_REG(SENS_SAR_START_FORCE_REG);
    reg_b = READ_PERI_REG(SENS_SAR_READ_CTRL2_REG);
    reg_c = READ_PERI_REG(SENS_SAR_MEAS_START2_REG);

    Serial.begin(115200);

    btStart();

    PS4.begin("03:03:03:03:03:03");

    WRITE_PERI_REG(SENS_SAR_START_FORCE_REG, reg_a);
    WRITE_PERI_REG(SENS_SAR_READ_CTRL2_REG, reg_b);
    WRITE_PERI_REG(SENS_SAR_MEAS_START2_REG, reg_c);

    pinMode(27, INPUT);
    analogSetPinAttenuation(27, ADC_11db);
}

uint16_t fixedAnalogRead(int pin_number)
{
    WRITE_PERI_REG(SENS_SAR_START_FORCE_REG, reg_a);
    WRITE_PERI_REG(SENS_SAR_READ_CTRL2_REG, reg_b);
    WRITE_PERI_REG(SENS_SAR_MEAS_START2_REG, reg_c);
    return analogRead(pin_number);
}

void Loop()
{
    // do fixedAnalogRead and Bluetooth stuff in Loop. I managed to use my PS4 controller and ADC2 / pin27 on SBC-NodeMCU-ESP32
    if(PS4.isConnected())
    {
        Serial.printf("Connected.. ");
    }
    Serial.printf("%d\r\n", fixedAnalogRead(pin));
    delay(100);
}

When doing a varistor sweep + using a DualShock PS4 controller via bluetooth connected to my ESP32:

Connected.. 0
Connected.. 17
Connected.. 55
Connected.. 93
Connected.. 81
Connected.. 162
Connected.. 200
Connected.. 229
Connected.. 257
Connected.. 304
Connected.. 321
Connected.. 365
Connected.. 410
Connected.. 755
Connected.. 1447
Connected.. 2173
Connected.. 3009
Connected.. 4095
Connected.. 4095
Connected.. 4095
Connected.. 4095
Connected.. 4095
Connected.. 4095
Connected.. 4095
Connected.. 4095
Connected.. 3022
Connected.. 2659
Connected.. 2253
Connected.. 1521
Connected.. 742
michox commented 4 years ago

@grasmanek94 I did this your way, but it won't work. Only after removing the writing of reg_a and reg_c will I get some differing values although they are inverted and only have attenutation of 1db

grasmanek94 commented 4 years ago

In the technical reference you probably can find the registers for the inverted values (something that can be disabled) and also change the attenuation, I think. The code I posted is created from multiple snippets throughout my codebase but simplified, It's possible that I missed analogSetAttenuation (or whatever the function is called).

CarlosGS commented 3 years ago

To fix the inverted values: https://github.com/espressif/arduino-esp32/issues/102#issuecomment-593650746

rrojasn17 commented 2 years ago

ESTO ME FUNCIONO!!!!!!!!!!!

Muchas gracias por los aportes.

Les cuento:

Tengo un ESP32 TTGO HIGROW, necesito leer en pin ADC 15 un sensor de humedad del suelo y enviarlo a mi plataforma IoT, obviamente necesito WiFI para eso.

Aquí mi proyecto: https://github.com/ISProjectsIoTCR/SensorSueloTTGO

Lo hice asÍ:

1-Leer sensores 2-Conectarme al Wifi 3-Desconectar Wifi 4-Ir a dormir esp_deep_sleep_start();

La primer lectura del sensor lo hacía bien, pero despues del lapso en sueño profundo, me disparaba un valor en alto de mi pin analógico. Eso pasa porque despues de usar analogRead iniciaba mi Wifi y modificaba esos registros que se mencionan en este hilo. Aun no entiendo mucho sobre esos regitros pero hice lo que pude leer aquí.

Lo mejoré asÍ:

1-Leer sensores 2-Leer registros 3-Conectarme al Wifi 4-Desconectar Wifi 5-Escribir los registros con los valores originales. 6-Ir a dormir esp_deep_sleep_start();

AL INICIO DEL CODIGO=>

define DR_REG_SENS_BASE 0x3ff48800

define SENS_SAR_START_FORCE_REG (DR_REG_SENS_BASE + 0x002c)

define SENS_SAR_READ_CTRL2_REG (DR_REG_SENS_BASE + 0x0090)

define SENS_SAR_MEAS_START2_REG (DR_REG_SENS_BASE + 0x0094)

DECLARAR VARIABLES GLOBALES "uint64" =>

uint64_t reg_a; uint64_t reg_b; uint64_t reg_c;

JUSTO ANTES DE INICIAR LA CONEXIÓN WIFI=>

reg_a = READ_PERI_REG(SENS_SAR_START_FORCE_REG); reg_b = READ_PERI_REG(SENS_SAR_READ_CTRL2_REG); reg_c = READ_PERI_REG(SENS_SAR_MEAS_START2_REG);

ANTES DE IR A DORMIR=>

WRITE_PERI_REG(SENS_SAR_START_FORCE_REG, reg_a); // fix ADC registers WRITE_PERI_REG(SENS_SAR_READ_CTRL2_REG, reg_b); WRITE_PERI_REG(SENS_SAR_MEAS_START2_REG, reg_c);

Y LISTO!!! FUNCIONÓ

Tobbera commented 2 years ago

I can confirm that this is working as a workaround.

// Initiate Wifi with ADC2 on ESP32 workaround bellow:
#include "soc/sens_reg.h"    // needed for manipulating ADC2 control register
uint32_t adc_register;
uint32_t wifi_register;
// End initiation of Wifi with ADC2 on ESP32 workaround.

setup:
Serial.begin(115200);
  adc_register = READ_PERI_REG(SENS_SAR_READ_CTRL2_REG); // Wifi with ADC2 on ESP32 workaround.
*** Connect WiFi / Bluetooth stuff here ***
  wifi_register = READ_PERI_REG(SENS_SAR_READ_CTRL2_REG); // Wifi with ADC2 on ESP32 workaround.

loop:
  WRITE_PERI_REG(SENS_SAR_READ_CTRL2_REG, adc_register); // Wifi with ADC2 on ESP32 workaround.
  SET_PERI_REG_MASK(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_DATA_INV);// Wifi with ADC2 on ESP32 workaround.
*** Analog read stuff here***
  WRITE_PERI_REG(SENS_SAR_READ_CTRL2_REG, wifi_register); // Wifi with ADC2 on ESP32 workaround.

BUT, its broken in the newer version of ESP32 in arduino. This works on 1.0.3 at the moment. I cant understand why they took it away.