[ULP] undefined reference to

Yes, this is due to a wrong extra_scripts directive starting with /, aka the root of the filesystem.

But even then, and with using the PR from Amend for espressif32@~5.2.0 by xtrinch · Pull Request #3 · likeablob/ulptool-pio · GitHub, it’s not running correctly, giving a “commandline too long” error due to a mass of -I flags. I’ll fix it quickly.

1 Like

Thank you for your fast reply’s and help Maximilian! :slightly_smiling_face:

I’m very very new to PlatformIO. In fact: this is my first project ever in Pio! I worked on the project for several months (spread over almost 3 years now) in the Arduino IDE and with the help of a friend we loaded it into Pio. So I’m a newby in this :innocent: But except for this problem/topic is works really great and I like it VERY much :sunglasses:

But due to my “newby-ness” I don’t know exactly what you mean, but If i’m correct you mean that this C:\C:\ “thing” is not the cause of those “undefined reference”?

And is there anything else that I can try to fix the undefined reference problem?

Thanks again!

Stephan

Can you clone GitHub - maxgerhardt/ulptool-pio: A thin wrapper of ulptool for PlatformIO and open examples/ulp-counter in PlatformIO and build it?

1 Like

That works! :sunglasses:

That’s good progress already.

But… :smiling_face_with_tear: I can’t get this working with my own code…
If I copy the corresponding files (the files that you have changed, just like I did with your/the sample project) to my project, then an error shows up:

src/ulptool.h:48:12: error: 'TAG' was not declared in this scope

I think we are going in the right direction :slight_smile:

[edit]

Ahhhh, YES!! I think it works now :heart_eyes:

I placed

static const char* TAG = "MyModule";

at the top of the main *.ino file and now it compiles.

Thanks for the very good help and support Maximilian :+1:
Where/how can I buy you a cup of coffee or “ein leckeres Bier”? :sunglasses:

Best!

Stephan

Ahhh… I was happy too early :smiling_face_with_tear:

Now the code does compile, but after uploading the code (via OTA) it bricked my chip…

I always worked with:

platform = espressif32@~3.5.0

And now, due to the fantastic help in this topic I used:

platform = espressif32@5.3.0

But then the chip doesn’t boot anymore…

That section of platform.ini looks like this:

platform = espressif32@5.3.0 ; There is a newer version, 5.1.1, but it somehow doesn't boot. Might need to change SPIFFS or partition tables. //platform = espressif32@~3.5.0
board = esp32dev
framework = arduino
upload_speed = 921600 ; The upload baud rate
monitor_speed = 115200 ; The serial (monitor) baud rate
board_build.flash_mode = qio
board_build.partitions = min_spiffs.csv
board_build.filesystem = spiffs

Is there something wrong?

Thanks for helping me out :grinning:

Stephan

Did you try with dio too? Or without a custom partition table?

With Arduino core upgrades like this it can also be that previously existing / working code in the firmware is the problem. If you see that the chip doesn’t even reach setup() and can print an initial message via Serial, your chip may be crashing in the constructor of a custom C++ class.

I will try dio in a minute :slight_smile: Thanks!

Without a custom partition table I get:

Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
Error: The program size (1517561 bytes) is greater than maximum allowed (1310720 bytes)
RAM:   [==        ]  19.2% (used 62808 bytes from 327680 bytes)
*** [checkprogsize] Explicit exit, status 1
Flash: [==========]  115.8% (used 1517561 bytes from 1310720 bytes)

Yes, a friend just told me that I better can do a full erase when doing this (“playing” with partition tables and such) kind of things. Therefore I program via the serial interface in PlatformIO the last hour :slightly_smiling_face: (then it does a full erase, right?)

It’s easier to do a flash erase if you use the “Erase Flash” project task.

1 Like

Ok, I didn’t know of that function. But it looks (and works) good :slight_smile: The chip is erased!

