• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 1 głosów - średnia: 1
  • 1
  • 2
  • 3
  • 4
  • 5
próba budowy systemu alarmowego
#21
(22-02-2020, 12:34)Lucek20 napisał(a): Mam problem. Dodałem do alarmu powiadomienie sms. Moduł działa, z tym, że nie mogę sobie poradzić z ilością wysyłanych sms. Mimo pętli for sms są wysyłane w dużych ilościach. Wrzucam część kodu.
W kodzie używasz delay, błąd nr 1. Radośnie zakładasz, ze komenda się wykona, błąd nr dwa. Trzeci, to wysyłając SMS czekasz dziesiątki ms, a odpowiedź może przyjść nawet po 60 sekundach. Błąd czwarty, nie sprawdzasz rezultatu komend.

(22-02-2020, 12:34)Lucek20 napisał(a): Jak będzie potrzebna całość to dodam.
Jeśli w tak krótkim kodzie masz tyle błędów to w całym pewnie się od nich roi.

(22-02-2020, 12:34)Lucek20 napisał(a): Proszę o pomoc.
Pomóc musisz sobie sam ucząc się podstaw programowania. Trzy tygodnie z Arduino (zwłaszcza z Arduino) nie zrobią z Ciebie dobrego programisty. Zacząłes od niełatwego projektu bo obsługa SIM800 banalna nie jest.
Zacznij od kursu Arduino, nauki C/C++. Poczytaj o algorytmach. Zapoznaj się z nota katalogową SIM800. Dopiero wtedy możesz napisać dobry kod obsługi SIM800. Wzorowanie się na przykładach z Internetu to poważny błąd. W 99% kod jest zły i działa tylko gdy wszystko jet dobrze. Jakikolwiek problem i program się "sypie".
Kod z delay to nie kod, to DEMO!
Możliwości sprzętowe uC trzeba wykorzystywać a nie /machać/. GPIO!
Jestem a usilnie chcę być amatorem to dwie różne rzeczy.

http://er-mik.prv.pl/projekty edw.php 
http://er-mik.prv.pl/projekty_avt.php
 
Odpowiedź
#22
Dlaczego jeżeli w void setup()  dodam "lcd.begin();" nie jestem w stanie dogadać się przez port szeregowy z modułem? Po wpisaniu komend AT moduł nie odpowiada. Jeżeli wywalę "lcd.begin();"  i wyślę jakąś komendę przez port to otrzymuję odpowiedź, ale za to lcd martwy. Przekopałem neta i nigdzie nic nie znalazłem.


Kod:
#include <SoftwareSerial.h>
#include <Timers.h>
#include <Keypad.h>
#include <Password.h>
#include <Wire.h>  
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);


SoftwareSerial gsmSerial(11, 12);

String newPasswordString;
char newPassword[5];

Password password = Password( (char*)"1234" );

byte currentPasswordLength = 0;

const byte ROWS = 4;
const byte COLS = 4;

//Define the keymap
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};

byte rowPins[ROWS] = {10,9,8,7};

byte colPins[COLS] = {6,5,4,3};

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

byte diodaZielona = 2;
byte diodaZulta = A2;
byte diodaCzerwona = A1;
//////czujnikRuchu = A7; odłączony brak miesca
byte buzzer = A3;
byte laser = A0;

volatile byte stanAlarmu = 0;

int x = 0; // zmienna do kursora LCD
int y = 0; // zmienna licząca ilość znaków w "aktywacja alarmu."

Timer czasNaPin;   // wpisanie pinu
Timer usuwaniePin; // usuwanie pin z lcd
Timer gaszenieLcd; // gaszenie lcd

int czasNaPinOdliczanie = 10000;   // czas na wpisanie pinu w milisekundach
int usuwaniePinOdliczanie = 7000;  // czas na usuwanięcie pinu z lcd w milisekundach
int gaszenieLcdOdliczanie = 15000; // czas na zgaszenie lcd w milisekundach

byte maxPasswordLength = 5;  //maksymalna długość hasła
byte minPasswordLength = 2; // minimalna długość hasła

byte zmianaHaslaPozycja = 1;
char zmianaHaslaCyfra1 = '0'; //
char zmianaHaslaCyfra2 = '0'; //
char zmianaHaslaCyfra3 = '0'; //
char zmianaHaslaCyfra4 = '0'; //
char zmianaHaslaCyfra5 = 'D'; //

byte aktywacjaAlarmuPozycja = 1;
char aktywacjaCyfra1 = 'A'; //
char aktywacjaCyfra2 = 'A'; //
char aktywacjaCyfra3 = 'A'; //  

void setup(){
  gaszenieLcd.begin(gaszenieLcdOdliczanie);
  lcd.begin();
  Serial.begin(9600);
  gsmSerial.begin(9600);

  Serial.println("TEST");
  gsmSerial.println("AT");
  odpowiedzlSerial();

  pinMode(diodaZielona, OUTPUT);
  pinMode(diodaZulta, OUTPUT);
  pinMode(diodaCzerwona, OUTPUT);
  pinMode(buzzer, OUTPUT);
  //pinMode(czujnikRuchu, INPUT_PULLUP);
  pinMode(laser, INPUT);
}

void loop() {
 
  odpowiedzlSerial();
 
  char key = keypad.getKey();
   if (key != NO_KEY){
      delay(60);
      switch (key){
      case '#': checkPassword(); break;
      case '*': resetPassword(); lcd.clear();  break;
      default:  processNumberKey(key);
      }
   }
  
   switch (stanAlarmu) {

    case 0: //czuwanie wyłączone
      Serial.print(key);
      if (key) { 
      if (aktywacjaAlarmuPozycja == 1 && key == aktywacjaCyfra1) {
          aktywacjaAlarmuPozycja++;
      }else if (aktywacjaAlarmuPozycja == 2 && key == aktywacjaCyfra2){
         aktywacjaAlarmuPozycja++;
      }else if (aktywacjaAlarmuPozycja == 3 && key == aktywacjaCyfra3){
      aktywacjaAlarmuPozycja = 1;
      stanAlarmu = 1;
      resetPassword();
      lcd.clear();
      }else {
         stanAlarmu = 0;
         aktywacjaAlarmuPozycja = 1;
        }
       y++;
     if (y > maxPasswordLength) {      
        y = 0; 
        lcd.clear();
        resetPassword(); 
      }
     }

    if (key) {
      if (zmianaHaslaPozycja == 1 && key == zmianaHaslaCyfra1) {
          zmianaHaslaPozycja++;
        } else if (zmianaHaslaPozycja == 2 && key == zmianaHaslaCyfra2) {
          zmianaHaslaPozycja++;
        } else if (zmianaHaslaPozycja == 3 && key == zmianaHaslaCyfra3) {
          zmianaHaslaPozycja++;
        } else if (zmianaHaslaPozycja == 4 && key == zmianaHaslaCyfra4) {
          zmianaHaslaPozycja++;
        } else if (zmianaHaslaPozycja == 5 && key == zmianaHaslaCyfra5) {
          zmianaHaslaPozycja++;
      changePassword();
      zmianaHaslaPozycja = 1;
      resetPassword();
      }    
  }
     lcd.home();
     lcd.print("ALARM WYLACZONY ");
     digitalWrite(diodaZielona, HIGH);
     digitalWrite(diodaZulta, LOW);
     digitalWrite(diodaCzerwona, LOW);
     digitalWrite(buzzer, LOW);
    break;

    case 1: //czuwanie włączone
     lcd.home();
     lcd.print("ALARM  WLACZONY");
     digitalWrite(diodaZielona, LOW);
     digitalWrite(diodaZulta, HIGH);
     digitalWrite(diodaCzerwona, LOW);
     digitalWrite(buzzer, LOW);
     //if (digitalRead(czujnikRuchu) == HIGH) {
      //  stanAlarmu = 2;
     //   lcd.clear();
      //  czasNaPin.begin(czasNaPinOdliczanie);
    // }
     if (digitalRead(laser) == LOW) {
        stanAlarmu = 2;
        lcd.clear();
        czasNaPin.begin(czasNaPinOdliczanie);
     }
    break;

    case 2: // czas na rozbrojenie alarmu po wykryciu  ruchu przez PIR
     gaszenieLcd.restart();
     lcd.backlight();
     lcd.display();
     lcd.home();
     lcd.print("WYKRYTO RUCH");
     digitalWrite(diodaZielona, LOW);
     digitalWrite(diodaZulta, LOW);
     digitalWrite(diodaCzerwona, HIGH);
     tone(buzzer, 2000);
     delay(50);
     tone(buzzer, 2000);
     delay(50);
     noTone(buzzer);
     if (czasNaPin.available()){
        stanAlarmu = 3; 
        lcd.setCursor(0, 0);          
        lcd.print("             ");
       // resetPassword();
        czasNaPin.restart();
     }
    break;
  
    case 3: // ALARM
    gaszenieLcd.restart();
    lcd.backlight();
    lcd.display();
    lcd.setCursor(4, 0);
    lcd.print("ALARM !");
    digitalWrite(diodaZielona, LOW);
    digitalWrite(diodaZulta, LOW);
    digitalWrite(diodaCzerwona, HIGH);
    tone(buzzer, 4000);
    delay(50);
    tone(buzzer, 3000);
    delay(50);
    tone(buzzer, 2000);
    delay(50);
    tone(buzzer, 1000);
    delay(50);
    noTone(buzzer); 
    break;   
}

  if (key) {
     x++;
     x++;
     usuwaniePin.begin(usuwaniePinOdliczanie);
     gaszenieLcd.begin(gaszenieLcdOdliczanie);
     lcd.backlight();
     lcd.display();
     }

  if (usuwaniePin.available()){
        resetPassword();
        lcd.print("          ");
     }
 
  if (gaszenieLcd.available()){
        lcd.noBacklight();
        lcd.noDisplay();
     }
}

void processNumberKey(char key) {
   lcd.setCursor(x, 1);
   lcd.print(key);
   currentPasswordLength++;
   password.append(key);
   if (currentPasswordLength == maxPasswordLength) {
      checkPassword();
   }
}

void checkPassword() {
   if (password.evaluate()){
      lcd.clear();
      stanAlarmu = 0;
   } else {
      lcd.clear();
      lcd.print("BLEDNY PIN");
      delay(1000);
      lcd.clear();
   }
   resetPassword();
}

void resetPassword() {
   lcd.setCursor(x, 1);
   lcd.print("          ");
   password.reset();
   currentPasswordLength = 0;
   aktywacjaAlarmuPozycja = 1;
    x = 0;
    y = 0;
}

void changePassword() {
   x = 0;
   lcd.clear();
   lcd.print("ZMIANA PINU");
   newPasswordString = Password();
   newPasswordString.toCharArray(newPassword, newPasswordString.length()+1);//convert string to char array
   password.set(newPassword);
   resetPassword();
   Serial.println(newPasswordString.length());
    if (newPasswordString.length() < minPasswordLength){
     newPasswordString.remove(0,20);
     Serial.println(newPasswordString.length());
     lcd.clear();
     lcd.setCursor(0, 0);
     lcd.print("ZA KROTKI PIN");
     lcd.setCursor(0, 1);
     lcd.print("MIN. DL. PINU");
     lcd.setCursor(15, 1);
     lcd.print(minPasswordLength);    
     x = 0;
     delay(3000);
     changePassword();
    }
   if (newPasswordString.length() > maxPasswordLength){
     newPasswordString.remove(0,20);
     Serial.println(newPasswordString.length());
     lcd.clear();
     lcd.setCursor(0, 0);
     lcd.print("ZA DLUGI PIN");
     lcd.setCursor(0, 1);
     lcd.print("MAKS DL. PINU");
     lcd.setCursor(15, 1);
     lcd.print(maxPasswordLength);    
     x = 0;
     delay(2000);
     changePassword();
   }else{
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("PIN ZMIENIONY NA:");
      lcd.setCursor(0, 1);
      lcd.print(newPasswordString);
      delay(3000);
      lcd.clear();
      x = 0;
     }
}

