ESP32 срабатывание прерывания кнопки при analogRead

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

На ESP32 стоят три кнопки (счетчики) при нажатии которых срабатывают прерывания, а также 4 аналоговых датчика, с которых по времени считываются значения. При analogRead срабатывают прерывание на кнопках, пины которых также завязаны на ADC2, кнопка которая на ADC1 и где сами аналоговые датчики такой проблемы не имеют.

Перечитал интернет, попробовал использование библиотеки driver/adc.h - не помогло. Как вариант перенести эти две кнопки на другие пины, не ADC, но все равно любопытно как это победить.

Просьба подсказать есть ли возможность отключить ADC2 совсем? - вдруг поможет.

#include <driver/adc.h>

#define d1s_pin 25
#define d2s_pin 26
#define timeDebounceSensor 1000UL
unsigned long timerD1s, timerD2s;
byte flD1s = 0, flD2s = 0;
byte valD1s = 0, valD2s = 0;

#define wifi_sw_pin 32
unsigned long timerWiFiKey; // таймер ожидания нажатия кнопки
byte keyWiFiPress = 0; // флаг нажатия кнопки

#define power_calc_pin 33
#define timeDebouncePower 2000UL
unsigned long timerPowerCalc;
byte flPowerCalc = 0;
byte valPowerCalc = 0;

#define a1p_pin 34
#define a2p_pin 35
#define a3p_pin 36
#define a4p_pin 39
word valA1p, valA2p, valA3p, valA4p;
#define periodGetAnalogData 9687UL
unsigned long timerGetAnalogData;

char deviceid[] = "317"; // уникальный идентификатоp устройства

unsigned long currentMillis; // главный таймер

byte deviceMode; // режимы работы

void setup() {
  Serial.begin(115200); Serial.println("Reset Serial");
  delay(500); // пауза
  // put your setup code here, to run once:
  pinMode(d1s_pin, INPUT_PULLUP); pinMode(d2s_pin, INPUT_PULLUP);
  pinMode(wifi_sw_pin, INPUT_PULLUP); pinMode(power_calc_pin, INPUT_PULLUP);
  //analogReadResolution(10); analogSetAttenuation(ADC_11db);
  /*pinMode(a1p_pin, INPUT);  pinMode(a2p_pin, INPUT);
  pinMode(a3p_pin, INPUT);  pinMode(a4p_pin, INPUT);*/
  /*adcAttachPin(a1p_pin); adcAttachPin(a2p_pin);
    adcAttachPin(a3p_pin); adcAttachPin(a4p_pin);
    adcStart(a1p_pin); adcStart(a2p_pin); adcStart(a3p_pin); adcStart(a4p_pin);*/
  adc1_config_width(ADC_WIDTH_BIT_10);
  adc1_config_channel_atten(ADC1_CHANNEL_6, ADC_ATTEN_DB_11); // GPIO34
  //adc2_config_width(ADC_WIDTH_BIT_10);
  adc2_config_channel_atten(ADC2_CHANNEL_4, ADC_ATTEN_DB_11); // GPIO13
  deviceMode = 0;
  attachInterrupt(d1s_pin, isr_d1s, FALLING);
  attachInterrupt(d2s_pin, isr_d2s, FALLING);
  attachInterrupt(power_calc_pin, isr_power_calc, FALLING);
  Serial.println("Start"); // запустились
}

void loop() {
  currentMillis = millis();
  // put your main code here, to run repeatedly:
  // read key set wifi
  if ((!digitalRead(wifi_sw_pin)) && ((deviceMode == 0) || (deviceMode == 4))) {
    // если кнопка нажата
    if (keyWiFiPress) { // и до этого была нажата
      if ((currentMillis - timerWiFiKey) >= 5000UL) { // аж 5 секунд
        deviceMode = 1; // переходим в режим точки доступа для ввода данных wifi сети
        delay(1000);
      }
    } else {
      Serial.println("Key pressed");
      keyWiFiPress = 1;
      timerWiFiKey = currentMillis;
    }
  } else {
    keyWiFiPress = 0;
  }
  // process ISR
  if (flD1s)
    if ((currentMillis - timerD1s) >= timeDebounceSensor) {
      timerD1s = currentMillis;
      flD1s = 0;
      Serial.println(1);
      attachInterrupt(d1s_pin, isr_d1s, FALLING);
    }
  if (flD2s)
    if ((currentMillis - timerD2s) >= timeDebounceSensor) {
      timerD2s = currentMillis;
      flD2s = 0;
      Serial.println(2);
      attachInterrupt(d2s_pin, isr_d2s, FALLING);
    }
  if (flPowerCalc)
    if ((currentMillis - timerPowerCalc) >= timeDebouncePower) {
      timerPowerCalc = currentMillis;
      flPowerCalc = 0;
      Serial.println(3);
      // save to EEPROM
      // end save
      attachInterrupt(power_calc_pin, isr_power_calc, FALLING);
    }
  if ((currentMillis - timerGetAnalogData) >= periodGetAnalogData) {
    timerGetAnalogData = currentMillis;
    /*valA1p = analogRead(a1p_pin); valA2p = analogRead(a2p_pin);
      valA3p = analogRead(a3p_pin); valA4p = analogRead(a4p_pin);*/
    valA1p = adc1_get_raw(ADC1_CHANNEL_6); // GPIO34
    Serial.print(valA1p); Serial.print(" "); Serial.print(valA2p); Serial.print(" ");
    Serial.print(valA3p); Serial.print(" "); Serial.println(valA4p);
  }
}

