Go Down

Topic: Fernsteuerung per SMS (Read 11943 times) previous topic - next topic

michael_x

Ich würde mir den Relais Zustand merken beim Schalten, und dann auf Anfrage ( oder bei Temperatur-Alarm ) eine SMS mit allen gemerkten Zuständen und Temperatur senden.

Mit sprintf kannst du viele Variable in einen char sendeSMS_Text[160] (oder kleiner) packen.
Oder eben mehrere SIM900.print nacheinander ausführen.

#16
Apr 05, 2015, 11:38 am Last Edit: Apr 05, 2015, 11:42 am by AndreasVan
Das mit dem Zustand merken ist ne gute Idee! Hab mir aber gedacht das ich auch mit "digitalRead" den Zustand auslesen könnte, aber irgendwo hab ich da wohl einen Denkfehler.
Die Relays schalten - #a1 #a0 etc.  Aber ich bekomme keine Rückmeldung wenn ich #s1 oder #s0 schicke ...  ::)

Code: [Select]

// Control of a Ralay shield - Last update: AndreasVan 2015-04-04 Version 1.01   
// Micro controller = Arduino UNO - GSM Shield
// this code is public domain, enjoy!

#include <SoftwareSerial.h>
char inchar;                          //Will hold the incoming character from the Serial Port.
SoftwareSerial SIM900(7,8);           // Software Serial Pin7 is Rx pin, pin 8 is Tx pin.

int relay01 = 10;
int relay02 = 11;
int relay03 = 12;
int relay04 = 13;
int led = 2;
int val1 = 0;     // variable to store the relay1 value


void setup()
{
  Serial.begin(19200);
  Serial.print(" Start ");
  pinMode(relay01, OUTPUT);              // prepare the digital output pins
  pinMode(relay02, OUTPUT);
  pinMode(relay03, OUTPUT);
  pinMode(relay04, OUTPUT);
  pinMode(led, OUTPUT);                 
  digitalWrite(relay01, LOW);
  digitalWrite(relay02, LOW);
  digitalWrite(relay03, LOW);
  digitalWrite(relay04, LOW);

  pinMode(9, OUTPUT );                  // software equivalent of pressing the GSM shield "power" button
  digitalWrite(9, HIGH);
  delay(2000);
  digitalWrite(9, LOW);
  Serial.print(" Wait for network ");
  SIM900.begin(19200);                 // Initialize GSM module serial port for communication.
  delay(30000);                        // give time for GSM module to register on network etc.
  SIM900.print("AT+CMGF=1\r");         // set SMS mode to text
  delay(200);
  SIM900.print("AT+CNMI=2,2,0,0,0\r"); // set module to send SMS data to serial out upon receipt
  delay(200);
  digitalWrite(led, HIGH);             // GSM Shield ready
  delay(500);
  digitalWrite(led, LOW);
  delay(500);
  digitalWrite(led, HIGH);
  Serial.print(" Ready ! "); 
 
}

void loop() {
 
  //If a character comes in from the SIM900ular module...
  if(SIM900.available() >0)
  {
    inchar=SIM900.read();
    if (inchar=='#')
    {
      delay(10);
      inchar=SIM900.read();
      if (inchar=='a')
      Serial.print(" Read Relay1 ");
      {
        delay(10);
        inchar=SIM900.read();
        if (inchar=='0')
          {
          digitalWrite(relay01, LOW);
        }
        else if (inchar=='1')
        {
          digitalWrite(relay01, HIGH);
        }
        delay(10);
        inchar=SIM900.read();
        if (inchar=='b')
        {
          inchar=SIM900.read();
          if (inchar=='0')
          {
            digitalWrite(relay02, LOW);
          }
          else if (inchar=='1')
          {
            digitalWrite(relay02, HIGH);
          }
          delay(10);
          inchar=SIM900.read();
          if (inchar=='c')
          {
            inchar=SIM900.read();
            if (inchar=='0')
            {
              digitalWrite(relay03, LOW);
            }
            else if (inchar=='1')
            {
              digitalWrite(relay03, HIGH);
            }
            delay(10);
            inchar=SIM900.read();
            if (inchar=='d')
            {
              delay(10);
              inchar=SIM900.read();
              if (inchar=='0')
              {
                digitalWrite(relay04, LOW);
              }
              else if (inchar=='1')
              {
                digitalWrite(relay04, HIGH);
              }
                  delay(10);
                 inchar=SIM900.read();
               Serial.print(" Read state ");
                if (inchar=='s')
                {
                  inchar=SIM900.read();
                  if (inchar=='0')
                  {
                   sendSMS();
                   do {} while (1);
                  }
                 else if (inchar=='1')
                 {
                 sendSMS();
                 }
                 delay(10);           }
                }
            SIM900.println("AT+CMGD=1,4"); // delete all SMS
        }
      }
    }
  }
}

}
void sendSMS(){
  val1 = digitalRead(relay01);                                    // read the relay pin
  Serial.print("relay01, val1");
  Serial.print(" Send SMS ");
  SIM900.print("AT+CMGF=1\r");                                    // AT command to send SMS message
  delay(100);
  SIM900.println("AT + CMGS = \"+4612345678\"");                 // recipient's mobile number, in international format
  delay(100);
  SIM900.println("relay01, val1");                                // message to send
  Serial.print("relay01, val1");
  delay(100);
  SIM900.println((char)26);                                       // End AT command with a ^Z, ASCII code 26
  delay(100);
  SIM900.println();
  delay(5000);                                                    // give module time to send SMS

}

