Zaprogramowana Atmega328P do zapalania diody za pomocą pilota od TV.

Witam 🙂

Tak jak w temacie – zaprogramowałem mikrokontroler, a dokładnie ATMEGA328P-PU (datasheet), która zapala diodę po wciśnięciu odpowiedniego przycisku na pilocie od telewizora.

Wszystko zostało zaprezentowane na filmiku poniżej:

 

W kilku prostych krokach pokażę wam jak tego dokonać.

1. Czego będziemy potrzebowali ?

  • Odbiornik podczerwieni – ja wykorzystuję TSOP31236 (Link do sklepu )
  • Dioda 5mm – u mnie jest niebieska 3.2V (Link do sklepu )
  • Rezystor 220R (Link do sklepu )
  • Mikrokontroler – tutaj zaprezentuję ATMEGA328P-PU (Link do sklepu) Celowo podałem link do wielu miktrokontrolerów ze względu na to, iż możemy kupić takiego AVR od razu z wgranym bootloaderem do Arduino co zmniejszy nasz nakład pracy (Osobiście uważam, że się nie opłaca kupować z wgranym bootloaderem. Lepiej nauczyć się go wypalać wtedy zaoszczędzimy aż 4 zł  🙂 )
  • Arduino – w moim przypadku UNO w wersji SMD (to ważne)
  • Przewody do łączenia z płytką prototypową
  • Pilot do TV

*Dodatkowo jeśli chcesz zwiększyć taktowanie tego AVR’a z 8MHz do 16MHz możesz kupić :

Nie będę poruszał tematu ATMEGI328P-PU na 16MHz, ale podałem listę elementów, które są do tego potrzebne ze względu na ich mały koszt porównując z kosztem przesyłki.

2. Odbiór sygnału z pilota do TV.

Na początek spróbujmy odczytać sygnały z naszego pilota. Podłączmy nasze Arduino w taki sposób :

Odbiornik_1

Następnie musimy zaopatrzyć się w bibliotekę IRemote. Możemy ją pobrać stąd : Git site ( Bezpośredni download ). Aktualnie jako środowisko wykorzystuję najnowsze Arduino 1.6.9. Wspominam o tym bo instalując bibliotekę napotkałem parę problemów, a ludzie na niektórych forach jako rozwiązanie proponowali przeinstalowanie do starszej wersji środowiska co wcale nie jest konieczne. Po ściągnięciu „ZIP’a” biblioteki uruchamiamy oprogramowanie Arduino. Następnie klikamy:

Szkic >> Dodaj bibliotekę >> Dodaj bibliotekę .ZIP

Następnie szukamy naszego nierozpakowanego archiwum .ZIP i zatwierdzamy przyciskiem OPEN.

Następnie wklejamy ten o to kod:


#include <IRremote.h>
#define irPin 11
IRrecv irrecv(irPin);
decode_results results;

void setup() {
Serial.begin(9600);
irrecv.enableIRIn();
}

void loop() {
if (irrecv.decode(&results)) {
Serial.print("0x");
Serial.println(results.value, HEX);
delay(250);
irrecv.resume();
}
}

Który ma na celu wyświetlanie kodów przycisków z pilota na monitorze szeregowym. Kompilujemy i wrzucamy program na Arduino. Niestety mój kompilator napotkał taki błąd:

IRemote_Error

 

Błąd ten spowodowany jest tym, że posiadam najnowsze środowisko, a w nim występuje biblioteka RobotIRemote, której uwzględnianie – „#include” jest takie samo jak naszej nowo-pobranej biblioteki. Dlatego występują konflikty. Jak je rozwiązać ? Wchodzimy do katalog_z_zainstalowanym_Arduino\libraries\ i tam usuwamy folder RobotIRremote. (Oczywiście jest to rozwiązanie dość drastyczne, bo wywalamy całą bibliotekę . Jeśli chcesz zrobić to w inny sposób musisz pokombinować ze zmianą nazwy biblioteki.) Ponownie wrzucamy kod na płytkę i … działa ! W środowisku klikamy Narzędzia >> Monitor szeregowy, chwytamy za pilot od telewizora, celujemy w odbiornik i wciskamy przyciski obserwując obraz monitora 🙂

Powinniśmy ujrzeć mniej więcej coś takiego :

Monitor_szeregowy

Są to kody przycisków, które wybieramy na pilocie. Nie wiem dokładnie jak to działa, ale zauważyłem, że gdy przytrzymamy przycisk, pilot wysyła (bynajmniej u mnie) sygnał 0xFFFFFFFF. Myślę, że oznacza on przedłużenie poprzedniego stanu. W każdym razie, wybieramy sobie przycisk i zapamiętujemy jego hexadecymalny kod. U mnie będzie to 0x20DF22DD – przycisk „OK”.

3. Odebranie zakodowanego sygnału