void isr_d1s() {
  detachInterrupt(d1s_pin); flD1s = 1; ++valD1s;
}

void isr_d2s() {
  detachInterrupt(d2s_pin); flD2s = 1; ++valD2s;
}

void isr_power_calc() {
  detachInterrupt(power_calc_pin); flPowerCalc = 1; ++valPowerCalc;
}

 

Reset Serial
Start
509 0 0 0
1
2
511 0 0 0
1
2
522 0 0 0
1
2
508 0 0 0
1
2
508 0 0 0
1
2
511 0 0 0
1
2
509 0 0 0
1
2
494 0 0 0
1
2
509 0 0 0
1
2
509 0 0 0
1
2
508 0 0 0
1
2
505 0 0 0
1
2
508 0 0 0
1
2
497 0 0 0
1
2
508 0 0 0
1
2
508 0 0 0
1
2
508 0 0 0
1
2
509 0 0 0
1
2
509 0 0 0
1
2
508 0 0 0
1
2
510 0 0 0
1
2
510 0 0 0
1
2
509 0 0 0
1
2
509 0 0 0
1
2
510 0 0 0
1
2
511 0 0 0
1
2
511 0 0 0
1
2
516 0 0 0
1
2
508 0 0 0
1
2
508 0 0 0
1
2
511 0 0 0
1
2
508 0 0 0
1
2
511 0 0 0
1
2
510 0 0 0
1
2
511 0 0 0
1
2
508 0 0 0
1
2
519 0 0 0
1
2
508 0 0 0
1
2
508 0 0 0
1
2
510 0 0 0
1
2
503 0 0 0
1
2
523 0 0 0
1
2
510 0 0 0
1
2
482 0 0 0
1
2
510 0 0 0
1
2
509 0 0 0
1
2
508 0 0 0
1
2
509 0 0 0
1
2
508 0 0 0
1
2
508 0 0 0
1
2
496 0 0 0
1
2
509 0 0 0
1
2

 

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Это видели :

  1. ADC2 используется драйвером Wi-Fi. Поэтому приложение может использовать ADC2, только если драйвер Wi-Fi не запущен.
andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

brokly пишет:

Это видели :

  1. ADC2 используется драйвером Wi-Fi. Поэтому приложение может использовать ADC2, только если драйвер Wi-Fi не запущен.

нет, наверное плохо смотрел, спасибо. Запущу WiFi и проверю.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Включение и работа с WiFi не помогло, чтение аналоговых датчиков запускает прерывания на пинах. Перенес кнопки на GPIO22 и 23.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Там наоборот сказано, что можно юзать только при выключеном вайвае.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

И так и так пробовал, вообще не понятная ситуация. И западные сайты форумы как смог (слаб в английском) прошерстил. Максимум что нашёл - люди отключают все прерывания на время чтения аналоговых датчиков. Но в данной задаче это непремлимо.

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Я думаю это связано со встроеными емкостными сенсорами. Нужно этот момент ковырять.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

на GPIO 25 26 нет Touch интерфейса, но в любом случае попробовал, не помогло

#include <driver/dac.h>
#include <soc/touch_channel.h>



  dac_output_disable(DAC_CHANNEL_1);
  dac_output_disable(DAC_CHANNEL_2);
  touch_pad_intr_disable();

 

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Может питание скачет. Ноги подтянуть PULLUP/PULLDOWN ?

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

brokly пишет:

Может питание скачет. Ноги подтянуть PULLUP/PULLDOWN ?

ну нет, все подтянуто, на других пинах такого нет, опять же прямая зависимость - запускаю команду AnalogRead - срабатывают прерывания на GPIO25 и 26. Выше скетч, даже паяь ничего не надо - загрузить в ESP32 и в мониторе будет видно.

Update: обуяло любопытство, вытащил МК из панельки/платы тестового стенда, запустил тестовый скетч, чуда не случилось :(

Reset Serial
Start
0 0 0 0
1
2
0 0 0 0
1
2