Danke für Euer Feedback!
Ich hab das ganze jetzt im Wohnwagen verbaut und es funktioniert soweit ganz gut.
Hab es so abgeändert das ich den ganzen code sende. ZB. #a0b1c0d1
Dafür bekomme ich dann gleich die Antwort mit den Schaltzuständen und zusätzlich Temperatur, Feuchtigkeit und Board-Spannung. Achja und das die Tür zu ist  ;)

Code: [Select]

// Control of a Ralay shield - Last update: AndreasVan 2015-04-11 Version 13.01   
// Micro controller = Arduino UNO - GSM Shield
// this code is public domain, enjoy!
#include <SoftwareSerial.h>
#include <DHT.h>
#define DHTPIN A5   
#define DHTTYPE DHT22 
DHT dht(DHTPIN, DHTTYPE);
char inchar;                          // Will hold the incoming character from the Serial Port.
SoftwareSerial SIM900(7,8);           // Software Serial Pin7 is Rx pin, pin 8 is Tx pin.

int relay01 = 10;
int relay02 = 11;
int relay03 = 12;
int relay04 = 13;
int led = 2;
int val1 = 1;                // variable to store the relay1 value - Light 1
int val2 = 1;                // variable to store the relay2 value - Light 2
int val3 = 1;                // variable to store the relay3 value - Heater
int val4 = 1;                // variable to store the relay4 value - Reserve
const int doorPin = 3;       // the number of the pushbutton pin
int door = 1;                // variable for reading the pushbutton status
void setup()
{
  Serial.begin(19200);
  Serial.print(" Start ");
  pinMode(relay01, OUTPUT);              // prepare the digital output pins
  pinMode(relay02, OUTPUT);
  pinMode(relay03, OUTPUT);
  pinMode(relay04, OUTPUT);
  pinMode(led, OUTPUT);                 
  digitalWrite(relay01, LOW);
  digitalWrite(relay02, LOW);
  digitalWrite(relay03, LOW);
  digitalWrite(relay04, LOW);
  pinMode(doorPin, INPUT);   

  pinMode(9, OUTPUT );                  // software equivalent of pressing the GSM shield "power" button
  digitalWrite(9, HIGH);
  delay(2000);
  digitalWrite(9, LOW);
  Serial.print(" Wait for network ");
  SIM900.begin(19200);                 // Initialize GSM module serial port for communication.
  delay(30000);                        // give time for GSM module to register on network etc.
  SIM900.print("AT+CMGF=1\r");         // set SMS mode to text
  delay(200);
  SIM900.print("AT+CNMI=2,2,0,0,0\r"); // set module to send SMS data to serial out upon receipt
  delay(200);
  digitalWrite(led, HIGH);             // GSM Shield ready
  delay(500);
  digitalWrite(led, LOW);
  delay(500);
  digitalWrite(led, HIGH);
  Serial.print(" Ready ! "); 
  dht.begin();
  sendSMS0();
}

