Jump to content

ESP32 brick programing and callbacks.


Recommended Posts


I have a bit of the problem programing ESP32 brick.  I try to do a standalone 0-10V dimmer with 4 buttons control. So I have 2 bricklets connected

Industrial_digital_in_4_v2 and


I did setup VS code environment with platformio and managed to program some basic functions  I can control both digital_in and analog_out corectly in the setup() 

I have a working callback that I define as following:

tf_industrial_digital_in_4_v2_register_all_value_callback(&idi, idi_callback_handler, this);
 tf_industrial_digital_in_4_v2_set_all_value_callback_configuration (&idi, 100, true);

Now the tricki part is the callback funcionality in the handler function 

static void idi_callback_handler(TF_IndustrialDigitalIn4V2 *idi, bool changed[4], bool value[4], void *user_data)
    logger.printfln("digital in state changed");
    logger.printfln("Channel 0: %s", value[0] ? "true" : "false");
    logger.printfln("Channel 1: %s", value[1] ? "true" : "false");
    logger.printfln("Channel 2: %s", value[2] ? "true" : "false");
    logger.printfln("Channel 3: %s", value[3] ? "true" : "false");
    if (value[0]== 0 && value[1] == 0) {
        logger.printfln("00 output 0%c", '%');
        tf_industrial_analog_out_v2_set_voltage(&iao, 0);

This will throw error on attempt to interact with analog_out from the digital_in callback, the very same line will work in the setup() but not


src/modules/dimmer/dimmer.cpp:26:50: error: 'iao' was not declared in this scope
         tf_industrial_analog_out_v2_set_voltage(&iao, 0);


Can anyone tell me what is wrong here? and how to workaround here to be able do something usefull from within calback




Link to comment
Share on other sites

Compiler complains: Don't know anything about iao. The thing is right. Always. All the functions are declared properly (and defined elsewhere, so the Linker won't complain) but the variable iao is not declared , that is unknown in the scope of where the call sits. It should be declared somewhere so the compiler gets happy und defined exactly once when linking that stuff. 

Cheers, Uwe 

Link to comment
Share on other sites

The error simply means that iao is declared elsewhere and therefore inaccessible. You could make it accessible, but the actual problem is that you cannot call API functions from within callback handlers. Our usual strategy to escape from callback handlers is using a scheduled task with a delay of 0. If you look around our ESP32 firmware code, you will find it in several places.

#include "task_scheduler.h"


    if (value[0]== 0 && value[1] == 0) {
        task_scheduler.scheduleOnce([]() {
            logger.printfln("00 output 0%%");
        }, 0);


void set_iao_out(uint16_t voltage)
    tf_industrial_analog_out_v2_set_voltage(&iao, voltage);

You will have to make iao accessible to the set_iao_out() function, either by making it global or public in your module’s class.

Btw, you can write "%%" if you want to print a % with a printf-style function.

Link to comment
Share on other sites

On 1/17/2024 at 5:26 PM, MatzeTF said:

You will have to make iao accessible to the set_iao_out() function, either by making it global or public in your module’s class.


Thank you for the answers,  They put me on the right track, the remainain problem is how do I exactly make the iao public or global.

Based on the Tutorial5 i declare iao in the header dimmer.h ,here it it all:

#pragma once

#include "config.h"
#include "module.h"
#include "bindings/bricklet_industrial_analog_out_v2.h"
#include "bindings/bricklet_industrial_digital_in_4_v2.h"

class Dimmer final : public IModule
    void pre_setup() override;
    void setup() override;
    void register_urls() override;
    void loop() override;

    void set_bricklet_voltage(int volt_out);
    void poll_bricklet_voltage();
    void set_iao_out(uint16_t voltage);

    // ConfigRoot object to represent the color to be send to the frontend module
    ConfigRoot config;

    // Extra ConfigRoot object to represent color updates received from the frontend module
    ConfigRoot config_update;

    // ConfigRoot object to represent the button state to be send to the frontend module
    ConfigRoot state;

    TF_IndustrialAnalogOutV2  iao;
    TF_IndustrialDigitalIn4V2 idi;


and then in the code file it still fails with "undefined reference to `iao'"  only this time in our set_iao_out()

I tried adding 

extern TF_IndustrialAnalogOutV2 iao;

but that does not help.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...