Skocz do zawartości

Dodatkowe ćwiczenia z wyświetlaczem 2x16 znaków


Pomocna odpowiedź

Gość
33 minuty temu, ethanak napisał:

Masz oryginalł Arduino czy klona?

Gdybym miał kupić oryginał, to prawdopodobnie przygoda skończyła by się na sterownikach PLC

Było tanio to kupiłem. Kidy przyszło to nano, to praktycznie jak dla mnie było bezużyteczne. Położyłem go obok monitora (może niepotrzebnie) i za każdym razem kiedy na to patrzyłem to dostawałem złości, że nic z tym nie mogę zrobić. No i tak to się zaczęło.  

37 minut temu, ethanak napisał:

Jak chcesz się poważnie bawić to kup sobie ESP32 DevKit. Najlepiej polskiego klona 30 pinów. 

Najpierw chcę poznać podstawy na tanich zabawkach 8 bit. Słyszałem, że na start edukacji jest to całkiem, całkiem. 

 

1 godzinę temu, ethanak napisał:

2) zawsze możesz zapytać

Pomijając dokładność rezonatora próbuję zaimplementować zegar millis do działania na sekundach. Bez konwersji na którymkolwiek etapie, to nie ma szans. Nawet dla sekund trzeba przeprowadzić operację konwersji do wartości 59. Nie wiem, może mam jakieś zaćmienie związane z nawykami PLC. 

#include <LCD-I2C.h> // https://github.com/hasenradball/LCD-I2C

LCD_I2C lcd(0x27, 16, 2);

unsigned long TT = 0; unsigned long t0 = 0; unsigned long t1 = 0; unsigned long t2 = 0;

void setup() {
  
lcd.begin();
lcd.display();
lcd.backlight();

}

void loop() {

TT = millis();  

t0 = TT / 1000;
t1 = t0 - t2; 
if (t1 > 59) {t2 = t0;}
 
lcd.setCursor(5, 1); lcd.print(t1);
}

Różnica jest taka, że w przypadku sekund program niczego nie zgubi, natomiast jak sekundy przypniesz do konwersji setnych, to bez kompensacji czasu pętli zgubisz ms. W pierwszej wersji sekundy były właśnie przypięte do setnych. 

Nie wiem co kombinujesz.

timems = (millis() - Tstart);
timesec = timems / 1000;
seconds = timesec % 60;
minutes = timesec / 60;

 

I tak dalej.

 


 

 

Gość
(edytowany)
59 minut temu, ethanak napisał:

Nie wiem co kombinujesz.

Nie pomyślałem o tym. W PLC nie ma modulo. A minuty będą prawidłowo pokazywane po przekroczeniu wartości timesec 3600?

P.S.

w PLC też jest modulo tylko pod inną nazwą rozdzielaczy liczby. 

Edytowano przez rafal220

A było tam "i tak dalej"? Naucz się jezyka i rozwiń to do godzin i dni. To nie jest forum dla madków z bombelkami, nie ma "dej".

A że w klockach Lego czegoś nie ma to chyba normalne. Tam przecież też siedzi jakiś wypasiony mikrokontroler - tyle ze ktoś już go zaprogramował i masz dostęp jedynie do aplikacji "PLC". Tu masz inaczej - masz goły mikrokontroler i nie ma żadnych klocków. Trzeba zrobić samemu (ewentualnie posiłkując się bibliotekami).

Dam Ci przykład. Jest na Arduino Uno/Nano biblioteka do syntezy mowy (talkie). Oczywiście mówi tylko po angielsku, i jeszcze trzeba jej fonemy przygotować. Ale mówi. Zrób coś takiego na swoich klockach Lego jeśli nie masz bloczka "speech" czy nawet "klatt". Jakis "audio" też by się przydał ale go nie ma...

A to tylko taki przykład...

Aha, PLC na Arduino istnieje. Co prawda niewiele potrafi, ale na 32 kB flasha i 2 kB ramu to i tak dobrze. Pokaż mi emulator Arduino na PLC.

Gość
2 minuty temu, ethanak napisał:

A było tam "i tak dalej"? Naucz się jezyka i rozwiń to do godzin i dni. To nie jest forum dla madków z bombelkami, nie ma "dej".