But after I upload new code, only this is what I get:

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:13104
load:0x40080400,len:3036
entry 0x400805e4
[     5][W][esp32-hal-timer.c:226] timerAttachInterrupt(): EDGE timer interru␃��␗R�.H�␗Ү␗.�K␗W␖V$��Y]�Z�␖$�␋␒��U␔��ɩHh␅         ␒R&�W+QW�Y.\&�KZX�K,\]�,'&MMW��Y](\]��equencyMhz(): PLL: 480 / 2 = 240 Mhz, APB: 80000000 Hz
Starting...

It doesn’t boot…

Do you call some setCPUFrequency() command maybe?

Can you confirm the simplest of blinky works?

No, I do nothing with setCPUFrequency() or so.

Yes, other (smaller/simpler) programs (like for example the examples/ulp-counter you told me about yesterday) work perfectly :grinning:

But there I only use:

platform = espressif32@5.3.0
board = esp32dev
framework = arduino
monitor_speed = 115200

Instead of:

platform = espressif32@5.3.0 ; There is a newer version, 5.1.1, but it somehow doesn't boot. Might need to change SPIFFS or partition tables. //platform = espressif32@~3.5.0
board = esp32dev
framework = arduino
upload_speed = 921600 ; The upload baud rate
monitor_speed = 115200 ; The serial (monitor) baud rate
board_upload.flash_size = 16MB
board_upload.maximum_size = 16777216
board_build.flash_mode = dio ; qio
board_build.partitions = large_spiffs_16MB.csv ; min_spiffs.csv
board_build.filesystem = spiffs
custom_device_type = 0 ; Override this for every new environment

So I have the idea that it has to do something with those partitions, don’t you think?

Very weird… I can only recommend to partially comment out the creation of custom C++ objects and code in setup() and loop() until you get a stable bootup again, then comment it back in one-by-one to see where it breaks.

1 Like

Okay, with the help of a friend I got it working now :grinning:

No Idea WHY exactly this is, but here is the corresponding platform.ini code:

platform = espressif32@~3.5.0 ; There is a newer version, 5.1.1, but it somehow doesn't boot. Might need to change SPIFFS or partition tables. //platform = espressif32@~3.5.0
board = esp32dev
framework = arduino
upload_speed = 921600 ; The upload baud rate
monitor_speed = 115200 ; The serial (monitor) baud rate
board_build.flash_mode = qio
board_build.partitions = min_spiffs.csv
board_build.filesystem = spiffs
lib_deps = 
	https://github.com/powelllens/ulptool-pio
extra_scripts =
    pre:$PROJECT_LIBDEPS_DIR/$PIOENV/ulptool-pio/pre_extra_script_ulptool.py
    post:$PROJECT_LIBDEPS_DIR/$PIOENV/ulptool-pio/post_extra_script_ulptool.py

With this, the code compiles and works! :sunglasses:

BUT: now comes the thing that also didn’t work when I was still programming in the Arduino-IDE :innocent:

I use the code below to put the ESP32 in sleep and wake on 2 things:

  1. if a button is pushed
  2. if the ADC measures a value that is below ulp_low_threshold (in my case 2000)
if (EnableSleep){
  esp_sleep_wakeup_cause_t wakeReason = esp_sleep_get_wakeup_cause();    // 0 = BOOT, 3 = Wake by Push Button, 6 = Wake by ADC
  if (wakeReason != ESP_SLEEP_WAKEUP_ULP){
    Serial.println(String(wakeReason));
  } else {
    ulp_ADC_reading &= UINT16_MAX;
    Serial.println("ulp_ADC_reading: " + String(ulp_ADC_reading)); 
    Serial.println(String(wakeReason));
  }


  if (wakeReason == 0 || wakeReason == 6){
    init_ulp_program(wakeReason);
  }

  start_ulp_program();
  
  ESP_ERROR_CHECK(esp_sleep_enable_ulp_wakeup());

  esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK,ESP_EXT1_WAKEUP_ALL_LOW);  //wake with pushbutton (BUTTON_PIN_BITMASK is 0x4000)

  Serial.println("Going into sleep...");
  esp_deep_sleep_start();

}






