Before logging an issue, please update to the latest release of Visual Micro from the Downloads Page.

When Logging a Support Issue in the Forum, please ensure you have also:-

  • Enabled vMicro > Compiler > Show Build Properties
  • Re-Compile your program with these settings enabled
 
Save the new Output to a Text File and....
  • Click the Reply button and attach as .txt file OR
  • Click here to Email us with the file attached, and a link to your post
Support requests without the output above may be impossible to answer, so please help us to help you
 
Page Index Toggle Pages: 1 Send TopicPrint
Normal Topic ESP32 ULP (Read 1718 times)
Sylvain
Junior Member
**
Offline


Posts: 68
Location: Montreal, Canada
Joined: Nov 13th, 2014
ESP32 ULP
Jul 30th, 2023 at 7:15pm
Print Post  
Hi,

   is there someone who have success to write code for the ESP32 low power processor (ULP)?

   I try to install ulptool but without success.

Thanks for your time
Sylvain Bissonnette
  
Back to top
 
IP Logged
 
Sylvain
Junior Member
**
Offline


Posts: 68
Location: Montreal, Canada
Joined: Nov 13th, 2014
Re: ESP32 ULP
Reply #1 - Aug 15th, 2023 at 10:25pm
Print Post  
Hi,

     Finally after 5 weeks I found how to make it work.  My project is a anemometer, the way it's work the ULP count the pulse of the anemometer within 6 second store those value in a global non volatile ram who is accessible for the main CPU after one minute the ULP wake up the main processor who take the highest reading and connect to AP and send via UDP this value and immediately go back to deep sleep.   

     the way it work just download the library HULP from https://github.com/boarchuz/HULP
it's a bundle of macro, there is no really doc but there is a lot of example and the .h file are well documented,  you can do many things but the ULP is very very limited in term of op-code.  I join my code maybe it could help you.
 
Sylvain Bissonnette
Code (C++)
Select All
// In datasheet 430a -> 3.57mph/hz -> 5.75kh/hz -> 0.575kmh/10hz

#include <WiFi.h>
#include <WiFiAP.h>
#include <WiFiClient.h>
#include <WiFiGeneric.h>
#include <WiFiMulti.h>
#include <WiFiScan.h>
#include <WiFiServer.h>
#include <WiFiSTA.h>
#include <WiFiType.h>
#include <WiFiUdp.h>
#include <dummy.h>
#include "esp_sleep.h"
#include "hulp.h"
//#include "hulp_macros.h"

#define DEBUG

#define BUTTON_PIN                      GPIO_NUM_4
#define LED_PIN                         GPIO_NUM_26
#define LED_PIN2                        GPIO_NUM_27
#define ULP_INTERVAL_MS                 10

#define NETWORK_PORT					4445
#define NETWORK_ABCD					"192.168.225.255"

RTC_DATA_ATTR ulp_var_t PulseCounter;
RTC_DATA_ATTR ulp_var_t LoopCounter;
RTC_DATA_ATTR ulp_var_t SaveCnt;

RTC_DATA_ATTR ulp_var_t SaveValue0;
RTC_DATA_ATTR ulp_var_t SaveValue1;
RTC_DATA_ATTR ulp_var_t SaveValue2;
RTC_DATA_ATTR ulp_var_t SaveValue3;
RTC_DATA_ATTR ulp_var_t SaveValue4;
RTC_DATA_ATTR ulp_var_t SaveValue5;
RTC_DATA_ATTR ulp_var_t SaveValue6;
RTC_DATA_ATTR ulp_var_t SaveValue7;
RTC_DATA_ATTR ulp_var_t SaveValue8;
RTC_DATA_ATTR ulp_var_t SaveValue9;
RTC_DATA_ATTR ulp_var_t SaveValue10;

int MaxHz = 0;
float Kmh = 0;
unsigned long Elipse;

