boarchuz / HULP

ESP32 ULP Coprocessor Helper
MIT License
183 stars 19 forks source link

Possible confrontation with some libraries #19

Closed freetoair closed 2 years ago

freetoair commented 2 years ago

This is not an issue but it could indicate that there is a problem. Here's what it's all about: I have completed one small program that finds the min and max sine waves sampled by the ADC converter on the input GPIO34. That program is run by a ULP co-processor and everything is fine. However when I add that program to the existing ESP32 program, for WiFi connection and tracking results, I get completely irrelevant values ​​from ULP. Of course, I first suspected WiFi, and then added the ULP program to one of the examples for the ESP32 wifi server. Except that you have to add a small 330pF capacitor between the ADC inputPIN and ground, everything else works great. I use several libraries to run the main program and I can't guess which one has an impact on the ULP program. To analyze this, I could somehow get data on how the ULP program and the variables arranged in memory. Is it possible to extract this from the compilation files?

regards, freetoair

boarchuz commented 2 years ago

Hi @freetoair, It would be really helpful if you could strip away as much as possible until you're left with the bare minimum to reproduce the issue. My money would be on WiFi too - does it help at all with adc_power_acquire(); (without releasing)? What irrelevant values are you seeing? Too high? low? 0?

freetoair commented 2 years ago

Yes, I went that route too. I'm trying to take a few steps back and define exactly where the problem is. But in the meantime, I would like you to look at one fact that appears. Namely, there are two .ino files attached. In the first, everything is fine, but in the second, after the compilation, a message appears that is quite unusual. However, after that message, ESP32 connects to the local network and everything is fine. Maybe that will help to find the cause of this behavior later.

#include "hulp_arduino.h"
#define PIN_ADC_PIN2    GPIO_NUM_34
#define EQU_COUNT    20
#define PIN2_OVERSAMPLE_SHIFT 4

long valueNEW = 0;
long valueOLD = 0;

RTC_DATA_ATTR struct {
  ulp_var_t valueNEW;
  ulp_var_t valueOLD;
  ulp_var_t valueCOUNT;
  ulp_var_t MAXvalue;
  ulp_var_t MINvalue;
  ulp_var_t DIFvalue;
  ulp_var_t zeroLEVEL;
} ulp_vars;

