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