No I’m sorry It’s a very big project with a lot of code… (months and months of work every day)
But ulptool-pio/examples/ulp-counter at feat-pio-integration · likeablob/ulptool-pio · GitHub works?
No, unfortunately not…
Same error(s):
.pio\build\test_detector\src\main.cpp.o:(.literal._Z5setupv+0x14): undefined reference to `_binary_ulp_main_bin_end'
.pio\build\test_detector\src\main.cpp.o:(.literal._Z5setupv+0x18): undefined reference to `_binary_ulp_main_bin_start'
.pio\build\test_detector\src\main.cpp.o:(.literal._Z5setupv+0x1c): undefined reference to `ulp_count'
.pio\build\test_detector\src\main.cpp.o:(.literal._Z5setupv+0x20): undefined reference to `ulp_entry'
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\test_detector\firmware.elf] Error 1
One other strange thing I see there (earlier in the terminal output) is:
warning: Ignoring missing SConscript 'C:\C:\Users\Stephan\Documents\PlatformIO\Projects\TestULP\.pio\libdeps\test_detector\ulptool-pio\post_extra_script_ulptool.py'
So 2x “C:\” that can’t be correct, right?
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.
Thank you for your fast reply’s and help Maximilian!
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 But except for this problem/topic is works really great and I like it VERY much
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?
That works!
That’s good progress already.
But… 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
[edit]
Ahhhh, YES!! I think it works now
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
Where/how can I buy you a cup of coffee or “ein leckeres Bier”?
Best!
Stephan
Ahhh… I was happy too early
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
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 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 (then it does a full erase, right?)
Ok, I didn’t know of that function. But it looks (and works) good 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…
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
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.
Okay, with the help of a friend I got it working now
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!
BUT: now comes the thing that also didn’t work when I was still programming in the Arduino-IDE
I use the code below to put the ESP32 in sleep and wake on 2 things:
- if a button is pushed
- 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
It there a chance that you know the solution?
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…
I’ve got it fully working now
Unbelievable how much time this took…
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!