Skocz do zawartości

Optymalizacja kodu.


Danielos01

Pomocna odpowiedź

Witam

robię sobie alarm domowy i mam problem z ilością pamięci. Nie jestem bardzo doświadczony w takim dłuższym pisaniu kodów i nie wiem czy popełniam jakiś duży błąd w ich pisaniu skoro dość szybko kończy mi się pamięć.

#include <Wire.h>     //biblioteka komunikacji dla zegara
#include <DS3231.h>   //biblioteka zegara DS3231

#include <SPI.h>      //biblioteka komunikacji SPI
#include <SD.h>       //biblioteka karty SD
File plik;            //utworzenie pliku dla karty SD

//ustawienia wyświetlacza LCD + biblioteka wyświetlacza
#include <LiquidCrystal.h>
LiquidCrystal lcd(8,9,4,5,6,7);

//przyciski wyświetlacza
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

DS3231 clock;     //zegar czasu rzeczywistego
RTCDateTime dt;

//przypisanie pinów dla urządzeń
#define PIR         A1
#define czujnik     A2
#define LED         1
#define buzzer      2
#define odbiornik   3


boolean alarm_uzbrojony=false;  //zmnienna sygnalizująca uzbrojenie alarmu
int w1[]={1,1,1,1}; //wartości prawidłowego PINU
int w2[]={0,0,0,0}; //wartości wpisywanego PINU

int read_LCD_buttons()  //funkcja odczytu wciśniętego przycisku
{
  int adc_key_in = analogRead(0);      
  if (adc_key_in > 1000) return btnNONE; 
  if (adc_key_in < 50)   return btnRIGHT;  
  if (adc_key_in < 250)  return btnUP; 
  if (adc_key_in < 450)  return btnDOWN; 
  if (adc_key_in < 650)  return btnLEFT; 
  if (adc_key_in < 850)  return btnSELECT;  

  return btnNONE;
}

void menu()       //wyświetlanie funkcji MENU
{
 lcd.clear();
 lcd.print("Centralka alarmu"); 
}

void czas()         //wyświetlanie czasu z DS3231
{
 lcd.clear();
 do
 {
   dt = clock.getDateTime();   //pobieranie danych z zegara

   lcd.setCursor(0,0);         //wyświetlanie czasu na LCD
   lcd.print(dt.year);lcd.print("-");
   if(dt.month<10)
   {
     lcd.print("0");lcd.print(dt.month);lcd.print("-");  
   }
   else
     lcd.print(dt.month);
   if(dt.day<10)
   {
     lcd.print("0");lcd.print(dt.day);
   }
   else 
     lcd.print(dt.day);

   lcd.setCursor(0,1);
   if(dt.hour<10)
   {
     lcd.print("0");lcd.print(dt.hour); lcd.print(":");
   }
   else
     lcd.print(dt.hour);lcd.print(":");
   if(dt.minute<10)
   {
     lcd.print("0");lcd.print(dt.minute);lcd.print(":");
   }
   else
     lcd.print(dt.minute);lcd.print(":");
   if(dt.second<10)
   {
     lcd.print("0");lcd.print(dt.second);  
   }
   else
     lcd.print(dt.second);

   delay(400);    
  } while(read_LCD_buttons()!=btnDOWN);     //wyłączenie funkcji czas po naciśnięciu przycisku DOWN

 menu();

}

void alarm()    //działanie ukłądu w trybie uzbrojonym
{
 digitalWrite(odbiornik,HIGH);
 zapis_SD("WŁAMANIE");
 lcd.clear(); lcd.print("    Wlamanie");
 for(int i=0;i<=35;i++)
   dzwiek(150,4300,3500);
 noTone(buzzer);
 digitalWrite(odbiornik,LOW);
}

boolean uzbrajanie()   //proces uzbrajania alarmu, sprawdzanie czujników
{
   lcd.clear();lcd.print("   UZBRAJANIE");lcd.setCursor(0,1);lcd.print("   Opusc dom");
   for(int i=0;i<=5;i++)
   {
     digitalWrite(LED,HIGH);
     delay(500);
     digitalWrite(LED,LOW);
     delay(500);     
   }
   if(digitalRead(czujnik)==HIGH&&digitalRead(PIR)==LOW)
   {
      zapis_SD("uzbrojenie alarmu");
      return alarm_uzbrojony=true;     
   }
   else
      {
         lcd.clear();
         lcd.print("Uzbrajanie nie"); lcd.setCursor(0,1); lcd.print("powiodlo sie");
         for(int i=0;i<=15;i++);
           dzwiek(1000,1000,1000);
         noTone(buzzer);
         zapis_SD("uzbrajanie nie powiodło się");
         menu();
         return alarm_uzbrojony=false;
      }      
}

void dzwiek(int czas_przerwy, int czestotliwosc1, int czestotliwosc2)  //odtwarzanie sygnału BUZZERA
{
 tone(buzzer,czestotliwosc1),
 delay(czas_przerwy);
 tone(buzzer,czestotliwosc2),
 delay(czas_przerwy);
}

void zapis_SD(String stan)  //funkcja do zapisu danych na kartę SD
{
 SD.begin(0);    //ustawienie pinu CS=0
 dt = clock.getDateTime();
 plik=SD.open("Alarm.txt",FILE_WRITE);
 plik.print("Data: ");plik.print(dt.year);plik.print("-");plik.print(dt.month);plik.print("-");plik.print(dt.day);
 plik.print(" Godzina: ");plik.print(dt.hour);plik.print(":");plik.print(dt.minute);plik.print(":");plik.print(dt.second);
 plik.print("   ");plik.println(stan);plik.close();
}