void ulp_init()
{
  enum {
    LBL_START,
    LBL_PIN2_OVERSAMPLE_LOOP,
    LBL_LOWER,
    LBL_LOOP,
    LBL_FINISH,
    LBL_CHECK,
    LBL_COUNT_UPDATE,
    LBL_UPDATE_MIN_MAX
  };

  const ulp_insn_t program[] = {

    M_LABEL(LBL_START),
    I_MOVI(R0, EQU_COUNT),
    I_MOVI(R3, 0),                       // else
    I_PUT(R0, R3, ulp_vars.valueCOUNT),

    M_LABEL(LBL_LOOP),
    I_STAGE_RST(),
    I_MOVI(R3, 0),
    M_LABEL(LBL_PIN2_OVERSAMPLE_LOOP),
    I_ANALOG_READ(R1, PIN_ADC_PIN2),
    I_ADDR(R0, R0, R1),
    I_STAGE_INC(1),
    M_BSLT(LBL_PIN2_OVERSAMPLE_LOOP, (1 << PIN2_OVERSAMPLE_SHIFT)),
    I_RSHI(R0, R0, PIN2_OVERSAMPLE_SHIFT),
    I_MOVI(R3, 0),
    I_PUT(R1, R3, ulp_vars.valueNEW),

//    I_GPIO_SET(GPIO_NUM_14, 1),//This produces 1.43 uS pulse
//    I_GPIO_SET(GPIO_NUM_14, 0),// for test, nothing else !

    I_MOVI(R3, 0),
    I_GET(R2, R3, ulp_vars.valueOLD),
    I_SUBR(R0, R1, R2),                  // if valueNEW > valueOLD & direc = 1 goto FINISH
    M_BXZ(LBL_CHECK),                  // if lower goto check monotony

    M_LABEL(LBL_FINISH),
    I_MOVI(R3, 0),
    I_GET(R0, R3, ulp_vars.valueNEW),
    I_MOVI(R3, 0),
    I_PUT(R0, R3, ulp_vars.valueOLD),
    M_BX(LBL_LOOP),

    M_LABEL(LBL_CHECK),
    I_MOVI(R3, 0),                       // else
    I_GET(R0, R3, ulp_vars.valueCOUNT),
    I_SUBI(R0, R0, 1),
    M_BL(LBL_COUNT_UPDATE, EQU_COUNT),

    I_MOVI(R3, 0),                       //
    I_GET(R0, R3, ulp_vars.valueNEW),    //
    M_BL(LBL_LOWER,1825),

    I_MOVI(R3, 0),                       // else
    I_GET(R1, R3, ulp_vars.valueNEW),
    I_MOVI(R3, 0),                       //
    I_PUT(R0, R3, ulp_vars.MAXvalue),    // change MINvalue to valueNEW
    M_BX(LBL_UPDATE_MIN_MAX),

    M_LABEL(LBL_LOWER),
    I_MOVI(R3, 0),                       // else
    I_GET(R1, R3, ulp_vars.valueNEW),
    I_MOVI(R3, 0),                       //
    I_PUT(R0, R3, ulp_vars.MINvalue),    // change MINvalue to valueNEW
    M_BX(LBL_UPDATE_MIN_MAX),

    M_LABEL(LBL_COUNT_UPDATE),
    I_MOVI(R3, 0),                       // else
    I_PUT(R0, R3, ulp_vars.valueCOUNT),
    M_BX(LBL_LOOP),

    M_LABEL(LBL_UPDATE_MIN_MAX),
    I_MOVI(R3, 0),                       //
    I_GET(R0, R3, ulp_vars.MAXvalue),
    I_MOVI(R3, 0),                       //
    I_GET(R1, R3, ulp_vars.MINvalue),
    I_SUBR(R2,R0,R1),
    I_MOVI(R3, 0),                       // else
    I_RSHI(R0, R2, 4),
    I_PUT(R0, R3, ulp_vars.DIFvalue),
    I_RSHI(R2, R2, 1),
    I_ADDR(R0,R1,R2),
    I_MOVI(R3, 0),                       // else
    I_PUT(R0, R3, ulp_vars.zeroLEVEL),
    M_BX(LBL_START),
  };
  ESP_ERROR_CHECK(hulp_configure_pin(GPIO_NUM_14, RTC_GPIO_MODE_OUTPUT_ONLY, GPIO_FLOATING, 1));
  //ESP_ERROR_CHECK(hulp_configure_pin(GPIO_NUM_34, RTC_GPIO_MODE_INPUT_ONLY, GPIO_FLOATING, 1));
  ESP_ERROR_CHECK(hulp_configure_analog_pin(PIN_ADC_PIN2, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_12));
  //ESP_ERROR_CHECK(hulp_ulp_load(program, sizeof(program), 1000UL * ULP_WAKEUP_INTERVAL_MS, 0));
  size_t size = sizeof(program) / sizeof(ulp_insn_t);
  ESP_ERROR_CHECK(ulp_process_macros_and_load(0, program, &size));
  ESP_ERROR_CHECK(hulp_ulp_run(0));
}

void setup()
{
  Serial.begin(115200);
  if (hulp_is_deep_sleep_wakeup())
  {
    Serial.print("Wakeup !");
  }
  else
  {
    ulp_init();
  }
}

void loop() {
// valueNEW = ulp_vars.valueNEW.val;
//  Serial.println(ulp_vars.valueNEW.val);
//  Serial.println(ulp_vars.valueOLD.val);
//  Serial.println(ulp_vars.direc.val);
//  Serial.println(ulp_vars.MAXvalue.val);
//  Serial.println(ulp_vars.zeroLEVEL.val);
  Serial.println(ulp_vars.DIFvalue.val);
  Serial.println();
}


#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>

const char* ssid = "xxxxxxxxxxxxx";
const char* password = "xxxxxxxxx";

WebServer server(80);

const int led = 13;

#include "hulp_arduino.h"
#define PIN_ADC_PIN2    GPIO_NUM_34
#define EQU_COUNT    20
#define PIN2_OVERSAMPLE_SHIFT 4

long valueNEW = 0;
long valueOLD = 0;

RTC_DATA_ATTR struct {
  ulp_var_t valueNEW;
  ulp_var_t valueOLD;
  ulp_var_t valueCOUNT;
  ulp_var_t MAXvalue;
  ulp_var_t MINvalue;
  ulp_var_t DIFvalue;
  ulp_var_t zeroLEVEL;
} ulp_vars;

