Hello,
I have a project where I am sending an LED on/off command from a Teensy 4.1 to an MKR Wifi 1010 via I2C using Wire.h and then need to send that same LED on/off via BLE to a second MKR Wifi 1010 that will have an actual light attached to it. I have setup the first MKR as the Central and the second MKR as the Peripheral with an LED Service and a Characteristic that I can write to and all of that is good. I can read the on/off via the I2C bus and light up the local LED on the Teensy as well as the Builtin LED on the first MKR fine. As a BLE test, I can also send an LED on/off loop to the second MKR via the Characteristic.writeValue and that also works fine. The part I'm stuck on is how to take the Wire.read LED on/off and send that via LED Characteristic.writeValue?
Here is my code and the heart of the read/write are towards the bottom. Thanks for any help on this.
#include <ArduinoBLE.h>
#include <Wire.h>
int LED = 3;
int x = 0;
void setup() {
Serial.begin(9600);
//WiFiDrv::pinMode(27, OUTPUT); //define blue pin
pinMode ( LED, OUTPUT);
// initialize the Bluetooth® Low Energy hardware
BLE.begin();
Serial.println("Bluetooth® Low Energy Central - LED control");
// start scanning for peripherals
BLE.scanForUuid("79055cb9-70d2-4739-a687-c6065d41fb83");
Wire.begin(1);
Wire.onReceive(receiveEvent);
}
void loop() {
// check if a peripheral has been discovered
BLEDevice peripheral = BLE.available();
if (peripheral) {
// discovered a peripheral, print out address, local name, and advertised service
Serial.print("Found ");
Serial.print(peripheral.address());
Serial.print(" '");
Serial.print(peripheral.localName());
Serial.print("' ");
Serial.print(peripheral.advertisedServiceUuid());
Serial.println();
if (peripheral.localName() != "LED") {
return;
}
// stop scanning
BLE.stopScan();
controlLed(peripheral);
// peripheral disconnected, start scanning again
BLE.scanForUuid("79055cb9-70d2-4739-a687-c6065d41fb83");
}
}
void controlLed(BLEDevice peripheral) {
// connect to the peripheral
Serial.println("Connecting ...");
if (peripheral.connect()) {
Serial.println("Connected");
} else {
Serial.println("Failed to connect!");
return;
}
// discover peripheral attributes
Serial.println("Discovering attributes ...");
if (peripheral.discoverAttributes()) {
Serial.println("Attributes discovered");
} else {
Serial.println("Attribute discovery failed!");
peripheral.disconnect();
return;
}
// retrieve the LED characteristic
BLECharacteristic ledCharacteristic = peripheral.characteristic("74b3ab05-e45b-4706-8504-89113a04c570");
if (!ledCharacteristic) {
Serial.println("Peripheral does not have LED characteristic!");
peripheral.disconnect();
return;
} else if (!ledCharacteristic.canWrite()) {
Serial.println("Peripheral does not have a writable LED characteristic!");
peripheral.disconnect();
return;
}
//------------------------------------------------------------------------------------------------------------------
// This part is just a test to write the LED on/off via BLE to the second MKR WiFi-This works as it should
//------------------------------------------------------------------------------------------------------------------
while (peripheral.connected()) {
// while the peripheral is connected
ledCharacteristic.writeValue((byte)0x01);
delay(1000);
ledCharacteristic.writeValue((byte)0x00);
delay(1000);
}
Serial.println("Peripheral disconnected");
}
//------------------------------------------------------------------------------------------------------------------
// This is reading the I2C value and does write to the builtin LED as it should.
//. ***. This is the value I want to write to the second MKR via BLE***
//------------------------------------------------------------------------------------------------------------------
void receiveEvent(int howMany) {
x = Wire.read(); // read one character from the I2C
if (x == 1) {
digitalWrite(LED, HIGH);
}
else{
digitalWrite(LED, LOW);
}
}
Hello @Railroader! What I mean by "Characteristic.writeValue".. At the end of my code there is this code that shows how I can write the LED Characteristic to MKR #2 via BLE. Whats in the code right now is just a simple LED Blink being written via BLE to the second MKR-and this works fine. Right below that is the "void receiveEvent" code that is being received by the Wire iC2 READ and it assigns a variable X(or 1 or a 0) and turns on/off the local LED on MKR 1- This works fine. So now that I have proved I'm receiving the blink message from the PC>to the Teensy>to the MKR #1 via iC2 - and I have a good BLE link from MKR 1 to MKR 2 now I'm trying to understand how I get my Wire read via the iC2 bus to blink on my MKR 2 via BLE. Everything I have tried gives me the "not declared in this scope" error. Like trying to write to the ledCharacteristic.writeValue right from the x= Wire.read code.
//------------------------------------------------------------------------------------------------------------------
// This part is just a test to write the LED on/off via BLE to the second MKR WiFi-This works as it should
//------------------------------------------------------------------------------------------------------------------
while (peripheral.connected()) {
// while the peripheral is connected
ledCharacteristic.writeValue((byte)0x01);
delay(1000);
ledCharacteristic.writeValue((byte)0x00);
delay(1000);
}
Serial.println("Peripheral disconnected");
}
//------------------------------------------------------------------------------------------------------------------
// This is reading the I2C value and does write to the builtin LED as it should.
//. ***. This is the value I want to write to the second MKR via BLE***
//------------------------------------------------------------------------------------------------------------------
void receiveEvent(int howMany) {
x = Wire.read(); // read one character from the I2C
if (x == 1) {
digitalWrite(LED, HIGH);
}
else{
digitalWrite(LED, LOW);
}
Here's the whole sketch with trying to print to the ledCharacteristic.writeValue at the bottom.
#include <ArduinoBLE.h>
#include <Wire.h>
int LED = 3;
int x = 0;
void setup() {
Serial.begin(9600);
//WiFiDrv::pinMode(27, OUTPUT); //define blue pin
pinMode ( LED, OUTPUT);
// initialize the Bluetooth® Low Energy hardware
BLE.begin();
Serial.println("Bluetooth® Low Energy Central - LED control");
// start scanning for peripherals
BLE.scanForUuid("79055cb9-70d2-4739-a687-c6065d41fb83");
Wire.begin(1);
Wire.onReceive(receiveEvent);
}
void loop() {
// check if a peripheral has been discovered
BLEDevice peripheral = BLE.available();
if (peripheral) {
// discovered a peripheral, print out address, local name, and advertised service
Serial.print("Found ");
Serial.print(peripheral.address());
Serial.print(" '");
Serial.print(peripheral.localName());
Serial.print("' ");
Serial.print(peripheral.advertisedServiceUuid());
Serial.println();
if (peripheral.localName() != "LED") {
return;
}
// stop scanning
BLE.stopScan();
controlLed(peripheral);
// peripheral disconnected, start scanning again
BLE.scanForUuid("79055cb9-70d2-4739-a687-c6065d41fb83");
}
}
void controlLed(BLEDevice peripheral) {
// connect to the peripheral
Serial.println("Connecting ...");
if (peripheral.connect()) {
Serial.println("Connected");
} else {
Serial.println("Failed to connect!");
return;
}
// discover peripheral attributes
Serial.println("Discovering attributes ...");
if (peripheral.discoverAttributes()) {
Serial.println("Attributes discovered");
} else {
Serial.println("Attribute discovery failed!");
peripheral.disconnect();
return;
}
// retrieve the LED characteristic
BLECharacteristic ledCharacteristic = peripheral.characteristic("74b3ab05-e45b-4706-8504-89113a04c570");
if (!ledCharacteristic) {
Serial.println("Peripheral does not have LED characteristic!");
peripheral.disconnect();
return;
} else if (!ledCharacteristic.canWrite()) {
Serial.println("Peripheral does not have a writable LED characteristic!");
peripheral.disconnect();
return;
}
//------------------------------------------------------------------------------------------------------------------
// This part is just a test to write the LED on/off via BLE to the second MKR WiFi-This works as it should
//------------------------------------------------------------------------------------------------------------------
while (peripheral.connected()) {
// while the peripheral is connected
ledCharacteristic.writeValue((byte)0x01);
delay(1000);
ledCharacteristic.writeValue((byte)0x00);
delay(1000);
}
Serial.println("Peripheral disconnected");
}
//------------------------------------------------------------------------------------------------------------------
// This is reading the I2C value and does write to the builtin LED as it should.
//. ***. This is the value I want to write to the second MKR via BLE***
//------------------------------------------------------------------------------------------------------------------
void receiveEvent(int howMany) {
x = Wire.read(); // read one character from the I2C
if (x == 1) {
ledCharacteristic.writeValue((byte)0x01);
}
else{
ledCharacteristic.writeValue((byte)0x00);
}
}
Returns this error:
/private/var/folders/8x/700kp8mj6vd5w_x8stw53z_r0000gn/T/.arduinoIDE-unsaved2024922-8753-1v4pa5a.q0wr/sketch_oct22a/sketch_oct22a.ino: In function 'void receiveEvent(int)':
/private/var/folders/8x/700kp8mj6vd5w_x8stw53z_r0000gn/T/.arduinoIDE-unsaved2024922-8753-1v4pa5a.q0wr/sketch_oct22a/sketch_oct22a.ino:115:7: error: 'ledCharacteristic' was not declared in this scope
ledCharacteristic.writeValue((byte)0x01);
^~~~~~~~~~~~~~~~~
/private/var/folders/8x/700kp8mj6vd5w_x8stw53z_r0000gn/T/.arduinoIDE-unsaved2024922-8753-1v4pa5a.q0wr/sketch_oct22a/sketch_oct22a.ino:115:7: note: suggested alternative: 'BLECharacteristic'
ledCharacteristic.writeValue((byte)0x01);
^~~~~~~~~~~~~~~~~
BLECharacteristic
/private/var/folders/8x/700kp8mj6vd5w_x8stw53z_r0000gn/T/.arduinoIDE-unsaved2024922-8753-1v4pa5a.q0wr/sketch_oct22a/sketch_oct22a.ino:118:7: error: 'ledCharacteristic' was not declared in this scope
ledCharacteristic.writeValue((byte)0x00);
^~~~~~~~~~~~~~~~~
/private/var/folders/8x/700kp8mj6vd5w_x8stw53z_r0000gn/T/.arduinoIDE-unsaved2024922-8753-1v4pa5a.q0wr/sketch_oct22a/sketch_oct22a.ino:118:7: note: suggested alternative: 'BLECharacteristic'
ledCharacteristic.writeValue((byte)0x00);
^~~~~~~~~~~~~~~~~
BLECharacteristic
exit status 1
Compilation error: 'ledCharacteristic' was not declared in this scope
This variable is change within an interrupt routine, and should be declared volatile. It should also be a byte, as you are reading a single byte in the receive event.
//int x = 0;
volatile byte x = 0;
Then, I would use this variable as follows.
void receiveEvent(int howMany) {
x = Wire.read(); // read one character from the I2C
}
Then in while (peripheral.connected())
while (peripheral.connected()) {
// while the peripheral is connected
static unsigned long lastWriteTime = 0;
if (millis() - lastWriteTime >= 1000)
{
lastWriteTime = millis();
ledCharacteristic.writeValue(x);
//delay(1000);
//ledCharacteristic.writeValue((byte)0x00);
//delay(1000);
}
}
Serial.println("Peripheral disconnected");
}
This comes from the <ArduinoBLE.h> library. Then in:
void controlLed(BLEDevice peripheral) {
// connect to the peripheral
Serial.println("Connecting ...");
if (peripheral.connect()) {
Serial.println("Connected");
} else {
Serial.println("Failed to connect!");
return;
}
I use:
// retrieve the LED characteristic
BLECharacteristic ledCharacteristic = peripheral.characteristic("74b3ab05-e45b-4706-8504-89113a04c570");
if (!ledCharacteristic) {
Serial.println("Peripheral does not have LED characteristic!");
peripheral.disconnect();
return;
} else if (!ledCharacteristic.canWrite()) {
Serial.println("Peripheral does not have a writable LED characteristic!");
peripheral.disconnect();
return;
}