String Password(){
  lcd.setCursor(x, 1);
    String password = "";
    while (1){
        char key = keypad.getKey();
          if (key){     
                if ((key=='1') || (key=='2') ||
                    (key=='3') || (key=='4') || (key=='5') ||
                    (key=='6') || (key=='7') || (key=='8') ||
                    (key=='9'))   // jesli wcisnąłem klawisze 0 - 9                 
                    {  
                         lcd.print(key);
                         lcd.print(" ");     
                         password = password + key; // taka konkatenacja, to tylko w Adruino zadziała        
                    }
                    if (key=='#') break;// zatwierdzamy wybór                                            
        }
    }
    return password;
}

void odpowiedzlSerial(){
delay(500);
  while (Serial.available())
  {
    gsmSerial.write(Serial.read());
  }
  while(gsmSerial.available())
  {
    Serial.write(gsmSerial.read());
  }
}
 
Odpowiedź
#23
Raczej konflikt przerwań... Spróbuj użyć sprzętowego UART....
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#24
Zmieniłem piny na 3 , 2 i działa.
 
Odpowiedź
#25
Dlaczego  po wpisaniu AT+CUSD=1, "*101#"  w porcie szeregowym, w momencie zwrócenia stanu konta na Lcd i port szeregowy gaśnie lcd? Jeżeli wywalę tą część kodu :
Kod:
if (usuwaniePin.available()){
        resetPassword();
        lcd.print("          ");
     }
  if (gaszenieLcd.available()){
        lcd.noBacklight();
        lcd.noDisplay();
     }

wtedy jest dobrze.  Oczywiście lcd gaśnie przed upływem ustawionego czasu.

Za wyświetlenie na lcd stanu konta odpowiada ta część kodu:
Kod:
void sprawdzanieStanuKonta()
{
   
    if(SIM800.available()>0){
    stanKontaString = SIM800.readString();
    stanKontaString.toCharArray(stanKonta, stanKontaString.length() );
    Serial.print(stanKontaString.length());
    Serial.print(stanKonta);
    if(stanKontaString.length()>62){
    lcd.clear(); 
    lcd.setCursor(0,0);
    lcd.print("Zostalo");
    lcd.print(stanKonta[25]);
    lcd.print(stanKonta[26]);
    lcd.print(stanKonta[27]);
    lcd.print(stanKonta[28]);
    lcd.print(stanKonta[29]);
    lcd.print(stanKonta[30]);
    lcd.print(stanKonta[31]);
    lcd.setCursor(0, 1);
    lcd.print(stanKonta[50]);
    lcd.print(stanKonta[51]);
    lcd.print(stanKonta[52]);
    lcd.print(stanKonta[53]);
    lcd.print(stanKonta[54]);
    lcd.print(stanKonta[55]);
    lcd.print(stanKonta[56]);
    lcd.print(stanKonta[57]);
    lcd.print(stanKonta[58]);
    lcd.print(stanKonta[59]);
    lcd.print(stanKonta[60]);
    lcd.print(stanKonta[61]);
    lcd.print(stanKonta[62]);
    }
  }
}



A tu cały kod. Przed fragmentami kodu których musiałem się chwilowo pozbyć, ze względu na braku wolnych pinów umiesciłem "//"
Kod:
#include <SoftwareSerial.h>
#include <Timers.h>
#include <Keypad.h>
#include <Password.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);


SoftwareSerial SIM800(3, 2);

String textMessage; //Zmienna do przechowywania wiadomości tekstowej
String alarm = "";
String stanKontaString;
char  stanKonta[20];

String newPasswordString;
char newPassword[5];

Password password = Password( (char*)"1234" );

byte currentPasswordLength = 0;

const byte ROWS = 4;
const byte COLS = 4;

//Define the keymap
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};

byte rowPins[ROWS] = {12,11,10,9};

byte colPins[COLS] = {8,7,6,5};

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

byte diodaZielona = 4;
byte diodaZulta = A2;
byte diodaCzerwona = A1;
//////czujnikRuchu = A7; odłączony brak miesca
byte buzzer = A3;
byte laser = A0;

volatile byte stanAlarmu = 0;

int x = 0; // zmienna do kursora LCD
int y = 0; // zmienna licząca ilość znaków w "aktywacja alarmu."
int sms1 = 0; // zmienna do pierwszego sms Alarm
int sms2 = 0; // zmienna do drugiego sms Alarm

Timer czasNaPin;   // wpisanie pinu
Timer usuwaniePin; // usuwanie pin z lcd
Timer gaszenieLcd; // gaszenie lcd
Timer smsNr1;      // pierwszy sms Alarm
Timer smsNr2;      // drugi sms Alarm


int czasNaPinOdliczanie = 10000;   // czas na wpisanie pinu w milisekundach
int usuwaniePinOdliczanie = 7000;  // czas na usuwanięcie pinu z lcd w milisekundach
int gaszenieLcdOdliczanie = 60000; // czas na zgaszenie lcd w milisekundach
int smsNr1Odliczanie = 10000;      // odliczanie do wysłania pierwszego sms po wejsciu do stanu alarm
int smsNr2Odliczanie = 30000;      // odliczanie do wysłania drugiego sms po wejsciu do stanu alarm

byte maxPasswordLength = 5;  //maksymalna długość hasła
byte minPasswordLength = 2; // minimalna długość hasła

byte zmianaHaslaPozycja = 1;
char zmianaHaslaCyfra1 = '0'; //
char zmianaHaslaCyfra2 = '0'; //
char zmianaHaslaCyfra3 = '0'; //
char zmianaHaslaCyfra4 = '0'; //
char zmianaHaslaCyfra5 = 'D'; //

byte aktywacjaAlarmuPozycja = 1;
char aktywacjaCyfra1 = 'A'; //
char aktywacjaCyfra2 = 'A'; //
char aktywacjaCyfra3 = 'A'; // 


void setup()
{
  gaszenieLcd.begin(gaszenieLcdOdliczanie);
  lcd.begin();
  Serial.begin(19200);
  SIM800.begin(19200);

  delay(20000); // czas na zalogowanie się  GSM do sieci
  Serial.print("SIM800 ready...");

 
  SIM800.print("AT+CMGF=1\r"); // ustawienie gsm na text mode
  delay(100);
 
  SIM800.print("AT+CNMI=2,2,0,0,0\r");
  delay(100);

  pinMode(diodaZielona, OUTPUT);
  pinMode(diodaZulta, OUTPUT);
  pinMode(diodaCzerwona, OUTPUT);
  pinMode(buzzer, OUTPUT);
  //pinMode(czujnikRuchu, INPUT_PULLUP);
  pinMode(laser, INPUT);
}

void loop()
{
  sprawdzanieStanuKonta();

  if(SIM800.available()>0){
    textMessage = SIM800.readString();
    Serial.print(textMessage);   
    delay(10);
  }
  if(textMessage.indexOf("Wlacz")>=0){
    Serial.println("Alarm włączony "); 
    textMessage = "";
    stanAlarmu = 1; 
   
  }
  if(textMessage.indexOf("Wylacz")>=0){
    Serial.println("Alarm wylączony");
    textMessage = "";
    stanAlarmu = 0; 
  }
  if(textMessage.indexOf("Stan")>=0){
    String message = "Alarm jest " + alarm;
    wysliSMS(message);
    Serial.println("żądanie stanu alarmu");
    textMessage = "";
  }


 
char key = keypad.getKey();
   if (key != NO_KEY){
      delay(60);
      switch (key){
      case '#': checkPassword(); break;
      case '*': resetPassword(); lcd.clear();  break;
      default:  processNumberKey(key);
      }
   }
 
   switch (stanAlarmu) {

    case 0: //czuwanie wyłączone
      Serial.print(key);
      if (key) {
      if (aktywacjaAlarmuPozycja == 1 && key == aktywacjaCyfra1) {
          aktywacjaAlarmuPozycja++;
      }else if (aktywacjaAlarmuPozycja == 2 && key == aktywacjaCyfra2){
         aktywacjaAlarmuPozycja++;
      }else if (aktywacjaAlarmuPozycja == 3 && key == aktywacjaCyfra3){
      aktywacjaAlarmuPozycja = 1;
      stanAlarmu = 1;
      resetPassword();
      lcd.clear();
      }else {
         stanAlarmu = 0;
         aktywacjaAlarmuPozycja = 1;
        }
       y++;
     if (y > maxPasswordLength) {     
        y = 0;
        lcd.clear();
        resetPassword();
      }
     }

    if (key) {
      if (zmianaHaslaPozycja == 1 && key == zmianaHaslaCyfra1) {
          zmianaHaslaPozycja++;
        } else if (zmianaHaslaPozycja == 2 && key == zmianaHaslaCyfra2) {
          zmianaHaslaPozycja++;
        } else if (zmianaHaslaPozycja == 3 && key == zmianaHaslaCyfra3) {
          zmianaHaslaPozycja++;
        } else if (zmianaHaslaPozycja == 4 && key == zmianaHaslaCyfra4) {
          zmianaHaslaPozycja++;
        } else if (zmianaHaslaPozycja == 5 && key == zmianaHaslaCyfra5) {
          zmianaHaslaPozycja++;
      changePassword();
      zmianaHaslaPozycja = 1;
      resetPassword();
      }   
  } 
     alarm = "Wylaczony";
    // lcd.home();
    // lcd.print("ALARM WYLACZONY ");
     digitalWrite(diodaZielona, HIGH);
     digitalWrite(diodaZulta, LOW);
     digitalWrite(diodaCzerwona, LOW);
     digitalWrite(buzzer, LOW);
     smsNr1.restart();
     smsNr2.restart();
     sms1 = 0;
     sms2 = 0;
     czasNaPin.restart();
    
    break;

    case 1: //czuwanie włączone
     alarm = "Wlaczony";
     lcd.home();
     lcd.print("ALARM  WLACZONY");
     digitalWrite(diodaZielona, LOW);
     digitalWrite(diodaZulta, HIGH);
     digitalWrite(diodaCzerwona, LOW);
     digitalWrite(buzzer, LOW);
     //if (digitalRead(czujnikRuchu) == HIGH) {
      //  stanAlarmu = 2;
     //   lcd.clear();
      //  czasNaPin.begin(czasNaPinOdliczanie);
    // }
     if (digitalRead(laser) == LOW) {
        stanAlarmu = 2;
        lcd.clear();
        czasNaPin.begin(czasNaPinOdliczanie);
     }
    break;

    case 2: // czas na rozbrojenie alarmu po wykryciu  ruchu przez PIR
     gaszenieLcd.restart();
     lcd.backlight();
     lcd.display();
     lcd.home();
     lcd.print("WYKRYTO RUCH");
     digitalWrite(diodaZielona, LOW);
     digitalWrite(diodaZulta, LOW);
     digitalWrite(diodaCzerwona, HIGH);
     tone(buzzer, 2000);
     delay(50);
     tone(buzzer, 2000);
     delay(50);
     noTone(buzzer);
     if (czasNaPin.available()){
        stanAlarmu = 3;
        lcd.setCursor(0, 0);         
        lcd.print("             ");
       // resetPassword();
        czasNaPin.restart();
        smsNr1.begin(10000);
     }
    break;
 
    case 3: // ALARM
    gaszenieLcd.restart();
    lcd.backlight();
    lcd.display();
    lcd.setCursor(4, 0);
    lcd.print("ALARM !");
    digitalWrite(diodaZielona, LOW);
    digitalWrite(diodaZulta, LOW);
    digitalWrite(diodaCzerwona, HIGH);
    tone(buzzer, 4000);
    //delay(50);
   // tone(buzzer, 3000);
   // delay(50);
   // tone(buzzer, 2000);
   // delay(50);
   // tone(buzzer, 1000);
   // delay(50);
   // noTone(buzzer);
    if (smsNr1.available()){
        sms1++;    
        if(sms1 < 2){
           smsAlarm();
           Serial.print(sms1);
          }
    }
    if (smsNr2.available()){
        sms2++;
        if(sms2 < 2){
           smsAlarm();
           Serial.print(sms2);
           }
      }
       
    break;  
}
  if (key) {
     x++;
     x++;
     usuwaniePin.begin(usuwaniePinOdliczanie);
     gaszenieLcd.begin(gaszenieLcdOdliczanie);
     lcd.backlight();
     lcd.display();
     }
  if (usuwaniePin.available()){
        resetPassword();
        lcd.print("          ");
     }
  if (gaszenieLcd.available()){
        lcd.noBacklight();
        lcd.noDisplay();
     }
}