static void init_ulp_program(int wakeReason)
{
  esp_err_t err = ulp_load_binary(0, ulp_main_bin_start,
                                  (ulp_main_bin_end - ulp_main_bin_start) / sizeof(uint32_t));
  ESP_ERROR_CHECK(err);

  ulp_low_threshold = 2000; 
  ulp_high_threshold = 4096; 

  digitalWrite(POWER, HIGH); //pcb power
  digitalWrite(26, HIGH);    //tcrt led power

  gpio_hold_en(GPIO_NUM_13); //pcb power
  gpio_hold_en(GPIO_NUM_26); //tcrt power
  gpio_deep_sleep_hold_en(); 

  //if (wakeReason == 0 || wakeReason == 6){
    adc1_config_channel_atten(ADC1_CHANNEL_4, ADC_ATTEN_DB_11);
    adc1_config_width(ADC_WIDTH_BIT_12);
    adc1_ulp_enable();
  //}

}

static void start_ulp_program()
{
  esp_err_t err = ulp_run((&ulp_entry - RTC_SLOW_MEM) / sizeof(uint32_t));
  ESP_ERROR_CHECK(err);
}

Both work. So I can wake the processor with ADC and with the pushbutton. BUT: if it wakes with the pushbutton, then the ADC doesn’t work anymore. So if it’s going back to sleep, I can’t wake it with ADC, but only with the button…

I tried sooooo many things/settings/code changes/whatever: I can’t get the ADC working anymore after pushing the button. This also didn’t work in the Arduino IDE. I even have paid people on Fivver (or Upwork, didn’t remind it anymore) for this, but they also couldn’t get this working :smiling_face_with_tear:

It there a chance that you know the solution? :grinning:

Thanks / best regards,

Stephan

This doesn’t seem to be too trivial then. Have you asked for help on Issues · espressif/arduino-esp32 · GitHub or esp32.com with the most minimal fully-contained code for reproduction? You might be running in some weird edge cases where, idk, the ADC peripheral’s clock isn’t started in one case, or the peripheral needs a reset, or something else…

1 Like

I’ve got it fully working now :sunglasses:

Unbelievable how much time this took… :innocent:
But if I’m really honest: I couldn’t find that much info about this. So it was literally trial and error.

Maybe someone else has the same problem in the future; this is the solution:

if (EnableSleep){

  digitalWrite(POWER, HIGH);  //pcb power
  digitalWrite(26, HIGH);     //tcrt led power
  gpio_hold_en(GPIO_NUM_13);  //pcb power
  gpio_hold_en(GPIO_NUM_26);  //tcrt power
  gpio_deep_sleep_hold_en(); 

  esp_sleep_wakeup_cause_t wakeReason = esp_sleep_get_wakeup_cause();    // 0 = BOOT, 3 = Wake by Push Button, 6 = Wake by ADC
  switch(wakeReason){
    case 0 : Serial.println("Reason 0 (boot)"); init_ulp_program(wakeReason); break;
    case 3 : Serial.println("Reason 3 (pushbutton)"); init_ulp_program(wakeReason); break;
    case 6 : Serial.println("Reason 6 (ADC)"); ulp_ADC_reading &= UINT16_MAX; Serial.println("ulp_ADC_reading: " + String(ulp_ADC_reading)); init_ulp_program(wakeReason); break; 
  }  

  start_ulp_program();

  ESP_ERROR_CHECK(esp_sleep_enable_ulp_wakeup());

  esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK,ESP_EXT1_WAKEUP_ALL_LOW);  //wake with pushbutton (BUTTON_PIN_BITMASK is 0x4000)

  Serial.println("Going into sleep...");
  esp_deep_sleep_start();

}