myślałem, że masz na myśli to co jest po za minutami. Bo linijka od minut którą zapisałeś  prawdopodobnie zwróci wartość powyżej 60.  Ale poradzę sobie z tym. Na razie zobaczyłem w praktyce same sekundy. Tutaj też trzeba to rozbić na 2 modulo 6 i 10, bo wyjdą bzdury na wyświetlaczu. 

 

6 minut temu, ethanak napisał:

Dam Ci przykład. Jest na Arduino Uno/Nano biblioteka do syntezy mowy (talkie). Oczywiście mówi tylko po angielsku, i jeszcze trzeba jej fonemy przygotować. Ale mówi. Zrób coś takiego na swoich klockach Lego jeśli nie masz bloczka "speech" czy nawet "klatt". Jakis "audio" też by się przydał ale go nie ma...

  Trzeba by zerknąć do not katalogowych nowości na rynku z obsługą kart SD. Ale w ciemno nie powiem, bo żeby dostać kompilator, to najpierw trzeba kupić sterownik. Wiem że te nowsze mają fajne opcje tj. rozpoznawanie mowy poleceń itd. Ale nie chcę się wypowiadać co  do szczegółów nie posiadając urządzenia. 

Na razie wykonuję ćwiczenia na nano by stwierdzić czy Arduino jest na moje siły.

5 minut temu, rafal220 napisał:

Na razie wykonuję ćwiczenia na nano by stwierdzić czy Arduino jest na moje siły.

Pewnie że jest, tylko przeczytaj kursy i powoli się ucz, czasem wszystko załapiesz...

Gość
4 minuty temu, farmaceuta napisał:

Pewnie że jest, tylko przeczytaj kursy i powoli się ucz, czasem wszystko załapiesz...

Dzięki.

Pierwsze ćwiczenia z Arduino dają pozytywne wrażenie. 🙂

Gość
1 godzinę temu, ethanak napisał:

A było tam "i tak dalej"? Naucz się jezyka i rozwiń to do godzin i dni.

Dni sobie odpuszczę, bo to stoper, aczkolwiek zasada deklaracji jest podobna. 

Czyli rozwiązaniem do tego zadania jest coś w tym stylu;

#include <LCD-I2C.h> // https://github.com/hasenradball/LCD-I2C

LCD_I2C lcd(0x27, 16, 2);

volatile byte sw1 = 0; volatile byte sw2 = 0;

unsigned long TT = 0; unsigned long t0 = 0; unsigned long t1 = 0;

unsigned long a0 = 0; unsigned long a1 = 0; unsigned long a2 = 0;
unsigned long a3 = 0; unsigned long a4 = 0; unsigned long a5 = 0;
unsigned long a6 = 0; unsigned long a7 = 0; unsigned long a8 = 0;

uint8_t sym1[8] = {0b01100, 0b00100, 0b00110, 0b01100, 0b00100, 0b00100, 0b01110, 0b00000,}; // 'ł'
uint8_t sym2[8] = {0b00100, 0b00010, 0b01001, 0b00001, 0b01001, 0b00010, 0b00100, 0b00000,}; // ':)'
uint8_t sym3[8] = {0b11011, 0b01001, 0b10010, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000,}; // '"'

void setup() {
 
lcd.begin();
lcd.display();
lcd.backlight();

pinMode(2, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(2), Start, FALLING);
pinMode(3, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(3), Stop, FALLING);
pinMode(4, INPUT_PULLUP);

lcd.createChar(0, sym1); lcd.setCursor(8, 0); lcd.write(0);
lcd.createChar(1, sym2); lcd.setCursor(10, 0); lcd.write(1);
lcd.createChar(1, sym2); lcd.setCursor(12, 0); lcd.write(1);

lcd.setCursor(4, 0);
lcd.print("Rafa");
lcd.setCursor(4, 2); lcd.print("forbot.pl");

delay(4000);

lcd.clear();

lcd.setCursor(6, 0); lcd.print("CZAS");
lcd.createChar(2, sym3); lcd.setCursor(10, 1); lcd.write(2);

}