void setup()
{
    if (hulp_is_ulp_wakeup())
    {

#ifdef DEBUG
        Serial.begin(115200);
#endif
        Elipse = millis();
       
        println("Woken up!\n");
       
        int i;

        for (i = 0; i < 10; i++)
        {
            if (i == 0) println("Save1: " + String(SaveValue1.val));
            if (i == 1) println("Save2: " + String(SaveValue2.val));
            if (i == 2) println("Save3: " + String(SaveValue3.val));
            if (i == 3) println("Save4: " + String(SaveValue4.val));
            if (i == 4) println("Save5: " + String(SaveValue5.val));
            if (i == 5) println("Save6: " + String(SaveValue6.val));
            if (i == 6) println("Save7: " + String(SaveValue7.val));
            if (i == 7) println("Save8: " + String(SaveValue8.val));
            if (i == 8) println("Save9: " + String(SaveValue9.val));
            if (i == 9) println("Save10: " + String(SaveValue10.val));
        }

        MaxHz = 0;
        if (MaxHz < SaveValue1.val) MaxHz = SaveValue1.val;
        if (MaxHz < SaveValue2.val) MaxHz = SaveValue2.val;
        if (MaxHz < SaveValue3.val) MaxHz = SaveValue3.val;
        if (MaxHz < SaveValue4.val) MaxHz = SaveValue4.val;
        if (MaxHz < SaveValue5.val) MaxHz = SaveValue5.val;
        if (MaxHz < SaveValue6.val) MaxHz = SaveValue6.val;
        if (MaxHz < SaveValue7.val) MaxHz = SaveValue7.val;
        if (MaxHz < SaveValue8.val) MaxHz = SaveValue8.val;
        if (MaxHz < SaveValue9.val) MaxHz = SaveValue9.val;
        if (MaxHz < SaveValue10.val) MaxHz = SaveValue10.val;

        println("Hz: " + String(MaxHz / 2 / 6)); // 2 pulse per revolution.  Read each 6 seconds
        Kmh = MaxHz / 2;
        Kmh *= 0.958; // 5.75kh/hz div 6
        println("Kmh: " + String(Kmh));
        SendReport();
        Serial.println("Up Time: " + String(millis() - Elipse));
        println("Go To Sleep\n");
        Serial.flush();
    }
    else
    {
#ifdef DEBUG
        Serial.begin(115200);
#endif
        println("Start!\n");
        Serial.flush();
        init_ulp();
        hulp_peripherals_on();
    }

    CLEAR_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SLEEP_EN);
    SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SLEEP_EN);
    esp_sleep_enable_ulp_wakeup();
    esp_deep_sleep_start();
}

// Don't use loop
void loop()
{
}

void SendReport()
{
    WiFiUDP Network;
    String Str;

    WiFi.disconnect(true);
    WiFi.hostname("WIND_SPEED");
    WiFi.mode(WIFI_AP_STA);
    WiFi.setAutoReconnect(true);
    WiFi.begin("xxxx", "xxxxx");
    int i = 0;
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(500);
        Serial.print(".");
        if (i++ > 15) return;
    }

    println("");
    println(PSTR("Connected to WiFi"));
    println(PSTR("IP: ") + String(WiFi.localIP().toString()));
    println(PSTR("MAC: ") + String(WiFi.macAddress()));
    println(PSTR("RSSI: ") + String(WiFi.RSSI()));
       
    Str = PSTR("<<<{&FROM=NEW_WIND}{SPEED=") + String(String(Kmh)) + PSTR("}>>>");
    Network.beginPacket("192.168.1.255", NETWORK_PORT);
    Network.print(Str.c_str());
    Network.endPacket();
    delay(250);
    Serial.flush();
}

void println(String Str)
{
#ifdef DEBUG
    Serial.println(Str);
#endif
}

