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.
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:
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?
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;
}