void loop() {

  if(SIM900.available() >0)
  {
    inchar=SIM900.read();
    if (inchar=='#')
    {
      delay(10);
      inchar=SIM900.read();
      if (inchar=='a')
      {
        delay(10);
        inchar=SIM900.read();
        if (inchar=='0')
          {
          digitalWrite(relay01, LOW);
        }
        else if (inchar=='1')
        {
          digitalWrite(relay01, HIGH);
        }
        delay(10);
        inchar=SIM900.read();
        if (inchar=='b')
        {
          inchar=SIM900.read();
          if (inchar=='0')
          {
            digitalWrite(relay02, LOW);
          }
          else if (inchar=='1')
          {
            digitalWrite(relay02, HIGH);
          }
          delay(10);
          inchar=SIM900.read();
          if (inchar=='c')
          {
            inchar=SIM900.read();
            if (inchar=='0')
            {
              digitalWrite(relay03, LOW);
            }
            else if (inchar=='1')
            {
              digitalWrite(relay03, HIGH);
            }
            delay(10);
            inchar=SIM900.read();
            if (inchar=='d')
            {
              delay(10);
              inchar=SIM900.read();
              if (inchar=='0')
              {
                digitalWrite(relay04, LOW);
              }
              else if (inchar=='1')
              {
                digitalWrite(relay04, HIGH);
              }
              delay(10);
            }
          }
          SIM900.println("AT+CMGD=1,4"); // delete all SMS
          sendSMS();
        }
      }
    }
  }
}


void sendSMS(){
  val1 = digitalRead(relay01);   // read the relay pin
  val2 = digitalRead(relay02);   // read the relay pin
  val3 = digitalRead(relay03);   // read the relay pin
  val4 = digitalRead(relay04);   // read the relay pin
  door = digitalRead(doorPin);
  // Wait a few seconds between measurements.
  delay(3000);
    // Reading temperature or humidity
  float h = dht.readHumidity();
  // Read temperature as Celsius
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit
  float f = dht.readTemperature(true);
  // Read Voltage (12V)
  float v = analogRead(A4) * 17.8 / 1023; // read voltage
  delay(2000);
  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
   Serial.println("Failed to read from DHT sensor!");
    return;
    }
     float hi = dht.computeHeatIndex(f, h);
  Serial.print(" Send SMS "); 
  Serial.print(" Temp: ");
  Serial.print(t);
  Serial.print(" Humidity: "); 
  Serial.print(h); 
  Serial.print(" Voltage "); 
  Serial.print(v); 
  SIM900.print("AT+CMGF=1\r");                                    // AT command to send SMS message
  delay(100);
  SIM900.println("AT + CMGS = \"+461234567\"");          // recipient's mobile number, in international format
  delay(100);
  SIM900.println("Indoor temp:");                                 // message to send                         
  SIM900.println(t); 
  SIM900.println("Indoor humidity:");
  SIM900.println(h);
  SIM900.println("Board voltage:");
  SIM900.println(v); 
  if (door == 0) {     
   SIM900.println("Door is open");  }
  else  {
  SIM900.println("Door is closed");  }
  if (val1 == 0) {     
  SIM900.println("Kitchen light is off"); }
  else  {
  SIM900.println("Kitchen light is on");  }
  if (val2 == 0) {     
  SIM900.println("Door light is off"); }
  else  {
  SIM900.println("Door light is on");  }
  if (val3 == 0) {     
  SIM900.println("Heater is off"); }
  else  {
  SIM900.println("Heater is on");  }
  if (val4 == 0) {     
  SIM900.println("Reserve is off"); }
  else  {
  SIM900.println("Reserve is on");  }
  delay(100);
  SIM900.println((char)26);                                       // End AT command with a ^Z, ASCII code 26
  delay(100);
  SIM900.println();
  delay(2000);                                                    // give module time to send SMS

}
void sendSMS0(){
  Serial.print(" Send SMS "); 
  SIM900.print("AT+CMGF=1\r");                                    // AT command to send SMS message
  delay(100);
  SIM900.println("AT + CMGS = \"+461234567\"");                 // recipient's mobile number, in international format
  delay(100);
  SIM900.println("Trailer System online!");
  delay(100);
  SIM900.println((char)26);                                       // End AT command with a ^Z, ASCII code 26
  delay(100);
  SIM900.println();
  delay(2000);                                                    // give module time to send SMS

}



Ich würde jetzt noch gerne die Absender-Telefonnummer von der SMS auslesen und die Antwort dort hin schicken. Wer hat den mal ein tipp wie das zuschauen könnte ?


kInGpIn-RR

#18
Apr 29, 2015, 09:55 pm Last Edit: May 24, 2015, 02:54 pm by kInGpIn-RR
Ich beschäftige mich auch gerade mit dem Thema. Der Thread hier und auch die anderen Vorschläge im Forum haben mir sehr geholfen. Vielen Dank!

Hier ist meine Lösung, die auch den Absender überprüft. Die Steuerbefehle werden in eckigen Klammern übergeben. Der Befehl <Relay01> beispielsweise schaltet das erste Relais. Die Steuerungsbefehle können nach dem Schema beliebig erweitert werden.

