Python code requires preloaded image of QR code to send it to LCD Display

For my project I need to generate a QR code to a website and display it on the LCD display.
After I tried to use the code from the Wifi Router project (see other issue) I used this project:

Although I am able to display preloaded images of QR codes I want to generate the QR code based on input variables received from MQTT subscription. I use a python library qrcode) to generate the QR Image but the display code needs a stored image instead of an image in memory. Not sure if I need to store it somehow temporarily in order to load it or if I can manipulate it as an array.

My Git project:

Hi, what data are you encoding to the QR Code?

Not sure I understand you right, but you would like to send custom string over MQTT which will be sent over radio and in the Core Module then encoded to QR Code image and displayed.

That’s basically what our other QR Code wifi password project does, you just need to remove the concatenation of the string in the Core Module.

How many bytes/characters are you sending over radio? There is a packet limit somewhere around 40-50 bytes. Is some part static - for example you change only some parameter in the URL?

See response in the other topic: Generated QR Code for LCD module not working

The setup in the Wifi project (letting eht LCD module generate the QR code after receiving an MQTT message) is more suitable for my project so I won’t be needing to get this alternative working.

Hi Robert,
is there in this thread anything I could help you with? You’ve answered to the other thread and now I’m not sure if I answered all your questions. Can I close this thread? Thanks

Hi Martin,

Thanks again for your help. I want to reach out for another question I have.

As next step I have now developed the MQTT flow that should send a URL with OrderID via Node Red to the LCD Module. However I can’t find in the documentation how that should work. I
have used some examples :

My repository:
https://github.com/robertrongen/bcf-lcd-qrcode

I guessed that with bc_radio_sub_t you can subscribe to the MQTT channel and when a message arrives the bc_change_qr_value function will be called. But somehow it doesn’t respond when
I send a message. I also added the start_listening function from the gas-meter project but that also does not help.

// Subscribe to MQTT message changes

static const bc_radio_sub_t subs[] = {

{"qr/-/chng/code", BC_RADIO_SUB_PT_STRING, bc_change_qr_value, NULL}

};

// bc_radio_set_subs(subs, sizeof(subs)/sizeof(subs[0]));

void bc_change_qr_value(uint64_t *id, const char *topic, void *value, void *param)

{

bc_log_info("bc_change_qr_value triggered.");

// orderIdUrl = *(char*)value; // compile warning "makes pointer from integer without a cast"

// orderIdUrl = (char*)value;

orderIdUrl = value;

bc_log_info("New URL set to %s.", orderIdUrl);

qrcode_project(orderIdUrl);

bc_scheduler_plan_now(500);

}

Hello,
what is a length of the string? Can you try shorter string? It has limit somewhere near 40-50 characters.

Please check also this thread
https://forum.bigclown.com/t/example-of-how-to-subscribe-to-custom-mqtt-topic/360

If yousearch forum for bc_radio_set_subs you’ll find more threads wchich could also help you.

What is your MQTT topic and payload you are sending exactly looks like?

Hi Martin,

Thanks for helping out!

I tried to remove the URL part and only send the payload (2 characters) and that didn’t work as well.

The topic is “qr/-/chng/code”. The flow is attached.

I checked the posts:

  • Use
    bc_radio_sub_t to register to topic as in your example (CHECK)

  • Initialize subscription with
    bc_radio_set_subs (CHECK)

  • Topic has four levels:
    qr/-/chng/code (CHECK)

  • Checked pairing name of module by re-pairing it with a new image of the original LCD module image and did not change the name:
    node/lcd-thermostat:0 (CHECK)

  • Publish message to [alias]/[topic]:
    node/lcd-thermostat:0/qr/-/chng/code (CHECK)

I removed the start listening function from the gas-meter project as I guess you don’t need this to start listening.

flow.json.txt (2.28 KB)

I’ve made some changes after reading some more threats but no result yet.
The bc_change_qr_value function is not triggered when a new message arrives.

#include <application.h>
#include "qrcodegen.h"

// Defaults
#define SERVICE_INTERVAL_INTERVAL (60 * 60 * 1000)

// GFX instance
bc_gfx_t *gfx;

void qrcode_project(char *project_name);

static const bc_radio_sub_t subs[] = {
        {"qr/-/chng/code", BC_RADIO_SUB_PT_STRING, bc_change_qr_value, NULL}
};

void bc_change_qr_value(uint64_t *id, const char *topic, void *value, void *param) {
        bc_log_info("bc_change_qr_value triggered.");
        char *newUrl = (char*)value;
        bc_log_info("New URL set to %s.", newUrl);
        qrcode_project(newUrl);
}

