-
Notifications
You must be signed in to change notification settings - Fork 0
/
ArduinoCode.ino
339 lines (304 loc) · 11.3 KB
/
ArduinoCode.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
#include <math.h>
#include <EEPROM.h>
#include "src/SimCom/SimCom.h"
#include "src/Keypad/Keypad.h"
#include "src/MicrowaveControl/MicrowaveControl.h"
#include "src/PresetFoods/PresetFoods.h"
#define KEYPAD_COL_START 22
#define KEYPAD_ROW_START 28
#define INH_ROW_8 34
#define INH_ROW_9 35
#define INH_ROW_10 36
#define INH_ROW_11 37
#define CH_SELECTOR_0 40
#define CH_SELECTOR_1 41
#define CH_SELECTOR_2 42
bool onCall = false;
bool isMicrowaving = false;
char pinCode[5] = "";
SIM7600 simModule(Serial1);
Keypad keypad = Keypad(KEYPAD_ROW_START, KEYPAD_COL_START);
MicrowaveControl mcu = MicrowaveControl(INH_ROW_8, INH_ROW_9, INH_ROW_10, INH_ROW_11,
CH_SELECTOR_0, CH_SELECTOR_1, CH_SELECTOR_2);
bool setPin(char *pinStr) {
int i = 0;
for(i = 0; pinStr[i] != '\0' && i < 4; ++i) {
Serial.println(pinStr[i]);
if(i >= 4 || pinStr[i] < '0' || pinStr[i] > '9') {
return false;
}
}
for(i = 0; i < 4; ++i) {
EEPROM.update(i,pinStr[i]);
}
return true;
}
void getPin() {
for(int i = 0; i < 4; ++i) {
pinCode[i] = EEPROM.read(i);
}
}
// Unused function for texting the location of the microwave with a Google Maps link
void textGPS(const char* phone_number) {
char latStr[16];
char longStr[16];
char replyStr[128];
SIM7600::GPSStruct gpsData = simModule.getGPSLocation(45000);
if (!gpsData.status) {
simModule.sendSMS(phone_number, "Failed to get GPS data");
}
dtostrf(gpsData.latitude, 3, 8, latStr);
dtostrf(gpsData.longitude, 4, 8, longStr);
sprintf(replyStr,
"https://www.google.com/maps/search/?api=1&query=%s%%2C%s", latStr,
longStr);
simModule.sendSMS(phone_number, replyStr);
}
void initCall(char* dataBuffer, int bufferSize) {
char phone_number[30] = "\0";
int number_length = 0;
char* token;
// Get the phone number of the phone calling
simModule.sendATCommand("AT+CLCC", 1000, dataBuffer, bufferSize);
token = strtok(dataBuffer, ",");
for (int i = 0; i < 5; i++) token = strtok(NULL, ",");
strcpy(phone_number, token + 1);
// Null terminate the number string
number_length = strlen(phone_number);
phone_number[--number_length] = '\0';
// Print phone number
Serial.print("Call from: ");
Serial.println(phone_number);
// Answer Phone Call
simModule.sendATCompare("ATA", 500, 0);
getPin();
// Set up TTS settings and play welcome message
simModule.sendATCompare("AT+CDTAM=1", 500, 0);
simModule.sendATCompare("AT+CTTSPARAM=2,3,0,1,2", 500, 0);
simModule.sendTTS("Please enter pin code");
onCall = true;
}
void handleCall(char* dataBuffer, int bufferSize) {
char* strPtr = dataBuffer;
static bool isUnlocked = false;
static int lockIndex = 0;
// Check if call has ended
if (strstr(dataBuffer, "VOICE CALL: END:") ||
strstr(dataBuffer, "NO CARRIER")) {
Serial.print("Call Ended");
onCall = false;
lockIndex = 0;
isUnlocked = false;
}
// Search for DTMF data
strPtr = strstr(strPtr, "+RXDTMF: ");
while (strPtr) {
char keyPressed = strPtr[9];
if(isUnlocked == false) {
if(keyPressed == '*') {
lockIndex = 0;
} else if(keyPressed != pinCode[lockIndex]) {
onCall = false;
lockIndex = 0;
// Hang up call
simModule.sendATCompare("AT+CHUP", 500, 0);
} else {
++lockIndex;
if(lockIndex == 4) {
simModule.sendTTS("Welcome to the Phone Micro wave");
isUnlocked = true;
lockIndex = 0;
}
}
} else {
// Match key pressed to microwave button
Keypad::readPin btnStruct = keypad.dtmfLookup(keyPressed);
// Simulate the microwave button press
mcu.simulateButton(btnStruct.rowPin, btnStruct.colPin);
}
// Scan for next DTMF key press
strPtr++;
strPtr = strstr(strPtr, "+RXDTMF: ");
}
}
void powerLvlSms(int powerLevel, char *responseBuffer, size_t len) {
Keypad::readPin button;
bool success = true;
char *response;
switch(powerLevel) {
case 1:
response = "SET POWER LEVEL TO LOW. TYPE START TO CONFIRM, CANCEL OTHERWISE.";
button = Keypad::BTN_LOW;
break;
case 2:
response = "SET POWER LEVEL TO MEDIUM. TYPE START TO CONFIRM, CANCEL OTHERWISE.";
button = Keypad::BTN_MED_LOW_DEFROST;
break;
case 3:
response = "SET POWER LEVEL TO MEDIUM. TYPE START TO CONFIRM, CANCEL OTHERWISE.";
button = Keypad::BTN_MEDIUM;
break;
case 4:
response = "SET POWER LEVEL TO MEDIUM HIGH. TYPE START TO CONFIRM, CANCEL OTHERWISE.";
button = Keypad::BTN_MED_HIGH;
break;
case 5:
response = "SET POWER LEVEL TO HIGH. TYPE START TO CONFIRM, CANCEL OTHERWISE.";
button = Keypad::BTN_HIGH;
break;
default:
response = "\"POWER <LEVEL>\", WHERE <LEVEL> IS A NUMBER FROM 1-5, WHERE 5 IS HIGHEST.";
success = false;
}
strncpy(responseBuffer, response, len);
if(success) {
Serial.print(button.rowPin);
Serial.print(button.colPin);
mcu.simulateButton(button.rowPin, button.colPin);
}
}
void defrostSms(int defrostOption, char *responseBuffer, size_t len) {
bool success = true;
char *response;
switch(defrostOption) {
case 1:
response = "DEFROSTING 1LB GROUND MEAT. TYPE START TO CONFIRM, CANCEL OTHERWISE.";
break;
case 2:
response = "DEFROSTING 2LB PORK CHOP. TYPE START TO CONFIRM, CANCEL OTHERWISE.";
break;
case 3:
response = "DEFROSTING 2LB STEAKS. TYPE START TO CONFIRM, CANCEL OTHERWISE.";
break;
case 4:
response = "DEFROSTING 2LB CHICKEN PIECES. TYPE START TO CONFIRM, CANCEL OTHERWISE.";
break;
case 5:
response = "DEFROSTING 3LB WHOLE CHICKEN. TYPE START TO CONFIRM, CANCEL OTHERWISE.";
break;
default:
response = "\"DEFROST <OPT>\", 1: 1LB GROUND MEAT, 2: 2LB PORK CHOP, 3: 2LB STEAKS, 4:2LB CHICKEN PIECES, 5: 3LB WHOLE CHICKEN.";
success = false;
}
strncpy(responseBuffer, response, len);
if(success) {
Keypad::readPin button = keypad.dtmfLookup('0'+defrostOption);
mcu.simulateButton(Keypad::BTN_EASY_DEFROST.rowPin, Keypad::BTN_EASY_DEFROST.colPin);
mcu.simulateButton(button.rowPin, button.colPin);
}
}
void reheatSms(int reheatOption, char *responseBuffer, size_t len) {
bool success = true;
char *response;
switch(reheatOption) {
case 1:
response = "REHEATING 1CUP CASSEROLE. TYPE START TO CONFIRM, CANCEL OTHERWISE.";
break;
case 2:
response = "REHEATING 1 DINNER PLATE. TYPE START TO CONFIRM, CANCEL OTHERWISE.";
break;
case 3:
response = "REHEATING 10-12oz FROZEN ENTREE. TYPE START TO CONFIRM, CANCEL OTHERWISE.";
break;
case 4:
response = "REHEATING 1CUP SOUP. TYPE START TO CONFIRM, CANCEL OTHERWISE.";
break;
case 5:
response = "REHEATING 1CUP VEGETABLES. TYPE START TO CONFIRM, CANCEL OTHERWISE.";
break;
default:
response = "\"REHEAT <OPT>\", 1: 1CUP CASSEROLE, 2: 1 DINNER PLATE, 3: 10-12oz FROZEN ENTREE, 4: 1CUP SOUP, 5: 1CUP VEGETABLES.";
success = false;
}
strncpy(responseBuffer, response, len);
if(success) {
Keypad::readPin button = keypad.dtmfLookup('0'+reheatOption);
mcu.simulateButton(Keypad::BTN_EASY_REHEAT.rowPin, Keypad::BTN_EASY_REHEAT.colPin);
mcu.simulateButton(button.rowPin, button.colPin);
}
}
void handleSMS(SIM7600::SMSStruct smsInput) {
char messageCpy[200] = "";
strncpy(messageCpy, smsInput.message, sizeof(smsInput.message));
char *token = strtok(messageCpy, " ");
char response[180] = "";
char *postConvert = NULL;
if(strncmp(token , "PIN", 3) == 0) {
token = strtok(NULL, " ");
if(token == NULL || setPin(token) == false) {
strncpy(response,"\"PIN <4 DIGIT CODE>\"", 180);
} else {
strncpy(response,"NEW PIN CODE SET", 180);
}
} else if(strncmp(token , "POWER", 5) == 0) {
token = strtok(NULL, " ");
int powerVal = (token == NULL)? 0: strtol(token, &postConvert, 10);
powerLvlSms(powerVal, response, 180);
} else if(strncmp(token , "DEFROST", 7) == 0) {
token = strtok(NULL, " ");
int defrostVal = (token == NULL)? 0: strtol(token, &postConvert, 10);
defrostSms(defrostVal, response, 180);
} else if(strncmp(token , "REHEAT", 6) == 0) {
token = strtok(NULL, " ");
int reheatVal = (token == NULL)? 0: strtol(token, &postConvert, 10);
reheatSms(reheatVal, response, 180);
} else if(strncmp(token , "PRESET", 6) == 0) {
token = strtok(NULL, " ");
int presetVal = (token == NULL)? 0: strtol(token, &postConvert, 10);
handlePresetFood(mcu, presetVal, response, 180);
} else if(strncmp(token , "CANCEL", 6) == 0) {
mcu.simulateButton(Keypad::BTN_STOP_CANCEL.rowPin, Keypad::BTN_STOP_CANCEL.colPin);
mcu.simulateButton(Keypad::BTN_STOP_CANCEL.rowPin, Keypad::BTN_STOP_CANCEL.colPin);
strncpy(response,"CANCELLING", 180);
} else if(strncmp(token , "START", 5) == 0) {
mcu.simulateButton(Keypad::BTN_START.rowPin, Keypad::BTN_START.colPin);
strncpy(response,"STARTING OPERATION.", 180);
} else {
strncpy(response,"AVAILABLE COMMANDS:\nPOWER\nDEFROST\nREHEAT\nPRESET", 180);
}
simModule.sendSMS(smsInput.number, response);
}
void setup() {
Serial.begin(115200);
Serial.println("Initializing");
Serial1.begin(9600);
keypad.initializePins();
mcu.initializePins();
delay(500);
mcu.simulateButton(Keypad::BTN_STOP_CANCEL.rowPin, Keypad::BTN_STOP_CANCEL.colPin);
simModule.initConfig(15000);
Serial.println("READY");
delay(500);
}
void loop() {
static char dataBuffer[256] = {0};
static SIM7600::SMSStruct smsData = {};
static boolean btnPressed = false;
char* index;
if (simModule.readToBuffer(dataBuffer, sizeof(dataBuffer)) > 0) {
if ((index = strstr(dataBuffer, "+CMTI: \"ME\",")) != NULL) {
index += 12;
smsData = {};
simModule.readSMS(atoi(index), smsData);
handleSMS(smsData);
}
if (onCall == false && (index = strstr(dataBuffer, "RING")) != NULL) {
index += 4;
initCall(dataBuffer, sizeof(dataBuffer));
}
if (onCall == true) {
handleCall(dataBuffer, sizeof(dataBuffer));
}
}
if (onCall == false) {
Keypad::readPin keypadRead = keypad.readKeypad();
if (keypadRead != Keypad::BTN_UNPRESSED && !btnPressed) {
Serial.println(keypad.buttonStr(keypadRead));
mcu.simulateButton(keypadRead.rowPin, keypadRead.colPin);
btnPressed = true;
}
else if(keypadRead == Keypad::BTN_UNPRESSED) {
btnPressed = false;
}
}
}