霍尔效应传感器发生变化时,如何唤醒ESP32?

时间:2019-02-03 05:39:20

标签: c++ assembly arduino microcontroller esp32

我正在尝试使用ULP检测ESP32内部霍尔效应传感器读数的变化。

我尝试为ULP编写一些程序集,以从ADC获得4个样本,将它们相加,然后与上一个循环的总和进行比较。如果差异大于宏值(DELTA),则循环结束,CPU唤醒。

到目前为止,这是我的代码:

#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会导致CPU立即唤醒,而与附近的磁体无关,而将其设置为11则会阻止CPU唤醒,即使钕磁体突然施加在ESP32的屏蔽层上也是如此。调整衰减或位深度无法解决此问题。

0 个答案:

没有答案