static void init_ulp_program(int wakeReason)
{

  if (wakeReason == 0){ //load ULP program only once (when booting)
    esp_err_t err = ulp_load_binary(0, ulp_main_bin_start,
                                  (ulp_main_bin_end - ulp_main_bin_start) / sizeof(uint32_t));
    ESP_ERROR_CHECK(err);
  }

  ulp_low_threshold = 2000; 
  ulp_high_threshold = 4096; 

  adc1_config_channel_atten(ADC1_CHANNEL_4, ADC_ATTEN_DB_11);
  adc1_config_width(ADC_WIDTH_BIT_12);
  adc1_ulp_enable();

  /* Set ULP wake up period to 20ms */
  ulp_set_wakeup_period(0, 20000);

}

static void start_ulp_program()
{
  esp_err_t err = ulp_run((&ulp_entry - RTC_SLOW_MEM) / sizeof(uint32_t));
  ESP_ERROR_CHECK(err);
}

@5.3.0nlumig,
Wow, you have persevered through this. Good on you!

I learned for your work. Thak you for taking the time to cover what has worked for you.

Have you tried to get this working with an ESP32-S3? I got the pulse example working with ESP32 but not with ESP32-S3.

I’m sorry, I don’t have a ESP32-S3 here… (never worked with it!)

Good luck! :+1:

Hello, how can I contact you? I have encountered the same problem and I cannot assemble. I would like to wake up through buttons and external registers

Hi everyone,
I’m replying to this thread because I have a similar problem.

platformio.ini

[env:esp32-s3]
platform = espressif32
board = esp32-s3-devkitc-1
framework = arduino
lib_deps = 
	paulstoffregen/OneWire@^2.3.7
	milesburton/DallasTemperature@^3.11.0
	xreef/EByte LoRa E220 library@^1.0.3
	adafruit/DHT sensor library@^1.4.4
	adafruit/Adafruit Unified Sensor@^1.1.13
	plerup/EspSoftwareSerial
	https://github.com/likeablob/ulptool-pio

extra_scripts =
  pre:/$PROJECT_LIBDEPS_DIR/$PIOENV/ulptool-pio/pre_extra_script_ulptool.py
  post:/$PROJECT_LIBDEPS_DIR/$PIOENV/ulptool-pio/post_extra_script_ulptool.py


lib_ldf_mode = chain+
upload_speed = 921600
build_flags = 
	#-DACTIVATE_SOFTWARE_SERIAL
	-DFREQUENCY_868
	-DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
monitor_speed = 115200
upload_port = COM19
monitor_port = COM19
test_port = COM19

my terminal:

Resolving esp32-s3 dependencies...
Already up-to-date.
Updating metadata for the vscode IDE...
UserSideException: Processing esp32-s3 (platform: espressif32; board: esp32-s3-devkitc-1; framework: arduino)
--------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option

*** missing SConscript file 'C:\\C:\\Users\\fabio\\Documents\\PlatformIO\\Projects\\abiot\\abiot-node-2.0\\.pio\\libdeps\\esp32-s3\\ulptool-pio\\pre_extra_script_ulptool.py'
File "C:\Users\fabio\.platformio\penv\Lib\site-packages\platformio\builder\main.py", line 167, in <module>
========================== [FAILED] Took 0.53 seconds ==========================

What can I do to solve the problem?

Sorry for the necro, I know this is three months later, I just thought this may help someone.

I don’t yet use PlatformIO for my projects, but the error you are getting could be due to your platformio.ini script.

I assume that removing the / immediately at the start of the extra script (pre and post) would fix the problem.

See for comparison in an apparent working code above (note the lack of / at the start of the pre and post):

I’m probably wrong though as GitHub - likeablob/ulptool-pio: A thin wrapper of ulptool for PlatformIO page includes the / in their examples.