void ulp_init()
{
  enum {
    LBL_START,
    LBL_PIN2_OVERSAMPLE_LOOP,
    LBL_LOWER,
    LBL_LOOP,
    LBL_FINISH,
    LBL_CHECK,
    LBL_COUNT_UPDATE,
    LBL_UPDATE_MIN_MAX
  };

  const ulp_insn_t program[] = {

    M_LABEL(LBL_START),
    I_MOVI(R0, EQU_COUNT),
    I_MOVI(R3, 0),                       // else
    I_PUT(R0, R3, ulp_vars.valueCOUNT),

    M_LABEL(LBL_LOOP),
    I_STAGE_RST(),
    I_MOVI(R3, 0),
    M_LABEL(LBL_PIN2_OVERSAMPLE_LOOP),
    I_ANALOG_READ(R1, PIN_ADC_PIN2),
    I_ADDR(R0, R0, R1),
    I_STAGE_INC(1),
    M_BSLT(LBL_PIN2_OVERSAMPLE_LOOP, (1 << PIN2_OVERSAMPLE_SHIFT)),
    I_RSHI(R0, R0, PIN2_OVERSAMPLE_SHIFT),
    I_MOVI(R3, 0),
    I_PUT(R1, R3, ulp_vars.valueNEW),

//    I_GPIO_SET(GPIO_NUM_14, 1),//This produces 1.43 uS pulse
//    I_GPIO_SET(GPIO_NUM_14, 0),// for test, nothing else !

    I_MOVI(R3, 0),
    I_GET(R2, R3, ulp_vars.valueOLD),
    I_SUBR(R0, R1, R2),                  // if valueNEW = valueOLD & direc = 1 goto FINISH
    M_BXZ(LBL_CHECK),                  // if lower goto check monotony

    M_LABEL(LBL_FINISH),
    I_MOVI(R3, 0),
    I_GET(R0, R3, ulp_vars.valueNEW),
    I_MOVI(R3, 0),
    I_PUT(R0, R3, ulp_vars.valueOLD),
    M_BX(LBL_LOOP),

    M_LABEL(LBL_CHECK),
    I_MOVI(R3, 0),                       // else
    I_GET(R0, R3, ulp_vars.valueCOUNT),
    I_SUBI(R0, R0, 1),
    M_BL(LBL_COUNT_UPDATE, EQU_COUNT),

    I_MOVI(R3, 0),                       //
    I_GET(R0, R3, ulp_vars.valueNEW),    //
    M_BL(LBL_LOWER,1825),

    I_MOVI(R3, 0),                       // else
    I_GET(R1, R3, ulp_vars.valueNEW),
    I_MOVI(R3, 0),                       //
    I_PUT(R0, R3, ulp_vars.MAXvalue),    // change MINvalue to valueNEW
    M_BX(LBL_UPDATE_MIN_MAX),

    M_LABEL(LBL_LOWER),
    I_MOVI(R3, 0),                       // else
    I_GET(R1, R3, ulp_vars.valueNEW),
    I_MOVI(R3, 0),                       //
    I_PUT(R0, R3, ulp_vars.MINvalue),    // change MINvalue to valueNEW
    M_BX(LBL_UPDATE_MIN_MAX),

    M_LABEL(LBL_COUNT_UPDATE),
    I_MOVI(R3, 0),                       // else
    I_PUT(R0, R3, ulp_vars.valueCOUNT),
    M_BX(LBL_LOOP),

    M_LABEL(LBL_UPDATE_MIN_MAX),
    I_MOVI(R3, 0),                       //
    I_GET(R0, R3, ulp_vars.MAXvalue),
    I_MOVI(R3, 0),                       //
    I_GET(R1, R3, ulp_vars.MINvalue),
    I_SUBR(R2,R0,R1),
    I_MOVI(R3, 0),                       // else
    I_RSHI(R0, R2, 4),
    I_PUT(R0, R3, ulp_vars.DIFvalue),
    I_RSHI(R2, R2, 1),
    I_ADDR(R0,R1,R2),
    I_MOVI(R3, 0),                       // else
    I_PUT(R0, R3, ulp_vars.zeroLEVEL),
    M_BX(LBL_START),
  };
  ESP_ERROR_CHECK(hulp_configure_pin(GPIO_NUM_14, RTC_GPIO_MODE_OUTPUT_ONLY, GPIO_FLOATING, 1));
  //ESP_ERROR_CHECK(hulp_configure_pin(GPIO_NUM_34, RTC_GPIO_MODE_INPUT_ONLY, GPIO_FLOATING, 1));
  ESP_ERROR_CHECK(hulp_configure_analog_pin(PIN_ADC_PIN2, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_12));
  //ESP_ERROR_CHECK(hulp_ulp_load(program, sizeof(program), 1000UL * ULP_WAKEUP_INTERVAL_MS, 0));
  size_t size = sizeof(program) / sizeof(ulp_insn_t);
  ESP_ERROR_CHECK(ulp_process_macros_and_load(0, program, &size));
  ESP_ERROR_CHECK(hulp_ulp_run(0));
}