static void print_qr(const uint8_t qrcode[]) {
    bc_gfx_clear(gfx);
    bc_gfx_set_font(gfx, &bc_font_ubuntu_13);
    bc_gfx_draw_string(gfx, 2, 0, orderIdUrl, true);
    uint32_t offset_x = 15;
    uint32_t offset_y = 16;
    uint32_t box_size = 3;
    int size = qrcodegen_getSize(qrcode);
    int border = 2;
    for (int y = -border; y < size + border; y++) {
        for (int x = -border; x < size + border; x++) {
            uint32_t x1 = offset_x + x * box_size;
            uint32_t y1 = offset_y + y * box_size;
            uint32_t x2 = x1 + box_size;
            uint32_t y2 = y1 + box_size;
            bc_gfx_draw_fill_rectangle(gfx, x1, y1, x2, y2, qrcodegen_getModule(qrcode, x, y));
        }
    }
    bc_gfx_update(gfx);
}

void qrcode_project(char *text) {
        bc_system_pll_enable();
        static uint8_t qrcode[qrcodegen_BUFFER_LEN_MAX];
        static uint8_t tempBuffer[qrcodegen_BUFFER_LEN_MAX];
  bool ok = qrcodegen_encodeText(text, tempBuffer, qrcode, qrcodegen_Ecc_MEDIUM,  qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);
        if (ok) {
            print_qr(qrcode);
        }
        bc_system_pll_disable();
}

void application_init(void) {
        // Initialize Radio
        bc_radio_init(BC_RADIO_MODE_NODE_LISTENING); 
        bc_radio_set_subs((bc_radio_sub_t *) subs, sizeof(subs)/sizeof(bc_radio_sub_t));
        // Initialize LCD
       bc_module_lcd_init();
       gfx = bc_module_lcd_get_gfx();}
}

Hi, I’ll test that on my hardware. Please give me a few days and I’ll get back to you.

Thanks Martin, I’ve done a lost of trouble shooting, latest code on https://github.com/robertrongen/bcf-lcd-qrcode.

I tried to send different messages by using the bch console with Test with shorter message and publish directly from bigclown console with e.g. bch pub node/lcd-thermostat:0/qr/-/chng/code "test" but to no result. I am not an experienced embedded C programmer so I haven’t been able to set up error logging in the module yet to find the root cause.

FYI we want to start testing the setup with our students using the 10 LCD modules from BigClown next week. If its a success we are able to extend the concept to other European institutes via a EU subsidy we received.

We’ve figured that out.

First you need to have enabled the pairing command in firmware. It may work but you will never be able to pair that node again. So uncomment the line and keep the name same as I have:

bc_radio_pairing_request("bcf-qr-code", VERSION);

Second thing which I did not realized is that the string needs to be in quotaition marks ", so this is how you inject the string.

Here’s the flow of that two nodes

[{"id":"c49c9358.c5d8f","type":"inject","z":"2c41a2bd.aa36ae","name":"","topic":"node/bcf-qr-code:0/qr/-/chng/code","payload":"\"hello\"","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":330,"y":200,"wires":[["9eb8c94d.85d638"]]},{"id":"9eb8c94d.85d638","type":"mqtt out","z":"2c41a2bd.aa36ae","name":"","topic":"","qos":"","retain":"","broker":"29fba84a.b2af58","x":520,"y":200,"wires":[]},{"id":"29fba84a.b2af58","type":"mqtt-broker","z":"","broker":"127.0.0.1","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","willTopic":"","willQos":"0","willPayload":""}]

If you use function node to build string, then in JavaScript you need to use escape sequence

text = "hello";
msg.payload = "\"" + text + "\"";

You can see that in this project in node-red flow if you import it.

Please note that the topic node/bcf-qr-code:0/qr/-/chng/code contains the same name like in teh firmware bc_radio_pairing_request("bcf-qr-code", VERSION); and also check that you have the same alias in Devices (screen below). I suggest that after you flash the firmware to remove the node from Devices and pair it again.

Then the text hello its displayed

Thanks Martin, saved by the bell, I’ve got it working now with these adjustments:

  • Initialize pairing with new name bc_radio_pairing_request("bcf-qr-code", VERSION);
  • Flashed LCD Module, first with radio-lcd-thermostat firmware to remove pairing, then with the updated custom firmware
  • adjusted the node name in the MQTT Out Node to “node/bcf-qr-code:0/blokko/order/qr/0”
  • adjusted the MQTT message function to shorter payload, the URL appeared to be too long so I had to concatenate the URL with the orderId in the application

In order to improve further coding effort it would help to better understand these topics:

  • How does the pairing exactly work? I would like to have more control over the names as I have 10 modules and 3 radio dongles.

  • What are the MQTT Out limitations in Node-Red? Apparently there is a length limitation for strings.