void processNumberKey(char key) {
   lcd.setCursor(x, 1);
   lcd.print(key);
   currentPasswordLength++;
   password.append(key);
   if (currentPasswordLength == maxPasswordLength) {
      checkPassword();
   }
}

void checkPassword() {
   if (password.evaluate()){
      lcd.clear();
      stanAlarmu = 0;
   } else {
      lcd.clear();
      lcd.print("BLEDNY PIN");
      delay(1000);
      lcd.clear();
   }
   resetPassword();
}

void resetPassword() {
   lcd.setCursor(x, 1);
   lcd.print("          ");
   password.reset();
   currentPasswordLength = 0;
   aktywacjaAlarmuPozycja = 1;
    x = 0;
    y = 0;
}

void changePassword() {
   x = 0;
   lcd.clear();
   lcd.print("ZMIANA PINU");
   newPasswordString = Password();
   newPasswordString.toCharArray(newPassword, newPasswordString.length()+1);//convert string to char array
   password.set(newPassword);
   resetPassword();
   Serial.println(newPasswordString.length());
    if (newPasswordString.length() < minPasswordLength){
     newPasswordString.remove(0,20);
     Serial.println(newPasswordString.length());
     lcd.clear();
     lcd.setCursor(0, 0);
     lcd.print("ZA KROTKI PIN");
     lcd.setCursor(0, 1);
     lcd.print("MIN. DL. PINU");
     lcd.setCursor(15, 1);
     lcd.print(minPasswordLength);   
     x = 0;
     delay(3000);
     changePassword();
    }
   if (newPasswordString.length() > maxPasswordLength){
     newPasswordString.remove(0,20);
     Serial.println(newPasswordString.length());
     lcd.clear();
     lcd.setCursor(0, 0);
     lcd.print("ZA DLUGI PIN");
     lcd.setCursor(0, 1);
     lcd.print("MAKS DL. PINU");
     lcd.setCursor(15, 1);
     lcd.print(maxPasswordLength);   
     x = 0;
     delay(2000);
     changePassword();
   }else{
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("PIN ZMIENIONY NA:");
      lcd.setCursor(0, 1);
      lcd.print(newPasswordString);
      delay(3000);
      lcd.clear();
      x = 0;
     }
}

String Password(){
  lcd.setCursor(x, 1);
    String password = "";
    while (1){
        char key = keypad.getKey();
          if (key){    
                if ((key=='1') || (key=='2') ||
                    (key=='3') || (key=='4') || (key=='5') ||
                    (key=='6') || (key=='7') || (key=='8') ||
                    (key=='9'))   // jesli wcisnąłem klawisze 0 - 9                
                    { 
                         lcd.print(key);
                         lcd.print(" ");    
                         password = password + key;    
                    }
                    if (key=='#') break; // zatwierdzamy wybór                                           
        }
    }
    return password;
}

void wysliSMS(String message){

  SIM800.print("AT+CMGF=1\r"); //ustawinie moduł w tryb text
  delay(100);

  SIM800.println("AT+CMGS=\"+48699542253\""); //numer odbiorcy powiadomień
  delay(100);
 
  SIM800.println(message); //Wyślij SMS
  delay(100);

  SIM800.println((char)26);
  delay(100);
  SIM800.println();
}

void smsAlarm(){
  SIM800.print("AT+CMGF=1\r"); //ustawinie moduł w tryb text
  delay(100);

  SIM800.println("AT+CMGS=\"+48699542253\""); //numer odbiorcy powiadomień
  delay(100);
 
  SIM800.println("alarm"); //Wyślij SMS
  delay(100);
  SIM800.println((char)26);
  Serial.print("alarm");
  smsNr2.begin(30000);
}

void sprawdzanieStanuKonta()
{
  }
    if(SIM800.available()>0){
    stanKontaString = SIM800.readString();
    stanKontaString.toCharArray(stanKonta, stanKontaString.length() );
    Serial.print(stanKontaString.length());
    Serial.print(stanKonta);
    if(stanKontaString.length()>62){
    lcd.clear(); 
    lcd.setCursor(0,0);
    lcd.print("Zostalo");
    lcd.print(stanKonta[25]);
    lcd.print(stanKonta[26]);
    lcd.print(stanKonta[27]);
    lcd.print(stanKonta[28]);
    lcd.print(stanKonta[29]);
    lcd.print(stanKonta[30]);
    lcd.print(stanKonta[31]);
    lcd.setCursor(0, 1);
    lcd.print(stanKonta[50]);
    lcd.print(stanKonta[51]);
    lcd.print(stanKonta[52]);
    lcd.print(stanKonta[53]);
    lcd.print(stanKonta[54]);
    lcd.print(stanKonta[55]);
    lcd.print(stanKonta[56]);
    lcd.print(stanKonta[57]);
    lcd.print(stanKonta[58]);
    lcd.print(stanKonta[59]);
    lcd.print(stanKonta[60]);
    lcd.print(stanKonta[61]);
    lcd.print(stanKonta[62]);
    }
  }
}


Przed chwilą zauważyłem, że gdy fragment kodu odpowiedzialny za wygaszanie i usuwanie pinu lcd jest aktywny to stanKontaString.lenght () ma 63 znaki, a gdy jest wyłączona ta część kodu to ma 79 znaków.

[Obrazek: b759e63faf211c77b28f3d01aa56f748.png]

Bez waszej pomocy chyba nie dam rady tego ogarnąć.
 
Odpowiedź
#26
Big Grin 
Ogarnąłem problem wyżej. Wypociny zredukowałem i nawet jest dobrze. Lcd nie wyłącza się, ogólnie git. Nawet nie wiedziałem, że tyle będę miał problemów przy tym projekcie, ale jestem zadowolony, że od jakiegoś czasu rozwiązuje je sam. Big Grin

Nie był bym sobą gdybym nie miał kolejnego. Chodzi jak wcześniej o sprawdzenie stanu konta. Kod:
Kod:
#include <Wire.h>
#include <hd44780.h>                     
#include <hd44780ioClass/hd44780_I2Cexp.h>
#include <SoftwareSerial.h>
#include <Timers.h>
#include <Keypad.h>
#include <Password.h>

hd44780_I2Cexp lcd;

const int LCD_COLS = 16;
const int LCD_ROWS = 2;

SoftwareSerial SIM800(3, 2);

String textMessage; //Zmienna do przechowywania wiadomości tekstowej
String alarm = "";
String stanKontaCz1;
String stanKontaCz2;
//String stanKonta;


String newPasswordString;
char newPassword[5];

Password password = Password( (char*)"1234" );

byte currentPasswordLength = 0;

const byte ROWS = 4;
const byte COLS = 4;

//Define the keymap
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};

byte rowPins[ROWS] = {12,11,10,9};

byte colPins[COLS] = {8,7,6,5};

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

byte diodaZielona = 4;
byte diodaZulta = A2;
byte diodaCzerwona = A1;
//////czujnikRuchu = A7; odłączony brak miesca
byte buzzer = A3;
byte laser = A0;

volatile byte stanAlarmu = 0;

int x = 0; // zmienna do kursora LCD
int y = 0; // zmienna licząca ilość znaków w "aktywacja alarmu."
int sms1 = 0; // zmienna do pierwszego sms Alarm
int sms2 = 0; // zmienna do drugiego sms Alarm
int stan = 0;


Timer czasNaPin;   // wpisanie pinu
Timer usuwaniePin; // usuwanie pin z lcd
Timer gaszenieLcd; // gaszenie lcd
Timer smsNr1;      // pierwszy sms Alarm
Timer smsNr2;      // drugi sms Alarm



int czasNaPinOdliczanie = 10000;   // czas na wpisanie pinu w milisekundach
int usuwaniePinOdliczanie = 7000;  // czas na usuwanięcie pinu z lcd w milisekundach
int gaszenieLcdOdliczanie = 60000; // czas na zgaszenie lcd w milisekundach
int smsNr1Odliczanie = 10000;      // odliczanie do wysłania pierwszego sms po wejsciu do stanu alarm
int smsNr2Odliczanie = 30000;      // odliczanie do wysłania drugiego sms po wejsciu do stanu alarm

byte maxPasswordLength = 5;  //maksymalna długość hasła
byte minPasswordLength = 2; // minimalna długość hasła

byte zmianaHaslaPozycja = 1;
char zmianaHaslaCyfra1 = '0'; //
char zmianaHaslaCyfra2 = '0'; //
char zmianaHaslaCyfra3 = '0'; //
char zmianaHaslaCyfra4 = '0'; //
char zmianaHaslaCyfra5 = 'D'; //

byte aktywacjaAlarmuPozycja = 1;
char aktywacjaCyfra1 = 'A'; //
char aktywacjaCyfra2 = 'A'; //
char aktywacjaCyfra3 = 'A'; //


void setup()
{
  int status;

  status = lcd.begin(LCD_COLS, LCD_ROWS);
  if(status)
  {
    status = -status;
    hd44780::fatalError(status);
  }
 
  gaszenieLcd.begin(gaszenieLcdOdliczanie);
 
  Serial.begin(9600);
  SIM800.begin(9600);

  Serial.print("SIM800 ready...");


  SIM800.print("AT+CMGF=1\r"); // ustawienie gsm na text mode
  delay(100);

  SIM800.print("AT+CNMI=2,2,0,0,0\r");
  delay(100);

  pinMode(diodaZielona, OUTPUT);
  pinMode(diodaZulta, OUTPUT);
  pinMode(diodaCzerwona, OUTPUT);
  pinMode(buzzer, OUTPUT);
 
  pinMode(laser, INPUT);
}

