QR Code
The QR-Code-generator library by nayuki is a 3rd-party library that generates QR-Code bitmaps.
The QR-Code-generator library by nayuki is a 3rd-party library that generates QR-Code bitmaps.
The lv_qrcode LVGL extension is an interface to that library which implements a custom Widget that generates and displays QR Codes using the library.
Usage
Enable LV_USE_QRCODE in lv_conf.h by setting its value to 1.
Use lv_qrcode_create to create the QR-Code Widget. Then set the
data to encode with lv_qrcode_update for arbitrary binary data, or
with lv_qrcode_set_data for a NUL terminated string.
The appearance can be configured with lv_qrcode_set_size,
lv_qrcode_set_dark_color, lv_qrcode_set_light_color
and lv_qrcode_set_quiet_zone. These can be called in any order,
before or after setting the data - a copy of the payload is kept, so a change that
needs a different bitmap re-encodes it automatically.
Update mode
Setting the size or the quiet zone re-encodes the stored payload. By default that
happens inside the setter, so several such changes in a row encode the bitmap several
times. lv_qrcode_set_update_mode collapses them into one:
LV_QRCODE_UPDATE_MODE_IMMEDIATE(the default) re-encodes as soon as a property changes.LV_QRCODE_UPDATE_MODE_DEFERREDonly marks the bitmap as out of date. You are then expected to encode it once, explicitly, when the changes are done.
lv_qrcode_set_update_mode(qr, LV_QRCODE_UPDATE_MODE_DEFERRED);
lv_qrcode_set_size(qr, 200);
lv_qrcode_set_quiet_zone(qr, true);
lv_qrcode_render(qr); /* encode once, here, and get the result */lv_qrcode_render re-encodes the payload the Widget already stores, so
unlike lv_qrcode_update it does not need the data passed in again.
If that call is forgotten the bitmap is still correct - the redraw notices it is out of date and encodes it - but that is a fallback, not the intended flow, and it logs a warning. Two things are worse about it: the encode is charged to that refresh instead of to your own code, and nothing is left to return the result to, so an unencodable payload fails silently. Prefer the explicit call.
Switching back to LV_QRCODE_UPDATE_MODE_IMMEDIATE while the bitmap is still out of
date also encodes it, but lv_qrcode_set_update_mode returns void, so
a failure there can only be logged - and it warns to say the result was not reported.
Render first and switch the mode afterwards if you want the result:
lv_qrcode_render(qr); /* result available here */
lv_qrcode_set_update_mode(qr, LV_QRCODE_UPDATE_MODE_IMMEDIATE); /* nothing left to encode */The mode does not affect setting the data: lv_qrcode_update and
lv_qrcode_set_data always encode right away and return the result,
so an unencodable payload is reported to the caller. The colors are never affected
either - they are a palette write in both modes.
Detecting a failed re-encode
lv_qrcode_update() and lv_qrcode_render() return the encode result, but the
re-encodes triggered by a property change cannot: lv_qrcode_set_size() and lv_qrcode_set_quiet_zone() return
void, and in deferred mode the work happens in the draw pass. A payload that no longer
fits - typically after shrinking the object - therefore fails without anything returning
an error. lv_qrcode_is_render_valid reports that state:
lv_qrcode_set_size(qr, 10); /* too small for this payload */
if(!lv_qrcode_is_render_valid(qr)) {
/* the bitmap is blank; pick a larger size */
}It is also false on a fresh QR code that has no data yet. A property change re-arms the
Widget and sets the flag back to true before the new encode runs, so true means "no
known failure", not "the bitmap is up to date" - in deferred mode a pending re-encode is
also true.
A failed encode leaves the bitmap marked as out of date, so it is never mistaken for a current one, and it is not retried on every redraw - only a property change makes the Widget try again.
Encode failures are not logged when the caller can see the result: lv_qrcode_update()
and lv_qrcode_render() return it, and the property setters are silent because the state
is available from lv_qrcode_is_render_valid(). Animating a size through values that
are all too small therefore produces no log output at all. The one exception is the
re-encode done by the redraw - there is no caller to return anything to, so that failure
is logged, along with the warning that the explicit render call was missed.
Notes
- QR Codes with less data are smaller, but they are scaled by an integer
value to best fit to the given size. If the size is too small to fit even one
pixel per QR Code module, the bitmap cannot be generated and
lv_qrcode_updatereportsLV_RESULT_INVALID. Enabling the quiet zone needs more room, so a size that works without it may be too small with it. - Changing the color (dark or light) only updates the palette, so it is cheap and never triggers a re-encode of the QR Code.
Last updated on