void handleRoot() {
  digitalWrite(led, 1);
  server.send(200, "text/plain", "hello from esp32!");
  digitalWrite(led, 0);
}

void handleNotFound() {
  digitalWrite(led, 1);
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET) ? "GET" : "POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i = 0; i < server.args(); i++) {
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
  digitalWrite(led, 0);
}

void setup(void) {
  pinMode(led, OUTPUT);
  digitalWrite(led, 0);
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.println("");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  if (MDNS.begin("esp32")) {
    Serial.println("MDNS responder started");
  }

  server.on("/", handleRoot);

  server.on("/inline", []() {
    server.send(200, "text/plain", "this works as well");
  });

  server.onNotFound(handleNotFound);

  server.begin();
  ulp_init();
  Serial.println("HTTP server started");
}

void loop(void) {
  server.handleClient();
  Serial.println(ulp_vars.DIFvalue.val);
  Serial.println();
  delay(2);//allow the cpu to switch to other tasks
}``
freetoair commented 2 years ago

After translating and starting SoC, I get a message:

Connecting Wifi .... E (2618) wifi: Association refused temporarily, comeback time 0 mSec E (2627) wifi: Association refused temporarily, comeback time 0 mSec E (2638) wifi: Association refused temporarily, comeback time 0 mSec E (2645) wifi: Association refused temporarily, comeback time 0 mSec E (2653) wifi: Association refused temporarily, comeback time 0 mSec E (2660) wifi: Association refused temporarily, comeback time 0 mSec E (2667) wifi: Association refused temporarily, comeback time 0 mSec E (2673) wifi: Association refused temporarily, comeback time 0 mSec E (2680) wifi: Association refused temporarily, comeback time 0 mSec and so about 50 times and then it connects normally.

boarchuz commented 2 years ago

It might be worth going over the ULP program carefully before getting lost in the weeds too much. I'll highlight some issues to get started:

M_LABEL(LBL_LOOP),
I_STAGE_RST(),
I_MOVI(R3, 0),
M_LABEL(LBL_PIN2_OVERSAMPLE_LOOP),
I_ANALOG_READ(R1, PIN_ADC_PIN2),
I_ADDR(R0, R0, R1), // <<< R0 is not initialised in this loop, may have EQU_COUNT/junk
I_STAGE_INC(1),
M_BSLT(LBL_PIN2_OVERSAMPLE_LOOP, (1 << PIN2_OVERSAMPLE_SHIFT)),
I_RSHI(R0, R0, PIN2_OVERSAMPLE_SHIFT),
I_MOVI(R3, 0),
I_PUT(R1, R3, ulp_vars.valueNEW), // <<< Stores most recent value, not the average (R0) which is discarded

I_MOVI(R3, 0),
I_GET(R2, R3, ulp_vars.valueOLD),
I_SUBR(R0, R1, R2),                  // if valueNEW = valueOLD & direc = 1 goto FINISH // <<< what is direc?

Also FYI if the program doesn't alter R3 there is no need to reset it to 0 each time you want to GET/PUT. Perhaps a very simple loop that reads and stores an ADC value would be a better demo?

freetoair commented 2 years ago

Hi @boarchuz
This makes the whole concept a lot easier, I probably misunderstood from the comment that R3 must be reset before each GET/PUT call. Certainly some library documentation would facilitate better understanding. Now I will try to change those commands if you think that could be the cause of this behavior. .

freetoair commented 2 years ago

These are all libraries I removed:

//#include //#include //#include //#include //#include //#include "freertos/FreeRTOS.h" //#include "freertos/task.h" //#include "freertos/queue.h" //#include "I2C_eeprom.h" //#include

but nothing has changed. Numbers still make no sense. It does not react to voltage changes. After that I inserted the ULP code into the ESP32 example for the SD web server and then everything is fine.

freetoair commented 2 years ago

Hi, @boarchuz

Solved. I'm sorry to bother you, of course it's my fault. I named two variables with only one letter difference. It cost me two days of annoyance and worst of all, I bored you too. However, that strange behavior during the connection still remains, because I can't determine it for now. Unfortunately, I still haven't been able to understand when to set R3 to zero. This coprocessor means a lot to me because the first variant was to use STM32F103 as an ADC converter, so now I have to change a lot in the program. If you are interested in how it works you can look at 45.86.59.207/index.html

regards, freetoair