void loop()
{    if(stan<1){
      stan++;
      SIM800.print("AT+CUSD=1, \"*101#\"");
}
 
  if(Serial.available()>0){
      SIM800.write(Serial.read());
     }

  if(SIM800.available()>0){
    textMessage = SIM800.readString();
    Serial.print(textMessage);
    if(textMessage.indexOf("Pozostalo Ci")>=0){
      smsStanKonta();
      stanKontaCz1 = textMessage;
      stanKontaCz2 = textMessage;
      stanKontaCz1.remove(0, 15);
      stanKontaCz1.remove(7,3);
      stanKontaCz1.remove(15,50);
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print(stanKontaCz1);
      stanKontaCz2.remove(0, 50);
      stanKontaCz2.remove(14, 15);
      lcd.setCursor(0,1);
      lcd.print(stanKontaCz2);
      delay(3000);
      lcd.clear();
    }
  }
 
  if(textMessage.indexOf("Wlacz")>=0){
    Serial.println("Alarm włączony ");
    textMessage = "";
    stanAlarmu = 1;
  
  }
  if(textMessage.indexOf("Wylacz")>=0){
    Serial.println("Alarm wylączony");
    textMessage = "";
    stanAlarmu = 0;
  }
  if(textMessage.indexOf("Stan")>=0){
    String message = "Alarm jest " + alarm;
    wysliSMS(message);
    Serial.println("żądanie stanu alarmu");
    textMessage = "";
  }
    if(textMessage.indexOf("PLN")>=0){
    stan=0;
    //skonta();
}




char key = keypad.getKey();
   if (key != NO_KEY){
      delay(60);
      switch (key){
      case '#': checkPassword(); break;
      case '*': resetPassword(); lcd.clear();  break;
      default:  processNumberKey(key);
      }
   }

   switch (stanAlarmu) {


    case 0: //czuwanie wyłączone
      Serial.print(key);
      if (key) {
      if (aktywacjaAlarmuPozycja == 1 && key == aktywacjaCyfra1) {
          aktywacjaAlarmuPozycja++;
      }else if (aktywacjaAlarmuPozycja == 2 && key == aktywacjaCyfra2){
         aktywacjaAlarmuPozycja++;
      }else if (aktywacjaAlarmuPozycja == 3 && key == aktywacjaCyfra3){
      aktywacjaAlarmuPozycja = 1;
      stanAlarmu = 1;
      resetPassword();
      lcd.clear();
      }else {
         stanAlarmu = 0;
         aktywacjaAlarmuPozycja = 1;
        }
       y++;
     if (y > maxPasswordLength) {    
        y = 0;
        lcd.clear();
        resetPassword();
      }
     }

    if (key) {
      if (zmianaHaslaPozycja == 1 && key == zmianaHaslaCyfra1) {
          zmianaHaslaPozycja++;
        } else if (zmianaHaslaPozycja == 2 && key == zmianaHaslaCyfra2) {
          zmianaHaslaPozycja++;
        } else if (zmianaHaslaPozycja == 3 && key == zmianaHaslaCyfra3) {
          zmianaHaslaPozycja++;
        } else if (zmianaHaslaPozycja == 4 && key == zmianaHaslaCyfra4) {
          zmianaHaslaPozycja++;
        } else if (zmianaHaslaPozycja == 5 && key == zmianaHaslaCyfra5) {
          zmianaHaslaPozycja++;
      changePassword();
      zmianaHaslaPozycja = 1;
      resetPassword();
      }  
  }

     alarm = "Wylaczony";
     lcd.home();
     lcd.print("ALARM WYLACZONY ");
     digitalWrite(diodaZielona, HIGH);
     digitalWrite(diodaZulta, LOW);
     digitalWrite(diodaCzerwona, LOW);
     digitalWrite(buzzer, LOW);     
     smsNr1.restart();
     smsNr2.restart();
     sms1 = 0;
     sms2 = 0;
     czasNaPin.restart();
   
    break;

    case 1: //czuwanie włączone
     alarm = "Wlaczony";
     lcd.home();
     lcd.print("ALARM  WLACZONY");
     digitalWrite(diodaZielona, LOW);
     digitalWrite(diodaZulta, HIGH);
     digitalWrite(diodaCzerwona, LOW);
     digitalWrite(buzzer, LOW);
    
     if (digitalRead(laser) == LOW) {
        stanAlarmu = 2;
        lcd.clear();
        czasNaPin.begin(czasNaPinOdliczanie);
     }
    break;

    case 2: // czas na rozbrojenie alarmu po wykryciu  ruchu przez PIR
     gaszenieLcd.restart();
     lcd.backlight();
     lcd.display();
     lcd.home();
     lcd.print("WYKRYTO RUCH");
     digitalWrite(diodaZielona, LOW);
     digitalWrite(diodaZulta, LOW);
     digitalWrite(diodaCzerwona, HIGH);
    
     if (czasNaPin.available()){
        stanAlarmu = 3;
        lcd.setCursor(0, 0);        
        lcd.print("             ");
       // resetPassword();
        czasNaPin.restart();
        smsNr1.begin(10000);
     }
    break;

    case 3: // ALARM
    gaszenieLcd.restart();
    lcd.backlight();
    lcd.display();
    lcd.setCursor(4, 0);
    lcd.print("ALARM !");
    digitalWrite(diodaZielona, LOW);
    digitalWrite(diodaZulta, LOW);
    digitalWrite(diodaCzerwona, HIGH);
   
    if (smsNr1.available()){
        sms1++;   
        if(sms1 < 2){
           smsAlarm();
           Serial.print(sms1);
          }
    }
    if (smsNr2.available()){
        sms2++;
        if(sms2 < 2){
           smsAlarm();
           Serial.print(sms2);
           }
      }
      
    break; 
}
  if (key) {
     x++;
     x++;
     usuwaniePin.begin(usuwaniePinOdliczanie);
     gaszenieLcd.begin(gaszenieLcdOdliczanie);
     lcd.backlight();
     lcd.display();
     }
  if (usuwaniePin.available()){
        resetPassword();
        lcd.print("          ");
     }
  if (gaszenieLcd.available()){
        lcd.noBacklight();
        lcd.noDisplay();
     }
}

void processNumberKey(char key) {
   lcd.setCursor(x, 1);
   lcd.print(key);
   currentPasswordLength++;
   password.append(key);
   if (currentPasswordLength == maxPasswordLength) {
      checkPassword();
   }
}

void checkPassword() {
   if (password.evaluate()){
      lcd.clear();
      stanAlarmu = 0;
   } else {
      lcd.clear();
      lcd.print("BLEDNY PIN");
      delay(1000);
      lcd.clear();
   }
   resetPassword();
}

void resetPassword() {
   lcd.setCursor(x, 1);
   lcd.print("          ");
   password.reset();
   currentPasswordLength = 0;
   aktywacjaAlarmuPozycja = 1;
    x = 0;
    y = 0;
}

void changePassword() {
   x = 0;
   lcd.clear();
   lcd.print("ZMIANA PINU");
   newPasswordString = Password();
   newPasswordString.toCharArray(newPassword, newPasswordString.length()+1);//convert string to char array
   password.set(newPassword);
   resetPassword();
   Serial.println(newPasswordString.length());
    if (newPasswordString.length() < minPasswordLength){
     newPasswordString.remove(0,20);
     Serial.println(newPasswordString.length());
     lcd.clear();
     lcd.setCursor(0, 0);
     lcd.print("ZA KROTKI PIN");
     lcd.setCursor(0, 1);
     lcd.print("MIN. DL. PINU");
     lcd.setCursor(15, 1);
     lcd.print(minPasswordLength);  
     x = 0;
     delay(3000);
     changePassword();
    }
   if (newPasswordString.length() > maxPasswordLength){
     newPasswordString.remove(0,20);
     Serial.println(newPasswordString.length());
     lcd.clear();
     lcd.setCursor(0, 0);
     lcd.print("ZA DLUGI PIN");
     lcd.setCursor(0, 1);
     lcd.print("MAKS DL. PINU");
     lcd.setCursor(15, 1);
     lcd.print(maxPasswordLength);  
     x = 0;
     delay(2000);
     changePassword();
   }else{
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("PIN ZMIENIONY NA:");
      lcd.setCursor(0, 1);
      lcd.print(newPasswordString);
      delay(3000);
      lcd.clear();
      x = 0;
     }
}

String Password(){
  lcd.setCursor(x, 1);
    String password = "";
    while (1){
        char key = keypad.getKey();
          if (key){   
                if ((key=='1') || (key=='2') ||
                    (key=='3') || (key=='4') || (key=='5') ||
                    (key=='6') || (key=='7') || (key=='8') ||
                    (key=='9'))   // jesli wcisnąłem klawisze 0 - 9               
                    {
                         lcd.print(key);
                         lcd.print(" ");   
                         password = password + key;   
                    }
                    if (key=='#') break; // zatwierdzamy wybĂłr                                          
        }
    }
    return password;
}

void wysliSMS(String message){

  SIM800.print("AT+CMGF=1\r");
  delay(100);

  SIM800.println("AT+CMGS=\"+48xxxxxxxxx\"");
  delay(100);

  SIM800.println(message);
  delay(100);

  SIM800.println((char)26);
  delay(100);
  SIM800.println();
}

void smsAlarm(){
  SIM800.print("AT+CMGF=1\r");
  delay(100);

  SIM800.println("AT+CMGS=\"+48xxxxxxxxx\"");
  delay(100);

  SIM800.println("alarm");
  delay(100);
  SIM800.println((char)26);
  Serial.print("alarm");
  smsNr2.begin(30000);
}

void smsStanKonta(){

  SIM800.print("AT+CMGF=1\r");
  delay(100);

  SIM800.println("AT+CMGS=\"+48xxxxxxxxx\"");
  delay(100);

  SIM800.println(textMessage);
  delay(100);

  SIM800.println((char)26);
  delay(100);
  SIM800.println();
}

void skonta(){
  SIM800.print("AT+CUSD=1, \"*101#\"");
}

Jeżeli wgram kod to przy pierwszym uruchomieniu wszystko jest cacy.
SIM800.print("AT+CUSD=1, \"*101#\"" zwraca stan konta, otrzymuje informację na port, LCD i SMS ze stanem konta. Natomiast jeżeli stworzę  takie coś:
Kod:
if(textMessage.indexOf("PLN")>=0){
    stan=0;
    //skonta();
}
Aby wyzerować zmienną stan, żeby w pętli loop wykonała się ponownie ta część kodu:
Kod:
if(stan<1){
      stan++;
      SIM800.print("AT+CUSD=1, \"*101#\"");
}
W pewnym stopniu działa bo na porcie szeregowym widzę, że wychodzi polecenie SIM800.print("AT+CUSD=1, \"*101#\""); , ale nic się już nie dzieje. Brak informacji zwrotnej czy to na port, czy na lcd i SMS.
Ta sama sytuacja jest gdy wywalę z loop  ifa odpowiedzialnego za sprawdzenie stanu konta ( tego wyżej), a stworzę funkcje :
Kod:
void skonta(){
  SIM800.print("AT+CUSD=1, \"*101#\"");
}
Gdzie wywołanie tej funkcji umieszczę w :
Kod:
if(textMessage.indexOf("PLN")>=0){
    //stan=0;
    skonta();
}
Treść SMS jest odbierana prawidłowo. Polecenie SIM800.print("AT+CUSD=1, \"*101#\"");
wychodzi, ale brak odpowiedzi z modułu. W każdym przypadku gdy wyzeruje zmienną stan czy to SMS czy jakaś inną funkcją ( naciśnięcie klawisza) zmienną się zeruje, kod USSD wychodzi, ale brak odpowiedzi. Jeszcze raz zaznaczę, że przy pierwszym uruchomieniu wszystko działa.  O co biega? Czemu to tak?
 
Odpowiedź
#27
Walki ciąg dalszy. Mam już jeden sukces na koncie, mianowicie już nie obcina wiadomości zwrotnej na  porcie. Przerobiłem trochę kod, zmieniłem bibliotekę na altserialport. Niestety sprawdzanie stanu konta nadal nie działa (jedynie przez port).
Zauważyłem, że gdy wywołam funkcję która wyśle polecenie sprawdzenia stanu konta, pojawia się ono na porcie i nic się nie dzieje. Jeżeli zresetuje arduino to nagle pojawia się odpowiedź. 
[Obrazek: 3068747132a3b5f567f1587805bf21c2.png]

Czerwoną krechą zaznaczyłem moment zresetowania. wydaje mi się, że coś "zajmuje" altserialport i nie może odebrać danych, dopiero jak pójdzie reset to dane są odbierane i wyświetlane na porcie.

kod programu odpowiedzialnego za komunikację z modułem gsm:
Kod:
void loop()

  char c;

  while (Serial.available()) {
    c = Serial.read();
    altSerial.print(c);
  }
  while (altSerial.available()) {
    c = altSerial.read();
    textMessage = altSerial.readString();
    Serial.print(c);
    Serial.print(textMessage);
    if(textMessage.indexOf("Pozostalo Ci")>=0){
      //smsStanKonta();
      stanKontaLcd = textMessage;
      stanKontaLcd.remove(22,2);
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print(stanKontaLcd.substring(14, 29));
      lcd.setCursor(0,1);
      lcd.print(stanKontaLcd.substring(46, 60));
      delay(3000);
      lcd.clear();
    }
  } 

if(textMessage.indexOf("Wlacz")>=0){
    Serial.println("Alarm wlaczony ");
    textMessage = "";
    stanAlarmu = 1;
 
  }
  if(textMessage.indexOf("Wylacz")>=0){
    Serial.println("Alarm wylaczony");
    textMessage = "";
    stanAlarmu = 0;
  }
  if(textMessage.indexOf("Stan")>=0){
    String message = "Alarm jest " + alarm;
    wysliSMS(message);
    Serial.println("Żadanie stanu alarmu");
    textMessage = "";
  }
    if(textMessage.indexOf("PLN")>=0){
    skonta();
  }
}

