Arduino Uno and SIM900 EFcom shield.
3 Outputs and 2 Inputs can be written/read over a short-message (SMS).
some SMS commands are:
“#s” : get status as SMS reply
“#u” : get status over usb, serial monitor
“#[a,b,c][0,1]” : set output level
(eg. “#c1” sets output c to 1)
some usb, serial monitor commands are:
“h” : show help
“c” : check credit
“s” : start/shutdown SIM900 shield
The communication between Arduino and the SIM900 shield utilizes AT-Commands.
my source code is a modified version of the following websites:
elecfreaks
instructables
circuitstoday
source code:
/* Author: Dejan Lauber Datum: 4.2017 File: sim900efcom_ATcomp.c Version: V1 Funktion: 3 ausgänge per sms steuerbar; statusabfrage von 2 eingängen und temperatur Pinbelegung: (EFCOM LCD5110 Header) 1 3.3V 2 GND 3 13 output a (+onboard LED) 4 12 output b 5 11 output c 6 10 input A 7 9 input B 8 LCD_BL */ #include <SoftwareSerial.h> SoftwareSerial mySerial(2, 3); #define sim900start 6 #define sim900reset 5 String tx; char rx, diding_stuff; String srx; void setup() { mySerial.begin(19200); // the GPRS baud rate Serial.begin(19200); // the usb baud rate pinMode(sim900start, OUTPUT); pinMode(sim900reset, OUTPUT); pinMode(9, INPUT_PULLUP); //B pinMode(10, INPUT_PULLUP); //A pinMode(11, OUTPUT); //c;(pwm) pinMode(12, OUTPUT); //b;auto-on pinMode(13, OUTPUT); //a;(led) digitalWrite(12, HIGH); //b auto-on delay(1000); mySerial.println("AT"); delay(2000); if(mySerial.available()){ Serial.println("\nSIM900 seems ready"); } else{ Serial.println("\nstarting up 20s"); digitalWrite(sim900start, HIGH); delay(3000); digitalWrite(sim900start, LOW); delay(20000); Serial.println("\ntext mode activated"); mySerial.println("AT+CMGF=1"); delay(500); Serial.println("\nsms forward activated"); mySerial.println("AT+CNMI=2,2,0,0,0"); delay(500); } } void loop() { if(Serial.available()) { tx=Serial.readString(); //mySerial.print(tx); //Serial.print(tx); if(tx=="a"){ //Serial.println("\nreceived A"); mySerial.println("AT"); } if(tx=="f"){ Serial.println("\nsms forward activated"); mySerial.println("AT+CNMI=2,2,0,0,0"); } if(tx=="m"){ Serial.println("\ntext mode activated"); mySerial.println("AT+CMGF=1"); } if(tx=="s"){ Serial.print("\nstarting up/down"); digitalWrite(sim900start, HIGH); delay(3500); digitalWrite(sim900start, LOW); } if(tx=="c"){ Serial.println("\nchecking credit"); mySerial.println("ATD*130#"); //swisscom 130; } if(tx=="h"){ Serial.println("\nvalid usb commands:"); Serial.println("s start/stop SIM900 (auto)"); Serial.println("m enable text mode (auto)"); Serial.println("f enable live sms forwarding (auto)"); Serial.println("a send 'AT' to SIM900 and show answer"); Serial.println("c check swisscom prepaid credit"); Serial.println("h show this help dialog"); Serial.println("\nvalid sms commands:"); Serial.println("#[a|b|c][1|0] set output a|b|c to 1|0"); Serial.println("#s request status report over sms"); Serial.println("#u request status report over usb"); } } if(mySerial.available()){ //Serial.print("\nrx:"); //Serial.print(mySerial.readString()); rx = mySerial.read(); srx = String(rx); Serial.print(srx); if(rx=='#'){ delay(10); rx = mySerial.read(); srx = String(rx); Serial.print(srx); switch(rx){ case 'a': delay(10); rx = mySerial.read(); srx = String(rx); Serial.print(srx); switch(rx){ case '1': digitalWrite(13, HIGH); break; case '0': digitalWrite(13, LOW); break; } break; case 'b': delay(10); rx = mySerial.read(); srx = String(rx); Serial.print(srx); switch(rx){ case '1': digitalWrite(12, HIGH); break; case '0': digitalWrite(12, LOW); break; } break; case 'c': delay(10); rx = mySerial.read(); srx = String(rx); Serial.print(rx); switch(rx){ case '1': digitalWrite(11, HIGH); break; case '0': digitalWrite(11, LOW); break; } break; case 'u': //usb status report requested Serial.println("\nreceived status report request"); Serial.print("Output a: "); Serial.println(digitalRead(13)); Serial.print("Output b: "); Serial.println(digitalRead(12)); Serial.print("Output c: "); Serial.println(digitalRead(11)); Serial.print("Input_pullup A: "); Serial.println(digitalRead(10)); Serial.print("Input_pullup B: "); Serial.println(digitalRead(9)); Serial.print("MCU Temperature: "); Serial.print((unsigned int)round(GetTemp())); Serial.write('°'); Serial.println("C"); break; case 's': //gsm status report requested delay(500); mySerial.println("AT+CMGF=1"); delay(500); Serial.print(mySerial.readString()); mySerial.println("AT+CMGS=\"+41787581181\""); delay(500); Serial.print(mySerial.readString()); mySerial.print("Output a: "); mySerial.println(digitalRead(13)); mySerial.print("Output b: "); mySerial.println(digitalRead(12)); mySerial.print("Output c: "); mySerial.println(digitalRead(11)); mySerial.print("Input_pullup A: "); mySerial.println(digitalRead(10)); mySerial.print("Input_pullup B: "); mySerial.println(digitalRead(9)); mySerial.print("MCU Temperature: "); mySerial.print((unsigned int)round(GetTemp())); mySerial.println("C"); delay(500); Serial.print(mySerial.readString()); mySerial.write(26); delay(500); Serial.print(mySerial.readString()); break; case 'W': //gsm easter egg activated //Serial.print("gogo"); delay(500); mySerial.println("AT+CMGF=1"); delay(500); Serial.print(mySerial.readString()); mySerial.println("AT+CMGS=\"+41787581181\""); delay(500); Serial.print(mySerial.readString()); mySerial.println("Triggering sequence activated!"); mySerial.println("Time left: T-00:9:56.32"); delay(500); Serial.print(mySerial.readString()); mySerial.write(26); delay(500); Serial.print(mySerial.readString()); break; } diding_stuff=1; } } else{ delay(1000); if(!mySerial.available()){ if(diding_stuff==1){ mySerial.println("AT+CMGD=1,4"); diding_stuff=0; } } } } double GetTemp(void) { unsigned int wADC; double t; // The internal temperature has to be used // with the internal reference of 1.1V. // Channel 8 can not be selected with // the analogRead function yet. // Set the internal reference and mux. ADMUX = (_BV(REFS1) | _BV(REFS0) | _BV(MUX3)); ADCSRA |= _BV(ADEN); // enable the ADC delay(20); // wait for voltages to become stable. ADCSRA |= _BV(ADSC); // Start the ADC // Detect end-of-conversion while (bit_is_set(ADCSRA,ADSC)); // Reading register "ADCW" takes care of how to read ADCL and ADCH. wADC = ADCW; // The offset of 324.31 / 1.22 could be wrong. It is just an indication t = (wADC - 329 ) / 1.22; // The returned temperature is in degrees Celsius. return (t); }