Es hat jedoch einen Schönheitsfehler: Wenn ein Angreifer die korrekte Absendernummer weiß, kann er diese den Steuerbefehlen in der SMS voranstellen. In diesem Fall müsste er aber genau wissen welche Befehle angenommen werden und es würde eine Bestätigungs-SMS an die hinterlegte Handynummer gehen. Für meinen Einsatzzweck ist das etwas womit ich leben kann. Falls jemand jedoch seine Haustür damit absichern möchte, dann sollte er sich darüber im Klaren sein. Über Verbesserungsvorschläge würde ich mich freuen.

Viel Spaß damit.

Nachtrag: Ich benutze ein Siemens TC 35. Bei anderen GSM Modulen kann ggf. die Baud-Rate hochgesetzt werden. Wenn Ihr den Code übernehmt, dann denkt daran die Baud-Rate im Serial-Monitor auf 4800 einzustellen.

Edit 2015-05-03: Ich habe den Code nochmal verfeinert und einen Bug behoben. Nun ist es eine bessere Vorlage.

Edit 2015-05-24: Code nochmals geändert und einen Bug behoben.


Code: [Select]

#include <SoftwareSerial.h>
SoftwareSerial gsm(2,3);


const int PowerLED =  4;                       // Power-LED red
const int InfoLED = 5;                         // Info-LED red
const int resetGSM = 8;                        // Reset PIN GSM
const int relay01 = 6;                        // Relais #01
const int relay02 = 7;                        // Relais #02
const String phoneNo = "491711234567";         // Phone number to send messages to and
                                               // which is allowed to operate the system


void setup() {
 
  Serial.begin(4800);                    // set the serial for debugging

  gsm.begin(4800);                       // set the GSM serial
 
  Serial.println("Initializing system...");
   
  // Set up the LED pin to be an output:
  pinMode(PowerLED, OUTPUT);
  pinMode(InfoLED, OUTPUT);
  pinMode(resetGSM, OUTPUT);
  pinMode(relay01, OUTPUT);
  pinMode(relay02, OUTPUT);
 

  digitalWrite(PowerLED, HIGH);
  digitalWrite(relay01, HIGH);
  digitalWrite(relay02, HIGH);
 


  // Waking up the Siemens TC35 (same as pressing the reset button on the device)
  delay(3000);
  digitalWrite(resetGSM, HIGH);
  digitalWrite(resetGSM, LOW);
  delay(100);
  digitalWrite(resetGSM, HIGH);
  delay(3000);
 
  gsm.println("AT+CMGF=1");                                // putting GSM device into text mode
  delay(100);
  while( gsm.available() ) gsm.read();

  delay(3000);
  deleteAllSMS();
  int SMSCounter = 0;    // variable to store amount of SMS
  Serial.println("Ready.");
  Serial.println("");
  Serial.println("System started. Waiting for SMS...");
  digitalWrite(InfoLED, HIGH);

}

