From aa426607d76ff61c984314760132d3434f7b7538 Mon Sep 17 00:00:00 2001 From: "Omar2.Zayed@live.uwe.ac.uk" <omar2.zayed@live.uwe.ac.uk> Date: Sun, 20 Apr 2025 17:31:39 +0000 Subject: [PATCH] final code for task 4 --- final code for task 4 | 319 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 319 insertions(+) diff --git a/final code for task 4 b/final code for task 4 index e69de29..8187f1d 100644 --- a/final code for task 4 +++ b/final code for task 4 @@ -0,0 +1,319 @@ +#include "mbed.h" +#include "arm_book_lib.h" + +#define TOTAL_KEYS 4 +#define GAS_ALARM_FLASH_INTERVAL 1000 +#define TEMP_ALARM_FLASH_INTERVAL 500 +#define COMBINED_ALARM_FLASH_INTERVAL 100 +#define TEMP_SAMPLE_COUNT 100 +#define TEMP_THRESHOLD_CELSIUS 30 +#define LOOP_DELAY_MS 10 +#define BUZZER_TONE_HZ 2000 + +DigitalIn enterKey(BUTTON1); +DigitalIn alarmCheckButton(D2); +DigitalIn keyA(D4); +DigitalIn keyB(D5); +DigitalIn keyC(D6); +DigitalIn keyD(D7); +DigitalIn gasSensor(PE_12); + +DigitalOut alarmIndicator(LED1); +DigitalOut wrongCodeIndicator(LED3); +DigitalOut lockoutIndicator(LED2); + +PwmOut buzzerOutput(PE_10); +UnbufferedSerial pcTerminal(USBTX, USBRX, 115200); + +AnalogIn potSensor(A0); +AnalogIn tempSensor(A1); + +bool isAlarmOn = OFF; +bool isCodeIncorrect = false; +bool isOverTempDetected = OFF; + +int failedAttempts = 0; +int currentKeyIndex = 0; +int unlockCode[TOTAL_KEYS] = { 1, 1, 0, 0 }; +int userCode[TOTAL_KEYS] = { 0, 0, 0, 0 }; +int blinkTimer = 0; + +bool gasDetected = OFF; +bool tempExceeded = OFF; + +float potValue = 0.0; +float avgTempReading = 0.0; +float tempSum = 0.0; +float tempBuffer[TEMP_SAMPLE_COUNT]; +float currentTempCelsius = 0.0; + +void setupInputs(); +void setupOutputs(); +void checkAlarmActivation(); +void handleAlarmDeactivation(); +void handleUartCommunication(); +void displayHelpMenu(); +bool verifyCode(); +float convertToFahrenheit(float celsius); +float convertLM35Reading(float analogVal); + +int main() +{ + setupInputs(); + setupOutputs(); + + buzzerOutput.period(1.0 / BUZZER_TONE_HZ); + buzzerOutput.write(0.5); + wait_us(500000); + buzzerOutput.write(0.0); + + while (true) { + checkAlarmActivation(); + handleAlarmDeactivation(); + handleUartCommunication(); + delay(LOOP_DELAY_MS); + } +} + +void setupInputs() +{ + alarmCheckButton.mode(PullDown); + keyA.mode(PullDown); + keyB.mode(PullDown); + keyC.mode(PullDown); + keyD.mode(PullDown); + + buzzerOutput.period(1.0 / BUZZER_TONE_HZ); + buzzerOutput.write(0.0); +} + +void setupOutputs() +{ + alarmIndicator = OFF; + wrongCodeIndicator = OFF; + lockoutIndicator = OFF; +} + +void checkAlarmActivation() +{ + static int tempSamplePos = 0; + + tempBuffer[tempSamplePos++] = tempSensor.read(); + if (tempSamplePos >= TEMP_SAMPLE_COUNT) tempSamplePos = 0; + + tempSum = 0.0; + for (int i = 0; i < TEMP_SAMPLE_COUNT; i++) { + tempSum += tempBuffer[i]; + } + + avgTempReading = tempSum / TEMP_SAMPLE_COUNT; + currentTempCelsius = convertLM35Reading(avgTempReading); + + isOverTempDetected = (currentTempCelsius > TEMP_THRESHOLD_CELSIUS); + + if (!gasSensor) { + gasDetected = ON; + isAlarmOn = ON; + } + + if (isOverTempDetected) { + tempExceeded = ON; + isAlarmOn = ON; + } + + if (alarmCheckButton) { + tempExceeded = ON; + gasDetected = ON; + isAlarmOn = ON; + } + + if (isAlarmOn) { + blinkTimer += LOOP_DELAY_MS; + buzzerOutput.write(0.5); + + if (gasDetected && tempExceeded) { + if (blinkTimer >= COMBINED_ALARM_FLASH_INTERVAL) { + blinkTimer = 0; + alarmIndicator = !alarmIndicator; + } + } else if (gasDetected) { + if (blinkTimer >= GAS_ALARM_FLASH_INTERVAL) { + blinkTimer = 0; + alarmIndicator = !alarmIndicator; + } + } else if (tempExceeded) { + if (blinkTimer >= TEMP_ALARM_FLASH_INTERVAL) { + blinkTimer = 0; + alarmIndicator = !alarmIndicator; + } + } + } else { + alarmIndicator = OFF; + gasDetected = OFF; + tempExceeded = OFF; + buzzerOutput.write(0.0); + } +} + +void handleAlarmDeactivation() +{ + if (failedAttempts < 5) { + if (keyA && keyB && keyC && keyD && !enterKey) { + wrongCodeIndicator = OFF; + } + + if (enterKey && !wrongCodeIndicator && isAlarmOn) { + userCode[0] = keyA; + userCode[1] = keyB; + userCode[2] = keyC; + userCode[3] = keyD; + + if (verifyCode()) { + isAlarmOn = OFF; + failedAttempts = 0; + } else { + wrongCodeIndicator = ON; + failedAttempts++; + } + } + } else { + lockoutIndicator = ON; + } +} + +void handleUartCommunication() +{ + char inputChar = '\0'; + char buffer[100]; + int len; + + if (pcTerminal.readable()) { + pcTerminal.read(&inputChar, 1); + + switch (inputChar) { + case '1': + pcTerminal.write( + isAlarmOn ? "The alarm is activated\r\n" : "The alarm is not activated\r\n", + isAlarmOn ? 24 : 28 + ); + break; + + case '2': + pcTerminal.write( + !gasSensor ? "Gas is being detected\r\n" : "Gas is not being detected\r\n", + !gasSensor ? 22 : 27 + ); + break; + + case '3': + pcTerminal.write( + isOverTempDetected ? "Temperature is above the maximum level\r\n" + : "Temperature is below the maximum level\r\n", + 40 + ); + break; + + case '4': + pcTerminal.write("Please enter the code sequence.\r\n", 33); + pcTerminal.write("Input '1' for pressed and '0' for not.\r\n", 40); + pcTerminal.write("Example: 1100\r\n", 15); + + isCodeIncorrect = false; + for (currentKeyIndex = 0; currentKeyIndex < TOTAL_KEYS; currentKeyIndex++) { + pcTerminal.read(&inputChar, 1); + pcTerminal.write("*", 1); + if ((inputChar == '1' && unlockCode[currentKeyIndex] != 1) || + (inputChar == '0' && unlockCode[currentKeyIndex] != 0)) { + isCodeIncorrect = true; + } + } + + if (!isCodeIncorrect) { + pcTerminal.write("\r\nThe code is correct\r\n\r\n", 25); + isAlarmOn = OFF; + wrongCodeIndicator = OFF; + failedAttempts = 0; + } else { + pcTerminal.write("\r\nThe code is incorrect\r\n\r\n", 27); + wrongCodeIndicator = ON; + failedAttempts++; + } + break; + + case '5': + pcTerminal.write("Enter a new code (e.g. 1100):\r\n", 31); + for (currentKeyIndex = 0; currentKeyIndex < TOTAL_KEYS; currentKeyIndex++) { + pcTerminal.read(&inputChar, 1); + pcTerminal.write("*", 1); + unlockCode[currentKeyIndex] = (inputChar == '1') ? 1 : 0; + } + pcTerminal.write("\r\nNew code generated\r\n\r\n", 24); + break; + + case 'p': + case 'P': + potValue = potSensor.read(); + sprintf(buffer, "Potentiometer: %.2f\r\n", potValue); + len = strlen(buffer); + pcTerminal.write(buffer, len); + break; + + case 'c': + case 'C': + sprintf(buffer, "Temperature: %.2f \xB0 C\r\n", currentTempCelsius); + pcTerminal.write(buffer, strlen(buffer)); + break; + + case 'f': + case 'F': + sprintf(buffer, "Temperature: %.2f \xB0 F\r\n", convertToFahrenheit(currentTempCelsius)); + pcTerminal.write(buffer, strlen(buffer)); + break; + + case 'b': + case 'B': + pcTerminal.write("Testing buzzer for 2 seconds...\r\n", 32); + buzzerOutput.write(0.5); + wait_us(2000000); + buzzerOutput.write(0.0); + pcTerminal.write("Buzzer test complete\r\n", 22); + break; + + default: + displayHelpMenu(); + break; + } + } +} + +void displayHelpMenu() +{ + pcTerminal.write("Available commands:\r\n", 21); + pcTerminal.write("1 - Alarm state\r\n", 19); + pcTerminal.write("2 - Gas detector\r\n", 20); + pcTerminal.write("3 - Temperature detector\r\n", 29); + pcTerminal.write("4 - Enter code\r\n", 19); + pcTerminal.write("5 - Change code\r\n", 20); + pcTerminal.write("P/p - Potentiometer value\r\n", 29); + pcTerminal.write("C/c - Temp in Celsius\r\n", 25); + pcTerminal.write("F/f - Temp in Fahrenheit\r\n", 28); + pcTerminal.write("B/b - Buzzer test\r\n\r\n", 22); +} + +bool verifyCode() +{ + for (int i = 0; i < TOTAL_KEYS; i++) { + if (unlockCode[i] != userCode[i]) return false; + } + return true; +} + +float convertLM35Reading(float analogVal) +{ + return analogVal * 3.3 / 0.01; +} + +float convertToFahrenheit(float celsius) +{ + return (celsius * 9.0 / 5.0) + 32.0; +} \ No newline at end of file -- GitLab