Hi, A little help would be greatly appreciated!
Me and my partner are completing a group project and we are just a little stuck.
The first Arduino we have contains a keypad and LCD I2C 4 pin display. We are inputing a password and then a drawer number into the first Arduino where it should send this data to the the second Arduino where it should receive the drawer number and open the corresponding servo motor. Also when each drawer opens it should takeaway 1 from the maximum in each drawer which we have set at 10. There are 4 servo motors (4 drawers) and there is also a LED RGB which should go green for a correct drawer number inputed and show that it is opening and then red for if an incorrect drawer number was inputted.
The Arduino's are connecting and the first Arduino is sending the data to the second Arduino but then the second one doesn't show or do anything and doesn't open any of the servo motors.
Please help!
Arduino 1 Code:
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <ArduinoBLE.h>
#include <Wire.h>
LiquidCrystal_I2C lcd(0x27, 20, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display
BLEService MeduinoService("ef96a1f0-d34b-4f33-9684-32c8effa5c05"); //Special line of bluetooth, names used even when the communication is not for drawer data, got from UUID.net
BLEByteCharacteristic KeypadCharacteristic("57237581-3952-49ac-a5f0-cc4fb440ae07", BLEWrite); //This sets up the bluetooth, but not two way.
BLEBoolCharacteristic ServoCharacteristic("be7ff53a-ddfb-4c4b-bde8-c8778ff03f74", BLERead); //reads if the drawer is opened
BLEBoolCharacteristic InterruptCharacteristic("44348dbf-eab6-43d5-a9d2-2211903ed6f0", BLEWrite);
BLECharacteristic MedStatsCharacteristic("2858f341-1630-4324-b0ab-3b375ed77fb3", BLERead, sizeof(int)*4 ); //Allows t communicate the stats for the medicines
BLEDevice Servo;
const byte ROWS = 4;
const byte COLS = 3;
char keys [ROWS] [COLS] = {
{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'},
{'*', '0', '#'}
};
byte rowPins[ROWS] = {A6,0,1,2};
byte colPins[COLS] = {3,4,5};
Keypad ctKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
BLEDevice Meduino2;
const String vKey[4] = {"1234", "2673", "3456", "1567"};//This makes an array for the valid passwords stored in vKey.
const int numPasswords = 4; //This shows how many valid passwprds there are.
//Each password between the '' is considered one elements, hence updating the password becomes easy. Hopefully.
//char num [4]= "";
//This stores the passkeys in the variable as a string, might help with the conversion between the types.
String Password = "";
bool accessGranted = false;//Not sure what this does.
bool drawerstate = false;
volatile bool Audit = false; //This checks if the button for the Audit is pressed
const int interruptPin = A1; //this is where the pin is added
void Reset(){
String Password = "";
bool accessGranted = false;
int counter = 0;
char num;
char dKey;
drawerstate =false;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Enter Password.");
}
bool access(){
for (int i = 0; i < numPasswords; i++) {
if (Password.equals(vKey[0])) {
accessGranted = true;
return accessGranted;
}
if (Password.equals(vKey[1])) {
accessGranted = true;
return accessGranted;
}
if (Password.equals(vKey[2])) {
accessGranted = true;
return accessGranted;
}
if (Password.equals(vKey[3])) {
accessGranted = true;
return accessGranted;
}
else{
accessGranted = false;
return accessGranted;
}
}
}
void handleAudit(){
MedStatsCharacteristic.setValue("1");
//MedStatsCharacteristic.notify();
}
int counter = 0;
bool drawer(){
while (counter<3){
lcd.clear();
lcd.print("Enter drawer no.");
delay(1000);
char dKey = ctKeypad.getKey();
if(dKey!= NO_KEY){
lcd.print(dKey);
if (dKey=='1'|| dKey == '2' || dKey == '3'|| dKey=='4'){
uint8_t drawerNum = dKey - '0';
Serial.println("Key detected.");
Serial.println(drawerNum);
// This converts the character to ASCII units, as it is stored
KeypadCharacteristic.setValue(drawerNum);
Serial.println("dKey sent");
//KeypadCharacteristic.notify();
if(ServoCharacteristic.valueUpdated()){
ServoCharacteristic.read();
bool DrawerStat = ServoCharacteristic.read();
if(DrawerStat==true) {
drawerstate = true;
Serial.println("1");
lcd.clear();
lcd.setCursor(0,1);
lcd.print("Drawer ");
lcd.print(dKey);
lcd.print(" opened.");
delay(9600);
counter+=2;
Reset();
} else if (DrawerStat==false) {
drawerstate = false;
lcd.clear();
lcd.print("Failed");
delay(1000);
Reset();
break;
}}} else {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Not Valid.Re-enter.");
delay(250);
lcd.clear();
drawerstate =false;
counter++;
//Want to make this a counter, more that three wrong tries and the system resets. Not sure if it's worth. Check with Gabrielle.
}
}
}
return drawerstate;
}
void setup() {
Serial.begin(9600);
BLE.begin();
BLE.setLocalName("Meduino1");
BLE.setAdvertisedService(MeduinoService);
MeduinoService.addCharacteristic(KeypadCharacteristic);
MeduinoService.addCharacteristic(ServoCharacteristic);
MeduinoService.addCharacteristic( MedStatsCharacteristic);
MeduinoService.addCharacteristic(InterruptCharacteristic);
BLE.addService(MeduinoService);
BLE.advertise();
Serial.println("Bluetooth on.");
Serial.println("Detecting 2nd Arduino.");
BLE.scan();
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), handleAudit, FALLING);
ctKeypad.setDebounceTime(200);//This was added because there was trouble in sensing the keys pressed.
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Enter Password.");
}
void loop() {
// put your main code here, to run repeatedly
BLE.poll();
BLEDevice Meduino2 =BLE.central();
if (!Meduino2) {
Serial.println("2nd Meduino not connected.");
//delay(1000);
}
while (Meduino2.connected()) {
Serial.println("Connected");
char num = ctKeypad.getKey();
if (num != NO_KEY){
if(Password.length()<4){
Password += num;
lcd.setCursor(0,1);
lcd.print(num);
}
delay(50);
}
if( Password.length()==4){
access();
if (access()== true){//This should be that it checks if the variable access is true and then perform the next operations
lcd.setCursor(0,1);
//lcd.print("Access Granted");
delay(150);
Serial.println("Access Granted");
lcd.clear();
lcd.setCursor(0,0);
drawer();
if (drawer()==true){
lcd.setCursor(0,0);
}
else if(access()==0) {
lcd.clear();
lcd.setCursor(0,1);
lcd.print("Access Denied");
Serial.println("Access Denied");
delay(250);
Reset();
}
}
}
}
}
Arduino 2 code:
#include <Servo.h>
#include <ArduinoBLE.h>
const int greenPin = 7;
const int redPin = 8;
unsigned long lastPrintTime = 0; // To track the last time the print interval happened
const long printInterval = 1000; // Interval to print debug info in milliseconds
Servo drawer1; //Declares the servo motors.
Servo drawer2;
Servo drawer3;
Servo drawer4;
//BLEDevice Meduino1;
BLECharacteristic KeypadCharacteristic;
BLECharacteristic ServoCharacteristic;
BLECharacteristic InterruptCharacteristic;
BLECharacteristic MedStatsCharacteristic;
int MedicineNumber[4]={10, 10, 10, 10};
void setup() {
// put your setup code here, to run once
Serial.begin(9600);
while (!Serial);
if (!BLE.begin()){
Serial.println("Meduino1 not connected");
while(1);
}
Serial.println("Meduino2 scanning");
BLE.scanForName("Meduino1");
drawer1.attach(2);//The pin is defined here
drawer2.attach(3);//The pin is defined here
drawer3.attach(4);//The pin is defined here
drawer4.attach(5);//The pin is defined here
drawer1.write(0);//The servo motor will be at rest
drawer2.write(0);//The servo motor will be at rest
drawer3.write(0);//The servo motor will be at rest
drawer4.write(0);//The servo motor will be at rest
pinMode(greenPin, OUTPUT);
pinMode(redPin, OUTPUT);
digitalWrite(greenPin, LOW); // make sure both are off initially
digitalWrite(redPin, LOW);
}
void loop() {
// unsigned long currentMillis = millis();
//
//if (currentMillis - lastPrintTime >= printInterval) {
// lastPrintTime = currentMillis;
//Serial.println("Loop running");
//}
BLE.poll();
BLEDevice peripheral = BLE.available();
if (peripheral && peripheral.localName() == "Meduino1") {
BLE.stopScan();
if (peripheral.connect()) {
Serial.println("Meduino1 connected");
if (peripheral.discoverAttributes()) {
KeypadCharacteristic = peripheral.characteristic("57237581-3952-49ac-a5f0-cc4fb440ae07");
ServoCharacteristic = peripheral.characteristic("be7ff53a-ddfb-4c4b-bde8-c8778ff03f74");
MedStatsCharacteristic = peripheral.characteristic("2858f341-1630-4324-b0ab-3b375ed77fb3");
InterruptCharacteristic = peripheral.characteristic("44348dbf-eab6-43d5-a9d2-2211903ed6f0");
if (!KeypadCharacteristic || !ServoCharacteristic || !MedStatsCharacteristic || !InterruptCharacteristic) {
Serial.println("Error: One or more characteristics not found.");
peripheral.disconnect();
} else {
Serial.println("Characteristics discovered.");
}
}
} else {
Serial.println("Failed to connect to Meduino1.");
BLE.scanForName("Meduino1"); // Try reconnecting by scanning again
}
}
// Turn off both LEDs before decision
if (peripheral.connected()) {
Serial.println("Bluetooth connection check.");
if (KeypadCharacteristic.canRead()) {
Serial.println("Keypad characteristic can definetely read. ");
//if (KeypadCharacteristic.valueUpdated()) { // Check if the value is updated
uint8_t dKey1 = 0;
BLE.poll();
int dKey= KeypadCharacteristic.readValue(dKey1); // Read the value
Serial.println(dKey);
// Check the received keypad value
if (dKey != 0) {
Serial.print("Keypad value: ");
Serial.println(dKey);
if (dKey == 1) {
Serial.print("1 received from Keypad");
digitalWrite(greenPin, HIGH);
drawer1.write(90);
bool drawerPosition = true;
ServoCharacteristic.writeValue((uint8_t)drawerPosition);
MedicineNumber[0]--;
delay(9600);
drawer1.write(0);
drawerPosition = false;
ServoCharacteristic.writeValue((uint8_t)drawerPosition);
delay(2000);
} else if (dKey == 2) {
Serial.print("2 received from Keypad");
digitalWrite(greenPin, HIGH);
drawer2.write(90);
bool drawerPosition = true;
ServoCharacteristic.writeValue((uint8_t)drawerPosition);
MedicineNumber[1]--;
delay(9600);
drawer2.write(0);
drawerPosition = false;
ServoCharacteristic.writeValue((uint8_t)drawerPosition);
delay(2000);
} else if (dKey == 3) {
Serial.println("3 received from Keypad");
digitalWrite(greenPin, HIGH);
drawer3.write(90);
bool drawerPosition = true;
ServoCharacteristic.writeValue((uint8_t)drawerPosition);
MedicineNumber[2]--;
delay(9600);
drawer3.write(0);
drawerPosition = false;
ServoCharacteristic.writeValue((uint8_t)drawerPosition);
delay(2000);
} else if (dKey == 4) {
Serial.println("4 received from Keypad");
digitalWrite(greenPin, HIGH);
drawer4.write(90);
bool drawerPosition = true;
ServoCharacteristic.writeValue((uint8_t)drawerPosition);
MedicineNumber[3]--;
delay(9600);
drawer4.write(0);
drawerPosition = false;
ServoCharacteristic.writeValue((uint8_t)drawerPosition);
delay(2000);
}
}
//}
} else {
digitalWrite(redPin, HIGH); // Red = invalid input
bool drawerPosition = false;
ServoCharacteristic.writeValue((uint8_t)drawerPosition);
Serial.print("Drawer NOT opened/ value not updated ");
delay(2000); // flash red briefly
}
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, LOW);
delay(500);
digitalWrite(redPin, LOW);
digitalWrite(greenPin, HIGH);
delay(500);
digitalWrite(redPin, LOW);
digitalWrite(greenPin, LOW);
}
// Print updated counts
//Serial.print("Medicine Counts: ");
// for (int i = 0; i < 4; i++) {
// Serial.print("Drawer ");
// Serial.print(i + 1);
// Serial.print(": ");
// Serial.print(MedicineNumber[i]);
// Serial.print(" ");
}