void skonta(){
altSerial.print("AT+CUSD=1, \"*101#\"");
}



A tu cały kod:
Kod:
#include <AltSoftSerial.h>

#include <LiquidCrystal_I2C.h>

#include <Wire.h>
#include <Timers.h>
#include <Keypad.h>
#include <Password.h>

//hd44780_I2Cexp lcd;
LiquidCrystal_I2C lcd(0x27, 16, 2);

const int LCD_COLS = 16;
const int LCD_ROWS = 2;


AltSoftSerial altSerial;

String textMessage; //Zmienna do przechowywania wiadomości tekstowej
String alarm = "";
String stanKontaLcd;

String newPasswordString;
char newPassword[5];

Password password = Password( (char*)"1234" );

byte currentPasswordLength = 0;

const byte ROWS = 4;
const byte COLS = 4;

//Define the keymap
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};

byte rowPins[ROWS] = {12,11,10,13};

byte colPins[COLS] = {7,6,5,A6 };

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

byte diodaZielona = 4;
byte diodaZulta = A2;
byte diodaCzerwona = A1;
//////czujnikRuchu = A7; odłączony brak miesca
byte buzzer = A3;
byte laser = A0;

volatile byte stanAlarmu = 0;

int x = 0; // zmienna do kursora LCD
int y = 0; // zmienna licząca ilość znaków w "aktywacja alarmu."
int sms1 = 0; // zmienna do pierwszego sms Alarm
int sms2 = 0; // zmienna do drugiego sms Alarm
int stan = 0;


Timer czasNaPin;   // wpisanie pinu
Timer usuwaniePin; // usuwanie pin z lcd
Timer gaszenieLcd; // gaszenie lcd
Timer smsNr1;      // pierwszy sms Alarm
Timer smsNr2;      // drugi sms Alarm



int czasNaPinOdliczanie = 10000;   // czas na wpisanie pinu w milisekundach
int usuwaniePinOdliczanie = 7000;  // czas na usuwanięcie pinu z lcd w milisekundach
int gaszenieLcdOdliczanie = 60000; // czas na zgaszenie lcd w milisekundach
int smsNr1Odliczanie = 10000;      // odliczanie do wysłania pierwszego sms po wejsciu do stanu alarm
int smsNr2Odliczanie = 30000;      // odliczanie do wysłania drugiego sms po wejsciu do stanu alarm

byte maxPasswordLength = 5;  //maksymalna długość hasła
byte minPasswordLength = 2; // minimalna długość hasła

byte zmianaHaslaPozycja = 1;
char zmianaHaslaCyfra1 = '0'; //
char zmianaHaslaCyfra2 = '0'; //
char zmianaHaslaCyfra3 = '0'; //
char zmianaHaslaCyfra4 = '0'; //
char zmianaHaslaCyfra5 = 'D'; //

byte aktywacjaAlarmuPozycja = 1;
char aktywacjaCyfra1 = 'A'; //
char aktywacjaCyfra2 = 'A'; //
char aktywacjaCyfra3 = 'A'; //


void setup()
{
  gaszenieLcd.begin(gaszenieLcdOdliczanie);
  lcd.begin();

  Serial.begin(9600);
  Serial.println("AltSoftSerial Test Begin");
  altSerial.begin(9600);

  altSerial.print("AT+CMGF=1\r"); // ustawienie gsm na text mode
  delay(100);

  altSerial.print("AT+CNMI=2,2,0,0,0\r");
  delay(100);

  pinMode(diodaZielona, OUTPUT);
  pinMode(diodaZulta, OUTPUT);
  pinMode(diodaCzerwona, OUTPUT);
  pinMode(buzzer, OUTPUT);

  pinMode(laser, INPUT);
}

void loop()

  char c;

  while (Serial.available()) {
    c = Serial.read();
    altSerial.print(c);
  }
  while (altSerial.available()) {
    c = altSerial.read();
    textMessage = altSerial.readString();
    Serial.print(c);
    Serial.print(textMessage);
    if(textMessage.indexOf("Pozostalo Ci")>=0){
      //smsStanKonta();
      stanKontaLcd = textMessage;
      stanKontaLcd.remove(22,2);
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print(stanKontaLcd.substring(14, 29));
      lcd.setCursor(0,1);
      lcd.print(stanKontaLcd.substring(46, 60));
      delay(3000);
      lcd.clear();
    }
  } 

if(textMessage.indexOf("Wlacz")>=0){
    Serial.println("Alarm wlaczony ");
    textMessage = "";
    stanAlarmu = 1;
 
  }
  if(textMessage.indexOf("Wylacz")>=0){
    Serial.println("Alarm wylaczony");
    textMessage = "";
    stanAlarmu = 0;
  }
  if(textMessage.indexOf("Stan")>=0){
    String message = "Alarm jest " + alarm;
    wysliSMS(message);
    Serial.println("Żadanie stanu alarmu");
    textMessage = "";
  }
    if(textMessage.indexOf("PLN")>=0){
    stan=0;
    skonta();
}




char key = keypad.getKey();
   if (key != NO_KEY){
      delay(60);
      switch (key){
      case '#': checkPassword(); break;
      case '*': resetPassword(); lcd.clear();  break;
      default:  processNumberKey(key);
      }
   }

   switch (stanAlarmu) {


    case 0: //czuwanie wylaczone
      Serial.print(key);
      if (key) {
      if (aktywacjaAlarmuPozycja == 1 && key == aktywacjaCyfra1) {
          aktywacjaAlarmuPozycja++;
      }else if (aktywacjaAlarmuPozycja == 2 && key == aktywacjaCyfra2){
         aktywacjaAlarmuPozycja++;
      }else if (aktywacjaAlarmuPozycja == 3 && key == aktywacjaCyfra3){
      aktywacjaAlarmuPozycja = 1;
      stanAlarmu = 1;
      resetPassword();
      lcd.clear();
      }else {
         stanAlarmu = 0;
         aktywacjaAlarmuPozycja = 1;
        }
       y++;
     if (y > maxPasswordLength) {   
        y = 0;
        lcd.clear();
        resetPassword();
      }
     }

    if (key) {
      if (zmianaHaslaPozycja == 1 && key == zmianaHaslaCyfra1) {
          zmianaHaslaPozycja++;
        } else if (zmianaHaslaPozycja == 2 && key == zmianaHaslaCyfra2) {
          zmianaHaslaPozycja++;
        } else if (zmianaHaslaPozycja == 3 && key == zmianaHaslaCyfra3) {
          zmianaHaslaPozycja++;
        } else if (zmianaHaslaPozycja == 4 && key == zmianaHaslaCyfra4) {
          zmianaHaslaPozycja++;
        } else if (zmianaHaslaPozycja == 5 && key == zmianaHaslaCyfra5) {
          zmianaHaslaPozycja++;
      changePassword();
      zmianaHaslaPozycja = 1;
      resetPassword();
      } 
  }

     alarm = "Wylaczony";
     lcd.home();
     lcd.print("ALARM WYLACZONY ");
     digitalWrite(diodaZielona, HIGH);
     digitalWrite(diodaZulta, LOW);
     digitalWrite(diodaCzerwona, LOW);
     digitalWrite(buzzer, LOW);    
     smsNr1.restart();
     smsNr2.restart();
     sms1 = 0;
     sms2 = 0;
     czasNaPin.restart();
  
    break;

    case 1: //czuwanie wlaczone
     alarm = "Wlaczony";
     lcd.home();
     lcd.print("ALARM  WLACZONY");
     digitalWrite(diodaZielona, LOW);
     digitalWrite(diodaZulta, HIGH);
     digitalWrite(diodaCzerwona, LOW);
     digitalWrite(buzzer, LOW);
   
     if (digitalRead(laser) == LOW) {
        stanAlarmu = 2;
        lcd.clear();
        czasNaPin.begin(czasNaPinOdliczanie);
     }
    break;

    case 2: // czas na rozbrojenie alarmu po wykryciu  ruchu przez PIR
     gaszenieLcd.restart();
     lcd.backlight();
     lcd.display();
     lcd.home();
     lcd.print("WYKRYTO RUCH");
     digitalWrite(diodaZielona, LOW);
     digitalWrite(diodaZulta, LOW);
     digitalWrite(diodaCzerwona, HIGH);
   
     if (czasNaPin.available()){
        stanAlarmu = 3;
        lcd.setCursor(0, 0);       
        lcd.print("             ");
       // resetPassword();
        czasNaPin.restart();
        smsNr1.begin(10000);
     }
    break;

    case 3: // ALARM
    gaszenieLcd.restart();
    lcd.backlight();
    lcd.display();
    lcd.setCursor(4, 0);
    lcd.print("ALARM !");
    digitalWrite(diodaZielona, LOW);
    digitalWrite(diodaZulta, LOW);
    digitalWrite(diodaCzerwona, HIGH);
  
    if (smsNr1.available()){
        sms1++;  
        if(sms1 < 2){
           smsAlarm();
           Serial.print(sms1);
          }
    }
    if (smsNr2.available()){
        sms2++;
        if(sms2 < 2){
           smsAlarm();
           Serial.print(sms2);
           }
      }
     
    break;
}
  if (key) {
     x++;
     x++;
     usuwaniePin.begin(usuwaniePinOdliczanie);
     gaszenieLcd.begin(gaszenieLcdOdliczanie);
     lcd.backlight();
     lcd.display();
     }
  if (usuwaniePin.available()){
        resetPassword();
        lcd.print("          ");
     }
  if (gaszenieLcd.available()){
        lcd.noBacklight();
        lcd.noDisplay();
     }
}

