I get this at the beginning : "WARNING: library LiquidCrystal I2C claims to run on avr architecture(s) and may be incompatible with your current board which runs on nrf52 architecture(s)." but the code is still sent but nothing shows up on the screen.
Ah! That warning is the key here — it explains why your LCD isn't working. Let me break it down clearly:
________________________________________
1. Why the warning happens
The LiquidCrystal_I2C library you're using was originally written for AVR-based boards (like Arduino Uno, Nano, Mega). The XIAO nRF52840 uses the nRF52 architecture, which has a different I²C implementation.
Some AVR-specific code (like Wire.h usage or certain delay functions) doesn't translate correctly, which is why your code uploads but the LCD stays blank.
________________________________________
2. Solution: Use an nRF52-compatible library
For nRF52 (and Adafruit boards), I recommend:
1. Use the hd44780 library instead of LiquidCrystal_I2C:
o It supports many architectures including nRF52.
o Works with most 1602/2004 I²C LCDs.
Install it via Arduino IDE → Library Manager → search “hd44780” → Install “HD44780 by Bill Perry”.
2. Use this code for XIAO nRF52840:
#include <Wire.h>
#include <hd44780.h> // main hd44780 header
#include <hd44780ioClass /hd44780_I2Cexp.h> // I2C expander i/o class
hd44780_I2Cexp lcd; // Create LCD object
void setup() {
// Initialize the LCD, specify I2C address
lcd.begin(16, 2);
lcd.setBacklight(HIGH); // Turn on backlight
lcd.setCursor(0, 0);
lcd.print("Hello");
lcd.setCursor(0, 1);
lcd.print("World");
}
void loop() {
// Nothing needed for static display
}
________________________________________
✅ Advantages of hd44780:
• Compatible with nRF52, SAMD, ESP32, AVR.
• Handles I²C communication properly on non-AVR boards.
• No blank-screen issues.
________________________________________
If you want, I can write a full working example with scrolling text for your XIAO nRF52840 using hd44780, so your LCD actually works like it should.
Do you want me to do that?
NRF52840, arduino ide and 0.96" 4 pins I2C oled screen.
Perfect! Now that we're talking about a 0.96" 4-pin I2C OLED screen with XIAO nRF52840 in Arduino IDE, we can go straight to a working setup.
These OLEDs usually use the SSD1306 driver, and the 4 pins are:
• GND → GND
• VCC → 3.3V (or 5V depending on your module)
• SCL → A5 (I²C clock on XIAO nRF52840)
• SDA → A4 (I²C data on XIAO nRF52840)
________________________________________
1. Install the Libraries
In Arduino IDE:
1. Go to Sketch → Include Library → Manage Libraries
2. Search for “Adafruit SSD1306” → Install
3. Also install “Adafruit GFX” (required by SSD1306)
________________________________________
2. Basic Example Code
Here's a minimal working sketch for the 0.96" OLED:
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED width in pixels
#define SCREEN_HEIGHT 64 // OLED height in pixels
#define OLED_RESET -1 // Not used
#define SCREEN_ADDRESS 0x3C // Common I2C address (0x3C or 0x3D)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void setup() {
Wire.begin(); // Initialize I2C
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.clearDisplay();
display.setTextSize(2); // Text size multiplier
display.setTextColor(SSD1306_WHITE); // Color (white)
display.setCursor(0, 0); // Top-left corner
display.println("Hello");
display.setCursor(0, 30); // Second line
display.println("World");
display.display(); // Send buffer to OLED
}
void loop() {
// Optional: scroll text
}
________________________________________
3. Tips
• Most 0.96" OLEDs have I²C address 0x3C, but some are 0x3D. If nothing shows, run an I²C scanner to find it.
• Use 3.3V for XIAO nRF52840. Some OLED modules tolerate 5V, but 3.3V is safer.
• display.display() is essential to actually draw anything on the screen.
________________________________________
If you want, I can provide a dynamic scrolling text example for your 0.96" OLED that continuously scrolls “Hello World” across the screen—this looks really nice on XIAO nRF52840.
Do you want me to make that?
Adafruit_SSD1306 i want to replace the content of line (0, 30) but it just places it on top of each other.
Ah! I see exactly what's happening. With Adafruit_SSD1306, when you draw text, it does not automatically erase what was previously there. So if you just call display.setCursor(0, 30) and display.println("New text"), it will draw on top of the old text, causing overlapping.
To replace the content on a specific line, you need to clear that area first.
________________________________________
1. Clear a specific line
You can use fillRect() to erase just the part of the display where your text will go:
int x = 0; // x-coordinate of line
int y = 30; // y-coordinate of line
int w = SCREEN_WIDTH; // width of the line
int h = 8 * display.getTextSize(); // height of the text (approx)
display.fillRect(x, y, w, h, SSD1306_BLACK); // erase the line
display.setCursor(x, y);
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
display.println("New text");
display.display();
Explanation:
• fillRect(x, y, w, h, color) draws a filled rectangle. Using SSD1306_BLACK “erases” the area.
• h = 8 * textSize works because the default character height is 8 pixels in Adafruit GFX.
________________________________________
2. Alternative: Clear entire display
If you don't need to keep other text or graphics:
display.clearDisplay(); // clears everything
display.setCursor(0, 30);
display.println("New text");
display.display();
________________________________________
💡 Tip: For updating text frequently on the same line (like a counter), it's better to erase just that line instead of clearing the whole screen. This reduces flickering.
________________________________________
If you want, I can give you a ready-to-use function called updateLine(y, text, size) that automatically clears and prints a new line without touching the rest of the screen. That's usually the cleanest way. Do you want me to do that?
Arduino ide board packages, what is the difference between the seeed xiao nrf52840 mbed-enabled board and the normal board ?
When you add Seeed Studio XIAO nRF52840 (or the Sense variant) to the Arduino IDE, you'll actually see two different board packages you can install in Tools → Boards Manager:
• Seeed nRF52 Boards
• Seeed nRF52 mbed enabled Boards
The physical boa rd itself (the XIAO) is the same Nordic nRF52840 based hardware; what you're choosing in the IDE is actually which “core” or software support package is used to compile your sketches.
________________________________________
🧠 What the Two Board Packages Mean
🔹 Seeed nRF52 Boards (Normal/Non mbed)
• This is the original Arduino core support for the nRF52840 provided by Seeed.
• It uses a more traditional Arduino style build system (and historically some Adafruit tooling underneath).
• Works fine for basic GPIO, BLE, I²C/SPI, etc.
• Some functions may require extra includes (e.g., serial over USB might need #include <Adafruit_TinyUSB.h>).
• Certain libraries (IMU, PDM mic, advanced BLE examples) may not work or compile with this core.
🔹 Seeed nRF52 mbed enabled Boards (Mbed based)
• This package uses Mbed OS as the underlying core — so sketches are still Arduino code, but compiled with Mbed support.
• Often has better support for Serial over USB out of the box (no extra includes).
• More compatible with advanced features like IMU, PDM microphone, TinyML workflows, and some Bluetooth libraries.
• Defines ARDUINO_ARCH_NRF52840 in the build, which some libraries rely on.
________________________________________
🧩 So What's the Difference for You?
| Feature | Normal Board Package | mbed Enabled Board Package |
|---|---|---|
| Basic Arduino support | ✅ | ✅ |
| Serial/USB without extra includes | ❌¹ | ✅ |
| Good BLE examples & libraries | Partial | Better |
| IMU / PDM mic support | Limited | Better |
| Some third party libraries | Works | Works more reliably |
¹ Might require #include <Adafruit_TinyUSB.h> to get Serial prints going with the normal core.
________________________________________
📌 When to Use Which
• Normal (non mbed) — If you only need basic BLE, GPIO, analog, etc., and don't mind manually adding USB support.
• Mbed enabled — If you plan to use more advanced peripherals (IMU, microphone), rely on Serial without extra tweaks, or want broader library compatibility.
________________________________________
🧠 Why This Setup Exists
Seeed provides both cores basically because:
• The classic board package works for basic Arduino functions but isn't always compatible with all newer libraries.
• The mbed enabled package leverages Mbed OS to improve driver support and compatibility — at the cost of being a slightly different toolchain.
________________________________________
If you want a quick recommendation: install both packages in the Arduino IDE. Then try compiling your intended libraries with each; if one fails, switch to the other.
Would you like a list of which specific libraries work/not work with each package (e.g., Bluetooth, IMU, microphone)?
Explain bluetooth low energy.
Bluetooth Low Energy (BLE) is a wireless communication technology designed for devices that need to send small amounts of data while using very little power. It's part of the broader Bluetooth family, but optimized for efficiency instead of continuous high-speed data transfer.
________________________________________
🔑 Core Idea
BLE lets devices communicate over short distances (typically up to ~100 meters) while consuming minimal battery—so devices can run for months or even years on small batteries.
________________________________________
⚙️ How BLE Works (Simple Version)
BLE uses a client-server model:
• Peripheral (server): broadcasts data (e.g., a fitness tracker)
• Central (client): scans and connects (e.g., your phone)
Communication happens in small bursts:
1. Devices advertise their presence
2. A central device connects
3. Data is exchanged in short packets
4. Devices go back to sleep quickly → saves power
________________________________________
🔋 Why It's “Low Energy”
BLE saves energy by:
• Sending small chunks of data instead of continuous streams
• Using short connection times
• Letting devices stay in sleep mode most of the time
That's why things like smartwatches or sensors don't need frequent charging.
________________________________________
📡 Key Features
• Low power consumption → ideal for battery-powered devices
• Short bursts of data → not for heavy streaming
• Fast connection setup → connects quickly
• Works in 2.4 GHz band (same as regular Bluetooth & Wi-Fi)
________________________________________
📱 Common Uses
BLE is everywhere in modern tech:
• Fitness trackers (heart rate, steps)
• Smartwatches
• Wireless medical devices
• Smart home sensors (temperature, motion)
• Beacons (used in stores or museums for location-based info)
________________________________________
🆚 BLE vs Classic Bluetooth
| Feature | BLE | Classic Bluetooth |
|---|---|---|
| Power usage | Very low | Higher |
| Data transfer | Small, infrequent | Continuous, larger data |
| Use cases | IoT, wearables, sensors | Audio (headphones, speakers) |
| Battery life | Months/years | Hours/days |
________________________________________
🧠 Quick Analogy
Think of BLE like sending quick text messages occasionally, while classic Bluetooth is like being on a continuous phone call.
________________________________________
If you want, I can break down BLE protocols like GATT/ATT or show how apps actually read data from BLE devices.
Using a XIAO nRF52840 and Arduino IDE with ArduinoBLE and BLE, how to do a simple communication with a sender and a receiver.
Got it! You want to set up a simple BLE communication between two devices using a Seeed XIAO nRF52840 with the Arduino IDE and ArduinoBLE library. I'll break it down step by step with a working example: one device as a BLE Peripheral (Sender) and the other as a BLE Central (Receiver).
________________________________________
1️⃣ Hardware Setup
• Two XIAO nRF52840 boards.
• USB connection to your PC for programming.
• Arduino IDE with ArduinoBLE library installed.
________________________________________
2️⃣ Peripheral (Sender) Code
This device will advertise a BLE service and send data.
#include <ArduinoBLE.h>
// Define BLE service and characteristic
BLEService messageService("180C"); // custom service UUID
BLEStringCharacteristic messageChar(
"2A56", // custom characteristic UUID
BLERead | BLENotify,
50 // max length
);
void setup() {
Serial.begin(115200);
while (!Serial)
;
if (!BLE.begin()) {
Serial.println("Starting BLE failed!");
while (1)
;
}
// Set device name
BLE.setLocalName("XIAO_BLE");
BLE.setAdvertisedService(messageService);
// Add characteristic to service
messageService.addCharacteristic(messageChar);
BLE.addService(messageService);
// Set initial value
messageChar.writeValue("Hello from XIAO!");
// Start advertising
BLE.advertise();
Serial.println("BLE device is now advertising...");
}
void loop() {
BLEDevice central = BLE.central();
if (central) {
Serial.print("Connected to central: ");
Serial.println(central.address());
while (central.connected()) {
// Send updated message every 2 seconds
messageChar.writeValue("Hello BLE!");
delay(2000);
}
Serial.println("Disconnected");
}
}
✅ What this does:
• Sets up a BLE service and characteristic.
• Advertises as "SenderDevice".
• Sends incremental values to any connected central
________________________________________
3️⃣ Central (Receiver) Code
This device will scan for the peripheral and read the data.
#include <ArduinoBLE.h>
const char* deviceName = "XIAO_BLE";
// UUIDs must match the peripheral!
BLEUuid serviceUUID("180C");
void setup() {
Serial.begin(115200);
while (!Serial);
if (!BLE.begin()) {
Serial.println("BLE failed to start");
while (1);
}
Serial.println("Scanning for BLE device...");
BLE.scan();
}
void loop() {
BLEDevice peripheral = BLE.available();
if (peripheral) {
// Check if it's our device
if (peripheral.localName() == deviceName) {
Serial.println("Found XIAO device!");
BLE.stopScan();
if (connectToPeripheral(peripheral)) {
Serial.println("Done reading.");
}
// Restart scanning after disconnect
BLE.scan();
}
}
}
bool connectToPeripheral(BLEDevice peripheral) {
Serial.print("Connecting to: ");
Serial.println(peripheral.address());
if (!peripheral.connect()) {
Serial.println("Connection failed!");
return false;
}
Serial.println("Connected!");
if (!peripheral.discoverAttributes()) {
Serial.println("Attribute discovery failed!");
peripheral.disconnect();
return false;
}
BLECharacteristic messageChar = peripheral.characteristic("2A56");
if (!messageChar) {
Serial.println("Characteristic not found!");
peripheral.disconnect();
return false;
}
if (!messageChar.canRead()) {
Serial.println("Cannot read characteristic!");
peripheral.disconnect();
return false;
}
while (peripheral.connected()) {
BLECharacteristic messageChar = peripheral.characteristic("2A56");
if (messageChar && messageChar.canRead()) {
char buffer[50];
int len = messageChar.readValue((unsigned char*)buffer, sizeof(buffer));
if (len > 0 && len < sizeof(buffer)) {
buffer[len] = '\0';
Serial.print("Received: ");
Serial.println(buffer);
}
}
delay(2000);
}
Serial.println("Disconnected.");
return true;
}
✅ What this does:
• Continuously scans for "SenderDevice".
• Connects and reads the characteristic 2A56.
• Prints received values to Serial Monitor.
________________________________________
4️⃣ Notes and Tips
1. Make sure both devices use the same UUIDs for service and characteristic.
2. Use BLERead + BLENotify in Peripheral and canRead() in Central.
3. You can also use myCharacteristic.subscribe() on Central to get notified automatically (no polling required).
4. BLE is limited in data size per packet (~20 bytes for simple characteristics).
5. Use Serial Monitor at 9600 baud for debugging.
________________________________________
If you want, I can also provide a version using notifications so the central doesn't need to poll—making communication faster and more efficient.
Do you want me to show that version?