Hi,
looking for assistance here.
Trying to display pressure sensor (FSR) data on an android app.
I've got the following sketch and it runs, but the LED flashes and then goes off on the Nano and i cant get it to connect to my phone. I've paired it to the phone but then no app i use can find the Nano.
What am i doing wrong?
/*
Embedded system:
- Arduino Nano 33 IoT,
Peripheral devices and apps
- Samsung Galaxy S22 Ultra (Android)
- ArduTooth application available at Google Play Store (Android)
*/
// include libraries
#include <ArduinoBLE.h>
// the FSR and 10K pulldown are connected to A0
#define FORCE_SENSOR_PIN A0
//define device and local names,
//and LED PIN
#define BLE_DEVICE_NAME "FSR"
#define BLE_LOCAL_NAME "FSR"
#define BLE_LED_PIN LED_BUILTIN
//define constants
// Bluetooth® Low Energy LED Service
BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214");
// Bluetooth® Low Energy LED Switch Characteristic - custom 128-bit UUID, read and writable by central
BLEByteCharacteristic switchCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);
// pin to use for the LED
const int ledPin = LED_BUILTIN;
// the FSR and 10K pulldown are connected to a0
int fsrPin = 0;
// the analog reading from the FSR resistor divider
int fsrReading;
int noPressure = 10;
int mediumPressure = 451;
int highPressure = 710;
void setup() {
Serial.begin(9600);
while (!Serial);
// set LED pin to output mode
pinMode(ledPin, OUTPUT);
// begin initialization
if (!BLE.begin()) {
Serial.println("starting Bluetooth® Low Energy module failed!");
while (1);
}
else
{
Serial.println( "BLE initialized. Waiting for clients to connect." );
}
// set advertised local name and service UUID:
BLE.setLocalName("FSR");
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 FSR Peripheral Active");
}
void loop() {
// listen for Bluetooth® Low Energy 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());
digitalWrite(LED_BUILTIN, HIGH);
// 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
Serial.println("FSR on");
digitalWrite(ledPin, HIGH); // will turn the LED on
} else { // a 0 value
Serial.println(F("FSR off"));
digitalWrite(ledPin, LOW); // will turn the LED off
}
}
}
// when the central disconnects, print it out and switch off LED:
digitalWrite(LED_BUILTIN, LOW);
Serial.print(F("Disconnected from central: "));
Serial.println(central.address());
}
fsrReading = analogRead(fsrPin);
Serial.print("Analog reading = ");
// print the raw analog reading
Serial.print(fsrReading);
map(fsrReading, -1, 710, 0, 100);
if ((-1 < fsrReading) && (fsrReading < 450)) { // from 0 to 450
Serial.println(" - Low pressure");
} else if ((451 < fsrReading) && (fsrReading < 600)) { // from 451 to 600
Serial.println(" - Advisory warning");
} else { // from 601 to 710
Serial.println(" - Take action");
}
delay(2000);
}
Pairing is on optional feature for BLE and not supported by the ArduinoBLE library. Do not try pairing on the OS level. You should connect from the app itself. Try a few other generic BLE apps to check whether it is working.
Using delay is a bad programming practice especially when you use communication stacks. Use millis to control timing in your code. Have a look at the following example
Here is an example I wrote for the Arduino Nano 33 BLE that will show you another way of creating a BLE peripheral. Some of the code will not work because it uses the sensors of the Arduino but the overall structure and library calls for BLE are the same.
You may want to assign the fsrReading value when you map it. And do not use the same variable. The value is different so use a variable with a different name. The variable is global you want to make sure you can always read it and make sense of it.
i adjusted it a little (see below). it's giving me a much faster interval now. Still unsure how to get the data to display on android - I've tried 8/9 different apps now.
Im not sure what you meant when you mentioned the fsrReading value (apologies for my noobishness).
/*
Embedded system:
- Arduino Nano 33 IoT,
Peripheral devices and apps
- Samsung Galaxy S22 Ultra (Android)
- ArduTooth application available at Google Play Store (Android)
*/
// include libraries
#include <ArduinoBLE.h>
// the FSR and 10K pulldown are connected to A0
#define FORCE_SENSOR_PIN A0
//define device and local names,
//and LED PIN
#define BLE_DEVICE_NAME "Arduino NANO 33 IoT"
#define BLE_LOCAL_NAME "Arduino NANO 33 IoT"
#define BLE_LED_PIN LED_BUILTIN
#define FSR "Force Sensing Resistor"
// Bluetooth® Low Energy LED Service
BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214");
// Bluetooth® Low Energy LED Switch Characteristic - custom 128-bit UUID, read and writable by central
BLEByteCharacteristic switchCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);
// pin to use for the LED
const int ledPin = LED_BUILTIN;
int ledState = LOW; // ledState used to set the LED
unsigned long previousMillis = 1000; // will store last time LED was updated
// constants won't change:
const long interval = 100000000; // interval at which to blink (milliseconds)
// the FSR and 10K pulldown are connected to a0
int fsrPin = 0;
// the analog reading from the FSR resistor divider
int fsrReading;
int noPressure = 10;
int mediumPressure = 451;
int highPressure = 710;
void setup() {
Serial.begin(9600);
while (!Serial);
// set LED pin to output mode
pinMode(ledPin, OUTPUT);
// begin initialization
if (!BLE.begin()) {
Serial.println("starting Bluetooth® Low Energy module failed!");
while (1);
}
else
{
Serial.println( "BLE initialized. Waiting for clients to connect." );
}
// set advertised local name and service UUID:
BLE.setLocalName("FSR");
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 FSR Peripheral Active");
}
void loop() {
// listen for Bluetooth® Low Energy 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());
digitalWrite(LED_BUILTIN, HIGH);
// 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
Serial.println("FSR on");
digitalWrite(ledPin, HIGH); // will turn the LED on
} else { // a 0 value
Serial.println(F("FSR off"));
digitalWrite(ledPin, LOW); // will turn the LED off
}
}
}
// when the central disconnects, print it out and switch off LED:
digitalWrite(LED_BUILTIN, LOW);
Serial.print(F("Disconnected from central: "));
Serial.println(central.address());
}
fsrReading = analogRead(fsrPin);
Serial.print("Analog reading = ");
// print the raw analog reading
Serial.print(fsrReading);
map(fsrReading, -1, 710, 0, 100);
if ((-1 < fsrReading) && (fsrReading < 450)) { // from 0 to 450
Serial.println(" - Low pressure");
} else if ((451 < fsrReading) && (fsrReading < 600)) { // from 451 to 600
Serial.println(" - Advisory warning");
} else { // from 601 to 710
Serial.println(" - Take action");
} unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}
bool setupBleMode()
{
if ( !BLE.begin() )
{
return false;
}
// set advertised local name and service UUID
BLE.setDeviceName( BLE_DEVICE_NAME );
BLE.setLocalName( BLE_LOCAL_NAME );
}
for anybody who sees this;
I struggled getting the BLE to work correctly despite numerous attempts at coding and numerous apps for a display. Eventually i used Arduino IoT Cloud and set it to run on an android display (must download it from Play Store onto phone).
The main issue i had was it turned out the board i had been given was broken so would connect but not show as "online" in the app. Swapped for different board and it worked first time.
Little bit of tweaking and it worked fine.
I've posted the coding below if it helps anyone else. The "thingProperties.h" is a library created automatically by the app using examples.
#include "arduino_secrets.h"
/*
Sketch generated by the Arduino IoT Cloud Thing "Untitled"
https://create.arduino.cc/cloud/things/66331143-5499-4e73-875e-02da599f2f21
Arduino IoT Cloud Variables description
The following variables are automatically generated and updated when changes are made to the Thing
float pressureSensorFSR;
bool warningLED;
Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
which are called when their values are changed from the Dashboard.
These functions are generated with the Thing and added at the end of this sketch.
*/
#include "thingProperties.h"
// the FSR and 10K pulldown are connected to A0
#define FORCE_SENSOR_PIN A0
#define FSR "Force Sensing Resistor"
// pin to use for the LED
const int ledPin = LED_BUILTIN;
int ledState = LOW; // ledState used to set the LED
unsigned long previousMillis = 1000; // will store last time LED was updated
// constants won't change:
const long interval = 100000000; // interval at which to blink (milliseconds)
// the FSR and 10K pulldown are connected to a0
int fsrPin = 0;
// the analog reading from the FSR resistor divider
int fsrReading;
int noPressure = 10;
int mediumPressure = 451;
int highPressure = 710;
void setup() {
// Initialize serial and wait for port to open:
Serial.begin(9600);
// This delay gives the chance to wait for a Serial Monitor without blocking if none is found
delay(1500);
// Defined in thingProperties.h
initProperties();
// Connect to Arduino IoT Cloud
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
/*
The following function allows you to obtain more information
related to the state of network and IoT Cloud connection and errors
the higher number the more granular information you’ll get.
The default is 0 (only errors).
Maximum is 4
*/
setDebugMessageLevel(2);
ArduinoCloud.printDebugInfo();
}
void loop() {
ArduinoCloud.update();
// Your code here
fsrReading = analogRead(fsrPin);
Serial.print("Analog reading = ");
// print the raw analog reading
Serial.print(fsrReading);
pressureSensorFSR=fsrReading;
map(fsrReading, -1, 1023, 0, 100);
if ((-1 < fsrReading) && (fsrReading < 450)) { // from 0 to 450
Serial.println(" - Low pressure");
warningLED = false;
} else if ((451 < fsrReading) && (fsrReading < 600)) { // from 451 to 600
Serial.println(" - Advisory warning");
warningLED = false;
} else { // from 601 to 1023
Serial.println(" - Take action");
warningLED = true;
} unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}