This shows you the differences between two versions of the page.
iothings:proiecte:2022:smart_backpack [2023/01/20 00:09] vlad.gavan |
iothings:proiecte:2022:smart_backpack [2023/01/20 07:55] (current) vlad.gavan |
||
---|---|---|---|
Line 2: | Line 2: | ||
* Student: Vlad Găvan, ACES | * Student: Vlad Găvan, ACES | ||
+ | * {{:iothings:proiecte:2022:gavan_vlad_iot.zip|}} | ||
=== 1. Overview === | === 1. Overview === | ||
Line 14: | Line 15: | ||
* NEO-6M GPS Module | * NEO-6M GPS Module | ||
* Piezoelectric buzzer | * Piezoelectric buzzer | ||
+ | * RFID tags | ||
+ | |||
+ | The ESP32 microcontroller is used to process the data received by the GPS module and transmit it to Firebase as well as to signal if more than the needed books were carried if a tag doesn't correspond the timetable. Communication between ESP32 and the GPS module is achieved true the UART protocol, while communication to the RFID is done through SPI. The buzzer buzzes when the GPIO14 pin on the ESP32 is set to HIGH. | ||
+ | |||
+ | {{ :iothings:proiecte:2022:smart_backpack_system.jpg?300 |}} | ||
+ | |||
+ | {{ :iothings:proiecte:2022:smart_backpack_circuit.jpg?300 |}} | ||
+ | |||
+ | === 3. Software === | ||
+ | The application was developed using Arduino IDE. The following libraries were used for the code: WiFi for the WiFi connection, Wire, TinyGPSPlus for interpreting the GPS data, Firebase_ESP_Client for transmitting the data to Firebase web server, SPI for communicating with the RFID, MFRC522, time to get the current day of the week. The WiFi credentials as well as the Firebase API_KEY, URL, email and password are defined at the beginning of the code. It also uses a TokenHelper and a RTDBHelper variable for token generation and RTDB payload printing. | ||
+ | |||
+ | The code inside the loop starts with finding the week of the day with the help of the time structure, but also the timetable gets defined: | ||
+ | <code> | ||
+ | // Time structure that contains components of the calendar date | ||
+ | struct tm timeinfo; | ||
+ | // Variable for day of the week | ||
+ | char timeWeekDay[10]; | ||
+ | | ||
+ | // Array of structs for the timetable | ||
+ | timetable daily_program[2]; | ||
+ | daily_program[0].dayOfWeek = "Monday"; | ||
+ | daily_program[0].uid = "031D471C"; | ||
+ | daily_program[0].dayOfWeek = "Tuesday"; | ||
+ | daily_program[0].uid = "126051DD"; | ||
+ | daily_program[0].dayOfWeek = "Wednesday"; | ||
+ | daily_program[0].uid = "BC80C16E"; | ||
+ | daily_program[0].dayOfWeek = "Thursday"; | ||
+ | daily_program[0].uid = "5364CF06"; | ||
+ | daily_program[1].dayOfWeek = "Friday"; | ||
+ | daily_program[1].uid = "126051DD"; | ||
+ | </code> | ||
+ | |||
+ | Then, the GPS data, if available is retrieved and printed to the serial monitor. This only happens with the help of a boolean variable that gets set to true only if there is GPS data available. | ||
+ | <code> | ||
+ | if(newData == true) | ||
+ | { | ||
+ | newData = false; | ||
+ | Serial.println("Lat: "); | ||
+ | Serial.println(gps.location.lat(),6); | ||
+ | Serial.println("Long: "); | ||
+ | Serial.println(gps.location.lng(),6); | ||
+ | Serial.println("Alt: "); | ||
+ | Serial.println(gps.altitude.meters(),6); | ||
+ | Serial.println("\n"); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | Next in line is the RFID scanner. Whenever a tag is scanned, the code checks if the UID corresponds with the one set for the respective day. If that is not the case, a small "alarm" is started by the buzzer. A separate function is used to convert the UID from HEX to a char array for the comparison. | ||
+ | |||
+ | <code> | ||
+ | for (int i = 0; i < rfid.uid.size; i++) { | ||
+ | Serial.print(rfid.uid.uidByte[i] < 0x10 ? " 0" : " "); | ||
+ | Serial.print(rfid.uid.uidByte[i], HEX); | ||
+ | } | ||
+ | Serial.println(); | ||
+ | | ||
+ | // Save RFID as char array | ||
+ | char userid[32] = ""; | ||
+ | //Insert (byte array, length, char array for output) | ||
+ | array_to_string(rfid.uid.uidByte, 4, userid); | ||
+ | |||
+ | // If an UID that doesn't belong to a specific day has been read, buzzer buzzes | ||
+ | for (int i = 0; i < 2; i++){ | ||
+ | // Compare week day with days initialezide in the struct | ||
+ | if (strcmp(timeWeekDay, daily_program[i].dayOfWeek) == 0){ | ||
+ | // If a different UID is found for that day buzz | ||
+ | if (strcmp(userid, daily_program[i].uid) != 0){ | ||
+ | digitalWrite(14, HIGH); | ||
+ | delay(100); | ||
+ | digitalWrite(14, LOW); | ||
+ | Serial.println("Book is not part of today's subjects"); | ||
+ | overLimit = "More books than expected"; | ||
+ | } | ||
+ | else { | ||
+ | Serial.println("Book is part of today's subjects"); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | At the end the data is sent to Firebase: | ||
+ | <code> | ||
+ | json.set(longPath.c_str(), String(gps.location.lat())); | ||
+ | json.set(latPath.c_str(), String(gps.location.lng())); | ||
+ | json.set(altPath.c_str(), String(gps.altitude.meters())); | ||
+ | json.set(timePath, String(timestamp)); | ||
+ | json.set(overPath.c_str(), String(overLimit)); | ||
+ | Serial.printf("Set json... %s\n", Firebase.RTDB.setJSON(&fbdo, parentPath.c_str(), &json) ? "ok" : fbdo.errorReason().c_str()); | ||
+ | </code> | ||
+ | |||
+ | Flow diagram: | ||
+ | {{ :iothings:proiecte:2022:flow_diagram_smart_backpack.jpg?300 |}} | ||
+ | |||
+ | Firebase images: | ||
+ | {{ :iothings:proiecte:2022:firebase_1_smart_backpack.jpg?300 |}} | ||
+ | |||
+ | {{ :iothings:proiecte:2022:firebase_2_smart_backpack.jpg?300 |}} | ||
+ | |||
+ | === 4. Demonstration === | ||
+ | Short demonstrative video. Because of the GPS module acting up this demo was created a bit before the final code. | ||
+ | https://www.youtube.com/shorts/tpSXw9D4iDU | ||
+ | |||
+ | |||
+ | === 5. Conclusion === | ||
+ | In conclusion, this project can be considered a prototype for a smart backpack, using microcontroller programming and data visualization concepts to create an IoT system that can make the life of students easier all around the globe. | ||
+ | |||
+ | Future possible improvements: | ||
+ | * While accurate (except for altitude) this specific GPS module takes a lot to calibrate and doesn't really work indoors; | ||
+ | * Find another solution to send GPS data efficiently instead of WiFi. Nobody ha WiFi inside their backpacks; | ||
+ | * Find another solution to get current day of the week, same reason, WiFi isn't always available; | ||
+ | * Store the timetable externally, some memory problems appeared when comparing the dates form time to time; | ||
+ | * Add more features: such us notifying you when you also forget a book for the respective day | ||
+ | * Improvement of security. The data should be sent in a more secure way, otherwise the GPS tracking can turn from a security reason to the exact opposite. | ||
+ | |||
+ | === 6. References === | ||
+ | * https://randomnerdtutorials.com/ | ||
+ | * https://esp32io.com | ||
+ | * https://cplusplus.com/reference/ctime/tm/ | ||
+ | * https://patient.info/bones-joints-muscles/back-and-spine-pain/back-pain-in-children | ||