void loop() {
 
  digitalWrite(InfoLED, HIGH);
  char c;

  boolean newSMS = false;
  boolean authSucc = false;
  boolean cmdSucc = false;
  boolean ack = false;
  String auth = "";
  String command = "";
  String report = "";
  delay(1000);
 
 gsm.println("AT+CMGL=\"REC UNREAD\"");   
     
 
  int count = 5;                           // Number of 100ms intervals before
                                           // assuming there is no more data
  while(count-- != 0) {                    // Loop until count = 0


    delay(100);                            // Delay 100ms

    while ( gsm.available() ){             // If there is data read it
       c = char( gsm.read() );
       //Serial.print(c);                  // Uncomment for debugging
       
       
       auth = auth + String( c );                                        // putting gsm.read() into auth
       if ( auth.endsWith( "+CMGL:" ) ) newSMS = true;                   // trigger for new SMS
       if ( auth.endsWith( phoneNo ) ) authSucc = true;                  // checking auth against phoneNo
       if ( authSucc &&  auth.endsWith( "<" ) ) cmdSucc = true;          // begin parsing the command on a "<"
       if ( authSucc && cmdSucc ) command = command + String( c );       // putting gsm.read() into command
       if ( auth.endsWith( ">" ) ) cmdSucc = false;                      // end parsing the command on a ">"

// at this point we have checked that the sender
// has the defined phone number (however this is tricky since a hacker may 
// put the phone number in the SMS message text - so it is not 100% secure
// I had not time for final testing yet - use with caution)
// and we have the command that shall be executed in the variable 'command'
             
       count = 5;
    }
  }
 
  if ( newSMS ) {


    digitalWrite(InfoLED, LOW);
    SMSCounter++;
    report = "Command '" + command + "' received.";
    Serial.println("SMS received! SMS Count is: " + String( SMSCounter ));
    if ( authSucc ) Serial.println( "Auth success. Command is: " + command );
    else {
      Serial.println("No valid authentication. Reporting possible break-in attempt.");




      report = "Attention! Unknown sender tried to send a message to this device. Possible break-in attempt.";
      command = "<Alert>";     
    }
   


    // Code for command <Relay01>   
    if ( command.equals( "<Relay01>" ) ) {
      Serial.println("Engaging Relay01.");
      digitalWrite(relay01, LOW);
      delay(1000);
      digitalWrite(relay01, HIGH);
      report = report + " Relay01 engaged.";
      ack = true;
    }
   
    // Code for command <Relay02>
    if ( command.equals( "<Relay02>" ) ) {
      Serial.println("Engaging Relay02.");
      digitalWrite(relay02, LOW);
      delay(1000);
      digitalWrite(relay02, HIGH);
      report = report + " Relay02 engaged.";
      ack = true;
    }
   
    // Code for command <Status>
    if ( command.equals( "<Status>" ) ) {
      Serial.println("Reporting status to " + phoneNo );
      report = report + " Status is up and running."; // you may want to add some other stuff here like temperature or else
      ack = true;
    }

 
    // Code for command <Info>
    if ( command.equals( "<Info>" ) ) {
      Serial.println("Sending command info to " + phoneNo );
      report = report + " You can use: <Relay01>, <Relay02>, <Status> and <Info> as command.";
      ack = true;
    }

   
    // Code for command <Alert>
    if ( command.equals( "<Alert>" ) ) {
      Serial.println("Sending possible break-in alert to " + phoneNo );
      ack = true;
    }
   
    if ( !ack ) {
       Serial.println("Command not recognized. Aborting.");
       report = report + " Command not recognized. Aborting. Send <Info> for a list of commands.";
     }
    sendSMS( report , phoneNo ); // be careful if there is a prepaid SIM card in the device since it will produce costs
    delay(1000);
    SMSCounter++;
    if ( SMSCounter > 12 ) { deleteAllSMS(); SMSCounter = 0; }          // Adapt to the storage capacity of the SIM card. Notice that messages will be sent, too.
    delay(1000);
    }
}


void sendSMS(String message , String receiverNo ) {
 
  gsm.print("AT+CMGF=1\r");
  delay(100);
  gsm.println("AT+CMGS=\"+" + receiverNo + "\"");
  delay(100);
  gsm.print( message );
  delay(100);
  gsm.println((char)26);
 
}


void callNumber() {
  gsm.println("AT");                      // Wake-up GSM module
  gsm.println("ATD<+"+ phoneNo + ">;");   // Call phoneNo (for i.e. emergencies)
  delay(10000);                           // Wait some seconds to establish the call
  gsm.println("AT+CHUP");                 // Hang up (to be more precise: AT+CHUP closes all connections)
 
}


void deleteAllSMS()
{

  digitalWrite(InfoLED, LOW);
  Serial.println("Clearing SMS storage...");
  char c;
  delay(300);
 


  for ( int i=1 ; i<=20 ; i++ )
  {
 
  gsm.println("AT+CMGD=" + String( i )); // delete all SMS

  int count = 5;                       // Number of 100ms intervals before
                                       // assuming there is no more data
  while(count-- != 0) {                // Loop until count = 0


    delay(100);                        // Delay 150ms

    while (gsm.available() > 0){  // If there is data, read it and reset
       c = (char)gsm.read();      // the counter, otherwise go try again

       //Serial.print(c);
       count = 5;
    }
  } 
  }
  Serial.println("SMS storage cleared.");
  digitalWrite(InfoLED, HIGH);
}

michael_x

Quote
Für meinen Einsatzzweck ist das etwas womit ich leben kann. Falls jemand jedoch seine Haustür damit absichern möchte, dann sollte er sich darüber im Klaren sein
Was nutzt es einem "Angreifer" per SMS deine Haustür zu öffnen, wenn er nicht davor steht?
Und wenn er davor steht, sind die üblichen mechanischen Einbruchshilfen wohl ebenso effektiv ...

Aber du hast natürlich recht, mit IT-Sicherheit hat eine konstante Absenderkennung nichts zu tun.
Die Nummer unter der dein GSM Shield zu erreichen ist, solltest du einfach geheim halten ;)

ElEspanol

oder einen code mitsenden.

Go Up