void loop() {
  
byte sw3 = digitalRead(4);

TT = millis();

if (sw1 == 1) {t1 = TT - t0;}     
else {t0 = TT - t1; sw2 = 0;}   // Stoper start

if (sw2 == 1) {sw1 = 0;}  // Stoper stop

if (sw3 == 0) {sw1 = 0; sw2 = 0; t1 = 0;} // stoper reset    

a1 = (t1 / 100) % 10;   // setne
a2 = (t1 / 10) % 10;
            
a3 = (t1 / 10000) % 6;  // sekundy 
a4 = (t1 / 1000) % 10;

a5 = (t1 / 600000) % 6;   // minuty
a6 = (t1 / 60000) % 10;

a7 = (t1 / 36000000) % 10;  // godziny
a8 = (t1 / 3600000) % 10;

lcd.setCursor(11, 1); lcd.print(a1); // setne
lcd.setCursor(12, 1); lcd.print(a2); 

lcd.setCursor(8, 1); lcd.print(a3); // sekundy
lcd.setCursor(9, 1); lcd.print(a4);

lcd.setCursor(7, 1); lcd.print("'");

lcd.setCursor(5, 1); lcd.print(a5); // minuty
lcd.setCursor(6, 1); lcd.print(a6);

lcd.setCursor(4, 1); lcd.print(':');

lcd.setCursor(2, 1); lcd.print(a7); // godziny
lcd.setCursor(3, 1); lcd.print(a8);

}

void Start() { 
sw1 = 1;
}
void Stop() { 
sw2 = 1;
}

pomijając, że przydałby się jakiś kurs odnośnie tego co pisał kolega @_LM_. Czyli jak zadeklarować ilość n zmiennych w tym samym ciągu, albo wysłać n zmiennych na wyświetlacz przy jednorazowym odświeżeniu. No i tutaj też dla godzin wychodzą duże liczby, ale wiem że gdzieś mi się rzuciło w oczy operowanie na potęgach. Muszę tylko sobie przypomnieć gdzie to było, bo za pierwszym razem nie zapamiętałem, ale wiem że cos takiego jest.  

(edytowany)

@rafal220 ja bym na twoim miejscu ruszył i zatrzymał czas w przerwaniu...teraz ustawiasz tylko flagi do warunków i musisz czekać aż kod "dotrze" do nich...nie ma sensu co pętlę przypisywać czasu millis()...poczytaj też o "debouncing" bo napewno temat Cię dopadnie w przypadku używania guzików 

Edytowano przez farmaceuta
Gość
(edytowany)
1 godzinę temu, farmaceuta napisał:

poczytaj też o "debouncing" bo napewno temat Cię dopadnie w przypadku używania guzików

ten temat akurat jest mi dobrze znany ze sterowników PLC. Mówiąc prościej zjawisko mikro stykowe, czy też inaczej zwane szumami łączeniowymi. Akurat w przypadku tego kodu nie ma ono większego znaczenia.

1 godzinę temu, farmaceuta napisał:

ja bym na twoim miejscu ruszył i zatrzymał czas w przerwaniu...teraz ustawiasz tylko flagi do warunków i musisz czekać aż kod "dotrze" do nich...

No to tak przecież jest aktualnie zrobione. Chyba że masz na myśli wklejenie w przerwaniach całych warunków do których odnoszą się zmienne  sw1 i sw2. 

1 godzinę temu, farmaceuta napisał:

nie ma sensu co pętlę przypisywać czasu millis()

  W pierwszej wersji było stopniowanie liczników, ale program zajął tyle samo pamięci flash  i ramu.  No chyba że taki zabieg przyśpieszy szybkość programu.  

P.S.

Co do mikro drgań styków, to mam taki kod. Jak na razie działa ;


unsigned long TT = 0; unsigned long t0 = 0; unsigned long t1 = 0;

byte d1 = 0;

void setup() {
  
pinMode(2, INPUT_PULLUP);

}

void loop() {

int sw1 = digitalRead(2);
TT = millis();

if (sw1 == 0) {t0 = TT - t1; if (t0 > 30) {d1 = 1;}}
else {t1 = TT; d1 = 0;}

}

 

Edytowano przez rafal220
(edytowany)

Jeśli zastosujesz obsługę przerwań podaną wczoraj przez @ethanaka, to automatycznie pozbędziesz się problemu drgań styków. Ewentualne dodatkowe przerwania mogą się co prawda pojawić, ale ze względu na zastosowanie zmiennej "running" nie będą miały efektu.

I jeszcze raz - proces pomiaru czasu powinien być odrębny od procesu wyświetlania. Wszelkie opóźnienia w tym drugim nie mają znaczenia. 

Edytowano przez jand
(edytowany)
12 godzin temu, rafal220 napisał:

trzeba to rozbić na 2 modulo 6 i 10, bo wyjdą bzdury na wyświetlaczu.

No i znów kwestia nieznajomości języka...

