Zapewne każdy z nas korzystał chociaż raz z kalkulatora. Będąc dzieckiem zawsze zastanawiałem się jak to jest możliwe, że takie małe urządzenie potrafi tak szybko obliczyć wszystkie wpisywane przeze mnie działania. Pragnąłem w przyszłości zbudować własną maszynkę do liczenia ( No co? Każdy ma przecież jakieś dziwne marzenia ;) )
Wreszcie nastał ten dzień kiedy leżąc sobie chory w łóżku z kubkiem gorącej herbaty postanowiłem spełnić swoje dziecięce pragnienie.
Pod ręką leżało akurat arduino które kilka dni wcześniej przyleciało od naszych skośnookich przyjaciół wiec trzeba było je przetestować.
To do roboty.
Rzeczy wykorzystane w projekcie:
- Klon Arduino Uno
- Wyświetlacz LCD 16×2
- Konwerter I2C
- Klawiatura tact switch 4×4
- Płytka stykowa
- Przewody połączeniowe
- Komputer z arduino ide
- I oczywiście kubek gorącej herbaty :)
Po skompletowaniu elementów zabrałem się za połączenie tego wszystkiego do kupy.
Przygotowałem schemat połączenia
Następnie połączyłem wszystko według schematu
No i przyszła pora na napisanie programu dla mojego kalkulatora. Założenie było takie aby kalkulator liczył tylko liczby całkowite, bez żadnych przecinków ponieważ zabrakło by na to miejsca na klawiaturze. Tak wiec herbata w dłoń i piszemy.
Pierwsze co musimy zrobić to dodać biblioteki których jeszcze nie mamy. Ja skorzystałem z :
- Wire.h – domyślna biblioteka w arduino IDE
- LiquidCrystal_I2C.h – do pobrania tutaj
- Keypad.h – do pobrania tutaj
W celu wgrania biblioteki przechodzimy do Szkic -> Dołącz bibliotekę -> Dodaj bibliotekę .ZIP i wyszukujemy nasze pliki do dodania.
Po tym możemy się już zabrać za pisanie właściwego kodu.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
//KALKULATOR ARDUINO - MAJSTERKOWO.PL //Dołączone biblioteki #include <Wire.h> //Biblioteka I2C #include <LiquidCrystal_I2C.h> //Biblioteka wyświetlacza #include <Keypad.h> //Biblioteka klawiatury //Ustawienie wyświelacza LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); //Ustawnienie klawiatury const byte ROWS = 4; // Ilość wierszy klawiatury const byte COLS = 4; // Ilość kolumn klawiatury byte rowPins[ROWS] = {13, 12, 11, 10}; //numery pinów w arduino dla wierszy byte colPins[COLS] = {9, 8, 7, 6}; //numery pinów w arduino dla kolumn //Podpisanie klawiszy char keys[ROWS][COLS] = { {'A','#','0','*'}, {'B','3','2','1'}, {'C','6','5','4'}, {'D','9','8','7'} }; //Inicjalizacja klawiatury Keypad klawiatura = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); void setup() { Serial.begin(9600); //połączenie z monitorem portu szeregowego lcd.begin(16, 2); //deklaracja typu wyświetlacza lcd.backlight(); // włączenie podwietlenia lcd.setCursor(0,0); //ustawienie kursora w kolumnie 0, lini 0 lcd.print("KALKULATOR"); //Wyświetlanie tekstu lcd.setCursor(0, 1); //ustawienie kursora w kolumnie 0, lini 1 lcd.print("MAJSTERKOWO :)"); //Wyświetlanie tekstu delay(2000); //Odczekanie lcd.clear(); //Wyczyszczenie ekranu } //Zmienne do przechowywania wartości long Numer1,Numer2,Numer; char klawisz,akcja; boolean wynik = false; void loop() { klawisz = klawiatura.getKey(); //pobranie wartości i przypisanie do zmiennej klawisz if (klawisz!=NO_KEY) //jeśli nie ma wartości wzmiennej klawisz WykryjKlawisz(); // wykonaj "WykryjKlawisz" if (wynik==true) //jeśli wartość wynik jest prawdziwa Przelicz(); // wykonaj "Przelicz" Wyswietl(); // wykonaj "Wyswietl" } //Wykryj klawisz void WykryjKlawisz() { lcd.clear(); //wyczyszczenie wyswietlacza if (klawisz=='*') //jeżeli wciśnięty klawisz C { Serial.println ("klawisz c"); //w monitorze portu wyświetl "klawisz c" Numer=Numer1=Numer2=0; wynik=false; //Przypisz 0 do zmiennych Numer, Numer1, Numer2 } if (klawisz == '1') //jeżeli klawisz 1 wciśnięty { Serial.println ("klawisz 1"); // w konsoli wyświetl klawisz 1 if (Numer==0) //jeżeli zmienna jest pusta Numer=1; //zmień wartość zmiennej na 1 else // jeżeli w zmiennej jest już jakaś liczba/cyfra Numer = (Numer*10) + 1; //wpisz 1 za tą liczbą/cyfrą } if (klawisz == '2') { Serial.println ("klawisz 2"); if (Numer==0) Numer=2; else Numer = (Numer*10) + 2; } if (klawisz == '3') { Serial.println ("klawisz 3"); if (klawisz==0) Numer=3; else Numer = (Numer*10) + 3; } if (klawisz == '4') { Serial.println ("klawisz 4"); if (Numer==0) Numer=4; else Numer = (Numer*10) + 4; } if (klawisz == '5') { Serial.println ("klawisz 5"); if (Numer==0) Numer=5; else Numer = (Numer*10) + 5; } if (klawisz == '6') { Serial.println ("klawisz 6"); if (Numer==0) Numer=6; else Numer = (Numer*10) + 6; } if (klawisz == '7') { Serial.println ("klawisz 7"); if (Numer==0) Numer=7; else Numer = (Numer*10) + 7; } if (klawisz == '8') { Serial.println ("klawisz 8"); if (Numer==0) Numer=8; else Numer = (Numer*10) + 8; } if (klawisz == '9') { Serial.println ("klawisz 9"); if (Numer==0) Numer=9; else Numer = (Numer*10) + 9; } if (klawisz == '0') { Serial.println ("klawisz 0"); if (Numer==0) Numer=0; else Numer = (Numer*10) + 0; } if (klawisz == '#') { Serial.println ("klawisz ="); Numer2=Numer; wynik = true; } if (klawisz == 'A' || klawisz == 'B' || klawisz == 'C' || klawisz == 'D') //jeżeli wykryty zostanie klwaisz a, b, c lub d { Numer1 = Numer; Numer =0; if (klawisz == 'A') {Serial.println ("dodawanie"); akcja = '+';} if (klawisz == 'B') {Serial.println ("odejmowanie"); akcja = '-'; } if (klawisz == 'C') {Serial.println ("mnozenie"); akcja = '*';} if (klawisz == 'D') {Serial.println ("dzielenie"); akcja = '/';} delay(100); } } //Przelicz void Przelicz() { if (akcja=='+') Numer = Numer1+Numer2; if (akcja=='-') Numer = Numer1-Numer2; if (akcja=='*') Numer = Numer1*Numer2; if (akcja=='/') Numer = Numer1/Numer2; if (akcja=='/' and Numer2==0) dzieleniePrzezZero(); } void dzieleniePrzezZero(){ Numer1=Numer2=Numer=0; wynik=false; lcd.setCursor(4,1); lcd.print("blad"); } void Wyswietl() { lcd.setCursor(0, 0); lcd.print(Numer1); lcd.print(akcja); lcd.print(Numer2); if (wynik==true){ lcd.print(" ="); lcd.print(Numer); } lcd.setCursor(0, 1); lcd.print(Numer); } |
W kodzie jak możecie zauważyć jest również połączenie z monitorem portu szeregowego po to aby można było sprawdzić czy klawisze są dobrze rozpoznawane.
W zależności od podłączenia przewodów do arduino klawiatura może różnie je wykrywać. W razie potrzeby można zmienić układ klawiszy w poniższych linijkach kodu.
1 2 3 4 5 6 7 |
//Podpisanie klawiszy char keys[ROWS][COLS] = { {'A','#','0','*'}, {'B','3','2','1'}, {'C','6','5','4'}, {'D','9','8','7'} }; |
Po kilku błędach kompilacji przez brakujące przecinki czy literówki w nazwach zmiennych mogłem wreszcie wgrać program do arduino i zacząć bawić się moim “nowym wynalazkiem”.
Tak oto spełniłem swoje małe marzenie z dzieciństwa. Nie jest to co prawda maszynka z NASA a na rynku dostępne są o wiele lepsze kalkulatory, no ale nic tak nie cieszy jak własnoręczna robota, przecież o to chodzi w majsterkowaniu :)
Ps. Proszę o wyrozumiałość ponieważ jest to mój pierwszy post na portalu. Mam nadzieję, że przymiecie mnie do majsterkowej rodzinki i podpowiecie co mógłbym poprawić aby następne posty były coraz lepsze.
Fajne, ale kod to masakra.
Co się stanie przy próbie dzielenia przez zero?
Zrób coś z tym, bo na razie nie mogę ocenić :(
Dzięki za podpowiedź.
Dodałem wyświetlenie błędu przy próbie dzielenia przez zero.
Mógłbyś napisać coś więcej o kodzie, bo za bardzo nie wiem co mam w nim poprawić. Bazuje teraz na wiedzy którą zdobyłem na dodatkowych lekcjach w technikum i cały czas uczę się sam, więc chętnie przeczytam co mogę poprawić. ;)
Sprawa jest prosta….
– używaj bloków instrukcji za pomocą {} przy if-ach żeby później uniknąć sytuacji typu czemu się to nie wykonuje jak powinno;
– jeśli już tak dużo if używasz , to zrób jeden if a następnie else if … a nie tyle if-ów bo strasznie nieczytelne się to staje;
– następnie zamiast tych if-ów zastosuj w przyszłości switch (jest to wtedy bardziej czytelne jak dla mnie !) albo zrób proste przeliczenia, redukując ilość tych if-ów.
Ogólnie projekt spoko :) ale popracuj trochę nad kodem.
Pozdrawiam Piro
Dzięki za porady.
Trochę się podszkolę i mam nadzieję, że przyszłe kody będą już lepsze :)
Dzięki ;)
psst : uzyj odwrotnej notacji polskiej :)
Projekt fajny, lecz tak jak poprzednicy napisali problem z jest z kodem.
Myślę, że jak trochę się podszkolisz to będzie super.
Arduino:1.8.7 (Windows XP), Płytka:”Arduino/Genuino Uno”
sketch_nov24a:10:53: error: ‘POSITIVE’ was not declared in this scope
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
ciągle wyskakuje mi ten błąd .Co robić.
exit status 1
‘POSITIVE’ was not declared in this scope
Ten raport powinien zawierać więcej informacji jeśli w \\\\\\
File -> Preferencje zostanie włączona opcja “Pokaż
szczegółowe informacje podczas kompilacji”
A masz odpowiednią bibliotekę do obsługi LCD? Znaczy bibliotekę: LiquidCrystal_I2C masz w jakiej wersji?
mam wersję v1.2.1
A ściągnąłeś całą bibliotekę? Wszystkie pliki? I dodałeś do arduino ide?
Z tego, co widzę, to w tej wersji biblioteki (sprawdzane na opis=github ), taka wartość jest dopuszczalna.
Nie mam pewności. Czy mógł byś napisać mi krok po kroku jak to prawidłowo zainstalować ,bo naprawdę mam problem.
Postaram się wieczorem napisać. Teraz nie mam za bardzo jak…
I mam jeszcze prośbę. Prześlij mi spakowany do formatu .zip projekt, który Ci nie działa. Znaczy ten plik sketch_nov24a. Mój mail: marhef1@ <- tu wstaw konto na gmail
okey wielkie dzięki wyślę ci ale ten projekt to kalkulator u góry. wyślę potem teraz mam mało czasu.
Właśnie spróbowałem skompilować ten kod. U mnie działa.
Dodałeś te dwie biblioteki tak, jak opisał autor artykułu? Wybierając Szkic -> Dołącz bibliotekę -> Dodaj bibliotekę .ZIP… ?
dodałem ale kilka razy czy to problem i kilka razy ściągałem inne ,jaką ty ściągnołeś wersję LiquidCrystal_I2C
Tą samą co Ty. 1.2.1. I mi też wywalało błąd, ale zupełnie inny niż Tobie.
Spróbuj usunąć wszystkie dodane biblioteki do obsługi LCD (będzie gdzieś w moich dokumentach). Ściągnij tylko tą wersję (1.2.1) z linku autora projektu. Zainstaluj przez Szkic -> Dołącz bibliotekę -> Dodaj bibliotekę .ZIP…
A najlepiej załóż temat na forum, może ktoś inny pomoże :)
A jak zainstalować tą bibliotekę jak nie mogę?
Czy moglibyśćie mi podpowiedzieć stronę o wersjii 1.2.1?
zamiast LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
daj tam to z bilioteki hello world przykład u mie zadziałałLiquidCrystal_I2C lcd(0x27,20,4)