QRCode: generate a QR code on the board itself
Richard Moore鈥檚 QRCode library builds a QR code on the microcontroller from any text, a URL, a WiFi login or a serial number, so a device can show a code that changes without a phone app or an internet service. It hands you the code as a grid of dark and light squares (modules), and you draw them on a display or print them to Serial.
Built in on Mokxi: #include <qrcode.h> and it builds, with nothing to install. Free, and no account needed.
What QRCode does
Two numbers control the code. The version, from 1 to 40, sets its size: version 1 is 21 by 21 modules and each version adds 4. The error correction level, ECC_LOW to ECC_HIGH, sets how much of the code can be damaged and still read, at the cost of how much text fits. Version 3 with ECC_LOW holds 53 bytes of text, enough for a short URL.
The buffer for the code is yours to provide, sized with qrcode_getBufferSize(version). On a 128x64 OLED, a version 3 code at two pixels a module is 58 pixels square, which fits with room for the quiet zone scanners need around it.
| Library Manager name | QRCode |
|---|---|
| Author | Richard Moore |
| Include | #include <qrcode.h> |
| Boards | every board Mokxi compiles for but ATtiny85 |
| In the simulator | Simulated: it runs against the part the way it does on the bench. |
| Parts it drives | OLED display, 128x64 |
Install it
It builds on every board Mokxi compiles for but ATtiny85.
In Mokxi it is built in: #include <qrcode.h> and the sketch compiles, with no download, no zip and no Library Manager.
On a real board, install "QRCode" by Richard Moore from the Arduino IDE鈥檚 Library Manager (Sketch, Include Library, Manage Libraries), or add QRCode to lib_deps in PlatformIO. Mokxi follows the calls of release 0.0.1, so a sketch written here builds there too.
What to know in the simulator: The mask is the lowest penalty under the standard鈥檚 rules; another library may pick another, and either scans.
ESP32-C3 路 Arduino Uno 路 Arduino Nano 路 Arduino Mega 2560 路 Arduino Leonardo 路 SparkFun Pro Micro 路 Arduino Micro 路 ESP32-C6 路 Raspberry Pi Pico 路 Raspberry Pi Pico W 路 Seeed XIAO SAMD21 路 STM32 路 STM32 Nucleo-F411RE 路 STM32 Blue Pill 路 micro:bit V2 路 Arduino Uno R4 路 ESP32 DevKit 路 ESP32-S3-DevKitC-1 路 ESP8266 NodeMCU 路 Arduino Pro Mini 3.3 V 路 Seeed XIAO ESP32-C3 路 ESP32-C3 SuperMini 路 Seeed XIAO ESP32-C6 路 ESP32-DevKitC V4 路 LOLIN32 Lite 路 Wemos D1 R32 路 Cheap Yellow Display 路 TTGO T-Display 路 Seeed XIAO ESP32-S3 路 Arduino Nano ESP32 路 Arduino Nano RP2040 Connect 路 Seeed XIAO RP2040 路 Waveshare RP2040-Zero 路 Arduino Uno R4 WiFi
The calls you will use
In the order a sketch meets them.
QRCode qrcode
Holds the code鈥檚 size and a pointer to its modules once it is built.
qrcode_getBufferSize(3)
How many bytes a version 3 code needs. Use it to size a uint8_t array.
uint8_t qrcodeData[qrcode_getBufferSize(3)];qrcode_initText(&qrcode, qrcodeData, 3, ECC_LOW, "https://mokxi.com")
Builds the code for the text at that version and error correction level. It returns 0 on success and a negative number if the text does not fit.
qrcode_getModule(&qrcode, x, y)
True when the module at x, y is dark. qrcode.size is the number of modules along each side.
for (uint8_t y = 0; y < qrcode.size; y++)
for (uint8_t x = 0; x < qrcode.size; x++)
if (qrcode_getModule(&qrcode, x, y))
display.fillRect(ox + x * 2, oy + y * 2, 2, 2, SSD1306_WHITE);qrcode_initBytes(&qrcode, qrcodeData, 3, ECC_LOW, data, length)
The same for binary data of a given length, always using byte mode.
Example: A QR code on the Serial Monitor
On the Arduino Uno R3. It runs in the browser exactly as printed.
#include "qrcode.h"
void setup() {
Serial.begin(115200);
QRCode qrcode;
uint8_t qrcodeData[qrcode_getBufferSize(1)];
qrcode_initText(&qrcode, qrcodeData, 1, ECC_LOW, "HELLO WORLD");
for (uint8_t y = 0; y < qrcode.size; y++) {
for (uint8_t x = 0; x < qrcode.size; x++) {
Serial.print(qrcode_getModule(&qrcode, x, y) ? "##" : " ");
}
Serial.println();
}
Serial.print("version 1, mask ");
Serial.println(qrcode.mask);
}
void loop() {}Common errors and how to fix them
The code is blank or qrcode_initText() returns a negative value
The text is too long for the version and error correction chosen. Raise the version by one or two, or drop to ECC_LOW, and size the buffer again with qrcode_getBufferSize().
Phones will not scan the code on the screen
Draw each module at least two pixels wide, leave a blank border of about four modules around the code, and if a scanner struggles with white on black, draw dark modules on a lit background.
The board resets when making a large code
A high version needs a big buffer, and a local array that large overflows an Uno鈥檚 2 KB of RAM. Keep to small versions on AVR boards, or make the buffer a global so the compiler reports its size.
Try QRCode without installing anything
Open the example, change the sketch, and keep your version in a free account.