Ale zacznijmy od czegoś innego. Przede wszystkim zacznij jakoś nazywać te swoje zmienne - być może w świecie programistów klocków Lego nazywanie zmiennych w stylu "t1", "x1" to dobry zwyczaj, być może Twoim pierwszym językiem programowania był Basic na C64 i tak zostało... ale uwierz, za miesiąc jak spojrzysz na własny kod nie będziesz za nic go rozumiał.

No i teraz obliczanie zmiennych sekundy, minuty i tak dalej.

Załóżmy że mamy zmienną Tstart zawierającą moment startu pomiaru w milisekundach.

int secs, mins, hours; // tu będziemy sobie trzymać wiadomo co
uint32_t T = millis() - Tstart;  // czyli wiemy ile czasu minęło od początku pomiaru

//obliczymy sobie teraz te trzy zmienne
T=T/1000 ; // czyli milisekundy na sekundy
secs = T % 60;
T=T / 60; // tu mamy ilość minut od startu
mins = T % 60;
T = T / 60 ; //a teraz ilość godzin od startu
hours = T % 100; dlaczego?

Na razie nie wychodzę poza materiał z kursu Arduino - ale przecież kurs nie zawiera wszystkiego, prawda? To jak kurs na prawo jazdy - nauczysz się jako tako jeździć, w dobrych warunkach zaparkujesz, po pewnym czasie zaczniesz również skręcać w lewo...[1] ale tak naprawdę jeździć będziesz dopiero po pewnym czasie.

A w skład języka programowania wchodzą nie tylko składnia i semantyka, ale również coś co nazywa się "biblioteki standardowe". Funkcji z tych bibliotek jest dość dużo, niekoniecznie trzeba znać wszystkie, ale warto poczytać sobie choćby o avr-libc (czyli funkcjach których możesz użyć programując swoje Nano w C/C++, niekoniecznie używając Arduino IDE). Taką przykładową biblioteką jest stdio, i zawarta w niej funkcja sprintf.

Oczywiście nie będę tu przepisywał dokumentacji, możesz sobie zerknąć do manuala z linku powyżej. Ważne jest to, że sprintf służy do formatowania tekstu.

I teraz spróbujmy jej użyć.

char bufor[9]; // dlaczego 9?
sprintf(bufor,"%02d:%02d:%02d", hours, mins, secs);
lcd.setCursor(gdzieś tam); // tu sobie wstawisz gdzie
lcd.print(bufor);

To tak jak z Twoimi klockami Lego - używam funkcji standardowych, czyli tak jakby tych Twoich ukochanych bloczków.

Oczywiście można nie używać zmiennych pomocniczych hours, mins i secs ale wyjdzie z tego jakiś mało zrozumiały jednolinijkowiec.

A poza tym mam prośbę do @Treker - możesz tę całą dyskusję o wyższości PLC nad Arduino przenieść do osobnego wątku? Bo trudno się nie zgodzić że kolega @rafal220 może z tego skorzystać i czegoś tam się naumieć, ale ni czorta nie pasuje to do tematu całego wątku...

--

[1] można nie skręcać w lewo tylko robić objazdy skręcając wyłącznie w prawo. Coś ktoś mówił swego czasu o operatorach logicznych?

 

Edytowano przez ethanak
Gość
2 godziny temu, ethanak napisał:

Ale zacznijmy od czegoś innego. Przede wszystkim zacznij jakoś nazywać te swoje zmienne

Do tego trzeba mieć bardzo dobrą pamięć. Gdybyś zauważył kod dzielę na linijki/ grupy linijek do których dodaję komentarz. Przy dłuższym kodzie można dać nieco inne nazwy zmiennych wyprowadzających...

3 godziny temu, ethanak napisał:

ale uwierz, za miesiąc jak spojrzysz na własny kod nie będziesz za nic go rozumiał.

Tutaj to jeszcze jest nic. Zobaczyłbyś siatkę. Tam można się totalnie zakręcić. Trzeba robić bloki i podbloki + opisy, by w miarę szybko się odnaleźć. Analogicznie to tak jakbyś łączył ze sobą całe mini biblioteki które wcześniej przygotowałeś. Tworzysz tzw. stopniowaną redukcję kawałków które łączysz ze sobą i zamykasz. Gdybyś w grafice wszystko naraz władował na jedną stronę i byłoby tego minimum kilkaset, to obawiam się, że nie po miesiącu, a po kilku dniach byś się w tym wszystkim zaczął gubić. No chyba że masz mega mocną pamięć wzrokowo-logiczną. 

