Как я могу разбудить ESP32, если на датчике эффекта Холла произошли изменения? - PullRequest
0 голосов
/ 03 февраля 2019

Я пытаюсь обнаружить изменения в показаниях внутреннего датчика Холла ESP32 с использованием ULP.

Я попытался написать некоторую сборку для ULP, чтобы получить 4 образца из АЦП, добавить ихи сравните с суммой предыдущего цикла.Если разница больше, чем значение макроса (DELTA), цикл заканчивается, и процессор просыпается.

Вот мой код:

#include "esp32/ulp.h"
#include "soc/rtc_cntl_reg.h"
#include "driver/rtc_io.h"
#include "driver/adc.h"

#define DELTA 10

void ulp_adc() {
  adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_11);
  adc1_config_width(ADC_WIDTH_BIT_10);
  adc1_ulp_enable();

  rtc_gpio_init(GPIO_NUM_36);

  const ulp_insn_t program[] = { //R0: LOOP HANLDER AND CONDITIONALS R1: NEW VALUE R2: PREVIOUS VALUE R3: ADC BUFFER
    // SETUP
      I_DELAY(32000),        // Wait until ESP32 goes to deep sleep
      //WE NEED TO INITIALIZE THE "PREVIOUS" VALUE TO A FIRST MULTISAMPLE
      I_MOVI(R1, 0),         // INITIALIZE R2 TO 0
      I_MOVI(R0, 0),         // INITIALIZE LOOP COUNTER (R0) TO 0
    M_LABEL(1),              // LABEL 1: INITIAL MULTISAMPLE LOOP
      I_ADC(R3, 0, 0),       // ADC READ TO R3 (TEMP BUFFER) 
      I_ADDI(R1, R1, R3),    // ADD ADC (R3) TO TOTAL (R1)
      I_ADDI(R0, R0, 1),     // COUNTER++
    M_BL(1, 4),              // JUMP BACK TO LABEL 1 UNLESS COUNTER>4
    // MAIN LOOP
    M_LABEL(2),              // LABEL 2: ADC SAMPLE LOOP SETUP
      I_MOVI(R2, R1),         // SET R2 (OLD SAMPLE) TO R1 ("NEW" VALUE)
      I_MOVI(R1, 0),         // SET R1 (NEW SAMPLE) TO 0 (TO PREP FOR ACCUMULATION)
      I_MOVI(R0, 0),         // INITIALIZE LOOP COUNTER (R0) TO 0
      //BEGIN MULTISAMPLING
    M_LABEL(3),              // LABEL 3: ADC MULTISAMPLE LOOP
      I_ADC(R3, 0, 0),       // ADC READ TO R3 (TEMP BUFFER) 
      I_ADDI(R1, R1, R3),    // ADD ADC (R3) TO TOTAL (R1)
      I_ADDI(R0, R0, 1),     // COUNTER++
    M_BL(3, 4),              // JUMP BACK TO LABEL 3 UNLESS COUNTER>4
    //AT THIS POINT R1 IS THE SUM OF 4 ADC SAMPLES
      I_SUBI(R0, R1, R2),    // GET DIFFERENCE FROM NEW SUM AND LAST AND STORE IN R0 FOR CONDITIONALS
    M_BGE(4, 0),             // JUMP OVER THE INVERSION TO LABEL 4 IF WE ALREADY HAVE A POSITIVE VALUE
      I_SUBI(R0, 0, R0),     // R0 = 0 - R0
    M_LABEL(4),              // WE HAVE A POSITIVE VALUE, READY FOR COMPARISON
      I_DELAY(1300000),      // WAIT A LITTLE UNDER 1S, SO THAT EACH SAMPLE IS FAR ENOUGH AWAY FOR A DELTA TO MATTER
    M_BL(2, DELTA),          // JUMP BACK TO THE START IF WE ARE BELOW THE TARGET DELTA
    // END PROGRAM, WAKE MAIN CPU
      I_WAKE(),              // Wake up ESP32
      I_END(),               // Stop ULP program timer
      I_HALT()               // Halt the coprocessor
  };

  size_t size = sizeof(program)/sizeof(ulp_insn_t);
  ulp_process_macros_and_load(0, program, &size);

  ulp_run(0);
  esp_sleep_enable_ulp_wakeup();
  esp_deep_sleep_start();
}


void setup() {
  Serial.begin(115200);
  adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_11);
  adc1_config_width(ADC_WIDTH_BIT_10);

  Serial.println(adc1_get_raw(ADC1_CHANNEL_0));
}

void loop() {
  ulp_adc();
}

Установка DELTA в10 заставляет ЦП мгновенно просыпаться независимо от соседних магнитов, а установка на 11 предотвращает пробуждение ЦП, даже когда неодимовый магнит внезапно прикладывается к экранированию ESP32.Регулировка затухания или битовой глубины не смогла это исправить.

...