Gdy mamy już zapamiętany kod naszego przycisku dokładamy do układu diodę LED
z rezystorem tak jak na schemacie :

Odbiornik_Z_LED_1

  • Pin 9 Arduino -> rezystor -> Anoda diody (dłuższa nóżka)
  • Katoda diody -> GND

Następnie zmieniamy nieco nasz kod. Usuwamy niepotrzebny SerialMonitor. Dodajemy stan (zmienna state), który będzie się zmieniał za każdym razem jak Arduino wykryje wciśnięcie przycisku o naszym kodzie „0x20DF22DD”. W zależności od wartości naszego stanu (0/1) dioda będzie się świeciła bądź nie.


#include <IRremote.h>
#define irPin 8
#define diodePin 9
IRrecv irrecv(irPin);
decode_results results;

void setup() {
irrecv.enableIRIn();
pinMode(diodePin, OUTPUT);
}

bool state = 0;

void loop()
{
if (irrecv.decode(&results))
{
if(results.value == 0x20DF22DD) state = !state;
irrecv.resume();
}

if(state) digitalWrite(diodePin, HIGH);
else digitalWrite(diodePin, LOW);
}

Wszystko wgrywamy na nasze Arduino. Powinno ładnie się wgrać.

Teraz chwila prawdy. Znów celujemy pilotem w odbiornik wciskając parę razy wcześniej zdefiniowany przycisk. Jeśli dioda zapala się i gaśnie – udało się, jeśli nie, wróć krok 3, albo lepiej wyceluj 🙂

Zapiszmy nasz program, bo później będziemy chcieli go wgrać na naszego scalaka.

4. Wgranie ArduinoISP

Uff łatwiejsza część za nami. Mam nadzieję, że wszystko Ci się udało i jesteś w pełni zdeterminowany, aby zaprogramować swój pierwszy mikrokontroler !

Ale zanim do tego przejdziemy najpierw troszkę teorii (też chciałem tego uniknąć, ale tylko dzięki niej mi się udało ). Randall Bohn napisał oprogramowanie na Arduino, które pozwala mu przekształcić się w programator. Dzięki czemu nie potrzebujemy wydawać pieniędzy na dedykowane do tych czynności urządzenia. Projekt Randalla nazywa się ArduinoISP. Dokładne informacje odnośnie tej technologii znajdziecie oczywiście na oficjalnej dokumentacji Arduino (TUTAJ).

Bierzmy się do roboty, wchodzimy w :

IDE >> Plik >> Przykłady >> 11.ArduinoISP >> ArduinoISP

Szukamy takiej linijki kodu :

 #define SPI_CLOCK (1000000/6) 

Zmieniamy liczbę 1000000 na moc taktowania naszego zegara. Czyli, nasza Atmega ma wewnętrzny zegar taktujący 8MHz więc zamiast 1 000 000 wstawimy 8 000 000. Linijka po zmianie powinna wyglądać tak :

 #define SPI_CLOCK (8000000/6) 

Co więcej szukamy linijki :

 // #define USE_OLD_STYLE_WIRING 

I pozbywamy się 2 przednich znaków. Linijka ta powinna wyglądać tak :

 #define USE_OLD_STYLE_WIRING 

Odkomentowanie tej linijki pozwala nam na używanie pinów 13,12,11,10 do komunikacji między naszym mikrokontrolerem. Są to 2 niezbędne rzeczy, które musimy tutaj zmienić.
W „Narzędziach” sprawdzamy czy mamy dobrze wybraną płytkę, port i programator (standardowe, jeśli tego nie ruszałeś powinno być dobrze) u mnie wygląda to tak :

Ustawienia_do_wgrania_ARDISP

Po czym wszystko wgrywamy do Arduino.

5. Wypalenie bootloadera

Jeśli nie masz wgranego programu ArduinoISP (patrz krok 4) to nie możesz wypalić bootloadera. Co więcej, jeśli kupiłeś mikrokontroler z wgranym bootloaderem nie musisz już tego robić. Robi się to tylko raz.

Jak się za to zabrać ?

Po pierwsze potrzebujemy znaleźć w sieci bootloader pod konkretny AVR do Arduino. Będzie miał on rozszerzenie .hex . Do ATMEGI328P-PU 8MHz możecie pobrać stąd. Jeśli już go mamy przenosimy do miejsca, które będzie łatwo dostępne przez środowisko, czyli: folder_z_IDE_Arduino\hardware\arduino\avr\bootloaders\rodzina_mikrokontrolera
gdzie, w tym wypadku rodzina_mikrokontrolera to atmega. U mnie wygląda to tak:

Bootloader_1.png

Następnie musimy edytować plik boards.txt, który znajdziemy w folder_z_IDE_Arduino\hardware\arduino\avr\. Na samym jego końcu dodajemy opis naszego AVR, którego chcemy wypalić. U mnie będzie to wyglądało tak :