void processNumberKey(char key) {
   lcd.setCursor(x, 1);
   lcd.print(key);
   currentPasswordLength++;
   password.append(key);
   if (currentPasswordLength == maxPasswordLength) {
      checkPassword();
   }
}

void checkPassword() {
   if (password.evaluate()){
      lcd.clear();
      stanAlarmu = 0;
   } else {
      lcd.clear();
      lcd.print("BLEDNY PIN");
      delay(1000);
      lcd.clear();
   }
   resetPassword();
}

void resetPassword() {
   lcd.setCursor(x, 1);
   lcd.print("          ");
   password.reset();
   currentPasswordLength = 0;
   aktywacjaAlarmuPozycja = 1;
    x = 0;
    y = 0;
}

void changePassword() {
   x = 0;
   lcd.clear();
   lcd.print("ZMIANA PINU");
   newPasswordString = Password();
   newPasswordString.toCharArray(newPassword, newPasswordString.length()+1);//convert string to char array
   password.set(newPassword);
   resetPassword();
   Serial.println(newPasswordString.length());
    if (newPasswordString.length() < minPasswordLength){
     newPasswordString.remove(0,20);
     Serial.println(newPasswordString.length());
     lcd.clear();
     lcd.setCursor(0, 0);
     lcd.print("ZA KROTKI PIN");
     lcd.setCursor(0, 1);
     lcd.print("MIN. DL. PINU");
     lcd.setCursor(15, 1);
     lcd.print(minPasswordLength); 
     x = 0;
     delay(3000);
     changePassword();
    }
   if (newPasswordString.length() > maxPasswordLength){
     newPasswordString.remove(0,20);
     Serial.println(newPasswordString.length());
     lcd.clear();
     lcd.setCursor(0, 0);
     lcd.print("ZA DLUGI PIN");
     lcd.setCursor(0, 1);
     lcd.print("MAKS DL. PINU");
     lcd.setCursor(15, 1);
     lcd.print(maxPasswordLength); 
     x = 0;
     delay(2000);
     changePassword();
   }else{
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("PIN ZMIENIONY NA:");
      lcd.setCursor(0, 1);
      lcd.print(newPasswordString);
      delay(3000);
      lcd.clear();
      x = 0;
     }
}

String Password(){
  lcd.setCursor(x, 1);
    String password = "";
    while (1){
        char key = keypad.getKey();
          if (key){  
                if ((key=='1') || (key=='2') ||
                    (key=='3') || (key=='4') || (key=='5') ||
                    (key=='6') || (key=='7') || (key=='8') ||
                    (key=='9'))   // jesli wcisnąłem klawisze 0 - 9              
                    {
                         lcd.print(key);
                         lcd.print(" ");  
                         password = password + key;  
                    }
                    if (key=='#') break; // zatwierdzamy wybĂłr                                         
        }
    }
    return password;
}

void wysliSMS(String message){

  altSerial.print("AT+CMGF=1\r");
  delay(100);

  altSerial.println("AT+CMGS=\"+48xxxxxxxx\"");
  delay(100);

  altSerial.println(message);
  delay(100);

  altSerial.println((char)26);
  delay(100);
  altSerial.println();
}

void smsAlarm(){
  altSerial.print("AT+CMGF=1\r");
  delay(100);

  altSerial.println("AT+CMGS=\"+48xxxxxxxx\"");
  delay(100);

  altSerial.println("alarm");
  delay(100);
  altSerial.println((char)26);
  Serial.print("alarm");
  smsNr2.begin(30000);
}

void smsStanKonta(){

  altSerial.print("AT+CMGF=1\r");
  delay(100);

  altSerial.println("AT+CMGS=\"+48xxxxxxxx\"");
  delay(100);

  altSerial.println(textMessage);
  delay(100);

  altSerial.println((char)26);
  delay(100);
  altSerial.println();
}

void skonta(){
  altSerial.print("AT+CUSD=1, \"*101#\"");
}
 
Odpowiedź
#28
Wszystkie problemy rozwiązane. Sprawdzenie stanu konta działa. Ogólnie jest ok. Dodałem menu, a do niego przeniosłem wszystkie opcje tzn.  zmiany pinu, sprawdzenie stanu konta itd. bo robił się bałagan na klawiaturze i brakowało przycisków.  Staram się zrobić tak, że gdy zajdzie potrzeba zmiany nr telefonu, operatora, można było zmienić dane (kod ussd stanu konta, nr telefonu na które przychodzą powiadomienia)  bez potrzeby podpinania arduino do kompa. 

Napisałem taką funkcję do zmiany kodu ussd:
Kod:
void zmianaKoduUSSD(){ // zmiana kodu ussd
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(F("Wpisz Kod USSD"));
  lcd.setCursor(12,1);
  lcd.print(F(" D-"));
  lcd.print((char)2);
  lcd.setCursor(0,1);
      String nowyKodUSSD = "";
    while (1){
        char key = keypad.getKey();
          if (key){  
                if ((key=='1') || (key=='2') || (key=='3') ||
                    (key=='4') || (key=='5') || (key=='6') ||
                    (key=='7') || (key=='8') || (key=='9') ||
                    (key=='0') || (key=='*') || (key=='#'))      
                  {
                    lcd.print(key);
                    nowyKodUSSD = nowyKodUSSD + key;
                  }
                
                if(key == 'D') {kodUSSD = nowyKodUSSD; zapisEEprom(); break;}  
          }                    
        
    }

I funkcje podglądu wprowadzonego kodu USSD
Kod:
void pokazKodUSSD(){ // pokazanie kodu USSD
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(F("Kod USSD:"));
    lcd.setCursor(0,1);
    lcd.print(kodUSSD);
    delay(3000);
    lcd.clear();
}

Działa elegancko do czasu odłączenia zasilania. Po jego odłączeniu znikają wprowadzone zmiany, dlatego postanowiłem skorzystać z dobrodziejstwa EEPROM. W tym celu napisałem( z pomocą internetu) taką funkcję do zapisu:

zmienne: 
Kod:
int addr = 0;
int charLength = 0;
int currentAddr = 0;
String kodUSSD = "*101#";
String nowyKodUSSD= "";


Kod:
void zapisEEPROM(){
for (int index = 0; index < kodUSSD.length(); index++)
{ EEPROM.write(addr, kodUSSD[index]);
  delay10);
  Serial.print("Writing ");
  Serial.print(kodUSSD[index]);
  Serial.print(" in address ");
  Serial.println(addr);
  addr++;
}
EEPROM.write(addr, '\0');
odczytEEPROM();
}


i taką do odczytu: 
Kod:
void odczytEEPROM(){
EEPROM.read(addr);
char readChar;
while (readChar != '\0') {
Serial.print("Reading ");
readChar = EEPROM.read(currentAddr);
if (readChar != '\0') {
nowyKodUSSD += readChar;
}
currentAddr++;
}
Serial.print("Final string read from EEPROM: ");
Serial.println(nowyKodUSSD);
kodUSSD = nowyKodUSSD;
}
Na porcie szeregowym widzę, że zmiany zapisały się w eeprom, ale po odłączeniu zasilania gdzieś one giną tzn. Gdy wywołam funkcje pokazKodUSSD (); to na moją głowę, na lcd powinien wyświetlic się zmieniony kod USSD;, a tak nie jest. Gdzie jest błąd?
Cały kod programu:
Kod:
#include <EEPROM.h>


#include <AltSoftSerial.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <Timers.h>
#include <Keypad.h>
#include <Password.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);

const int LCD_COLS = 16;
const int LCD_ROWS = 2;


AltSoftSerial altSerial;

String textMessage; //Zmienna do przechowywania wiadomosci tekstowej
String alarm = "";
String stanKontaLcd; // zmienna do wyświetlalnia stanu konta na lcd

String newPasswordString;
char newPassword[5];


Password password = Password( (char*)"1234" );

byte currentPasswordLength = 0;

const byte ROWS = 4;
const byte COLS = 4;

//Define the keymap
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
                    //  10,9,8,7
byte rowPins[ROWS] = {12,11,10,7};

                      //6,5,4,3
byte colPins[COLS] = {6,5,4,3 };

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

byte diodaZielona = 2;
byte diodaZulta = A2;
byte diodaCzerwona = A1;
//////czujnikRuchu = A7; odlaczony brak miesca
byte buzzer = A3;
byte laser = A0;

volatile byte stanAlarmu = 0;

int x = 0; // zmienna do kursora LCD
int y = 0; // zmienna liczaca ilosc znakoww w "aktywacja alarmu."
int sms1 = 0; // zmienna do pierwszego sms Alarm
int sms2 = 0; // zmienna do drugiego sms Alarm



Timer czasNaPin;  // wpisanie pinu
Timer usuwaniePin; // usuwanie pin z lcd
Timer gaszenieLcd; // gaszenie lcd
Timer smsNr1;      // pierwszy sms Alarm
Timer smsNr2;      // drugi sms Alarm
Timer czasNaWyjscie;// wyjscie po aktywacji

int czasNaPinOdliczanie = 10;  // czas na wpisanie pinu w sekundach
int usuwaniePinOdliczanie = 7;  // czas na usuwaniecie pinu z lcd w sekundach
int gaszenieLcdOdliczanie = 30; // czas na zgaszenie lcd w sekundach
int smsNr1Odliczanie = 10;      // odliczanie do wyslania pierwszego sms po wejsciu do stanu alarm
int smsNr2Odliczanie  = 30;      // odliczanie do wyslania drugiego sms po wejsciu do stanu alarm
int czasNaWyjscieOdliczanie  = 5;// czas na wyjscie po aktywacji alarmu  w sekundach

byte maxPasswordLength = 5;  //maksymalna dlugosc hasla
byte minPasswordLength = 2; // minimalna dlugosc hasla

byte menuPozycja = 1;
char menuCyfra1 = '0'; //
char menuCyfra2 = '0'; //
char menuCyfra3 = '0'; //
char menuCyfra4 = '0'; //
char menuCyfra5 = 'D'; //

byte aktywacjaAlarmuPozycja = 1;
char aktywacjaCyfra1 = 'A'; //
char aktywacjaCyfra2 = 'A'; //
char aktywacjaCyfra3 = 'A'; //

String numer = "699542253";
String nowyNumer = "";
//String kodUSSD = "*101#";
//String nowyKodUSSD = "";

int timer = 0;
int menu = 1;
unsigned long preMillis = 0;

int addr = 0;
int charLength = 0;
int currentAddr = 0;
String kodUSSD = "*101#";
String nowyKodUSSD = "";


byte strzalkaWgore[8] = { //strzałka w góre
  0b00100,
  0b01110,
  0b11111,
  0b00100,
  0b00100,
  0b00100,
  0b00100,
  0b00100
};

byte strzalWdul[8] = { // strzalka w dol
  0b00100,
  0b00100,
  0b00100,
  0b00100,
  0b00100,
  0b11111,
  0b01110,
  0b00100
};

byte wyjdz[8] = { // wyjdz
  0b00000,
  0b00111,
  0b00001,
  0b00001,
  0b01001,
  0b11101,
  0b01001,
  0b01111
};

void setup()
{
  gaszenieLcd.begin(gaszenieLcdOdliczanie * 1000);

  lcd.begin();
  lcd.createChar(0, strzalkaWgore);
  lcd.createChar(1, strzalWdul);
  lcd.createChar(2, wyjdz);

  Serial.begin(9600);
  Serial.println(F("AltSoftSerial Test Begin"));
  altSerial.begin(9600);

  altSerial.print(F("AT+CMGF=1\r")); // ustawienie gsm na text mode
  delay(100);

  altSerial.print(F("AT+CNMI=2,2,0,0,0\r"));
  delay(100);

  pinMode(diodaZielona, OUTPUT);
  pinMode(diodaZulta, OUTPUT);
  pinMode(diodaCzerwona, OUTPUT);
  pinMode(buzzer, OUTPUT);

  pinMode(laser, INPUT);

}

