├── assets
└── images
│ ├── appwrite.png
│ ├── mongodb.png
│ └── CSMS_coloured.png
├── README.md
├── esp32.ino
└── esp32cam.ino
/assets/images/appwrite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xditya/csms-hardware/main/assets/images/appwrite.png
--------------------------------------------------------------------------------
/assets/images/mongodb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xditya/csms-hardware/main/assets/images/mongodb.png
--------------------------------------------------------------------------------
/assets/images/CSMS_coloured.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xditya/csms-hardware/main/assets/images/CSMS_coloured.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Campus Services Management System - ESP32 Components
2 |
3 | This repository contains the ESP32 components for the Campus Services Management System project. These components handle the IoT functionality of the system.
4 |
5 | ## Files
6 |
7 | - `esp32.ino` - Contains the code for the main ESP32 microcontroller that handles sensor data and communication with the server
8 | - `esp32cam.ino` - Contains the code for the ESP32-CAM module that handles image capture and processing
9 |
10 | ## Main Project
11 |
12 | This is a component of the larger Campus Services Management System project. For the complete project, please visit:
13 | [Campus Services Management System](https://github.com/xditya/CampusServicesManagementSystem)
14 |
15 |
16 |
17 |
18 |  |
19 |  |
20 |  |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/esp32.ino:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | WiFiClient client;
5 |
6 | #include
7 | #include
8 |
9 | LCD_I2C lcd(0x27,20,4);
10 |
11 |
12 | float val,d=6000;
13 | int digits[8];
14 |
15 | void setup()
16 | {
17 | Serial.begin(9600);
18 | WiFi.mode(WIFI_STA);
19 | WiFi.begin("iot","123456789");
20 | Serial.println("connecting");
21 | while(WiFi.status() != WL_CONNECTED)
22 | {
23 | Serial.print(".");
24 | delay(100);
25 | }
26 |
27 | ThingSpeak.begin(client);
28 |
29 |
30 |
31 | lcd.begin(); // initialize the lcd
32 | //lcd.init();
33 | // Print a message to the LCD.
34 | lcd.backlight();
35 | lcd.clear();
36 | lcd.setCursor(0,1);
37 | lcd.print(" SHOW ");
38 | lcd.setCursor(0,2);
39 | lcd.print(" QR ");
40 | delay(2000);
41 |
42 | pinMode(32,OUTPUT);
43 | pinMode(33,OUTPUT);
44 | pinMode(25,OUTPUT);
45 | pinMode(26,OUTPUT);
46 | pinMode(27,OUTPUT);
47 | pinMode(16,OUTPUT);
48 | pinMode(19,OUTPUT);
49 | pinMode(18,OUTPUT);
50 |
51 | digitalWrite(32,0);
52 | digitalWrite(33,0);
53 | digitalWrite(25,0);
54 | digitalWrite(26,0);
55 | digitalWrite(27,0);
56 | digitalWrite(16,0);
57 | digitalWrite(18,0);
58 | digitalWrite(19,0);
59 |
60 |
61 | }
62 |
63 | void loop()
64 | {
65 | val = ThingSpeak.readFloatField(2888489,1,"93YYKUSCH3YW7S18");
66 | lcd.begin();
67 | if(val>0)
68 | {
69 | lcd.clear();
70 | lcd.setCursor(0,1);
71 | lcd.print(" ORDER RECEIVED...");
72 | delay(2000);
73 | // lcd.clear();
74 | // lcd.setCursor(0,1);
75 | // lcd.print(" ORDER RECEIVED...");
76 | // delay(2000);
77 |
78 | String payload = String((int)val); // Convert float to integer and then to string
79 |
80 | // String payload = String((int)val); // Convert float to integer and then to string
81 | while (payload.length() < 8) {
82 | payload = "0" + payload; // Add leading zeros until length is 8
83 | }
84 | Serial.println("Received Data: " + payload);
85 |
86 | if (payload.length() == 8) {
87 | for (int i = 0; i < 8; i++) {
88 | digits[i] = payload[i] - '0'; // Convert char to integer
89 | Serial.print("Digit ");
90 | Serial.print(i + 1);
91 | Serial.print(": ");
92 | Serial.println(digits[i]);
93 | }
94 |
95 | if(digits[0]>0)
96 | {
97 | lcd.clear();
98 | lcd.setCursor(0,1);
99 | lcd.print(" PAROTTA x");
100 | lcd.print(digits[0]);
101 | delay(2000);
102 |
103 | digitalWrite(27,1);
104 | delay(digits[0]*d);
105 | digitalWrite(27,0);
106 |
107 | }
108 |
109 | if(digits[1]>0)
110 | {
111 | lcd.clear();
112 | lcd.setCursor(0,1);
113 | lcd.print(" BIRIYANI x");
114 | lcd.print(digits[1]);
115 | delay(2000);
116 |
117 | digitalWrite(16,1);
118 | delay(digits[1]*d);
119 | digitalWrite(16,0);
120 |
121 | }
122 |
123 | if(digits[2]>0)
124 | {
125 | lcd.clear();
126 | lcd.setCursor(0,1);
127 | lcd.print(" CHAPATTI x");
128 | lcd.print(digits[2]);
129 | delay(2000);
130 |
131 | digitalWrite(26,1);
132 | delay(digits[2]*d);
133 | digitalWrite(26,0);
134 |
135 | }
136 |
137 | if(digits[3]>0)
138 | {
139 | lcd.clear();
140 | lcd.setCursor(0,1);
141 | lcd.print(" CHICKEN CURRY x");
142 | lcd.print(digits[3]);
143 | delay(2000);
144 |
145 | digitalWrite(25,1);
146 | delay(digits[3]*d);
147 | digitalWrite(25,0);
148 |
149 | }
150 |
151 | if(digits[4]>0)
152 | {
153 | lcd.clear();
154 | lcd.setCursor(0,1);
155 | lcd.print(" BEEF CURRY x");
156 | lcd.print(digits[4]);
157 | delay(2000);
158 |
159 | digitalWrite(32,1);
160 | delay(digits[4]*d);
161 | digitalWrite(32,0);
162 |
163 | }
164 |
165 | if(digits[5]>0)
166 | {
167 | lcd.clear();
168 | lcd.setCursor(0,1);
169 | lcd.print(" FISH CURRY x");
170 | lcd.print(digits[5]);
171 | delay(2000);
172 |
173 | digitalWrite(33,1);
174 | delay(digits[5]*d);
175 | digitalWrite(33,0);
176 |
177 | }
178 |
179 | if(digits[6]>0)
180 | {
181 | lcd.clear();
182 | lcd.setCursor(0,1);
183 | lcd.print(" VEG CURRY x");
184 | lcd.print(digits[6]);
185 | delay(2000);
186 |
187 | digitalWrite(18,1);
188 | delay(digits[6]*d);
189 | digitalWrite(18,0);
190 |
191 | }
192 |
193 |
194 | if(digits[7]>0)
195 | {
196 | lcd.clear();
197 | lcd.setCursor(0,1);
198 | lcd.print(" MEALS x");
199 | lcd.print(digits[7]);
200 | delay(2000);
201 |
202 | digitalWrite(19,1);
203 | delay(digits[7]*d);
204 | digitalWrite(19,0);
205 |
206 | }
207 | lcd.clear();
208 | lcd.setCursor(0,1);
209 | lcd.print(" ORDER DELIVERED...");
210 | delay(5000);
211 | lcd.clear();
212 | lcd.setCursor(0,1);
213 | lcd.print(" THANK YOU....");
214 | delay(5000);
215 | ThingSpeak.writeField(2888489,1,0,"Q6DL0DTT0H47UGAR");
216 |
217 | } else {
218 | Serial.println("Error: Received data is not 8 digits long");
219 | }
220 |
221 |
222 | }
223 | lcd.clear();
224 | lcd.setCursor(0,1);
225 | lcd.print(" SHOW ");
226 | lcd.setCursor(0,2);
227 | lcd.print(" QR ");
228 | delay(2000);
229 | //delay(1000);
230 | }
--------------------------------------------------------------------------------
/esp32cam.ino:
--------------------------------------------------------------------------------
1 | #include "esp_camera.h"
2 | #include "soc/soc.h"
3 | #include "soc/rtc_cntl_reg.h"
4 | #include "quirc.h"
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | // LED Control Pins
12 | #define LED_BUILTIN 4
13 | #define LED_DETECT 12
14 | #define LED_SUCCESS 13
15 | #define LED_COMPLETE 14
16 |
17 | // ThingSpeak Configuration
18 | const char *thingspeakAPIKey = "Q6DL0DTT0H47UGAR";
19 | const char *thingspeakURL = "https://api.thingspeak.com/update";
20 |
21 | // Network Configuration
22 | const char *ssid = "iot";
23 | const char *password = "123456789";
24 | const int WIFI_RETRIES = 5;
25 | const int HTTP_TIMEOUT = 15000;
26 |
27 | TaskHandle_t QRCodeReader_Task;
28 | #define CAMERA_MODEL_AI_THINKER
29 |
30 | #if defined(CAMERA_MODEL_AI_THINKER)
31 | // Camera pin definitions
32 | #define PWDN_GPIO_NUM 32
33 | #define RESET_GPIO_NUM -1
34 | #define XCLK_GPIO_NUM 0
35 | #define SIOD_GPIO_NUM 26
36 | #define SIOC_GPIO_NUM 27
37 | #define Y9_GPIO_NUM 35
38 | #define Y8_GPIO_NUM 34
39 | #define Y7_GPIO_NUM 39
40 | #define Y6_GPIO_NUM 36
41 | #define Y5_GPIO_NUM 21
42 | #define Y4_GPIO_NUM 19
43 | #define Y3_GPIO_NUM 18
44 | #define Y2_GPIO_NUM 5
45 | #define VSYNC_GPIO_NUM 25
46 | #define HREF_GPIO_NUM 23
47 | #define PCLK_GPIO_NUM 22
48 | #else
49 | #error "Camera model not selected"
50 | #endif
51 |
52 | struct quirc *q = NULL;
53 |
54 | void setup()
55 | {
56 | WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
57 | Serial.begin(115200);
58 | Serial.setDebugOutput(true);
59 |
60 | // Initialize LED pins
61 | pinMode(LED_BUILTIN, OUTPUT);
62 | pinMode(LED_DETECT, OUTPUT);
63 | pinMode(LED_SUCCESS, OUTPUT);
64 | pinMode(LED_COMPLETE, OUTPUT);
65 | digitalWrite(LED_BUILTIN, LOW);
66 | digitalWrite(LED_DETECT, LOW);
67 | digitalWrite(LED_SUCCESS, LOW);
68 | digitalWrite(LED_COMPLETE, LOW);
69 |
70 | // Initialize quirc decoder
71 | q = quirc_new();
72 | if (!q)
73 | {
74 | Serial.println("Failed to create quirc object");
75 | ESP.restart();
76 | }
77 |
78 | // Connect to Wi-Fi with enhanced stability
79 | WiFi.setSleep(false);
80 | WiFi.setTxPower(WIFI_POWER_19_5dBm);
81 | connectToWiFi();
82 |
83 | // Camera configuration
84 | configureCamera();
85 |
86 | xTaskCreatePinnedToCore(
87 | QRCodeReader,
88 | "QRCodeReader_Task",
89 | 20000,
90 | NULL,
91 | 1,
92 | &QRCodeReader_Task,
93 | 0);
94 | }
95 |
96 | void loop()
97 | {
98 | delay(1);
99 | }
100 |
101 | void connectToWiFi()
102 | {
103 | Serial.println("\nConnecting to Wi-Fi");
104 | WiFi.begin(ssid, password);
105 |
106 | int retries = 0;
107 | while (WiFi.status() != WL_CONNECTED && retries < WIFI_RETRIES)
108 | {
109 | digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
110 | delay(500);
111 | Serial.print(".");
112 | retries++;
113 | }
114 |
115 | if (WiFi.status() != WL_CONNECTED)
116 | {
117 | Serial.println("\nWiFi connection failed");
118 | ESP.restart();
119 | }
120 |
121 | Serial.println("\nConnected! IP address: ");
122 | Serial.println(WiFi.localIP());
123 |
124 | // Blink built-in LED 3 times
125 | for (int i = 0; i < 3; i++)
126 | {
127 | digitalWrite(LED_BUILTIN, HIGH);
128 | delay(100);
129 | digitalWrite(LED_BUILTIN, LOW);
130 | delay(100);
131 | }
132 | }
133 |
134 | void configureCamera()
135 | {
136 | camera_config_t config;
137 | config.ledc_channel = LEDC_CHANNEL_0;
138 | config.ledc_timer = LEDC_TIMER_0;
139 | config.pin_d0 = Y2_GPIO_NUM;
140 | config.pin_d1 = Y3_GPIO_NUM;
141 | config.pin_d2 = Y4_GPIO_NUM;
142 | config.pin_d3 = Y5_GPIO_NUM;
143 | config.pin_d4 = Y6_GPIO_NUM;
144 | config.pin_d5 = Y7_GPIO_NUM;
145 | config.pin_d6 = Y8_GPIO_NUM;
146 | config.pin_d7 = Y9_GPIO_NUM;
147 | config.pin_xclk = XCLK_GPIO_NUM;
148 | config.pin_pclk = PCLK_GPIO_NUM;
149 | config.pin_vsync = VSYNC_GPIO_NUM;
150 | config.pin_href = HREF_GPIO_NUM;
151 | config.pin_sscb_sda = SIOD_GPIO_NUM;
152 | config.pin_sscb_scl = SIOC_GPIO_NUM;
153 | config.pin_pwdn = PWDN_GPIO_NUM;
154 | config.pin_reset = RESET_GPIO_NUM;
155 | config.xclk_freq_hz = 20000000;
156 | config.pixel_format = PIXFORMAT_GRAYSCALE;
157 | config.frame_size = FRAMESIZE_QVGA;
158 | config.jpeg_quality = 7;
159 | config.fb_count = 1;
160 |
161 | esp_err_t err = esp_camera_init(&config);
162 | if (err != ESP_OK)
163 | {
164 | Serial.printf("Camera init failed: 0x%x", err);
165 | ESP.restart();
166 | }
167 |
168 | sensor_t *s = esp_camera_sensor_get();
169 | s->set_framesize(s, FRAMESIZE_QVGA);
170 | }
171 |
172 | void QRCodeReader(void *pvParameters)
173 | {
174 | Serial.println("\nQR Code Reader Task Started");
175 |
176 | while (1)
177 | {
178 | camera_fb_t *fb = esp_camera_fb_get();
179 | if (!fb)
180 | {
181 | Serial.println("Camera capture failed");
182 | vTaskDelay(100 / portTICK_PERIOD_MS);
183 | continue;
184 | }
185 |
186 | // Validate frame buffer
187 | size_t expected_size = fb->width * fb->height;
188 | if (fb->len != expected_size)
189 | {
190 | Serial.printf("Invalid frame buffer: Expected %zu, got %zu\n", expected_size, fb->len);
191 | esp_camera_fb_return(fb);
192 | vTaskDelay(100 / portTICK_PERIOD_MS);
193 | continue;
194 | }
195 |
196 | quirc_resize(q, fb->width, fb->height);
197 | uint8_t *image = quirc_begin(q, NULL, NULL);
198 | if (image)
199 | {
200 | memcpy(image, fb->buf, fb->len);
201 | quirc_end(q);
202 |
203 | int count = quirc_count(q);
204 | if (count > 0)
205 | {
206 | digitalWrite(LED_DETECT, HIGH);
207 | struct quirc_code code;
208 | struct quirc_data data;
209 | quirc_extract(q, 0, &code);
210 |
211 | if (!quirc_decode(&code, &data))
212 | {
213 | processQRCode((const char *)data.payload);
214 | }
215 | digitalWrite(LED_DETECT, LOW);
216 | }
217 | }
218 |
219 | esp_camera_fb_return(fb);
220 | vTaskDelay(50 / portTICK_PERIOD_MS);
221 | }
222 | }
223 |
224 | void processQRCode(const char *payload)
225 | {
226 | Serial.printf("\nDecoded Payload: %s\n", payload);
227 |
228 | // Split email and hash
229 | String qrData(payload);
230 | int underscoreIndex = qrData.indexOf('_');
231 | if (underscoreIndex == -1)
232 | {
233 | Serial.println("Invalid QR Code format");
234 | return;
235 | }
236 |
237 | String email = qrData.substring(0, underscoreIndex);
238 | String hash = qrData.substring(underscoreIndex + 1);
239 | String orderURL = "https://csms-api.deno.dev/order?email=" + email + "&hash=" + hash;
240 | Serial.println("Generated Order URL: " + orderURL);
241 |
242 | HTTPClient http;
243 | http.begin(orderURL);
244 | http.setTimeout(HTTP_TIMEOUT);
245 |
246 | int httpCode = http.GET();
247 | if (httpCode == HTTP_CODE_OK)
248 | {
249 | processAPIResponse(http.getString(), email, hash);
250 | }
251 | else
252 | {
253 | Serial.printf("Order API Error: %d - %s\n", httpCode, http.errorToString(httpCode).c_str());
254 | }
255 | http.end();
256 | }
257 |
258 | void processAPIResponse(String response, String email, String hash)
259 | {
260 | Serial.println("API Response: " + response);
261 |
262 | DynamicJsonDocument doc(1024);
263 | deserializeJson(doc, response);
264 | const char *error = doc["error"];
265 |
266 | Serial.print("Error Status: ");
267 | Serial.println(error ? error : "null");
268 |
269 | if (!error)
270 | {
271 | handleValidOrder(doc, email, hash);
272 | }
273 | else if (strcmp(error, "Order deliverd!") == 0)
274 | {
275 | handleCompleteOrder();
276 | }
277 | }
278 |
279 | void handleValidOrder(DynamicJsonDocument &doc, String &email, String &hash)
280 | {
281 | // Process items
282 | String itemString = "00000000";
283 | if (doc.containsKey("items"))
284 | {
285 | JsonObject items = doc["items"];
286 | for (JsonPair kv : items)
287 | {
288 | int itemCode = atoi(kv.key().c_str());
289 | int count = kv.value().as();
290 |
291 | if (itemCode >= 1 && itemCode <= 8)
292 | {
293 | itemString[itemCode - 1] = (count > 9) ? '9' : (count + '0');
294 | }
295 | }
296 | }
297 | Serial.print("Item Codes: ");
298 | Serial.println(itemString);
299 |
300 | // Upload to ThingSpeak
301 | if (uploadToThingSpeak(itemString))
302 | {
303 | Serial.println("ThingSpeak update successful");
304 | }
305 |
306 | // Send completion URL
307 | if (sendCompletionRequest(email, hash))
308 | {
309 | Serial.println("Completion URL notified");
310 | }
311 |
312 | // Activate success LED
313 | digitalWrite(LED_SUCCESS, HIGH);
314 | delay(5000);
315 | digitalWrite(LED_SUCCESS, LOW);
316 | }
317 |
318 | void handleCompleteOrder()
319 | {
320 | digitalWrite(LED_COMPLETE, HIGH);
321 | delay(5000);
322 | digitalWrite(LED_COMPLETE, LOW);
323 | }
324 |
325 | bool uploadToThingSpeak(String &itemString)
326 | {
327 | HTTPClient httpTS;
328 | String tsURL = String(thingspeakURL) + "?api_key=" + thingspeakAPIKey + "&field1=" + itemString;
329 |
330 | httpTS.begin(tsURL);
331 | httpTS.setTimeout(HTTP_TIMEOUT);
332 |
333 | int tsCode = httpTS.GET();
334 | bool success = (tsCode == HTTP_CODE_OK);
335 |
336 | if (!success)
337 | {
338 | Serial.printf("ThingSpeak Error: %d - %s\n", tsCode, httpTS.errorToString(tsCode).c_str());
339 | }
340 |
341 | httpTS.end();
342 | return success;
343 | }
344 |
345 | bool sendCompletionRequest(String &email, String &hash)
346 | {
347 | String completionURL = "https://csms-api.deno.dev/order/complete?email=" + email + "&hash=" + hash;
348 | Serial.println("Attempting Completion URL: " + completionURL);
349 |
350 | WiFiClientSecure client;
351 | HTTPClient httpComplete;
352 | client.setInsecure();
353 | client.setTimeout(HTTP_TIMEOUT);
354 |
355 | bool success = false;
356 | int retries = 3;
357 |
358 | while (retries-- > 0 && !success)
359 | {
360 | if (httpComplete.begin(client, completionURL))
361 | {
362 | httpComplete.setTimeout(HTTP_TIMEOUT);
363 | int code = httpComplete.GET();
364 |
365 | if (code == HTTP_CODE_OK)
366 | {
367 | success = true;
368 | }
369 | else
370 | {
371 | Serial.printf("Completion Error (Attempt %d): %d - %s\n",
372 | 3 - retries, code, httpComplete.errorToString(code).c_str());
373 | }
374 | httpComplete.end();
375 | }
376 | client.stop();
377 | delay(1000);
378 | }
379 |
380 | return success;
381 | }
--------------------------------------------------------------------------------