Na razie zmienne będę opisywać tak, aby szybciej ogarnąć podstawy tego Arduino. Jeżeli dodatkowo zacznę wymyślać jakieś nazewnictwo zmiennych w języku którego praktycznie nie znam (w szkole był rosyjski i tylko rosyjski wszelkie inne języki obce były bee) to będzie to wszystko jeszcze bardziej oporne.

3 godziny temu, ethanak napisał:

Załóżmy że mamy zmienną Tstart zawierającą moment startu pomiaru w milisekundach.

Czyli dzielisz czas przez siebie wyciągając modulo z sekund, minut i godzin. No jest to prostsze, ale jak widzisz muszę sobie trochę myślenie dostosować. To tak jak przesiadka z fiata 126P na BMW.

 I teraz spróbujmy jej użyć.

char bufor[9]; // dlaczego 9?

Trudno jest od tak raz czytając zapamiętać cały kurs. Ale gdzieś to rzuciło mi się w oczy. Liczba oznacza ilość znaków char, a jak nic nie wstawisz w nawiasie, to kompilator powinien wstawić. Tylko w tym przypadku jak za nawiasem kwadratowym nic nie ma, to trzeba chyba to określić. Znaków sekund minut i godzin jest 8, czemu 9? Gdzieś tam wyczytałem że daje się o jeden więcej, ale dlaczego? nie było wyjaśnione.

 

3 godziny temu, ethanak napisał:
"%02d:%02d:%02d"

Tej linijki kompletnie nie rozumiem. Nawet jeżeli jest to kod znaku który znajduje się pomiędzy sekundami, minutami i godzinami, to nadal nie rozumiem tej składni. 

3 godziny temu, ethanak napisał:

o tak jak z Twoimi klockami Lego - używam funkcji standardowych, czyli tak jakby tych Twoich ukochanych bloczków.

W przypadku zmiennych wyjściowych tj. switch = sw. W tym przypadku użyłbym zmiennych s, m i h. albo sec, min i hur. 

 

3 godziny temu, ethanak napisał:

Na razie nie wychodzę poza materiał z kursu Arduino - ale przecież kurs nie zawiera wszystkiego, prawda? To jak kurs na prawo jazdy - nauczysz się jako tako jeździć, w dobrych warunkach zaparkujesz, po pewnym czasie zaczniesz również skręcać w lewo...[1] ale tak naprawdę jeździć będziesz dopiero po pewnym czasie.

Nie no ok. W materiale było tylko o wyświetlaczu. A na przykładzie stopera można dalej kontynuować wątek jego obsługi.

 

3 godziny temu, ethanak napisał:

A w skład języka programowania wchodzą nie tylko składnia i semantyka, ale również coś co nazywa się "biblioteki standardowe". Funkcji z tych bibliotek jest dość dużo, niekoniecznie trzeba znać wszystkie, ale warto poczytać sobie choćby o avr-libc (czyli funkcjach których możesz użyć programując swoje Nano w C/C++, niekoniecznie używając Arduino IDE). Taką przykładową biblioteką jest stdio, i zawarta w niej funkcja sprintf.

Ale tam trzeba będzie  dodać jakąś bibliotekę do obsługi bootloadera ?  Inaczej to nie pójdzie. No chyba że hex po SPI, ale wówczas nadpiszę obecnego bootloadera, i trzeba będzie go znowu wgrywać. Oczywiście problemu nie ma, ale jest jedno ale. Jakiś rok do tyłu kupiłem tiny13 ponieważ chciałem wypróbować (nie pamiętam nazwy) środowisko IDE w C++ Ale nie było żadnych konkretnych poradników do tego i odinstalowałem. W przypadku tego C/C++ to IDE ma jakąś konkretną nazwę?

52 minuty temu, rafal220 napisał:

Jeżeli dodatkowo zacznę wymyślać jakieś nazewnictwo zmiennych w języku którego praktycznie nie znam

Nic nie stou na przeszkodzie by nazwy zmiennych były po polsku. 

Nie chodzi tu o jakiś konkretny język, tylko o to by nazwa w sposób zrozumiały opisywała to, co sobą reprezentuje. Wtedy po kilku miesiącach masz szansę zrozumieć, "co autor miał na myśli". 

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...