# Embedded-operating-systems-NCKU
### Simple AirTag Implementation(2025 Final Project)
組員: 程品叡、廖栩旻、吳睿秉、黃蕙馨
Github : https://github.com/Chengray8/Airtag
[Concept sketch design](https://www.canva.com/design/DAGpXmo3PPE/RC9DeHDyNsGa3Og8wwwCFA/edit?utm_content=DAGpXmo3PPE&utm_campaign=designshare&utm_medium=link2&utm_source=sharebutton)
## App introduction
### Draft of cellphone app design

### Real app design

### Mode-based state machine

### Flow chart

## Pin Connection
### HM-10
| HM-10 | STM32 |
| ----- | ----- |
| RXD | PD8 |
| TXD | PB11 |
| GND | GND |
| VCC | 5V |
### Buzz Connection
| Buzz | STM32 |
| ----- | ----- |
| I/O | PD9 |
| GND | GND |
| VCC | 3V |

## IOC Setting
### LED Setting

### Buzz
PD9 GPIO_Output
### UART3
**Baud Rate: 9600 Bits/s**

Remember to check the **USART3 global interrupt** option.


* PB11: USART3_RX
* PD8: USART3_TX

## Bluetooth
Declared in `main.c`
```c
/* USER CODE BEGIN PV */
static uint8_t receiveData[20];
/* USER CODE END PV */
```
In `main()`.
```c
/* USER CODE BEGIN 2 */
HAL_UARTEx_RxEventCallback(&huart3, sizeof(receiveData));
/* USER CODE END 2 */
```
Insert the following code between `/* USER CODE BEGIN 0 */` and `/* USER CODE END 0 */` in the main file.
Remember to add `#include "string.h"` at the top of `main.c`.
```c
//Code Version 1
/* USER CODE BEGIN 0 */
//GPIO_PIN_12 Green
//GPIO_PIN_13 Orange
//GPIO_PIN_14 Red
//GPIO_PIN_15 Blue
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) {
if (huart == &huart3 && Size > 0) {
HAL_UART_Transmit_DMA(huart, receiveData, Size);
//HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_12);//Green
if(strcmp((char*)receiveData, "1")==0){
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_13);//Orange
}
else if(strcmp((char*)receiveData, "2")==0){
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_14);//Red
}
else{
HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_15);//Blue
}
HAL_UARTEx_ReceiveToIdle_DMA(huart, receiveData, sizeof(receiveData));
__HAL_DMA_DISABLE_IT(&hdma_usart3_rx, DMA_IT_HT);
}
}
/* USER CODE END 0 */
```
### Mode declaration
:::success
`BT_password` and `BT_Name` are not used in this project. **In future work**, you can try using the Bluetooth **AT mode** and use an app to switch modes, change the device name, and modify the connection password.
:::
```c
typedef enum {
WAIT_MODE,
WORK_MODE,
FIND_MODE
} BLUETOOTH_STATETypeDef;
typedef struct{
char BT_Name[20];
uint8_t BT_password;
uint8_t BT_distance;
BLUETOOTH_STATETypeDef BT_state;
}BLUETOOTH_DEVICE_InfoTypeDef;
```
**Wait mode** represents a low energy state. In our project, this is indicated by all four LEDs being turned off. We call it `wait mode` because it reflects the state of waiting for a connection.
**Work mode** represents the active operating state, indicated by the green LED being turned on. Based on the design concept, I implemented the red LED as a switch and the orange LED as a blinking switch, both functioning during the work_mode state.
**Find mode** is indicated by the blue LED. In this mode, the buzzer can be turned on or off, and its frequency is controlled based on the Bluetooth RSSI (Received Signal Strength Indicator) distance. Although the sound alone helps users identify the direction of the lost item, we designed the system so that the buzzer's frequency automatically changes with distance, making the feature more distinctive.
**SwitchMode** refers to switching between modes. Based on code smell principles, I replaced the initialization process with a dedicated function to improve code readability, maintainability, and scalability.
```c
/*
* Function: Wait_init
* -------------------
* Initializes the system for WAIT_MODE.
*
* Behavior:
* - Turns off all LEDs (connected to GPIOD Pins 12–15).
* - Intended to disable or initialize other peripheral components (commented out).
* - Sets the system mode to WAIT_MODE.
*/
void Wait_init(){
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_RESET); // Turn off Green LED
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_RESET); // Turn off Orange LED
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_RESET); // Turn off Red LED
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_RESET); // Turn off Blue LED
// ClosePeripheralComponents(); // Shut down other modules
// Activate required functions.
// low_energy_operation();
BT_INFO.BT_state = WAIT_MODE; // Set the current mode to WAIT_MODE
}
/*
* Function: Work_init
* -------------------
* Initializes the system for WORK_MODE.
*
* Behavior:
* - Turns on the Green LED (GPIOD Pin 12) to indicate WORK_MODE.
* - Turns off the Orange, Red, and Blue LEDs (Pins 13–15).
* - Placeholder for other functions required in WORK_MODE (commented out).
* - Sets the Bluetooth state to WORK_MODE in the BT_INFO structure.
*/
void Work_init(){
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_RESET);
//OtherfunctionworkinWORK_MODE();
BT_INFO.BT_state = WORK_MODE;
}
/*
* Function: Find_init
* -------------------
* Initializes the system for FIND_MODE.
*
* Behavior:
* - Turns on the Blue LED (GPIOD Pin 15) to indicate FIND_MODE.
* - Turns off the Green, Orange, and Red LEDs (Pins 12–14).
* - Placeholder for other functions required in FIND_MODE (commented out).
* - Sets the Bluetooth state to FIND_MODE in the BT_INFO structure.
*/
void Find_init(){
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_15, GPIO_PIN_SET);
////OtherfunctionworkinFIND_MODE();
BT_INFO.BT_state = FIND_MODE;
}
/**
* Function: SwitchMode
* --------------------
* Switches the Bluetooth operating mode based on the given state.
*
* Parameters:
* state - The target Bluetooth state to switch to. Possible values:
* WAIT_MODE: Sets the device into idle/waiting mode.
* WORK_MODE: Sets the device into active/working mode.
* FIND_MODE: Sets the device into scanning/searching mode.
*
* Notes:
* - Optional functions like ClosePeripheralComponents() and OpenPeripheralComponents()
* can be enabled to manage power or peripherals when entering specific modes.
* - The current mode is stored in the global variable BT_MODE.
*/
void SwitchMode(BLUETOOTH_STATETypeDef state){
switch(state){
case WAIT_MODE:
//ClosePeripheralComponents();
Wait_init();
break;
case WORK_MODE:
//OpenPeripheralComponents();
Work_init();
break;
case FIND_MODE:
Find_init();
break;
default:
break;
}
}
```
## Reference
https://github.com/JiaChangGit/Embedded-operating-systems-NCKU
https://www.youtube.com/watch?v=A2-wd0rj9GA
https://blog.embeddedexpert.io/?p=1829
https://blog.embeddedexpert.io/?p=1822
https://youtu.be/A2-wd0rj9GA?si=fKGNsvlkuuqvYcAp
https://youtu.be/2RYLPlemvEQ?si=iX-0H8D1CFsieMLf