void wpisywanie_pinu(int tab[],String x,int czas,int w)  //funkcja do wpisywania PINU
{
 int i=0;    //zmienna pomocnicza licząca czas
 delay(150);
 lcd.clear();lcd.print(x);

 for(int j=0;j<=3;j++)   //pętla do przechodzenia do kolejnych cyfr PINU
 {
   lcd.setCursor(5+j,1);lcd.print(tab[j]);
   do                                   //wprowadzanie cyfry PINU
 {
   if(read_LCD_buttons()==btnUP&&tab[j]<9)
   {
     delay(200);
     tab[j]++;
     lcd.setCursor(5+j,1);lcd.print(tab[j]);   
   }
   else
     if(read_LCD_buttons()==btnUP&&tab[j]==9)
     {
       delay(200);
       tab[j]=0;
       lcd.setCursor(5+j,1);lcd.print(tab[j]); 
     }
     else
       if(read_LCD_buttons()==btnDOWN&&tab[j]<=9&&tab[j]>0)
       {
         delay(200);
         tab[j]--;
         lcd.setCursor(5+j,1);lcd.print(tab[j]); 
       }
       else
         if(read_LCD_buttons()==btnDOWN&&tab[j]==0)
         {
           delay(200);
           tab[j]=9;
           lcd.setCursor(5+j,1);lcd.print(tab[j]);
         }
         else 
           if(i>=czas&&w==1)
             alarm();        

   delay(200);
   i++;
 }while(read_LCD_buttons()!=btnRIGHT);
 }

 while(w==1)
 {
   if(tab[0]==w1[0]&&tab[1]==w1[1]&&tab[2]==w1[2]&&tab[3]==w1[3]) //sprawdzenie czy PIN prawidłowy
   {
     lcd.clear();lcd.print("  PIN poprawny");
     alarm_uzbrojony=false;
     zapis_SD("rozbrojenie");
     delay(500);
     menu();
   }
   else                                              //działanie w przypadku złego PINU
   {
     lcd.clear();lcd.print("PIN niepoprawny");
     delay(500);
     alarm();
   }
 }
}

void ustawienia()
{
 lcd.clear();lcd.print("   Ustawienia");
 delay(1500);
 lcd.setCursor(0,1);lcd.print("Ustawianie PINU");
 delay(1000);
 wpisywanie_pinu(w1,"Podaj nowy PIN",0,0);
 lcd.clear();lcd.print("    Gotowe");
 delay(2000);

}

void setup() 
{
 clock.begin();      //uruchomienie zegara
 lcd.begin(16, 2);   //ustawienie wyświetlacza LCD

 //ustawienia wejść i wyjść
 pinMode(LED,OUTPUT);
 pinMode(buzzer,OUTPUT);
 pinMode(odbiornik,OUTPUT);
 pinMode(czujnik,INPUT);
 pinMode(PIR,INPUT);

 zapis_SD("Alarm załączony");  
 menu();             //uruchomienie startowe funkcji MENU
}

void loop() 
{
 switch(read_LCD_buttons())                 //sprawdzanie wciskanych przycisków i przejścia do innych opcji na LCD
 {
   case btnLEFT: ustawienia();break;
   case btnDOWN: czas(); break;
   case btnSELECT: uzbrajanie(); break;
 }

 if(digitalRead(czujnik)==LOW&&alarm_uzbrojony==false)
   {
     lcd.setCursor(0,1);
     lcd.print("otwarte drzwi");
   }
   else 
     if(digitalRead(PIR)==HIGH&&alarm_uzbrojony==false)
     {
       lcd.setCursor(0,1);lcd.print("wykryto ruch ");
     }
     else
       if(alarm_uzbrojony==false)
          menu();
       else
       {
         lcd.clear();lcd.print("Alarm uzbrojony");
         digitalWrite(LED,HIGH);
       }

  if(alarm_uzbrojony==true&&(digitalRead(czujnik)==LOW||digitalRead(PIR)==HIGH))
  {
    int w2[]={0,0,0,0};
     wpisywanie_pinu(w2,"   Podaj PIN",100,1);
  }

 delay(200);   //przerwa w działaniu programu

}

Chcę dopisać do tego jeszcze parę przydatnych opcji a na ten moment po kompilacji wyświetla mi komunikat:

Szkic używa 18772 bajtów (58%) pamięci programu. Maksimum to 32256 bajtów.

Zmienne globalne używają 1542 bajtów (75%) pamięci dynamicznej, pozostawiając 506 bajtów dla zmiennych lokalnych. Maksimum to 2048 bajtów.

Niski poziom dostępnej pamięci, mogą wystąpić problemy ze stabilnością.

Proszę o jakieś podpowiedzi co robię źle i co można ulepszyć.

Link do komentarza
Share on other sites

Pewnie już za późno dla Ciebie, ale może innym się przyda.

Dla zaoszczędzenia pamięci ram należy używać funkcji F()

np zamiast: lcd.print(" UZBRAJANIE");lcd.setCursor(0,1);lcd.print(" Opusc dom");

wpisz lcd.print(F(" UZBRAJANIE"));lcd.setCursor(0,1);lcd.print(F(" Opusc dom"));

  • Lubię! 1
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Dnia 8.04.2020 o 14:30, g_redman napisał:

Pewnie już za późno dla Ciebie, ale może innym się przyda.

Dla zaoszczędzenia pamięci ram należy używać funkcji F()

np zamiast: lcd.print(" UZBRAJANIE");lcd.setCursor(0,1);lcd.print(" Opusc dom");

wpisz lcd.print(F(" UZBRAJANIE"));lcd.setCursor(0,1);lcd.print(F(" Opusc dom"));

I to jest bardzo wazna informacja:-) juz wiele razy sie zastanawialem po co tam ten "F" jest czasem...

  • Lubię! 1
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.