Skocz do zawartości

slon

Użytkownicy
  • Zawartość

    130
  • Rejestracja

  • Ostatnio

Reputacja

87 Bardzo dobra

O slon

  • Ranga
    5/10

Informacje

  • Płeć
    Mężczyzna

Ostatnio na profilu byli

Blok z ostatnio odwiedzającymi jest wyłączony i nie jest wyświetlany innym użytkownikom.

  1. Co do chłodzenia to można by się zdziwić. Jeden z rekordów w podkręcaniu został ustanowiony na chłodzeniu powietrzem :). Jak dobrze pamiętam do było to za czasów gdy miałem zainstalowaną dystrybucję Mandrake. Co do zasilacza to swego czasu robiłem testy stabilności napięcia na linii 12V. Nie pamiętam nazwy programu ale chodziło o to , że miałem podgląd pod to jak zmienia się to napięcie przy różnym obciążeniu i czasie. Na ile takie testy są poprawne to trudno mi powiedzieć.
  2. Część trzecia będzie w pewnym stopniu nawiązywać do części pierwszej od strony szkicu oraz do części drugiej od strony schematu połączenia w simulIDE. W zasadzie zawarta tu treść miała znaleźć się w części drugiej aczkolwiek chciałem połączyć całość w czytelny sposób co w pewnym stopniu się udało ale nie do końca tak jak chciałem. Założenie było takie aby wyświetlić przewijany tekst z wykorzystaniem materiałów z wcześniejszych części. Przejdźmy więc do schematu. Spis treści serii artykułów: Matryca led: podstawy, proste wyświetlanie znaków - część 1 Matryca led: podstawy, proste wyświetlanie znaków - część 2 Matryca led: podstawy, proste wyświetlanie znaków - część 3 Trochę to dziwne jeśli chodzi i ten wyświetlacz aczkolwiek lepszego sposobu na ustawienie "linijek" led nie znalazłem. To co powinno się znajdować na schemacie lub to co nas interesuje to dwanaście linijek po osiem diod led. Gdybym ustawił w ten sposób "liniki" w sumulIDE do nic nie było by widać i pewnie nawet nie dało by się tego połączyć. Dlatego taka kombinacja , że każda kolejna linijka jest wyższa o trzy punkty. Całość wygląda tak: Nie należy przejmować się jakością tej grafiki (pliki do simulIDE na końcu artykułu). Rejestrów jest tyle co "linijek". Przejdźmy teraz do kodu: #define LATCH_PIN_MODE DDRB #define CLOCK_PIN_MODE DDRB #define DATA_PIN_MODE DDRB #define LATCH_PIN_STATE PORTB #define LATCH_PIN 12//stc #define CLOCK_PIN 13 //shc #define DATA_PIN 8 //ds #define LITERA_ALFABETU 26 /* każda z liter ma trzy kolumny + dwie kolumny w celu odseparowania liter i zwiększenia czytelności */ #define KOLUMNA_LITERY 5 const uint8_t litera[LITERA_ALFABETU][KOLUMNA_LITERY] = { /*----------litera A-----------*/ { 0b11111000, // COL_1 0b01010000, // COL_2 0b00111000, },// COL_3 /*----------litera B-----------*/ { 0b11111000, 0b10101000, 0b01010000 }, //B /*----------litera C-----------*/ { 0b11111000, 0b10001000, 0b00000000 }, //C /*----------litera D-----------*/ { 0b11111000, 0b10001000, 0b01110000 }, //D /*----------litera E-----------*/ { 0b11111000, 0b10101000, 0b00000000 }, //E /*----------litera F-----------*/ { 0b11111000, 0b10100000, 0b00000000 }, //F /*----------litera G-----------*/ { 0b01111000, 0b10001000, 0b10110000 }, //G /*----------litera H-----------*/ { 0b11111000, 0b00100000, 0b11111000 }, //H /*----------litera I-----------*/ { 0b00000000, 0b11111000, 0b00000000 }, //I /*----------litera J-----------*/ { 0b00010000, 0b00001000, 0b11110000 }, //J /*----------litera K-----------*/ { 0b11111000, 0b00100000, 0b01011000 }, //K /*----------litera L-----------*/ { 0b11111000, 0b00001000, 0b00000000 }, //L /*----------litera M-----------*/ { 0b11111000, 0b01100000, 0b11111000 }, //M /*----------litera N-----------*/ { 0b11111000, 0b01000000, 0b11111000 }, //N /*----------litera O-----------*/ { 0b01110000, 0b10001000, 0b01110000 }, //O /*----------litera P-----------*/ { 0b11111000, 0b10100000, 0b01000000 }, //P /*----------litera Q-----------*/ { 0b01100000, 0b10010000, 0b01101000 }, //Q /*----------litera R-----------*/ { 0b11111000, 0b10100000, 0b01011000 }, //R /*----------litera S-----------*/ { 0b01101000, 0b10101000, 0b10110000 }, //S /*----------litera T-----------*/ { 0b10000000, 0b11111000, 0b10000000 }, //T /*----------litera U-----------*/ { 0b11111000, 0b00001000, 0b11111000 }, //U /*----------litera V-----------*/ { 0b11110000, 0b00001000, 0b11110000 }, //V /*----------litera W-----------*/ { 0b11111000, 0b00010000, 0b11111000 }, //W /*-----------litera X----------*/ { 0b11011000, 0b00100000, 0b11011000 }, //X /*-----------litera Y----------*/ { 0b11000000, 0b00111000, 0b11000000 }, /*---------- Litera Z ---------*/ { 0b10011000, 0b10101000, 0b11001000 }, //Z }; void setup() { DATA_PIN_MODE |= 0b00000001; // D8 OUTPUT LATCH_PIN_MODE |= 0b00010000; //D12 OUTPUT CLOCK_PIN_MODE |= 0b00100000; //D13 OUTPUT } void loop() { for (int j = 0; j < LITERA_ALFABETU; j++) { for (int i = 0; i < KOLUMNA_LITERY; i++) { LATCH_PIN_STATE &= 0b00101111; //LOW shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, litera[j][i]); LATCH_PIN_STATE ^= 0b00010000; // HIGH delay(75); } } } Zgodnie z tym co pisałem na początku artykułu bazujemy na lekko zmodyfikowanym szkicu z części pierwszej. W tej wersji jest tylko jedna tablica litera[x][x]. Do wysyłania kolejnych bajtów (kolumn litery) została użyta funkcja znana z arduino IDE czyli shiftOut(); shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, litera[j][i]); W takiej postaci bajt jest wysyłany od najbardziej znaczącego bitu( pierwszy od lewej) most significant bit (MSB). Jaki będzie efekt takiej podmiany zapewne wiele osób wie ale jeśli ktoś nie wie to warto pogłówkować zanim sprawdzi się w symulatorze . W załączniku pliki shift595_x3_Leds.zip Spis treści serii artykułów: Matryca led: podstawy, proste wyświetlanie znaków - część 1 Matryca led: podstawy, proste wyświetlanie znaków - część 2 Matryca led: podstawy, proste wyświetlanie znaków - część 3
  3. Wymień baterię dużo nie kosztuje. Nowa powinna mieć ponad 3 V. Tyle mogę podpowiedzieć co do zapisywania ustawień BIOS. Co do samego podkręcania to niewiele ci powiem. Kiedyś podkręcałem przez mnożnik , FSB ale to czasem trzeba lepsze chłodzenie albo zasilacz itp (więc wolę ustawienia fabryczne)
  4. Druga część artykułu będzie poświęcona na krótkie omówienie rejestru przesuwnego (z takim określeniem spotkałem się w literaturze) 74HC595. Zagadnienie to chciałem zawrzeć w pierwszej części ale się nie udało. Dlatego teraz kontynuuję jako kolejną część pod tym samym tytułem. Temat nie jest na forum nowy ale warty odświeżenia. W/w układ jest dostępny w bardzo przystępnej cenie i daje też ciekawe możliwości. Podobnie jak ostatnio użyję symulatora SimulIDE aczkolwiek z góry też zaznaczę , że w rzeczywistości też sprawdziłem działanie układu. Podobnie jak poprzednio zaczniemy od podejścia manualnego. Spis treści serii artykułów: Matryca led: podstawy, proste wyświetlanie znaków - część 1 Matryca led: podstawy, proste wyświetlanie znaków - część 2 Matryca led: podstawy, proste wyświetlanie znaków - część 3 To będzie nasz układ testowy czyli trzy rejestry połączone w jeden łańcuch. Z góry zaznaczam , że kwadraty po prawej należy traktować jako podłączone do mikrokontrolera czyli na ten moment mamy stan LOW. Zgodnie z tym co podaje karta katalogowa piny od Data_Pin po Reset muszą być podłączone. Inaczej mówiąc musi być tam stan HIGH lub LOW w innym wypadku nasz układ nie będzie działał lub będzie działał niepoprawnie. Teraz pora zapoznać się z wprowadzaniem danych do rejestru (czyli 1 lub 0). Na początek musimy ustawić stan wysoki na pinie DS czyli nasz Data_Pin następnie ustawiamy stan wysoki na pinach MR czyli Reset (tutaj wszystkie są połączone razem). Teraz pora wprowadzić. W tym celu ustawiamy stan wysoki na pinie SHC czyli Clock_PIN I ponownie zmieniamy stan pinu SHC na niski. I to już prawie tyle Ostatnia czynność jaka nam została to ustawienie stanu wysokiego na pinie STC czyli Latch_Pin. I jak widać mamy aktywne wyjście Q0. Jeżeli chcemy ustawić stan wysoki na pinie Q1 to musimy ustawić stan niski na Latch_Pin i powtórzyć resztę procedury czyli Clock_Pin HIGH, Clock_PIN LOW, Latch_Pin HIGH. Teraz gdyby chcieć przełożyć działanie tego rejestru na codzienne życie ta dla mnie najlepiej kojarzy się to z zajęciami w szkole czyli: Dzwoni dzwonek na lekcję. Przychodzi pani/pan nauczyciel i otwiera klasę (ustawiamy Latch_PIN LOW). Następnie do klasy wchodzą uczniowie czyli stan osób zaczyna się zmieniać (również my zmieniamy stan na Pinie Clock_PIN HIGH i ponownie LOW). W momencie gdy wszyscy uczniowie weszli do klasy pani/pan nauczyciel zamyka drzwi (my ustawiamy Latch_Pin w na HIGH). Teraz sprawdzana jest obecność ale kilku osób brakuje więc i my musimy to w jakiś sposób zaznaczyć w naszym rejestrze. Zrobimy to wprowadzając zero: Postępujemy podobnie jak w poprzednim przykładzie z tym , że tym razem zmieniamy stan na pinie Data_Pin na niski. I ponownie Clock_Pin HIGH Clock_PIN LOW I proszę nasza jedynka przesunęła się o jedno miejsce do przodu. Skończyliśmy na sprawdzaniu listy. Wiadomo po sprawdzeniu listy zaczyna się lekcja. Podobnie w naszym wypadku ustawiany jest stan na pinach rejestru Q0....Q7 oraz Q7'. Z tym , że aby ten stan mógł być ustawiony musimy mieć pin OE czyli Output_Enable ustawiony w stan niski. W przeciwnym wypadku czyli jeśli mamy pin Out_En ustawiony na HIGH nasze wyjścia przestają być aktywne zachowują się tak jak by nie były do niczego podłączone czyli HIGH IMPEDANCE czyli niema tam ani 0 ani 1. Przy czym należy zaznaczyć , że stan rejestru jest zachowany. To tak jakby nauczyciel przerwał zajęcia i wyszedł z klasy. Zajęcia się nie odbywają ale ilość uczniów w klasie pozostaje taka sama. Nauczyciel po powrocie do kasy kontynuuje lekcję z tą samą ilością uczniów. I podobnie w naszym wypadku jeśli ponownie ustawimy pin Out_En na LOW będziemy mieli te same aktywne wyjścia. Tutaj pojawia się kolejna ciekawa możliwość. W trakcie gdy pin Out_en jest ustawiony na HIGH czyli wyjścia są nieaktywne możemy wprowadzić do rejestru nowe dane a po ustawieniu stanu LOW na pinie Out_en zobaczymy nową konfigurację dla wyjść. Można by to porównać do sytuacji gdy nauczyciel wychodzi z klasy a w trakcie jego nieobecności do klasy dochodzi jeden uczeń. Nauczyciel po powrocie do klasy aktualizuje listę obecności o jednego ucznia więcej i wznawia lekcję. Piny Out_en mogą być połączone razem tak jak na schemacie lub każdy oddzielnie (wtedy możemy kontrolować piny dla każdego z tych rejestrów oddzielnie). Pin MR czyli Reset działa inaczej. Jak zapewne większość osób się domyśla pin ten jest odpowiedzialny za kasowanie rejestru. Aby zresetować nasz rejestr należy kolejno ustawić pin MR na LOW i ustawić Latch_Pin na HIGH. I tu ponownie taka analogia do zajęć lekcyjnych czyli kończy się lekcja uczniowie wychodzą z klasy drzwi są zamykane i klasa zostaje pusta. Dla lepszego zrozumienia tematu najlepiej będzie poćwiczyć Arduino całkiem dobrze nada się do celów ćwiczebnych chodziarz nie ukrywam , że metody z przyciskami bez arduino też są dobre. Pin którego jeszcze nie omówiliśmy to Q7' czyli pin na którym pojawia się stan wysoki w momencie gdy na pinie Q7 jest stan wysoki. Dlatego też pin Q7' z pierwszego rejestru jest podłączony z pinem DS czyli Data_Pin drugiego rejestru. Czyli rejestr drugi odbiera od pierwszego a trzeci od drugiego. #define LATCH_PIN_MODE DDRB #define CLOCK_PIN_MODE DDRB #define DATA_PIN_MODE DDRB #define LATCH_PIN_STATE PORTB #define CLOCK_PIN_STATE PORTB #define DATA_PIN_STATE PORTB void setup() { DATA_PIN_MODE |= 0b00000001; // D8 OUTPUT LATCH_PIN_MODE |= 0b00010000; //D12 OUTPUT CLOCK_PIN_MODE |= 0b00100000; //D13 OUTPUT } void loop() { LATCH_PIN_STATE &= 0b00101111; // LOW DATA_PIN_STATE ^= 0b00000001; // TOGGLE kratka CLOCK_PIN_STATE |= 0b00100000; // HIGH CLOCK_PIN_STATE ^= 0b00100000; // LOW LATCH_PIN_STATE ^= 0b00010000; // HIGH delay(500); } Kod dla w/w schematu jak widać jest bardzo prosty. Robimy dokładnie to samo co wcześniej tylko już sami nie klikamy. tutaj typowa linijka oraz kod poniżej. void loop() { LATCH_PIN_STATE &= 0b00101111; // LOW DATA_PIN_STATE |= 0b00000001; // HIGH linijka CLOCK_PIN_STATE |= 0b00100000; // HIGH CLOCK_PIN_STATE ^= 0b00100000; // LOW LATCH_PIN_STATE ^= 0b00010000; // HIGH delay(500); } Polecam w w/w schemacie ustawić stan wysoki na jednym pinie OE (najlepiej dla środkowego rejestru) i zobaczyć co będzie się działo dla jednego i drugiego kodu. Następnie przywrócić stan niski na pinie OE a pin MR (też tylko dla środkowego rejestru) ustawić na LOW. Można dojść do ciekawych wniosków np: można podpiąć drugi taki sam łańcuch z trzema rejestrami do tych samych pinów arduino a efekty mogą być różne. Podobnie jak ostatnio dodaje pliki do SimulIDE shift595_schematic.zip Spis treści serii artykułów: Matryca led: podstawy, proste wyświetlanie znaków - część 1 Matryca led: podstawy, proste wyświetlanie znaków - część 2 Matryca led: podstawy, proste wyświetlanie znaków - część 3
  5. @Treker zgadza się pojawiła się opcja edycji. Cały artykuł aktualizowałem nawet fajnie to wyszło ale po kliknięciu w Aktualizuj pojawił się czarny ekran z informacją , że artykułu niemożna dłużej aktualizować. Zmiany, które wprowadziłem nie zostały zapisane (ja też nie mam ich zapisanych) więc trudno.
  6. Ten wpis bierze udział w konkursie na najlepszy artykuł o elektronice lub programowaniu, którego partnerem jest firma PCBWay (popularny producent prototypów PCB). W puli nagród karty podarunkowe Allegro o wartości 2300 zł. Sprawdź więcej informacji na temat konkursu » Temat z pewnością nie jest nowością na forum aczkolwiek postanowiłem spróbować opisać go w sposób trochę inny a czy bardziej przydatny to już ocenią inni. W ostatnim czasie pojawiła się seria świetnych artykułów autorstwa elwisa na temat wyświetlaczy TFT. Ten artykuł piszę w celu jak najprostszego przedstawienia zagadnienia matryc led co oznacza ograniczenie stosowanych elementów do minimum. Analogiczna sytuacja tyczy się sterowania matrycą czyli szkicu. Całość została wykonana w SimulIDE a więc w zasadzie każdy będzie mógł sobie to przećwiczyć. Zaczniemy od złożenia samej matrycy 5 rządów 3 kolumny. Spis treści serii artykułów: Matryca led: podstawy, proste wyświetlanie znaków - część 1 Matryca led: podstawy, proste wyświetlanie znaków - część 2 Matryca led: podstawy, proste wyświetlanie znaków - część 3 Aby wykonać taką matryc przeciągamy elementy z lewej strony symulatora będą to kolejno: Sources -----> Fixed Volt. Sources -----> Ground Switches -----> Switch Dip x2 Passive -------> Resistor Dip Outputs -------> Led Klikając prawym przyciskiem myszy na dany element możemy dostosować jego właściwości wybierając Properties. W naszym wypadku wystarczy , że zmodyfikujemy liczbę Dip Switchy do 5 rzędów i 3 dla kolumn. Możemy również dostosować wartość rezystora. W celu szybkiego złożenia matrycy polecam ustawić jedną kolumnę ledów a następnie skopiować dwa i połączyć całość tak ja na rysunku. Jeśli mamy już wszystko gotowe włączamy symulację (czerwony przycisk na górnej belce) i włączamy zasilanie naszego układu. Jeśli mamy wszystko dobrze podłączone to zaświecą się nam wszystkie ledy. Wyłączmy teraz dwie kolumny (obojętnie które) klikając w zielone kwadraty. Następnie wyłączmy kolejno rzędy. A teraz zadanie chcemy wyświetlić literę Z. Można by nad tym trochę pogłówkować ale jak by nie patrzeć albo raczej jak by nie naciskać w te zielone kwadraty to litery Z nie zobaczymy. Ale gdyby tak się dało klikać w te kwadraty tak szybko , że na rzędach ustalali byś my wzór który następnie był by przenoszony na każdą kolumnę z osobna to coś by z tego pewnie wyszło. Żeby zrobić to samo u siebie najprościej skopiować cały schemat i wkleić dwa razy. Teraz to jeszcze nie wygląd jak litera Z ale już niedużo do tego brakuje. Oczywiście do wykonania tego zadania zaprzęgniemy arduino uno (jeśli ktoś preferuje czystą atmege328p to też jest taka możliwość). No proszę mamy naszą literę Z. Teraz pora przejść do szkicu. #define ROW_PIN_MODE DDRD #define ROW_PIN_STATE PORTD #define COL_PIN_MODE DDRB #define col_1 2 #define col_2 4 #define col_3 8 #define ALL_ROWS_OUTPUT 252 #define ALL_ROWS_LOW 0 /*tablica z kolumnami matrycy*/ const uint8_t col[3] = {col_1, col_2, col_3}; /*tablica z kolumnami litery dla litery Z*/ const uint8_t literaZ[3] = {152, 168, 200}; void setup() { ROW_PIN_MODE = ALL_ROWS_OUTPUT; } void loop() { /*pętla skanująca kolumny matrycy i kolumny litery*/ for (int i = 0; i < 3; i++) { COL_PIN_MODE = col[i]; ROW_PIN_STATE = literaZ[i] >> 1; delay(2); ROW_PIN_STATE = ALL_ROWS_LOW; } } Poprawność wyświetlania znaków w symulatorze możemy sprawdzić włączając symulację a następnie klikając w ikonkę Debug i przechodzimy linijka po linijce Jak widać wszystko wyświetla się tak jak powinno. Na wstępie do operacji na bitach wykorzystamy kalkulator wbudowany w windowsa. Otwieramy sobie widok a następnie zaznaczamy Programisty i podstawowy. Zaznaczamy również byte czyli 8-bitów. Wpiszmy więc jedynkę a następnie klikajmy pomału w przycisk RoL i obserwujmy wartości dziesiętne będziemy mieli kolejno: 2, 4, 8, 16, 32, 64, -128 i ponownie 1. Pierwsze trzy wartości celowo pogrubiłem ponieważ możemy je zobaczyć już na początku szkicu przy col_1, col_2, col_3. Podobny efekt (nie taki sam) uzyskamy wpisując 1*2 i klikamy na znak równości. Wartości binarne celowo wziąłem w czerwoną ramkę ponieważ można klikać myszką bezpośrednio w poszczególne bity i w ten sposób ustawiać wartości. Wpiszmy teraz wartość 127 i już widać cały zakres liczb czyli od -128 do 127. Przejdźmy do kolejnej wartości ALL_ROWS_OUTPUT 252. Wpiszmy tą wartość do kalkulatora 2...5....ding...ding nieda się. No tak wszystko się zgada bo mamy wartość ze znakiem a chcemy mieć bez znaku. Jedyna opcja to chyba wybranie Word zamiast Byte teraz zobaczymy wartość binarną 11111100 czyli 6 jedynek , które odpowiadają rzędom (pierwsza jedynka z lewej to pin 7 który niebawem wykorzystamy). Przejdźmy więc do następnego przykładu. Co tu się stało ? gdzie jest Z? Można by tu przytoczyć przysłowie , że nie wszystko złote co się świeci albo inaczej patrz na to co się nie świeci. Od strony szkicu dodaliśmy operator Not ~. Kod dla pętli głównej będzie wyglądał następująco for (int i = 0; i < 3; i++) { COL_PIN_MODE = col[i]; /* ROW_PIN_STATE = literaZ[i] >> 1 */ ROW_PIN_STATE = ~(literaZ[i] >> 1); delay(2); ROW_PIN_STATE = ALL_ROWS_LOW; } Litera Z jest zgaszona ale wizualnie nie widzimy wszystkich zmian jakie zaszły. Teraz wyraźnie widać , że zmieniamy stan całego portu (PORTD od pinu D0 do D7) a nie tylko wybranych pinów. Gdyby piny D0 , D1 lub D7 były wykorzystywane do sterowania lub komunikacji to była by to nieoczekiwania zmiana ich stanu. Więcej informacji na ten temat znajduje się w komentarzu drugiego szkicu. Popatrzmy teraz na wartości w tablicy literaZ const uint8_t literaZ[3]= {152,168,200}; Taki zapis jest mało czytelny bo trzeba by było wartości dziesiętne ponownie konwertować do wartości binarnych czego nie będziemy robić. Rozpiszemy naszą tablicę ponownie. const uint8_t literaZ[3] = { 0b10011000, 0b10101000, 0b11001000 }; Taki zapis faktycznie jest o wiele łatwiejszy w edycji i nie trzeba go konwertować. Teraz pora nieco powiększyć naszą matrycę. Mamy teraz trochę więcej miejsca więc przesuniemy nasze Z w prawo. Kod dla pętli głównej będzie wyglądał następująco for (int i = 0; i < 3; i++) { /* COL_PIN_MODE = col[i]; */ COL_PIN_MODE = col[i] << 2; ROW_PIN_STATE = literaZ[i] >> 1; delay(2); ROW_PIN_STATE = ALL_ROWS_LOW; } Dokonaliśmy przesunięcia bitowego o dwa miejsca w lewo: col[0] 0b00000010 <<2 ---> 0b00001000 col[1] 0b00000100 <<2 ---> 0b00010000 col[2] 0b00001000 <<2 ---> 0b00100000 Teraz przesuniemy Z do góry. Kod dla pętli głównej będzie wyglądał następująco for (int i = 0; i < 3; i++) { COL_PIN_MODE = col[i] << 2; ROW_PIN_STATE = literaZ[i];// >> 1; delay(2); ROW_PIN_STATE = ALL_ROWS_LOW; } Usunęliśmy jedynie przesunięcie bitowe w prawo. W zasadzie można powiedzieć , że ustawiliśmy literę Z w domyślnym rzędzie. jedna litera to niewiele dlatego poniżej wklejam nowy szkic z całym alfabetem (wraz z komentarzami). #define BAUD_RATE 9600 #define BAUD_RATE_DIVISOR (F_CPU / 16 / BAUD_RATE - 1) #define ROW_PIN_MODE DDRD #define ROW_PIN_STATE PORTD #define COL_PIN_MODE DDRB #define ARDUINO_INTEGRATED_LED 0b00100000 #define col_1 0b00100010 #define col_2 0b00100100 #define col_3 0b00101000 #define ALL_ROWS_OUTPUT 0b01111100 #define ALL_ROWS_LOW 0b00000001 /*liczba liter w tablicy*/ #define LITERA_ALFABETU 26 /*liczba kolumn przypadających na jedną literę*/ #define KOLUMNA_LITERY 3 /*liczba kolumn w matrycy*/ #define MATRIX_COLS 3 #define ASCII_A 65 #define ASCII_Z 90 /*znak odebrany z klawiatury */ char SerialRX; /*tablica z kolumnami matrycy*/ const uint8_t col[MATRIX_COLS] = {col_1, col_2, col_3}; /*tablica z literami i kolumnami liter*/ const uint8_t litera[LITERA_ALFABETU][KOLUMNA_LITERY] = { /*litery bez polskich znaków*/ /*----------litera A-----------*/ { 0b11111000, // COL_1 0b01010000, // COL_2 0b00111000 },// COL_3 /*----------litera B-----------*/ { 0b11111000, 0b10101000, 0b01010000 }, //B /*----------litera C-----------*/ { 0b11111000, 0b10001000, 0b00000000 }, //C /*----------litera D-----------*/ { 0b11111000, 0b10001000, 0b01110000 }, //D /*----------litera E-----------*/ { 0b11111000, 0b10101000, 0b00000000 }, //E /*----------litera F-----------*/ { 0b11111000, 0b10100000, 0b00000000 }, //F /*----------litera G-----------*/ { 0b01111000, 0b10001000, 0b10110000 }, //G /*----------litera H-----------*/ { 0b11111000, 0b00100000, 0b11111000 }, //H /*----------litera I-----------*/ { 0b11111000, 0b00000000, 0b00000000 }, //I /*----------litera J-----------*/ { 0b00010000, 0b00001000, 0b11110000 }, //J /*----------litera K-----------*/ { 0b11111000, 0b00100000, 0b01011000 }, //K /*----------litera L-----------*/ { 0b11111000, 0b00001000, 0b00000000 }, //L /*----------litera M-----------*/ { 0b11111000, 0b01100000, 0b11111000 }, //M /*----------litera N-----------*/ { 0b11111000, 0b01000000, 0b11111000 }, //N /*----------litera O-----------*/ { 0b01110000, 0b10001000, 0b01110000 }, //O /*----------litera P-----------*/ { 0b11111000, 0b10100000, 0b01000000 }, //P /*----------litera Q-----------*/ { 0b01100000, 0b10010000, 0b01101000 }, //Q /*----------litera R-----------*/ { 0b11111000, 0b10100000, 0b01011000 }, //R /*----------litera S-----------*/ { 0b01101000, 0b10101000, 0b10110000 }, //S /*----------litera T-----------*/ { 0b10000000, 0b11111000, 0b10000000 }, //T /*----------litera U-----------*/ { 0b11111000, 0b00001000, 0b11111000 }, //U /*----------litera V-----------*/ { 0b11110000, 0b00001000, 0b11110000 }, //V /*----------litera W-----------*/ { 0b11111000, 0b00010000, 0b11111000 }, //W /*-----------litera X----------*/ { 0b11011000, 0b00100000, 0b11011000 }, //X /*-----------litera Y----------*/ { 0b11000000, 0b00111000, 0b11000000 }, /*---------- Litera Z ---------*/ { 0b10011000, 0b10101000, 0b11001000 }, //Z }; void setup() { Serial_Rx_Begin(); ROW_PIN_MODE |= ALL_ROWS_OUTPUT; } void loop() { if (PINB == ARDUINO_INTEGRATED_LED) display_Letter_Highlighted(false); /*wyświetlamy literę zgaszoną*/ else display_Letter_Highlighted(true); /*wyświetlamy literę podświetloną*/ } /*Serial skonfigurowany tylko do odbierania łącznie z aktywowaniem przerwania */ void Serial_Rx_Begin() { UCSR0A = 0 << TXC0 | 0 << U2X0 | 0 << MPCM0; UCSR0B = 1 << RXCIE0 | 0 << TXCIE0 | 0 << UDRIE0 | 1 << RXEN0 | 0 << TXEN0 | 0 << UCSZ02 | 0 << TXB80; UCSR0C = 0 << UMSEL01 | 0 << UMSEL00 | 0 << UPM01 | 0 << UPM00 | 0 << USBS0 | 1 << UCSZ01 | 1 << UCSZ00 | 0 << UCPOL0; UBRR0 = BAUD_RATE_DIVISOR; } void display_Letter_Highlighted(bool letterBacklight) { /*jeżeli odebrana literę A...Z*/ if (SerialRX >= ASCII_A || SerialRX <= ASCII_Z) { /*pętla skanująca kolumny matrycy i kolumny litery*/ for (int i = 0; i < 3; i++) { COL_PIN_MODE = col[i]; if /* ustawiamy odebraną literę na właściwej pozycji w matrycy znak np: 'A' zgodnie z ASCII to 65 - 65= 0 czyli litera[0][] itd.*/ (letterBacklight) ROW_PIN_STATE = (litera[SerialRX - ASCII_A][i]) >> 1; else /* rzędy liter w tablicy zaczynają się od litera[][0b10000000] dlatego >>1. W tym wypadku litera nie jest podświetlona a odbywa się to poprzez zastosowanie operatora NOT ~(tyltda), który powoduje odwrócenie stanu wszystkich bitów portu. Dlatego dokonujemy kolej operacji z udziałem operatora XOR ^(kareta), który zmienia stan wybranych bitów na przeciwny. (litera[][]>>1) musi być w nawiasie ponieważ operator >> ma niższy priorytet niż operator ~ np: litera[0][col_1) czyli A kolumna pierwsza 0b11111000 >> 1 ---> ~0b01111100 ---> 0b10000011 ^ 0b10000011 ---> 0b00000000 */ ROW_PIN_STATE = ~(litera[SerialRX - ASCII_A][i] >> 1) ^ 0b10000011; delay(2); /*opóźnienie dla prawidłowego wyświetlania litery*/ ROW_PIN_STATE &= ALL_ROWS_LOW; } } } /*procedura przerwania*/ ISR(USART_RX_vect) { SerialRX = UDR0; /*odbieramy znaki wysłane z klawiatury*/ /*po wciśnięciu litery Q włączany/wyłączamy podświetlenie liter wyświetlanych na matrycy oraz zmieniamy stan diody Arduino na przeciwny nie naruszając stanu pozostałych bitów*/ if (SerialRX == 'Q') PORTB ^= ARDUINO_INTEGRATED_LED; } Na koniec zachęcam do tworzenia własnych znaków (cyfr) w tym celu może być pomocna aplikacja na smartfona. Dla leniwych w załączniku pliki do simulIDE: pliki.zip Spis treści serii artykułów: Matryca led: podstawy, proste wyświetlanie znaków - część 1 Matryca led: podstawy, proste wyświetlanie znaków - część 2 Matryca led: podstawy, proste wyświetlanie znaków - część 3
  7. Ja na swoim modemie testowałem zdalne wykonywanie poleceń przez sms. W pierwszej kolejności był sprawdzany nr telefonu z którego nadszedł sms a następnie treść sms'a. if (Serial.find("numer telefonu\r\n")) { Serial.print("Znalazłem twój numer"); delay(500); if (Serial.find("kod\r\n")) { Serial.print(" i odczytalem wiadomosc"); } } domyślny czas oczekiwania na dane to 1000ms chyba , że zmienisz przez Seria.setTimeout(); Działało to całkiem fajnie aczkolwiek do rozbrajania alarmu to bym tego nie stosował.
  8. W folderze, który podałeś domyślnie instalują się wszystkie biblioteki, które pobierasz przez Arduino IDE. Jeśli sam pobierałeś biblioteki to też zapewne kopiowałeś je do tego folderu. Natomiast biblioteki jak np: Servo.h znajdziesz w katalogu C:\Program Files (x86)\Arduino\libraries. Może być też tak , że biblioteki są w folderze z projektem. Jeżeli chcesz zacząć z platform IO to tutaj jest fajny filmik.
  9. można odczytać wartość licznika w pętli głównej używając __HAL_TIM_GET_COUNTER np: int czas = __HAL_TIM_GET_COUNTER(&htim10); Możesz to zrobić postępują zgodnie z kursem dla F4 z tą różnicą , że po wykonaniu Kroku. 5 od razu generujesz projekt w CubeMX (nie konfigurujesz przerwań). W wygenerowanym projekcie przechodzisz do funkcji konfigurującej przerwanie TIM_Init i jako ostatnie polecenie dopisujesz : HAL_TIM_Base_Start(&htim10); Oczywiście konfigurację zegarów i timera możesz ustawić wedle własnych potrzeb. Nie jest to najbardziej optymalne rozwiązanie ale lepsze od HAL_Delay(). Nawiązując do Arduino a konkretnie płytek opartych o układy SAM/SAMD to wielozadaniowość jest możliwa z wykorzystanie delay() przykład.
  10. Dzięki za linki @FlyingDutch na pewno się przydadzą. Co do dokumentacji to na chwilę obecną korzystałem z informacji zawartych w SW4STM32 w zasadzie to te same opisy aczkolwiek user manual podaje więcej szczegółów.
  11. Ja ze swojej strony mogę się podzielić doświadczeniami związanymi z płytką Discovery F411 na której bazuje drugi kurs. Ogólnie ujmując to wszystko było by świetnie gdyby nie CubeMX. Idea graficznego wyklikiwania kodu sporo ułatwia ale też i utrudnia szczególnie na początku. Ja osobiście nie bardzo mogłem się w tym odnaleźć. Nie wspominając o wpisywaniu własnego kodu w odpowiednie miejsca w wygenerowanym projekcie (niby jest to zrozumiałe ale mi to nie pasowało). Efekt był taki , że płytka długo przeleżała w pudełku czekając na lepsze czasy :) Aż do niedawna kiedy to tak sobie otworzyłem kurs STM32 F1 niby to kurs dedykowany dla innej płytki ale bez CubeMX i opiera się głównie na SW4STM32 a ten już miałem zainstalowany. Wiec zacząłem jeszcze raz i to podejście o wiele bardzie mi pasuje dodatkowo zaopatrzyłem się w książkę : Programing with stm32 Getting started with the Nucleo. I puki co to nauka przebiega bardzo przyjemnie.
  12. takie drobne wprowadzenie do processing jest na forum tutaj. Podałem tam dwa przykłady a poniżej masz kolejny float theta = 0; void setup() { size(500,500); background(0); } void draw() { stroke(0); // sun in center translate(width/2, height/2); fill(255,200,50); ellipse(0,0,20,20); // earth rotates around the sun pushMatrix(); rotate(theta); translate(50,0); fill(50,200,255); ellipse(0,0,10,10); // moon 1 rotates around the earth pushMatrix(); rotate(-theta*4); translate(15,0); fill(50,255,200); ellipse(0,0,6,6); popMatrix(); // moon 2 rotates around the earth pushMatrix(); rotate(theta*2); translate(25,0); fill(50,255,200); ellipse(0,0,6,6); popMatrix(); popMatrix(); theta+=0.01; } a tak to wygląda w praktyce. W rzeczywistości animacja jest o wiele płynniejsza (draw() domyślnie "rysuj" 60 razy na sekunde). Processing jest o tyle ciekawy co do tworzenia efektów graficznych , że jak coś napiszesz nie tak jak powinno być to można dostać efekt inny od zamierzonego ale często bardzo ciekawy. Poniżej przykład kwadrat myKwadrat1; kwadrat myKwadrat2; kwadrat myKwadrat3; kwadrat myKwadrat4; float theta; void setup() { size(500,500); background(0); myKwadrat1 = new kwadrat(100,124,124); myKwadrat2 = new kwadrat(100,52,52); myKwadrat3 = new kwadrat(100,52,52); myKwadrat4 = new kwadrat(100,52,52); } void draw() { theta +=0.1; myKwadrat1.display(); myKwadrat2.display(); myKwadrat3.display(); myKwadrat4.display(); } class kwadrat { color c; int x; int y; //float theta; kwadrat (color tempC, int tempX, int tempY) { // float tempTheta) { c = tempC; x = tempX; y = tempY; //theta = tempTheta; } void display() { fill(c); translate(x,y); // Translate to the center //translate(width/2,height/2); rotate(theta); // Rotate by theta rect(0, 0, 52, 52); } } tak to wygląda w rzeczywistości tutaj moje założenie co do tego jak to miało wyglądać możesz zobaczyć w wiadomości, którą podlinkowałem na początku tematu.
  13. Pierwsza informacja pochodzi z "Arduino internals" strona 210/211 Accuracy.
×
×
  • Utwórz nowe...