void loop()
{
  unsigned long ms = millis();     
  char c;
  while (Serial.available()) {
    c = Serial.read();
    altSerial.write(c);
  } 
  altSerial.flushOutput();

  while (altSerial.available()) {
    c = altSerial.read();
    textMessage = altSerial.readString();
    Serial.print(c);
    Serial.print(textMessage);
    if(textMessage.indexOf("Pozostalo Ci")>=0){
      stanKontaLcd = textMessage;
      stanKontaLcd.remove(22,2);
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print(stanKontaLcd.substring(14, 29));
      lcd.setCursor(0,1);
      lcd.print(stanKontaLcd.substring(46, 60));
      delay(3000);
      lcd.clear();
      //smsStanKonta();
    }
  } 

if(textMessage.indexOf(F("Wlacz"))>=0){
    Serial.println(F("Alarm wlaczony "));
    textMessage = "";
    stanAlarmu = 1;
 
  }
  if(textMessage.indexOf(F("Wylacz"))>=0){
    Serial.println(F("Alarm wylaczony"));
    textMessage = "";
    stanAlarmu = 0;
  }
  if(textMessage.indexOf(F("Stan"))>=0){
    String message =
    "Alarm jest " + alarm;
    stanAlarmuSMS;
    Serial.println(F("Ĺťadanie stanu alarmu"));
    textMessage = "";
  }
  if(textMessage.indexOf(F("PLN"))>=0){//// zmienione
    if(altSerial.available()>0){
      textMessage = altSerial.readString();
      if(textMessage.indexOf("Pozostalo Ci")>=0){
        smsStanKonta();
      }   
    }
  }


char key = keypad.getKey();
  if (key != NO_KEY){
      delay(60);
      switch (key){
      case '#': checkPassword(); break;
      case '*': resetPassword(); lcd.clear(); break;
      default:  processNumberKey(key);
      }
  }

  switch (stanAlarmu) {

    case 0: //czuwanie wylaczone
      Serial.print(key);
      if (key) {
      if (aktywacjaAlarmuPozycja == 1 && key == aktywacjaCyfra1) {
          aktywacjaAlarmuPozycja++;
      }else if (aktywacjaAlarmuPozycja == 2 && key == aktywacjaCyfra2){
        aktywacjaAlarmuPozycja++;
      }else if (aktywacjaAlarmuPozycja == 3 && key == aktywacjaCyfra3){
      aktywacjaAlarmuPozycja = 1;
      resetPassword();
      lcd.clear();
      stanAlarmu = 1;
      lcd.home();
      lcd.print(F("ALARM AKTYWNY ZA"));
      lcd.setCursor(0,1);
      czasNaWyjscie.begin(czasNaWyjscieOdliczanie * 1000);
     
  for(timer = czasNaWyjscieOdliczanie; timer > 0; --timer){
    if(timer >= 10) {
      lcd.setCursor(3,1);
  } else { 
      lcd.setCursor(3,1);
      lcd.print("0");
      lcd.setCursor(4,1);
  }
  lcd.print(timer);
  lcd.print(" SEKUND");
  delay(1000);
  } 
  if(timer == 0) {
    lcd.clear();
  } 
      }else {
        stanAlarmu = 0;
        aktywacjaAlarmuPozycja = 1;
        }
      y++;
    if (y > maxPasswordLength) {   
        y = 0;
        lcd.clear();
        resetPassword();
      }
    }

    if (key) {
      if (menuPozycja == 1 && key == menuCyfra1) {
          menuPozycja++;
        } else if (menuPozycja == 2 && key == menuCyfra2) {
          menuPozycja++;
        } else if (menuPozycja == 3 && key == menuCyfra3) {
          menuPozycja++;
        } else if (menuPozycja == 4 && key == menuCyfra4) {
          menuPozycja++;
        } else if (menuPozycja == 5 && key == menuCyfra5) {
          menuPozycja++;
      stanAlarmu = 4;
      menuPozycja = 1;
      resetPassword();
      break;
      } 
  }

    alarm = "Wylaczony";
    lcd.home();
    lcd.print(F("ALARM WYLACZONY "));
    digitalWrite(diodaZielona, LOW); 
    if ((ms-preMillis)>=5000){
      preMillis = ms;
      digitalWrite(diodaZielona,HIGH);
      delay(1);} 
    digitalWrite(diodaZulta, LOW);
    digitalWrite(diodaCzerwona, LOW);
    digitalWrite(buzzer, LOW);   
    smsNr1.restart();
    smsNr2.restart();
    sms1 = 0;
    sms2 = 0;
    czasNaPin.restart();
 
    break;

    case 1: //czuwanie wlaczone
  if (czasNaWyjscie.available()){
    alarm = "Wlaczony";
    lcd.home();
    lcd.print(F("ALARM  WLACZONY"));
    digitalWrite(diodaZielona, LOW);
    digitalWrite(diodaZulta, LOW);
    if ((ms-preMillis)>=5000){
      preMillis = ms;
      digitalWrite(diodaZulta,HIGH);
      delay(1);} 
    digitalWrite(diodaCzerwona, LOW);
    digitalWrite(buzzer, LOW);
   
    if (digitalRead(laser) == LOW) {
        stanAlarmu = 2;
        lcd.clear();
        czasNaPin.begin(czasNaPinOdliczanie * 1000);
    }
  }
    break;

    case 2: // czas na rozbrojenie alarmu po wykryciu  ruchu przez PIR
    gaszenieLcd.restart();
    lcd.backlight();
    lcd.display();
    lcd.setCursor(2,0);
    lcd.print(F("WYKRYTO RUCH"));
    digitalWrite(diodaZielona, LOW);
    digitalWrite(diodaZulta, LOW);
    digitalWrite(diodaCzerwona, HIGH);
   
    if (czasNaPin.available()){
        stanAlarmu = 3;
        lcd.setCursor(0, 0);       
        lcd.print(F("              "));
      // resetPassword();
        czasNaPin.restart();
        smsNr1.begin(10000);
    }
    break;

    case 3: // ALARM
    gaszenieLcd.restart();
    lcd.backlight();
    lcd.display();
    lcd.setCursor(4, 0);
    lcd.print(F("ALARM !"));
    digitalWrite(diodaZielona, LOW);
    digitalWrite(diodaZulta, LOW);
    digitalWrite(diodaCzerwona, HIGH);
 
    if (smsNr1.available()){
        sms1++; 
        if(sms1 < 2){
          smsAlarm();
          Serial.print(sms1);
          }
    }
    if (smsNr2.available()){
        sms2++;
        if(sms2 < 2){
          smsAlarm();
          Serial.print(sms2);
          }
      } 
    break;
    case 4: // menu
      lcd.setCursor(0, 0);
      lcd.print(F("A-"));
      lcd.print((char)0);
      lcd.print(F(" B-"));;
      lcd.print((char)1);
      lcd.print(F(" C-OK"));
      lcd.print(F(" D-"));
      lcd.print((char)2);
     
      if(key){resetPassword();}
      if(key == 'A') {lcd.setCursor(0, 1); lcd.print(F("                ")); menu = (menu - 1); resetPassword();
      if (menu < 1){menu = 1; }}
      if(key == 'B') {lcd.setCursor(0, 1); lcd.print(F("                ")); menu = (menu + 1); resetPassword();
      if (menu > 8 ){menu = 1; }}
   

    switch (menu){

      case 1: //Zobacz PIN
        wlaczanielcd();
        lcd.setCursor(0, 1);
        lcd.print(F("Zobacz PIN"));
        if(key == 'C'){ przypomnienieHasla(); }
        if(key == 'D'){ resetPassword(); stanAlarmu=0; lcd.clear();}
      break;

      case 2: //Zmiana PINU
        wlaczanielcd();
        lcd.setCursor(0, 1);
        lcd.print(F("Zmiana PINU"));
        if(key == 'C'){ changePassword(); }
        if(key == 'D'){ resetPassword(); stanAlarmu=0; lcd.clear();}
      break;

      case 3: //Stan Konta
        wlaczanielcd();
        lcd.setCursor(0, 1);
        lcd.print(F("Stan Konta"));
        if(key == 'C'){ altSerial.print("AT+CUSD=1, \""+kodUSSD+"\"\r"); }
        if(key == 'D'){ resetPassword(); stanAlarmu=0; lcd.clear();}
        break;

      case 4: // Przypomnienie numeru
        wlaczanielcd();
        lcd.setCursor(0, 1);
        lcd.print(F("Zobacz Numer"));
        if(key == 'C'){ pokazNumer(); }
        if(key == 'D'){ resetPassword(); stanAlarmu=0; lcd.clear(); }
      break;

      case 5: //Zmiana Numeru
        wlaczanielcd();
        lcd.setCursor(0, 1);
        lcd.print(F("Zmiana Numeru"));
        if(key == 'C'){ zmianaNumeru(); }
        if(key == 'D'){ resetPassword(); stanAlarmu=0; lcd.clear(); }
      break;

      case 6: // Przypomnienie kodu USSD (stan konta)
        wlaczanielcd();
        lcd.setCursor(0, 1);
        lcd.print(F("Zobacz Kod USSD"));
        if(key == 'C'){ pokazKodUSSD();}
        if(key == 'D'){ resetPassword(); stanAlarmu=0; lcd.clear(); }
      break;

      case 7: //Zmiana kodu USSD (stan konta)
        wlaczanielcd();
        lcd.setCursor(0, 1);
        lcd.print(F("Zmiana Kodu USSD"));
        if(key == 'C'){ zmianaKoduUSSD(); lcd.clear(); }
        if(key == 'D'){ resetPassword(); stanAlarmu=0; lcd.clear(); }
      break;

    case 8:
        wlaczanielcd();
        lcd.setCursor(0, 1);
        lcd.print(F("6.Test"));
        if(key == 'C'){odczytEEPROM();}
        if(key == 'D'){ resetPassword(); stanAlarmu=0; }
      break;
      }
}

  if (key) {
    x++;
    x++;
    usuwaniePin.begin(usuwaniePinOdliczanie * 1000);
    gaszenieLcd.begin(gaszenieLcdOdliczanie * 1000);
    lcd.backlight();
    lcd.display();
    }
  if (usuwaniePin.available()){
        resetPassword();
        lcd.print(F("          "));
    }
  if (gaszenieLcd.available()){
        lcd.noBacklight();
        lcd.noDisplay();
    }
}

void processNumberKey(char key) {
  lcd.setCursor(x, 1);
  lcd.print(key);
  currentPasswordLength++;
  password.append(key);
  if (currentPasswordLength == maxPasswordLength) {
      checkPassword();
  }
}

void checkPassword() {
  if (password.evaluate()){
      lcd.clear();
      stanAlarmu = 0;
  } else {
      lcd.clear();
      lcd.print(F("BLEDNY PIN"));
      delay(1000);
      lcd.clear();
  }
  resetPassword();
}

void resetPassword() {
  lcd.setCursor(x, 1);
  lcd.print(F("          "));
  password.reset();
  currentPasswordLength = 0;
  aktywacjaAlarmuPozycja = 1;
    x = 0;
    y = 0;
}

