OpenSesame.ino
1 // SPDX-FileCopyrightText: 2019 Anne Barela for Adafruit Industries 2 // 3 // SPDX-License-Identifier: MIT 4 5 #include <SoftwareSerial.h> 6 #include "Adafruit_FONA.h" 7 8 #define FONA_TX 3 9 #define FONA_RX 4 10 #define FONA_RST 5 11 #define FONA_RI 2 12 13 #define MOTOR_PWM A1 14 #define MOTOR_1 A2 15 #define MOTOR_2 A3 16 17 #define LED 13 18 19 #define OPEN true 20 #define CLOSE false 21 22 #define BUSYWAIT 5000 // milliseconds 23 24 // this is a large buffer for replies 25 char replybuffer[255]; 26 27 // or comment this out & use a hardware serial port like Serial1 (see below) 28 SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX); 29 30 Adafruit_FONA fona = Adafruit_FONA(FONA_RST); 31 32 uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0); 33 34 boolean fonainit(void) { 35 Serial.println(F("Initializing....(May take 3 seconds)")); 36 37 digitalWrite(LED, HIGH); 38 delay(100); 39 digitalWrite(LED, LOW); 40 delay(100); 41 digitalWrite(LED, HIGH); 42 delay(100); 43 digitalWrite(LED, LOW); 44 delay(100); 45 46 // make it slow so its easy to read! 47 fonaSS.begin(4800); // if you're using software serial 48 //Serial1.begin(4800); // if you're using hardware serial 49 50 // See if the FONA is responding 51 if (! fona.begin(fonaSS)) { // can also try fona.begin(Serial1) 52 Serial.println(F("Couldn't find FONA")); 53 return false; 54 } 55 Serial.println(F("FONA is OK")); 56 return true; 57 58 } 59 60 void setup() { 61 while (!Serial); // useful for Leonardo/Micro, remove in production! 62 63 // set LED output for debugging 64 pinMode(LED, OUTPUT); 65 66 // set up motor pins, but turn them off 67 pinMode(MOTOR_1, OUTPUT); 68 digitalWrite(MOTOR_1, LOW); 69 pinMode(MOTOR_2, OUTPUT); 70 digitalWrite(MOTOR_2, LOW); 71 pinMode(MOTOR_PWM, OUTPUT); 72 digitalWrite(MOTOR_PWM, LOW); 73 74 Serial.begin(115200); 75 Serial.println(F("FONA basic test")); 76 77 while (! fonainit()) { 78 delay(5000); 79 } 80 81 // Print SIM card IMEI number. 82 char imei[15] = {0}; // MUST use a 16 character buffer for IMEI! 83 uint8_t imeiLen = fona.getIMEI(imei); 84 if (imeiLen > 0) { 85 Serial.print("SIM card IMEI: "); Serial.println(imei); 86 } 87 88 pinMode(FONA_RI, INPUT); 89 digitalWrite(FONA_RI, HIGH); // turn on pullup on RI 90 // turn on RI pin change on incoming SMS! 91 fona.sendCheckReply(F("AT+CFGRI=1"), F("OK")); 92 } 93 94 int8_t lastsmsnum = 0; 95 96 void loop() { 97 digitalWrite(LED, HIGH); 98 delay(100); 99 digitalWrite(LED, LOW); 100 101 while (fona.getNetworkStatus() != 1) { 102 Serial.println("Waiting for cell connection"); 103 delay(2000); 104 } 105 106 // this is a 'busy wait' loop, we check if the interrupt 107 // pin went low, and after BUSYWAIT milliseconds break out to check 108 // manually for SMS's and connection status 109 // This would be a good place to 'sleep' 110 for (uint16_t i=0; i<BUSYWAIT; i++) { 111 if (! digitalRead(FONA_RI)) { 112 // RI pin went low, SMS received? 113 Serial.println(F("RI went low")); 114 break; 115 } 116 delay(1); 117 } 118 119 int8_t smsnum = fona.getNumSMS(); 120 if (smsnum < 0) { 121 Serial.println(F("Could not read # SMS")); 122 return; 123 } else { 124 Serial.print(smsnum); 125 Serial.println(F(" SMS's on SIM card!")); 126 } 127 128 if (smsnum == 0) return; 129 130 // there's an SMS! 131 uint8_t n = 1; 132 while (true) { 133 uint16_t smslen; 134 char sender[25]; 135 136 Serial.print(F("\n\rReading SMS #")); Serial.println(n); 137 uint8_t len = fona.readSMS(n, replybuffer, 250, &smslen); // pass in buffer and max len! 138 // if the length is zero, its a special case where the index number is higher 139 // so increase the max we'll look at! 140 if (len == 0) { 141 Serial.println(F("[empty slot]")); 142 n++; 143 continue; 144 } 145 if (! fona.getSMSSender(n, sender, sizeof(sender))) { 146 // failed to get the sender? 147 sender[0] = 0; 148 } 149 150 Serial.print(F("***** SMS #")); Serial.print(n); 151 Serial.print(" ("); Serial.print(len); Serial.println(F(") bytes *****")); 152 Serial.println(replybuffer); 153 Serial.print(F("From: ")); Serial.println(sender); 154 Serial.println(F("*****")); 155 156 if (strcasecmp(replybuffer, "open sesame") == 0) { 157 // open the door! 158 digitalWrite(LED, HIGH); 159 moveMotor(OPEN, 800); 160 digitalWrite(LED, LOW); 161 } 162 if (strcasecmp(replybuffer, "close cadabra") == 0) { 163 // close the door! 164 digitalWrite(LED, HIGH); 165 moveMotor(CLOSE, 800); 166 digitalWrite(LED, LOW); 167 } 168 169 delay(3000); 170 break; 171 } 172 fona.deleteSMS(n); 173 174 delay(1000); 175 } 176 177 178 void moveMotor(boolean direction, uint16_t t) { 179 digitalWrite(MOTOR_PWM, HIGH); // enable motor 180 if (direction) { 181 digitalWrite(MOTOR_1, HIGH); 182 digitalWrite(MOTOR_2, LOW); 183 } else { 184 digitalWrite(MOTOR_2, HIGH); 185 digitalWrite(MOTOR_1, LOW); 186 } 187 delay(t); 188 digitalWrite(MOTOR_1, LOW); 189 digitalWrite(MOTOR_2, LOW); 190 191 digitalWrite(MOTOR_PWM, LOW); // disable motor 192 }