I am working on a project for which I need to get a panel of 7 buttons to light up led strips on a display about 5m away. So far I have made it so I can control 1 led strip with one button and this works well. I am now confused on how to get the other 6 to connect to the same arduino via BLE. The idea is to have one arduino with all the buttons connected, then 1 arduino for each led strip. You press button 1 on the button arduino and this sends a signal to the display 1 arduino, lighting the display.
Here is my code so far, what would I need to do to it to add multiple buttons in ?
Thanks !!
//this code is loaded onto the board that is connected to the led strip
//if the code doesnt work it seems to kick start it by opening the serial monitor and then it will connect, not sure why this is
#include <ArduinoBLE.h>
#include <Adafruit_DotStar.h>
#include <SPI.h>
#define NUMPIXELS 144 // Number of LEDs in strip
#define BUTTON_PIN 9 //pin the button is on
#define DATAPIN 4 //the pin the data is plugged into
#define CLOCKPIN 5 //the pin the clock wire is plugged into
BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214"); // adress of the ledstrip that is referenced in the other set of code
Adafruit_DotStar strip(NUMPIXELS, DATAPIN, CLOCKPIN, DOTSTAR_BRG);
// BLE LED Switch Characteristic - custom 128-bit UUID, read and writable by central
BLEByteCharacteristic switchCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);
const int ledPin = 2; // pin to use for the LED
void setup() {
// set LED pin to output mode
pinMode(ledPin, OUTPUT);
// begin initialization
if (!BLE.begin()) {
Serial.println("starting BLE failed!");
while (1);
}
// set advertised local name and service UUID:
BLE.setLocalName("LED");
BLE.setAdvertisedService(ledService);
// add the characteristic to the service
ledService.addCharacteristic(switchCharacteristic);
// add service
BLE.addService(ledService);
// set the initial value for the characeristic:
switchCharacteristic.writeValue(0);
// start advertising
BLE.advertise();
Serial.println("BLE LED Peripheral");
strip.begin();
strip.show(); //pixels to 'off'
}
uint32_t white= strip.Color(255, 255, 255); //colour you want the lights
uint32_t off= strip.Color(0, 0, 0); //colour 'off'
void loop() {
// listen for BLE peripherals to connect:
BLEDevice central = BLE.central();
// if a central is connected to peripheral:
if (central) {
Serial.print("Connected to central: ");
// print the central's MAC address:
Serial.println(central.address());
// while the central is still connected to peripheral:
while (central.connected()) {
// if the remote device wrote to the characteristic,
// use the value to control the LED:
if (switchCharacteristic.written()) {
if (switchCharacteristic.value()) { // any value other than 0
strip.fill(white, 0, 144); //fill(Color,first pixel,last pixel)
strip.setBrightness(5); //set the brightness of the leds here, would keep about 40, doesnt like anything above that
strip.show(); //update the leds
delay(7000); //time you want the LEDs
strip.fill(off, 0, 144); //turns off leds
strip.setBrightness(0);
strip.show();
} else { // a 0 value
strip.fill(off, 0, 144);
strip.setBrightness(0);
strip.show();
}
}
}
// when the central disconnects, print it out:
Serial.print(F("Disconnected from central: "));
Serial.println(central.address());
}
}
//this code gets loaded onto the button board
#include <ArduinoBLE.h>
// variables for button
const int buttonPin = 2;
int oldButtonState = LOW;
void setup() {
// configure the button pin as input
pinMode(buttonPin, INPUT);
// initialize the BLE hardware
BLE.begin();
Serial.println("BLE Central - LED control");
// start scanning for peripherals
BLE.scanForUuid("19b10000-e8f2-537e-4f6c-d104768a1214"); //Put the adress of what you want the button to control here
}
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("19b10000-e8f2-537e-4f6c-d104768a1214");
}
}
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("19b10001-e8f2-537e-4f6c-d104768a1214");
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;
}
while (peripheral.connected()) {
// while the peripheral is connected
// read the button pin
int buttonState = digitalRead(buttonPin);
if (oldButtonState != buttonState) {
// button changed
oldButtonState = buttonState;
if (buttonState) {
Serial.println("button pressed");
// button is pressed, write 0x01 to turn the LED on
ledCharacteristic.writeValue((byte)0x01);
} else {
Serial.println("button released");
// button is released, write 0x00 to turn the LED off
ledCharacteristic.writeValue((byte)0x00);
}
}
}
Serial.println("Peripheral disconnected");
A typical way of doing this with BLE would be for the button to be the Peripheral and the LED strip to be the Central. The Central would connect to the Peripheral and subscribe to notifications on the "button" characteristic. Typically libraries/hardware aren't setup to have multiple Centrals connected at the same time to one Peripheral. This would seem to rule out doing it this way with your required hardware setup.
An alternative would be to have the buttons as the Central and the LED strips as the Peripheral. The Central would already know the details of the Peripheral device and initiate a connection and then do a write when a button is pressed. I would expect there to be a lot of lag between the button being pressed and something happening on the LED strip with this setup.
Another alternative is to do this with connection-less BLE, if security isn't a concern. The button board could act as a BLE beacon and you could encode information about which button has been pressed in the Service Data or the Manufacturer Data. The LED strips would be scanners reading the data from the beacon. I am not very familiar with BLE libraries on Arduino, there appears to be the command to set the Manufacturer Data but I couldn't find any command to read the data.