##############################################################
atmega328bb.name=ATmega328p @8 MHz

##atmega328bb.upload.protocol=arduino
atmega328bb.upload.maximum_size=30720
##atmega328bb.upload.maximum_data_size=2048
##atmega328bb.upload.speed=57600

atmega328bb.bootloader.tool=arduino:avrdude
#atmega328bb.bootloader.tool=avrdude

atmega328bb.upload.tool=avrdude

atmega328bb.bootloader.low_fuses=0xE2
#atmega328bb.bootloader.low_fuses=0xFF
atmega328bb.bootloader.high_fuses=0xDA
atmega328bb.bootloader.extended_fuses=0x05

atmega328bb.bootloader.file=atmega/ATmegaBOOT_328p.hex
atmega328bb.bootloader.unlock_bits=0x3F
atmega328bb.bootloader.lock_bits=0x0F

atmega328bb.build.mcu=atmega328p
atmega328bb.build.f_cpu=8000000L
#atmega328bb.build.core=arduino:arduino
atmega328bb.build.core=arduino
#atmega328bb.build.variant=arduino:standard
atmega328bb.build.variant=standard
###Experimental name:
atmega328bb.build.board=AVR_BARE

Cały ten zabieg pozwala zobaczyć nam nową płytkę w środowisku. Aby tego dokonać wyłączamy nasze środowisko i włączamy ponownie. Po czym wchodzimy w Narzędzia >> Płytka >> i szukamy naszej ATmega328p @8 MHz >> wybieramy ją

Następnie w Narzędzia >> Programator >> Wybieramy Arduino as ISP (nie ArduinoISP)
Wszystko powinno wyglądać mniej więcej tak :

Wypal_bootloader

Następnie podłączamy naszego scalaka zgodnie ze schematem :

AtmegaIArdu_1

A dokładniej :
Reset (1) -> Arduino 10
MOSI PIN (17) -> Arduino 11
MISO  PIN (18) -> Arduino 12
SCK PIN (zegar – 19) -> Arduino 13
Vcc (7 i 20) -> Arduino 5v
GND (8 i 22) -> Arduino GND

Cały czas mając w pamięci Arduino program ArduinoISP klikamy
Narzędzia >> Wypal bootloader .

Jeśli coś Ci nie wyszło wróć krok 4.
U mnie wszystko działa 🙂

6. Wgranie programu do AVR’a

Arduino mamy zaprogramowane jako ISP, nasz scalak posiada bootloader – przyszedł czas na wgranie do niego programu.

Moja ATMEGA posiada dużo nóżek więc nie do końca wiedziałem jaki nr portu podać w programie. Prosta sprawa. Załatwiłem to metodą prób i błędów. Doszedłem do tego, że mam 20 pinów I/O, które zaczynają się od PD0 – 0 nr pinu.
Atmeda_OUTS

Następnie wybieramy sobie porty, z których chcemy korzystać ja wybrałem nr 0(PD0) oraz nr 1 (PD1). Łączymy je z naszym wcześniejszym układem (diodą i odbiornikiem) :AtmegaIOdbiornik_ALL

Wyjście odbiornika -> Atmega pin 0 (PD0)
Rezystor połączony z anodą diody LED -> Atmega pin 1 (PD1)
GND odbiornika i diody -> do GND Arduino
Vcc odbiornika -> 5v Arduino

Super! Już prawie gotowe. Teraz tylko kod. Przerabiamy nasze wcześniejsze bazgroły w taki sposób :

#include <IRremote.h>;
#define irPin 0
#define diodePin 1
IRrecv irrecv(irPin);
decode_results results;

void setup() {
 irrecv.enableIRIn();
 pinMode(diodePin, OUTPUT);
}

bool state = 0;

void loop()
{
 if (irrecv.decode(&results))
 {
 if(results.value == 0x20DF22DD) state = !state;
 irrecv.resume();
 }

if(state) digitalWrite(diodePin, HIGH);
 else digitalWrite(diodePin, LOW);
}

Zmieniły się tylko 2 i 3 linijka, a dokładniej  nr portów zgodne z naszym AVR.
Ciągle pamiętając o takich ustawieniach :Ustawienia_do_wgrania_naAtmege

Klikamy Szkic >> Wgraj używając programatora

Czekamy … i Voilà!
Tak oto zaprogramowaliśmy nasz pierwszy mikrokontroler. Teraz możemy testować nasze dzieło do woli, możemy również odłączyć piny „programujące” od Arduino (13,12,11,10) i podłączyć naszą zabawkę pod baterie 🙂

Pozdrawiam wszystkich, którzy dotrwali do końca !

Advertisements

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Log Out / Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Log Out / Zmień )

Facebook photo

Komentujesz korzystając z konta Facebook. Log Out / Zmień )

Google+ photo

Komentujesz korzystając z konta Google+. Log Out / Zmień )

Connecting to %s