void init_ulp()
{
    enum {
        LBL_INTERRUPT_TRIGGERED,
        LBL_HALT,
        LBL_SAVE,
        LBL_SAVE_1,
        LBL_SAVE_2,
        LBL_SAVE_3,
        LBL_SAVE_4,
        LBL_SAVE_5,
        LBL_SAVE_6,
        LBL_SAVE_7,
        LBL_SAVE_8,
        LBL_SAVE_9,
        LBL_SAVE_10,
    };

    const ulp_insn_t program[] = {
        //Read the interrupt bit
        I_GPIO_INT_RD(BUTTON_PIN),
        //If it's set, goto LAB_INTERRUPT_TRIGGERED
        M_BGE(LBL_INTERRUPT_TRIGGERED, 1),
        //Pin not triggered
        //Clear the interrupt bit
        I_GPIO_INT_CLR(BUTTON_PIN),
        //Turn off LED
        I_GPIO_SET(LED_PIN, 0),
        M_BX(LBL_HALT),

        // if pin set
        M_LABEL(LBL_INTERRUPT_TRIGGERED),
            I_GPIO_SET(LED_PIN, 1),
            M_DELAY_US_100_5000(1000),
            I_GPIO_INT_CLR(BUTTON_PIN),

            I_MOVI(R2, 0),
            I_GET(R0, R2, PulseCounter),
            I_ADDI(R0, R0, 1),
            I_PUT(R0, R2, PulseCounter),
            
        M_LABEL(LBL_HALT),
            I_MOVI(R2, 0),
            I_GET(R0, R2, LoopCounter),
            I_ADDI(R0, R0, 1),
            I_PUT(R0, R2, LoopCounter),
            M_BGE(LBL_SAVE,600),
            I_HALT(),

        M_LABEL(LBL_SAVE),
            I_MOVI(R2, 0),
            I_MOVI(R0, 0),
            I_PUT(R0, R2, LoopCounter),

            I_GET(R0, R2, SaveCnt),
            I_ADDI(R0, R0, 1),
            I_PUT(R0, R2, SaveCnt),

            M_BL(LBL_SAVE_1,2),
            M_BL(LBL_SAVE_2,3),
            M_BL(LBL_SAVE_3,4),
            M_BL(LBL_SAVE_4,5),
            M_BL(LBL_SAVE_5,6),
            M_BL(LBL_SAVE_6,7),
            M_BL(LBL_SAVE_7,8),
            M_BL(LBL_SAVE_8,9),
            M_BL(LBL_SAVE_9,10),
            M_BL(LBL_SAVE_10,11),
            I_HALT(),

        M_LABEL(LBL_SAVE_1),
            I_MOVI(R2, 0),
            I_GET(R0, R2, PulseCounter),
            I_PUT(R0, R2, SaveValue1),

            I_GET(R0, R2, PulseCounter),
            I_MOVI(R0, 0),
            I_PUT(R0, R2, PulseCounter),
            I_HALT(),

        M_LABEL(LBL_SAVE_2),
            I_MOVI(R2, 0),
            I_GET(R0, R2, PulseCounter),
            I_PUT(R0, R2, SaveValue2),

            I_GET(R0, R2, PulseCounter),
            I_MOVI(R0, 0),
            I_PUT(R0, R2, PulseCounter),
            I_HALT(),

        M_LABEL(LBL_SAVE_3),
            I_MOVI(R2, 0),
            I_GET(R0, R2, PulseCounter),
            I_PUT(R0, R2, SaveValue3),

            I_GET(R0, R2, PulseCounter),
            I_MOVI(R0, 0),
            I_PUT(R0, R2, PulseCounter),
            I_HALT(),

        M_LABEL(LBL_SAVE_4),
            I_MOVI(R2, 0),
            I_GET(R0, R2, PulseCounter),
            I_PUT(R0, R2, SaveValue4),

            I_GET(R0, R2, PulseCounter),
            I_MOVI(R0, 0),
            I_PUT(R0, R2, PulseCounter),
            I_HALT(),

        M_LABEL(LBL_SAVE_5),
            I_MOVI(R2, 0),
            I_GET(R0, R2, PulseCounter),
            I_PUT(R0, R2, SaveValue5),

            I_GET(R0, R2, PulseCounter),
            I_MOVI(R0, 0),
            I_PUT(R0, R2, PulseCounter),
            I_HALT(),

        M_LABEL(LBL_SAVE_6),
            I_MOVI(R2, 0),
            I_GET(R0, R2, PulseCounter),
            I_PUT(R0, R2, SaveValue6),

            I_GET(R0, R2, PulseCounter),
            I_MOVI(R0, 0),
            I_PUT(R0, R2, PulseCounter),
            I_HALT(),

        M_LABEL(LBL_SAVE_7),
            I_MOVI(R2, 0),
            I_GET(R0, R2, PulseCounter),
            I_PUT(R0, R2, SaveValue7),

            I_GET(R0, R2, PulseCounter),
            I_MOVI(R0, 0),
            I_PUT(R0, R2, PulseCounter),
            I_HALT(),

        M_LABEL(LBL_SAVE_8),
            I_MOVI(R2, 0),
            I_GET(R0, R2, PulseCounter),
            I_PUT(R0, R2, SaveValue8),

            I_GET(R0, R2, PulseCounter),
            I_MOVI(R0, 0),
            I_PUT(R0, R2, PulseCounter),
            I_HALT(),

        M_LABEL(LBL_SAVE_9),
            I_MOVI(R2, 0),
            I_GET(R0, R2, PulseCounter),
            I_PUT(R0, R2, SaveValue9),

            I_GET(R0, R2, PulseCounter),
            I_MOVI(R0, 0),
            I_PUT(R0, R2, PulseCounter),
            I_HALT(),

        M_LABEL(LBL_SAVE_10),
            I_MOVI(R2, 0),
            I_GET(R0, R2, PulseCounter),
            I_PUT(R0, R2, SaveValue10),

            I_GET(R0, R2, PulseCounter),
            I_MOVI(R0, 0),
            I_PUT(R0, R2, PulseCounter),

            I_GET(R0, R2, SaveCnt),
            I_MOVI(R0, 0),
            I_PUT(R0, R2, SaveCnt),

            I_WAKE(),
            I_HALT(),
    };

    ESP_ERROR_CHECK(hulp_configure_pin(BUTTON_PIN, RTC_GPIO_MODE_INPUT_ONLY, GPIO_PULLUP_ONLY, 0));
    ESP_ERROR_CHECK(hulp_configure_pin(LED_PIN, RTC_GPIO_MODE_OUTPUT_ONLY, GPIO_FLOATING, 0));
    ESP_ERROR_CHECK(hulp_configure_pin(LED_PIN2, RTC_GPIO_MODE_OUTPUT_ONLY, GPIO_FLOATING, 0));
    ESP_ERROR_CHECK(hulp_configure_pin_int(BUTTON_PIN, GPIO_INTR_ANYEDGE));
    ESP_ERROR_CHECK(hulp_ulp_load(program, sizeof(program), ULP_INTERVAL_MS * 1000, 0));
    ESP_ERROR_CHECK(hulp_ulp_run(0));
}
 

« Last Edit: Aug 15th, 2023 at 10:31pm by Sylvain »  
Back to top
 
IP Logged
 
Tim@Visual Micro
Administrator
*****
Offline


Posts: 12166
Location: United Kingdom
Joined: Apr 10th, 2010
Re: ESP32 ULP
Reply #2 - Aug 16th, 2023 at 12:31am
Print Post  
Well done! Thanks for the update. 

If you are able to attach a file with the code in that would help people. The forum editor isn't so great for large code chunks. The color coding tends to break things and there is also a size limit that causes truncation.

Thanks again
  
Back to top
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint