This commit is contained in:
Max 2021-04-08 16:03:34 +01:00
parent 84737a1a89
commit b9ad917346
2 changed files with 260 additions and 132 deletions

View File

@ -9,7 +9,7 @@ import UIKit
class ViewController: UIViewController {
var simpleBluetoothIO: SimpleBluetoothIO!
@IBOutlet var virtualButton:UISwitch!
@IBOutlet weak var ledToggleButton: UIButton!
@IBOutlet weak var statusLabel: UILabel!
@ -19,30 +19,30 @@ class ViewController: UIViewController {
@IBOutlet weak var pillsTotal: UILabel!
@IBOutlet weak var pillsAttached: UILabel!
@IBOutlet weak var refreshToggle: UISwitch!
let totalPills: Int = 6
var usedPills: Int = 0
var remainingPills: Int = 0
let updateFreq: Float = 2.0
weak var timer: Timer?
override func viewDidLoad() {
super.viewDidLoad()
overrideUserInterfaceStyle = .light
simpleBluetoothIO = SimpleBluetoothIO(serviceUUID: "4fafc201-1fb5-459e-8fcc-c5c9c331914b", delegate: self)
// startTimer()
}
deinit {
stopTimer()
}
func sendUpdateCommand(){
print("Sending update command...")
simpleBluetoothIO.writeValue(value: 51)
}
func startTimer() {
timer?.invalidate() // just in case you had existing `Timer`, `invalidate` it before we lose our reference to it
timer = Timer.scheduledTimer(withTimeInterval: TimeInterval(updateFreq), repeats: true) { [weak self] _ in
@ -53,15 +53,15 @@ class ViewController: UIViewController {
func stopTimer() {
timer?.invalidate()
}
@IBAction func ledToggleButtonDown(_ sender: UIButton) {
simpleBluetoothIO.writeValue(value:49)
}
@IBAction func ledToggleButtonUp(_ sender: UIButton) {
simpleBluetoothIO.writeValue(value: 50)
}
@IBAction func forcePillRefresh(_ sender: UIButton) {
self.sendUpdateCommand()
}
@ -72,7 +72,7 @@ class ViewController: UIViewController {
stopTimer()
}
}
}
extension ViewController: SimpleBluetoothIODelegate {
@ -85,12 +85,14 @@ extension ViewController: SimpleBluetoothIODelegate {
} else if value == 99 {
//view.backgroundColor = UIColor.black
virtualButton.setOn(false, animated: true)
} else if value == 55 {
} else if value == 97 {
self.pillsConsumed.text = "X"
self.pillsRemaining.text = "X"
self.pillsTotal.text = "X"
self.pillsAttached.text = "Detached"
self.pillsAttached.textColor = UIColor.red
} else if value == 96 {
self.pillsAttached.text = "TODO: Battery low..."
} else {
self.remainingPills = Int(value)
self.usedPills = self.totalPills - self.remainingPills
@ -101,7 +103,7 @@ extension ViewController: SimpleBluetoothIODelegate {
self.pillsAttached.textColor = UIColor.green
}
}
func simpleBluetoothIO(simpleBluetoothIO: SimpleBluetoothIO, didConnect value: Bool) {
print("VC: connect: \(value)")
self.cStatus.text = "Connected!"
@ -111,7 +113,7 @@ extension ViewController: SimpleBluetoothIODelegate {
self.sendUpdateCommand()
}
}
func simpleBluetoothIO(simpleBluetoothIO: SimpleBluetoothIO, didDisconnect value: Bool) {
print("VC: disconnect: \(value)")
self.cStatus.text = "Disconnected..."
@ -119,17 +121,17 @@ extension ViewController: SimpleBluetoothIODelegate {
self.pillsAttached.text = "Detached"
self.pillsAttached.textColor = UIColor.red
}
}
extension String {
func index(at position: Int, from start: Index? = nil) -> Index? {
let startingIndex = start ?? startIndex
return index(startingIndex, offsetBy: position, limitedBy: endIndex)
}
func character(at position: Int) -> Character? {
guard position >= 0, let indexPosition = index(at: position) else {
return nil

View File

@ -1,3 +1,13 @@
//
// main.ino
// PillTracker
//
// Created by Max Hunt on 16/01/2021.
// © Max Hunt 2021
// TODODODODODODO: SWITCH AROUND FOR PULLDOWN INPUT SYSTEM AND DEFAULT LOW RAIL OUTPUTS
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
@ -7,134 +17,250 @@
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
#define LED_PIN 2
#define BTN_PIN 5
#define PILL_1_PIN 25
#define PILL_2_PIN 13
#define PILL_3_PIN 12
#define PILL_4_PIN 26
#define PILL_5_PIN 27
#define PILL_6_PIN 14
#define DETECT_PIN 18
#define LED_PIN 13
#define TEST_BTN_PIN 5
int deviceConnected = false;
int waitingForUpdate = 0;
#define MUX_BIT_0 13
#define MUX_BIT_1 12
#define MUX_BIT_2 27
#define MUX_BIT_3 33
#define MUX_COM 32
#define RAIL_EVEN 15
#define RAIL_ODD 14
#define PILL_SENSE 21
#define BATTERY_PIN 35
// int deviceConnected = false;
bool waiting_for_update = false;
bool pills_plugged_in = false;
class MyCallbacks:public BLECharacteristicCallbacks {
void onConnect(BLEServer * pServer) {
deviceConnected = true;
Serial.println("device connected");
};
void onDisconnect(BLEServer * pServer) {
deviceConnected = false;
Serial.println("device disconnected");
}
void onWrite(BLECharacteristic * pCharacteristic) {
std::string value = pCharacteristic -> getValue();
if (value.length() > 0) {
Serial.print("*********");
Serial.print(value.c_str());
Serial.print("-");
Serial.print(atoi(value.c_str()));
Serial.print("-");
if (atoi(value.c_str()) == 1) {
digitalWrite(LED_PIN, HIGH);
Serial.print("LEDON");
} else if (atoi(value.c_str()) == 2) {
digitalWrite(LED_PIN, LOW);
Serial.print("LEDOFF");
} else if (atoi(value.c_str()) == 3) {
Serial.print("UPDATE_PILL_TRACK");
waitingForUpdate = 1;
} else {
Serial.println();
Serial.println(atoi(value.c_str()));
Serial.println();
}
Serial.println("*********");
}
}
void onConnect(BLEServer * pServer) {
// deviceConnected = true;
Serial.println("device connected");
};
void onDisconnect(BLEServer * pServer) {
// deviceConnected = false;
Serial.println("device disconnected");
}
void onWrite(BLECharacteristic * pCharacteristic) {
std::string value = pCharacteristic -> getValue();
if (value.length() > 0) {
if (atoi(value.c_str()) == 1) {
digitalWrite(LED_PIN, HIGH);
Serial.print("LEDON");
} else if (atoi(value.c_str()) == 2) {
digitalWrite(LED_PIN, LOW);
Serial.print("LEDOFF");
} else if (atoi(value.c_str()) == 3) {
Serial.print("UPDATE_PILL_TRACK");
waiting_for_update = true;
} else {
Serial.println("****************** UNEXPECTED MESSAGE!!! ******************");
Serial.println(atoi(value.c_str()));
Serial.println("****************** END UNEXPECTED MESSAGE!!! ******************");
}
}
}
};
BLECharacteristic * pCharacteristic;
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
pinMode(PILL_1_PIN, INPUT_PULLUP);
pinMode(PILL_2_PIN, INPUT_PULLUP);
pinMode(PILL_3_PIN, INPUT_PULLUP);
pinMode(PILL_4_PIN, INPUT_PULLUP);
pinMode(PILL_5_PIN, INPUT_PULLUP);
pinMode(PILL_6_PIN, INPUT_PULLUP);
pinMode(BTN_PIN, INPUT_PULLUP);
pinMode(DETECT_PIN, INPUT_PULLUP);
digitalWrite(LED_PIN, LOW);
Serial.println("1- Download and install an BLE scanner app in your phone");
Serial.println("2- Scan for BLE devices in the app");
Serial.println("3- Connect to MyESP32");
Serial.println("4- Go to CUSTOM CHARACTERISTIC in CUSTOM SERVICE and write something");
Serial.println("5- See the magic =)");
BLEDevice::init("PILL_TRACKER");
BLEServer * pServer = BLEDevice::createServer();
BLEService * pService = pServer -> createService(SERVICE_UUID);
pCharacteristic = pService -> createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY
);
pCharacteristic -> setCallbacks(new MyCallbacks());
pCharacteristic -> setValue("Hello World");
pService -> start();
BLEAdvertising * pAdvertising = pServer -> getAdvertising();
pAdvertising -> start();
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
pinMode(TEST_BTN_PIN, INPUT_PULLUP);
pinMode(MUX_BIT_0, OUTPUT);
pinMode(MUX_BIT_1, OUTPUT);
pinMode(MUX_BIT_2, OUTPUT);
pinMode(MUX_BIT_3, OUTPUT);
pinMode(MUX_COM, INPUT);
pinMode(RAIL_EVEN, OUTPUT);
pinMode(RAIL_ODD, OUTPUT);
pinMode(PILL_SENSE, INPUT_PULLUP);
pinMode(BATTERY_PIN, INPUT);
digitalWrite(LED_PIN, LOW);
digitalWrite(RAIL_EVEN, HIGH);
digitalWrite(RAIL_ODD, HIGH);
digitalWrite(MUX_BIT_0, LOW);
digitalWrite(MUX_BIT_1, LOW);
digitalWrite(MUX_BIT_2, LOW);
digitalWrite(MUX_BIT_3, LOW);
int debug_btn_previous_value = 0;
BLEDevice::init("PILL_TRACKER");
BLEServer * pServer = BLEDevice::createServer();
BLEService * pService = pServer -> createService(SERVICE_UUID);
pCharacteristic = pService -> createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY
);
pCharacteristic -> setCallbacks(new MyCallbacks());
pCharacteristic -> setValue("Hello World");
pService -> start();
BLEAdvertising * pAdvertising = pServer -> getAdvertising();
pAdvertising -> start();
}
int prevVal = LOW;
int prevVal2 = LOW;
bool seekValueFromMatrix(int column_id, int row_id) {
if (column_id > 1 || row_id > 15) {
Serial.println("@@@@@@@@@@@@@@@@@@@@ BINARY ERROR!!! @@@@@@@@@@@@@@@@@@@@");
}
int rail_to_GND = 0;
int rail_to_INPUT = 0;
int mux_bit_0 = 0;
int mux_bit_1 = 0;
int mux_bit_2 = 0;
int mux_bit_3 = 0;
bool is_pill_present = false;
if (column_id == 0) {
rail_to_GND = RAIL_EVEN;
rail_to_INPUT = RAIL_ODD;
} else if (column_id == 1) {
rail_to_GND = RAIL_ODD;
rail_to_INPUT = RAIL_EVEN;
} else { return -1;}
mux_bit_0 = row_id & 0b1000;
mux_bit_1 = row_id & 0b0100;
mux_bit_2 = row_id & 0b0010;
mux_bit_3 = row_id & 0b0001;
pinMode(rail_to_INPUT, INPUT);
digitalWrite(rail_to_GND, LOW);
digitalWrite(MUX_BIT_0, mux_bit_0);
digitalWrite(MUX_BIT_1, mux_bit_1);
digitalWrite(MUX_BIT_2, mux_bit_2);
digitalWrite(MUX_BIT_3, mux_bit_3);
delay(10);
if (digitalRead(PILL_SENSE) == LOW){
is_pill_present = true
}
Serial.println("########## COMPUTED BINARY ##########");
Serial.print("ROW ID: ");
Serial.print(row_id);
Serial.print(" | BIT 0: ");
Serial.print(mux_bit_0);
Serial.print(" | BIT 1: ");
Serial.print(mux_bit_1);
Serial.print(" | BIT 2: ");
Serial.print(mux_bit_2);
Serial.print(" | BIT 3: ");
Serial.print(mux_bit_3);
Serial.print(" | OBTAINED RESULT: ");
Serial.println(is_pill_present);
Serial.println("########## END COMPUTED BINARY ##########");
pinMode(rail_to_INPUT, OUTPUT);
digitalWrite(RAIL_EVEN, HIGH);
digitalWrite(RAIL_ODD, HIGH);
digitalWrite(MUX_BIT_0, LOW);
digitalWrite(MUX_BIT_1, LOW);
digitalWrite(MUX_BIT_2, LOW);
digitalWrite(MUX_BIT_3, LOW);
return is_pill_present;
}
int getPillCount() {
int totalCount = 0;
if (digitalRead(DETECT_PIN) == LOW) {
Serial.println("PROBE_ATTACHED");
if (digitalRead(PILL_1_PIN) == LOW){totalCount++;Serial.println("25:FULL");}
if (digitalRead(PILL_2_PIN) == LOW){totalCount++;Serial.println("13:FULL");}
if (digitalRead(PILL_3_PIN) == LOW){totalCount++;Serial.println("12:FULL");}
if (digitalRead(PILL_4_PIN) == LOW){totalCount++;Serial.println("26:FULL");}
if (digitalRead(PILL_5_PIN) == LOW){totalCount++;Serial.println("27:FULL");}
if (digitalRead(PILL_6_PIN) == LOW){totalCount++;Serial.println("14:FULL");}
} else {
Serial.println("PROBE_DETACHED");
totalCount = 55;
}
return totalCount;
int total_pill_count = 0;
if (digitalRead(PILL_SENSE) == LOW) {
Serial.println("PROBE_ATTACHED");
for (int col = 0; col < 2; col++){
for (int row = 0; row < 8; row++){
bool is_pill_present = false
is_pill_present = seekValueFromMatrix(col, row)
if (is_pill_present == true){
total_pill_count++;
}
}
}
} else {
Serial.println("PROBE_DETACHED");
totalCount = 97;
}
return total_pill_count;
}
float getVoltage(){
int sensorValue = analogRead(35);
float theVoltage = (sensorValue/4095.0)*6.6*1.1;
return theVoltage;
}
void printVoltage(){
Serial.println((String)"\nBattery Voltage: "+getVoltage()+"\n");
}
void checkBatteryVoltage() {
float voltage = getVoltage();
printVoltage();
if (voltage < 3.5) {
// Automatically notify the phone that battery is low
pCharacteristic -> setValue((uint8_t *) & 96, 4); // NOTE: WTF does the 4 mean?!?
pCharacteristic -> notify();
}
}
int loopcounter = 0;
void loop() {
// put your main code here, to run repeatedly:
int currentVal = digitalRead(BTN_PIN);
if (currentVal != prevVal) {
prevVal = currentVal;
if (currentVal == HIGH) {
int value = 99;
pCharacteristic -> setValue((uint8_t *) & value, 4);
pCharacteristic -> notify();
}
else {
int value = 98;
pCharacteristic -> setValue((uint8_t *) & value, 4);
pCharacteristic -> notify();
}
}
if (waitingForUpdate == 1) {
Serial.println("************************************************************");
Serial.println("**************UPDATE AND SEND PILL COUNT********************");
Serial.println("************************************************************");
waitingForUpdate = 0;
int value = getPillCount();
pCharacteristic -> setValue((uint8_t *) & value, 4);
pCharacteristic -> notify();
}
loopcounter++;
if(loopcounter > 50000000){
loopcounter = 0;
checkBatteryVoltage();
// TODO: Make a proper voltage to ios bt interface?
}
int debug_btn_current_value = digitalRead(BTN_PIN);
if (debug_btn_current_value != debug_btn_previous_value) {
debug_btn_previous_value = debug_btn_current_value;
if (debug_btn_current_value == HIGH) {
int debug_value = 99;
pCharacteristic -> setValue((uint8_t *) & debug_value, 4);
pCharacteristic -> notify();
}
else {
int debug_value = 98;
pCharacteristic -> setValue((uint8_t *) & debug_value, 4);
pCharacteristic -> notify();
}
}
if (waiting_for_update == true) {
Serial.println("************************************************************");
Serial.println("**************UPDATE AND SEND PILL COUNT********************");
Serial.println("************************************************************");
waiting_for_update = false;
int pill_quantity = getPillCount();
// pCharacteristic -> setValue("Hello World"); <-- Interesting!?!
pCharacteristic -> setValue((uint8_t *) & pill_quantity, 4); // NOTE: WTF does the 4 mean?!?
pCharacteristic -> notify();
printVoltage();
}
}