Created
February 19, 2018 10:35
-
-
Save mristau/8fe061636f4f0376e1ef8817ce1c2fec to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SPI.h> | |
#include <BLEPeripheral.h> | |
#include <nrf_sdm.h> | |
#include <nrf_soc.h> | |
#include <WInterrupts.h> | |
#define BAUDRATE 38400 | |
#define BUTTON_PIN 29 // Active Low Button on my Board at this pin | |
#define INTERRUPT_PIN 19 // Active High Interrupt from Lis2de12 accelerometer | |
#define BATTERY_PIN A2 // LiPo charging circuit output of battery voltage | |
#define DEVICE_NAME "BLE-Test Device" | |
#define DescriptorUUID "2901" | |
#define BatteryLevelServiceUUID "180F" | |
#define BatteryLevelCharUUID "2A19" | |
BLEPeripheral blePeripheral = BLEPeripheral(); | |
BLEService batteryLevelService = BLEService(BatteryLevelServiceUUID); | |
BLEUnsignedCharCharacteristic batteryLevelChar = BLEUnsignedCharCharacteristic(BatteryLevelCharUUID, BLERead | BLENotify); | |
BLEDescriptor batteryLevelDescriptor = BLEDescriptor(DescriptorUUID, "Battery Level 0 - 100%"); | |
volatile bool buttonPressed = false; | |
volatile bool accelInterrupt = false; | |
uint8_t checkForSoftDevice() { | |
uint8_t check; | |
sd_softdevice_is_enabled(&check); | |
return check; | |
} | |
void constLat() { | |
//NRF_POWER_MODE_CONSTLAT, /**< Constant latency mode. See power management in the reference manual. */ | |
if (checkForSoftDevice() == 1) { | |
// SoftDevice enabled | |
sd_power_mode_set(NRF_POWER_MODE_CONSTLAT); | |
} else { | |
// No SoftDevice | |
NRF_POWER->TASKS_CONSTLAT = 1; | |
} | |
} | |
void lowPower() { | |
//NRF_POWER_MODE_LOWPWR /**< Low power mode. See power management in the reference manual. */ | |
if (checkForSoftDevice() == 1) { | |
// SoftDevice enabled | |
sd_power_mode_set(NRF_POWER_MODE_LOWPWR); | |
} else { | |
// No SoftDevice | |
NRF_POWER->TASKS_LOWPWR = 1; | |
} | |
} | |
void powerOff() { | |
if (checkForSoftDevice() == 1) { | |
// SoftDevice enabled | |
sd_power_system_off(); | |
} else { | |
// No SoftDevice | |
NRF_POWER->SYSTEMOFF = 1; | |
} | |
} | |
void buttonHandler() { | |
buttonPressed = true; | |
} | |
void accelHandler() { | |
accelInterrupt = true; | |
} | |
/* | |
* The sketch uses BLEPeripheral to create an environmental sensor service and defines pressure, temperature, | |
* and elevation characteristics as well as a battery service to monitor the battery voltage level via a battery | |
* level characteristic. A resistor divider needs to be added to any analog pin so the voltage can be sampled | |
* between 0 and the 3V3 of the board (27K/100K will do) such that the ADC will read 0 at 0 V and 4095 at | |
* 4.2 V of LiPo battery voltage. | |
*/ | |
void updateBatteryLevel() { | |
float VBAT; | |
int16_t level = analogRead(BATTERY_PIN); | |
// (127.0f/100.0f) = ((R1+R2) / R2) | |
VBAT = (127.0f/100.0f) * 3.30f * ((float)level)/4095.0f; // convert to the LiPo battery voltage | |
Serial.print("VBAT = "); Serial.println(VBAT, 2); | |
// 3600 equals to 3.7V of a LiPo battery which is the nominal Voltage, so all above 3.7V will be 100% | |
level = constrain(level, 0, 3600); | |
// 3200 equals to 3.3V of a LiPo, as the chip will turn off at ~3.3V i'm mapping that to 0% | |
uint8_t batteryLevel = map(level, 3200, 3600, 0, 100); | |
batteryLevelChar.setValue((uint8_t)batteryLevel); // set the battery level characteristic value | |
} | |
void blePeripheralConnectHandler(BLECentral& central) { | |
Serial.print(F("Connected event, central: ")); | |
Serial.println(central.address()); | |
} | |
void blePeripheralDisconnectHandler(BLECentral& central) { | |
Serial.print(F("Disconnected event, central: ")); | |
Serial.println(central.address()); | |
} | |
void setupBLE() { | |
Serial.println("Setup BLE Peripheral"); | |
blePeripheral.setLocalName(DEVICE_NAME); | |
blePeripheral.setAdvertisedServiceUuid(batteryLevelService.uuid()); | |
blePeripheral.setAdvertisingInterval(100); | |
blePeripheral.setAppearance(0x0000); | |
blePeripheral.setConnectable(true); | |
blePeripheral.setDeviceName(DEVICE_NAME); | |
blePeripheral.addAttribute(batteryLevelService); | |
blePeripheral.addAttribute(batteryLevelChar); | |
blePeripheral.addAttribute(batteryLevelDescriptor); | |
// assign event handlers for connected, disconnected to peripheral | |
blePeripheral.setEventHandler(BLEConnected, blePeripheralConnectHandler); | |
blePeripheral.setEventHandler(BLEDisconnected, blePeripheralDisconnectHandler); | |
// begin initialization | |
blePeripheral.begin(); | |
} | |
void setup() { | |
Serial.begin(BAUDRATE); | |
delay(2000); | |
setupBLE(); | |
pinMode(INTERRUPT_PIN, INPUT); | |
pinMode(BATTERY_PIN, INPUT); | |
analogReadResolution(12); // take advantage of 12-bit ADCs | |
pinMode(BUTTON_PIN, INPUT_PULLUP); | |
attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), buttonHandler, FALLING); | |
attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), accelHandler, RISING); | |
NRF_GPIO->PIN_CNF[INTERRUPT_PIN] &= ~((uint32_t)GPIO_PIN_CNF_SENSE_Msk); | |
NRF_GPIO->PIN_CNF[INTERRUPT_PIN] |= ((uint32_t)GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos); | |
} | |
void loop() { | |
blePeripheral.poll(); | |
updateBatteryLevel(); | |
if (buttonPressed) { | |
// Button press will shutdown the nRF, choose the right function for your usage | |
buttonPressed = false; | |
powerOff(); | |
// lowPower(); | |
// constLat(); | |
} | |
if (accelInterrupt) { | |
accelInterrupt = false; | |
} | |
delay(1000); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment