#include <ArduinoBLE.h>
#include <LSM6DS3.h>
#include <Wire.h>
const int buttonPin = 2; // the number of the pushbutton pin
const int ledPin = 13; // the number of the LED pin
const int NTC_PIN = A0;
int buttonState = 0;
float temperature = 0.0;
const float BETA = 3950; // should match the Beta Coefficient of the thermistor
const int usbPin = LEDG;
int usbState = 0;
// https://github.com/NordicSemiconductor/bluetooth-numbers-database/blob/master/v1/characteristic_uuids.json
// Pressure 2A6D
// Scientific Temperature Celsius 2A3C
// "Temperature","uuid": "2A6E"
// "Temperature Celsius", "uuid": "2A1F"
//"Temperature Fahrenheit", "uuid": "2A20"
//"Temperature Measurement uuid": "2A1C"
// "Temperature uuid": "2A1D"
const char* blePeripheralName = "MyBLEDevice";
BLEService customService("2A3C");
BLEStringCharacteristic customCharacteristic("2A3C", BLERead | BLENotify, 1024);
LSM6DS3 myIMU(I2C_MODE, 0x6A); // IMU
#define int1Pin 2
uint8_t interruptCount = 0; // Amount of received interrupts
uint8_t prevInterruptCount = 0; // Interrupt Counter from last loop
void setup() {
Serial.begin(9600);
if (!BLE.begin()) {
Serial.println("Starting BLE failed!");
while (1);
}
BLE.setLocalName(blePeripheralName);
BLE.setAdvertisedService(customService);
customService.addCharacteristic(customCharacteristic);
BLE.addService(customService);
BLE.advertise();
Serial.println("Bluetooth device active, waiting for connections...");
if (myIMU.begin() != 0) {
Serial.println("IMU error");
} else {
Serial.println("IMU OK!");
}
myIMU.settings.gyroEnabled = 0; // Gyro currently not used, disabled to save power
setupDoubleTapInterrupt();
pinMode(int1Pin, INPUT);
attachInterrupt(digitalPinToInterrupt(int1Pin), int1ISR, RISING);
pinMode(LED_BUILTIN, OUTPUT);// initialize the LED pin as an output:
pinMode(buttonPin, INPUT_PULLUP);// initialize the pushbutton pin as an input:
pinMode(LEDR, OUTPUT);
pinMode(LEDG, OUTPUT);
pinMode(LEDB, OUTPUT);
setLedRGB(false, false, true); // set blue led
}
void loop() {
BLEDevice central = BLE.central();
temperature = getNTCTemperature();
usbState = digitalRead(usbPin);
if (central) {
Serial.print("Connected to central: ");
Serial.println(central.address());
while (central.connected()) {
buttonState = digitalRead(buttonPin);
Serial.println(buttonState);
// Check if digital input is LOW (0)
if ( buttonState == 0 ) {
// Send an alert to the connected central device
customCharacteristic.writeValue("Wire Disconnected!");
digitalWrite(ledPin, HIGH);
}
else
{
digitalWrite(ledPin, LOW);
customCharacteristic.writeValue("Wire Connected");
}
delay(1000); // Adjust the delay according to your requirements
}
digitalWrite(ledPin, HIGH);
Serial.print("Disconnected from central: ");
Serial.println(central.address());
}
Serial.print("\Iterrupt Counter: ");
Serial.println(interruptCount);
// if interrupt was received in this cycle
if (interruptCount > prevInterruptCount) {
Serial.println("\Interrupt received!");
setLedRGB(false, true, false); // set green only
}
prevInterruptCount = interruptCount;
if (interruptCount >= 3) {
// Trigger System OFF after 3 interrupts
goToPowerOff();
}
delay(500);
}
// NTC
float getNTCTemperature()
{
int analogValue = analogRead(NTC_PIN);
float celsius = 1 / (log(1 / (1023. / analogValue - 1)) / BETA + 1.0 / 298.15) - 273.15;
Serial.print("Temperature: ");
Serial.print(celsius);
Serial.println(" ℃");
return celsius;
}
// -------------------- System ------------------------- //
void goToPowerOff() {
setLedRGB(false, false, false);
Serial.println("Going to System OFF");
setupDoubleTapInterrupt(); // not needed here, if already applied..
delay(1000); // delay seems important to apply settings, before going to System OFF
//Ensure interrupt pin from IMU is set to wake up device
nrf_gpio_cfg_sense_input(digitalPinToInterrupt(int1Pin), NRF_GPIO_PIN_PULLDOWN, NRF_GPIO_PIN_SENSE_HIGH);
// Trigger System OFF
NRF_POWER->SYSTEMOFF = 1;
}
// -------------------- Interrupts ------------------------- //
void setupDoubleTapInterrupt() {
uint8_t error = 0;
uint8_t dataToWrite = 0;
// Double Tap Config
myIMU.writeRegister(LSM6DS3_ACC_GYRO_CTRL1_XL, 0x60); //* Acc = 416Hz (High-Performance mode)// Turn on the accelerometer
myIMU.writeRegister(LSM6DS3_ACC_GYRO_TAP_CFG1, 0x8E);// INTERRUPTS_ENABLE, SLOPE_FDS// Enable interrupts and tap detection on X, Y, Z-axis
myIMU.writeRegister(LSM6DS3_ACC_GYRO_TAP_THS_6D, 0x85);// Set tap threshold 8C
myIMU.writeRegister(LSM6DS3_ACC_GYRO_INT_DUR2, 0x7F);// Set Duration, Quiet and Shock time windows 7F
myIMU.writeRegister(LSM6DS3_ACC_GYRO_WAKE_UP_THS, 0x80);// Single & double-tap enabled (SINGLE_DOUBLE_TAP = 1)
myIMU.writeRegister(LSM6DS3_ACC_GYRO_MD1_CFG, 0x08);// Double-tap interrupt driven to INT1 pin
}
void int1ISR()
{
interruptCount++;
;
}
// -------------------- Utilities ------------------------- //
void setLedRGB(bool red, bool green, bool blue) {
if (!blue) { digitalWrite(LEDB, HIGH); } else { digitalWrite(LEDB, LOW); }
if (!green) { digitalWrite(LEDG, HIGH); } else { digitalWrite(LEDG, LOW); }
if (!red) { digitalWrite(LEDR, HIGH); } else { digitalWrite(LEDR, LOW); }
}
1 Like