void przypomnienieHasla(){
  if(newPasswordString.length()< minPasswordLength){
    lcd.clear();
    lcd.setCursor(5, 1);
    lcd.print(1234);
    delay(2000);
  }else{
    lcd.clear();
    lcd.setCursor(5, 1);
    lcd.print(newPasswordString);
    delay(2000);
  }
}

void changePassword() {
  x = 0;
  lcd.clear();
  lcd.print(F("ZMIANA PINU #-OK"));
  newPasswordString = Password();
  newPasswordString.toCharArray(newPassword, newPasswordString.length()+1);//convert string to char array
  password.set(newPassword);
  resetPassword();
  Serial.println(newPasswordString.length());
    if (newPasswordString.length() < minPasswordLength){
    newPasswordString.remove(0,20);
    Serial.println(newPasswordString.length());
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(F("ZA KROTKI PIN"));
    lcd.setCursor(0, 1);
    lcd.print(F("MIN. DL. PINU"));
    lcd.setCursor(15, 1);
    lcd.print(minPasswordLength); 
    x = 0;
    delay(3000);
    changePassword();
    }
  if (newPasswordString.length() > maxPasswordLength){
    newPasswordString.remove(0,20);
    Serial.println(newPasswordString.length());
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(F("ZA DLUGI PIN"));
    lcd.setCursor(0, 1);
    lcd.print(F("MAKS DL. PINU"));
    lcd.setCursor(15, 1);
    lcd.print(maxPasswordLength); 
    x = 0;
    delay(2000);
    changePassword();
  }else{
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(F("PIN ZMIENIONY NA:"));
      lcd.setCursor(0, 1);
      lcd.print(newPasswordString);
      delay(3000);
      lcd.clear();
      x = 0;
    }
}

String Password(){
  lcd.setCursor(x, 1);
    String password = "";
    while (1){
        char key = keypad.getKey();
          if (key){ 
                if ((key=='1') || (key=='2') ||
                    (key=='3') || (key=='4') || (key=='5') ||
                    (key=='6') || (key=='7') || (key=='8') ||
                    (key=='9'))  // jesli wcisnolem klawisze 1 - 9             
                    {
                        lcd.print(key);
                        lcd.print(" "); 
                        password = password + key; 
                    }
                    if (key=='#') break; // zatwierdzamy wybor                                         
        }
    }
    return password;
}

void stanAlarmuSMS(String message){

  altSerial.print(F("AT+CMGF=1\r"));
  delay(100);

  altSerial.println("AT+CMGS=\"+48" + numer +"\"");
  delay(100);

  altSerial.println(message);
  delay(100);

  altSerial.println((char)26);
  delay(100);
  altSerial.println();
}

void smsAlarm(){ // sms po wlaczeniu alarmu
  altSerial.print(F("AT+CMGF=1\r"));
  delay(100);

  altSerial.println("AT+CMGS=\"+48" +numer+ "\"");
  delay(100);

  altSerial.println(F("alarm"));
  delay(100);
  altSerial.println((char)26);
 
  smsNr2.begin(30000);
}

void smsStanKonta(){ // sms ze stanem konta

  altSerial.print(F("AT+CMGF=1\r"));
  delay(100);

  altSerial.print("AT+CMGS=\"+48" +numer+ "\"");  //  altSerial.println(F("AT+CMGS=\"+48xxxxxxx\""));
  delay(100);

  altSerial.println(textMessage);
  delay(100);

  altSerial.println((char)26);
  delay(100);
  altSerial.println();
}

void wlaczanielcd(){
  usuwaniePin.restart();
  gaszenieLcd.restart();
  usuwaniePin.restart();
}

void zmianaNumeru(){ // zmiana numeru tlefonu do odpowiedzi zwrotnej
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(F("Wpisz Nowy Numer"));
  lcd.setCursor(0,1);
      String nowyNumer = "";
    while (1){
        char key = keypad.getKey();
          if (key){ 
                if ((key=='1') || (key=='2') || (key=='3') ||
                    (key=='4') || (key=='5') || (key=='6') ||
                    (key=='7') || (key=='8') || (key=='9') ||
                    (key=='0'))  // jesli wcisnolem klawisze 1 - 9             
                  {
                    lcd.print(key);
                    nowyNumer = nowyNumer + key;
                  }
                    if (nowyNumer.length() >= 9){
                        numer = nowyNumer;
                        lcd.clear();
                        lcd.setCursor(0,0);
                        lcd.print(F("Nr Zmieniony Na"));
                        lcd.setCursor(0,1);
                        lcd.print(numer);
                        delay(4000); break;
                       
                          if (nowyNumer.length() < 9){
                            lcd.clear();
                            lcd.setCursor(0,0);
                            lcd.print(F("Nr Zmieniony Na"));
                            lcd.setCursor(0,1);
                            lcd.print(numer);
                            delay(4000); break;                     
                    }
                }
                if(key == 'D') {break;}                     
        }
    }
}

void pokazNumer(){ // pokazanie numeru
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(F("Zapisany Nr:"));
    lcd.setCursor(0,1);
    lcd.print(numer);
    delay(4000);
    lcd.clear();
}

void pokazKodUSSD(){ // pokazanie kodu USSD
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(F("Kod USSD:"));
    lcd.setCursor(0,1);
    lcd.print(kodUSSD);
    delay(3000);
    lcd.clear();
}

void zmianaKoduUSSD(){ // zmiana kodu ussd
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(F("Wpisz Kod USSD"));
  lcd.setCursor(12,1);
  lcd.print(F(" D-"));
  lcd.print((char)2);
  lcd.setCursor(0,1);
      String nowyKodUSSD = "";
    while (1){
        char key = keypad.getKey();
          if (key){ 
                if ((key=='1') || (key=='2') || (key=='3') ||
                    (key=='4') || (key=='5') || (key=='6') ||
                    (key=='7') || (key=='8') || (key=='9') ||
                    (key=='0') || (key=='*') || (key=='#'))// jesli wcisnolem klawisze 1 - 9             
                  {
                    lcd.print(key);
                    nowyKodUSSD = nowyKodUSSD + key;
                  }
               
                if(key == 'D') {kodUSSD = nowyKodUSSD; zapisEEPROM(); break;} 
          }                           
    }
}

void zapisEEPROM(){
  for (int index = 0; index < kodUSSD.length(); index++) {
    EEPROM.write(addr, kodUSSD[index]);
    delay(10);

    Serial.print("Writing ");
    Serial.print(kodUSSD[index]);
    Serial.print(" in address ");
    Serial.println(addr);

    addr++;
  }

  EEPROM.write(addr, '\0');
  odczytEEPROM();
}

void odczytEEPROM(){
 
  EEPROM.read(addr);

  char readChar;

  while (readChar != '\0') {
    Serial.print("Reading ");

    readChar = EEPROM.read(currentAddr);

    if (readChar != '\0') {
      nowyKodUSSD += readChar;
    }
    currentAddr++;
  }

  Serial.print("Final string read from EEPROM: ");
  Serial.println(nowyKodUSSD);
  kodUSSD = nowyKodUSSD;
}
 
Odpowiedź
#29
Ogarnąłem to z czym miałem problem i jest prawie ok, prawie bo czegoś nie ogarniam. Przy pierwszym zapisie hasła do eeprom jest ok, ale gdy chcę zmienić hasło ponownie i zapisać je do eeprom, to otrzymuje takie coś:

[Obrazek: 3c7f535fe1d85bfcf395cc68088b668d.png]

Tak wiem, że zapis jest w kolejnych bajtach, pytanie dlaczego tak się dzieje? Oczywiście próbowałem zerować zmienną index = 0; licząc, że zapis nastąpi od pierwszego bajta, ale nic to nie daje. 

zmienne:
Kod:
int addr = 0;
int index = 0;
int currentAddr = 0;

Część kodu z która mam problem:

Kod:
void changePassword() {
   x = 0;
   lcd.clear();
   lcd.print(F("ZMIANA PINU #-OK"));
   newPasswordString = Password();
   zapisEEPROM();
   newPasswordString.toCharArray(newPassword, newPasswordString.length()+1);//convert string to char array
   password.set(newPassword);
   resetPassword();
   Serial.println(newPasswordString.length());
    if (newPasswordString.length() < minPasswordLength){
     newPasswordString.remove(0,20);
     Serial.println(newPasswordString.length());
     lcd.clear();
     lcd.setCursor(0, 0);
     lcd.print(F("ZA KROTKI PIN"));
     lcd.setCursor(0, 1);
     lcd.print(F("MIN. DL. PINU"));
     lcd.setCursor(15, 1);
     lcd.print(minPasswordLength); 
     x = 0;
     delay(3000);
     changePassword();
    }
   if (newPasswordString.length() > maxPasswordLength){
     newPasswordString.remove(0,20);
     Serial.println(newPasswordString.length());
     lcd.clear();
     lcd.setCursor(0, 0);
     lcd.print(F("ZA DLUGI PIN"));
     lcd.setCursor(0, 1);
     lcd.print(F("MAKS DL. PINU"));
     lcd.setCursor(15, 1);
     lcd.print(maxPasswordLength); 
     x = 0;
     delay(2000);
     changePassword();
   }else{
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(F("PIN ZMIENIONY NA:"));
      lcd.setCursor(0, 1);
      lcd.print(newPasswordString);     
      delay(3000);
      lcd.clear();
      x = 0;
     }
}

String Password(){
  lcd.setCursor(x, 1);
    String password = "";
    while (1){
        char key = kpd.getKey();
          if (key){  
                if ((key=='1') || (key=='2') ||
                    (key=='3') || (key=='4') || (key=='5') ||
                    (key=='6') || (key=='7') || (key=='8') ||
                    (key=='9'))   // jesli wcisnolem klawisze 1 - 9              
                    {
                         lcd.print(key);
                         lcd.print(" ");  
                         password = password + key;  
                    }
                    if (key=='#'){break; }// zatwierdzamy wybor                                         
        }
    }
    return password;
}



void zapisEEPROM(){
  for (index = 0; index < newPasswordString.length(); index++) {
    EEPROM.write(addr, newPasswordString[index]);
    delay(10);

    Serial.print("Writing ");
    Serial.print(newPasswordString[index]);
    Serial.print(" in address ");
    Serial.println(addr);

    addr++;
  }
  EEPROM.write(addr, '\0');
  odczytEEPROM();
}

void odczytEEPROM(){
EEPROM.read(addr);

  int currentAddr = 0;
  char readChar;
  String readGreeting = "";

  while (readChar != '\0') {

    readChar = EEPROM.read(currentAddr);
    delay(10);
    if (readChar != '\0') {
      readGreeting += readChar;
    }

    currentAddr++;

    Serial.print(readChar);
    Serial.print(" in address ");
    Serial.println(currentAddr);
  }

  Serial.print("Final string read from EEPROM: ");
  Serial.println(readGreeting);
  if (currentAddr==addr){
    currentAddr=0;}
}
 
Odpowiedź
#30
Pytanie. Jak ugryźć kod aby działał na pcf8574 buzzer? Diody działają bez problemu.
Kod:
expander.pinMode(buzzer, OUTPUT); - w setupie


if ((ms-preMillis)>=5000){
       preMillis = ms;
       expander.digitalWrite(diodaZulta,HIGH);
       tone(buzzer, 2500);
       delay(60);}
       noTone(buzzer);   
     expander.digitalWrite(diodaCzerwona, LOW);
Dodanie expander przed tone nie działa, na necie przykładów nie znalazłem. Jak to ugryźć?
 
Odpowiedź
  


Skocz do:


Przeglądający: 2 gości