If you're new here, you may want to subscribe to my RSS feed. Thanks for visiting!
Można by rzec – na legendarnej giełdzie na Grzybowskiej nie takie rzeczy można było znaleźć :) No ale do rzeczy – Chris Fenton, elektronik mieszkający w NYC, zajmuje się w wolnym czasie różnymi projektami DIY takimi jak laptop na uC pixaxe (v1 i v2). Projekty te nie zawsze mają głębszy sens :) bo po co komu taki taki laptop, ale mają spory sens edukacyjny. Z projektu dwu-fazowe działo gazowe, z oczywistych powodów zakończonego eksplozją ;) (dlaczego oczywistych warto przeczytać całość) wpadł mi w oko cytat:
My Mom actually made me collect all of the pieces, lay them out, and try to root-cause the failure. Whatever happened to just grounding someone?!
Fajna mama zmuszająca do root cause analysis.
Cray-1 CC by http://www.flickr.com/photos/keitamiyoshi/
Ale do rzeczy. Kolejny projekt to kopia superkomputera (super to był w latach 70-tych) Cray-1 wykonana na FPGA. Największy problem – brak oprogramowania do tegoż, do sprawdzenia, że działa jak prawdziwy Cray. Jeśli masz jakieś to możesz pomóc przetestować całość :)
Albo. Jeśli masz ochotę to możesz zrobić swojego Craya :)
W ofercie Nettigo od dłuższego czasu dostępny jest kit Motor|Stepper|Servo. Jest to doskonały shield dla każdego kto myśli o robotyce – 2 serwa, 2 silniki krokowe lub 4 silniki DC.
Ponieważ shield jest w formie kitu (do samodzielnego zlutowania) przygotowaliśmy tłumaczenie angielskiej instrukcji jak go zmontować. Dostępna jest ona na naszym blogu tutaj. Instrukcje są tak precyzyjne, że nawet początkujący użytkownik lutownicy da sobie radę.
To naprawdę nie jest takie trudne, i mówię to ja, który pierwszy raz o Arduino słyszał w 2006 roku ale przez trzy lata nic nie zrobiłem w tym kierunku bo bałem się że będę musiał lutować :)
Jeśli odwiedzasz ten blog i jesteś posiadaczem Arduino zapewne marzyłeś kiedyś o budowie własnego robota. Te najłatwiejsze wykonują proste rozkazy (obróć się, przesuń o 20 cm). Co innego, gdy chcemy zbudować robota o większej autonomii. Takiego, który samodzielnie szuka drogi do celu, który omija przeszkody. Brzmi fantastycznie? Oczywiście! Ale to nić trudnego wymaga odrobiny praktyki i…
… czujników zmysłów.
Jednym z nich jest oferowany w Nettigo sonar. Sensor ten mierzy odległość do przeszkody. Robi to za pomocą ultradźwięków czyli fal o częstotliwości tak wysokiej, że nie reaguje na nie ludzkie ucho (około 42 kHz). Czujnik ten normalnie wykorzystywany jest w systemach alarmowych (w odróżnieniu od czujników na podczerwień pasywną, w tym można ustalić odległość, której przekroczenie powoduje uruchomienie alarmu), oraz w systemach parkowania do samochodów.
Umieszczając ten czujnik w robocie, zyskasz możliwość ustalania jak daleko znajduje się on od przeszkód lub stworzyć mapę otoczenia.
Maksymalna odległość wykrywana przez czujnik to 255 cali czyli ponad 6 metrów z dokładnością do 1 cala [2,54 cm]. Szerokość wiązki dźwięku “gołego” czujnika to około 24 cale [61 cm]. Minimalna odległość jaką wykrywa czujnik to 6 cali [15 cm].
Sonar EZ1 ma sporo wyprowadzeń, ale nie powinieneś się obawiać ich ilości. Większość z nich jest dla Twojej wygody. Pierwsze dwa (GND i +5) służą do zasilania czujnika. Podłącza się je w ich odpowiedniki w Arduino.
Pozostałe wyprowadzenia to różnorodne sygnały przedstawiające wykrytą odległość od przeszkody.
Arduino nie ma wbudowanego zegara. Znaczy to, że pewne operacje związane z czasem da się przeprowadzać (opóźnienia o zadany interwał), ale już kontrolowanie czasu i daty nie jest takie proste.
Aby Arduino mogło wiedzieć dokładnie jaki jest czas potrzebny jest zewnętrzny układ zegara. Takim układem jest Dallas DS1307, dostępny na Nettigo.pl w formie modułu do Arduino. Moduł ten posiada podtrzymywanie bateryjne, więc czas raz ustawiony nie zostaje skasowany po wyłączeniu Arduino.
Montaż
Moduł jest zlutowany, ale kwestia podłączenia do Arduino pozostaje otwarta. Moduł wygląda tak:
Moduł zegara DS1307
W lewym górnym rogu znajduje czteropinowe złącze o rastrze (odstępie między pinami) 2.54 mm. Niestety nie posiadamy na razie w ofercie kabelków do tego złącza. Pozostaje kombinowanie samemu, lub podłączenie się przez gniazdo (do ICSP) i goldpiny. Elementy te są dostępne razem z modułem (jak widać na zdjęciu), ale trzeba je przylutować do modułu (proste nawet dla początkujących).
Korzystając z kabelka możemy moduł podłączyć do dowolnego kontrolera wspierającego protokół I2C.
Gniazdo do podłączenia ICSP (z którego moduł w takim układzie bierze zasilanie) ma dwie pozycje w które można go przylutować. Jedna jest dla Arduino Duemilanove (i klonów zgodnych jeśli chodzi o rozmiary i wyprowadzenie pinów) lub Seeeduino Mega. Moduł przy takim podłączniu (przez ICSP i goldpiny) nie współpracuje z Arduino Mega (wzajemne położenie pinów ICSP i wyjścia magistrali I2C są różne).
Oczywiście zawsze zostaje opcja przylutowania kabelków zamiast goldpina oraz ICSP i wtedy możemy podłączyć się do dowolnego mikrokontrolera wspierającego I2C. Jak wygląda moduł z przylutowanym gniazdem i goldpine oraz założony na Arduino pokazują poniższe zdjęcia:
Podczas spotkań z czytelnikami dowiedziałem się, że wielu podoba się projekt Arduino, ale największą przeszkodą w rozpoczęciu przygody jest lutowanie. Niektórzy boją się tego wręcz panicznie – trzęsą im się ręce. W tym wpisie chcę odczarować lutowanie.
Część elementów elektronicznych dostępnych w postaci płytek drukowanych z uruchomionym podzespołem (modułów) ma gotowe wyprowadzenia sygnałów w otworach na płytce. Brakuje im tylko złącz lub przewodów. Do zastosowań w Arduino najlepszym rozwiązaniem będzie wlutowanie w te otwory “Goldpin-a”.
Goldpin to rodzaj wtyku z rzędowo rozmieszczonymi bolcami. W większości przypadków odstęp między bolcami i otworami w płytce drukowanej jest standardowy i wynosi 2,5 mm.
Goldpin bardzo dobrze nadaje się w prototypowaniu z użyciem płytki stykowej.
W tym wpisie zajmiemy się wlutowywaniem goldpina do Ultradźwiękowego czujnika odległości.
Składniki
Do lutowania potrzebne nam będą:
Lutownica
Jeśli jesteś elektronikiem amatorem – hobbystą, nie musisz kupować wyrafinowanych i drogich narzędzi. Sam od dawna używam prostej i taniej lutownicy o mocy 40W, dostępnej w sklepach z elektroniką za kilkanaście zł. Polecam oczywiście lutownicę kolbową. Lutownice pistoletowe nadają się bardziej do lutowania przewodów niż drobnych elementów, dlatego odrzucając je unikniesz wielu kłopotów.
W obsłudze lutownicy najważniejsze jest wiedzieć, który koniec się nagrzewa. Łapanie za nieodpowiedni może się źle skończyć.
Lutownica nagrzewa się około 2 minut. Poznajemy to po tym, że grot (zaostrzony koniec) łatwo topi cynę.
Cyna lutownicza
Cyna to rodzaj drutu ze stopu ołowiu i cynku z domieszką odpowiednich chemikaliów. Cynę zwykle można nabyć w postaci nawiniętej szpulki – drutem o różnych średnicach.
Polecam cynę o średnicy do 1 mm. Należy wziąć pod uwagę, że im mniejsza średnica, tym drobniejsze elementy możemy lutować. Jednak jeśli średnica będzie zbyt mała będziemy potrzebowali znaczne długości cyny do lutowania większych elementów, co może być niewygodne.
Do lutowania używam cyny 1 mm i w poniższym przypadku uważam, że jest ona trochę za gruba.
Goldpin
Goldpiny są dostępne w różnych konfiguracjach (od jednego do kilku rzędów). Nam wystarczy 1 rząd. Zwykle sprzedaje się je w rzędzie po 50 PINów.
Jeśli nasz układ wymaga mniej PINów, zwyczajnie odłamujemy tyle ile jest nam potrzebne.
Przygotowania
Otwory i miejsca lutownicze możemy przemyć z tłuszczu za pomocą szmatki nasączonej alkoholem, rozpuszczalnikiem lub wodą. Większość producentów zaleca ten ostatni środek, jednak należy być ostrożnym, gdyż woda łatwo powoduje zwarcia i długo odparowuje z trudno dostępnych szczelin takich jak miejsca pod układami scalonymi.
Odłamujemy potrzebną ilość PINów.
Przymierzamy czy pasują do płytki.
Dalsze przygotowania
Właściwie mógłbyś rozpocząć już lutowanie, gdyby nie fakt, że brakuje nam “trzeciej ręki”. Ciężko utrzymać element w miejscu podczas gdy w jednym ręku mamy lutownice, a w drugim cynę. Element oparty o podłoże goldpin-em nie da się zlutować prosto (tzn. pod kątem 90°).
W celu rozwiązania tego problemu wymyślono już wiele. Najpopularniejszymi rozwiązaniami są przykręcane do stołu szkła powiększające z “krokodylkami”. Ja jednak idąc ścieżką całkowitego amatorstwa użyłem…
…małego imadła.
Płytki nie należy wkręcać bezpośrednio w imadło. Mogłoby to ją uszkodzić. Poza tym nie będzie się stabilnie trzymała. Proponuję zatem obsadzić zaciski imadła czymś w rodzaju styropianowej gąbki służącej do izolowania rur.
Co zrobić z wypadającym z płytki goldpin-em?
Proponuję plastikowe końce złącza posmarować klejem typu “kropelka” i przykleić do płytki.
Proces lutowania
Lutowanie polega na przyłożeniu rozgrzanego grota w okolice punktu lutowniczego. Następnie do zaostrzonej końcówki grota przykładamy cynę, która musi spłynąć do punktu lutowniczego i go wypełnić.
Musisz pamiętać, że do jednego punktu nie można zbyt długo przykładać lutownicy. Producenci zalecają maksymalnie 2..3s.
Jeśli cyna przypadkowo rozpłynie się na dwa PINy łącząc je, należy ją roztopić i szybkim ruchem przerwać miejsce między PINami. Możemy to zrobić za pomocą kawałka zaostrzonego drewna (najlepiej wykałaczki lub dolnej części zapałki).
Prawidłowo zlutowany koniec ma kształt stożka.
Nieprawidłowe lutowanie najczęściej polega na dostarczeniu do punktu lutowniczego zbyt małej (punkt nie jest do końca pokryty cyną) lub zbyt dużej (zamiast stożka jest kulka) ilości cyny.
Moje lutowanie
Aby ostatecznie rozwiać strach związany z lutowaniem, postanowiłem nagrać materiał video z mojego lutowania goldpin-a.
Jak widzisz drogi czytelniku, to nie jest wcale takie trudne.
Każda amatorska jak i profesjonalna stacja meteo do pełni szczęścia wymaga czujnika wilgotności. Czujnik ten wraz z termometrem pozwala przewidzieć tzw. “punkt rosy”.
Punktem rosy jest temperatura, w której przy odpowiedniej wilgotności skrapla się para wodna zawarta w powietrzu. Zwykle powoduje to powstanie rosy na trawie, lecz w pewnych warunkach pozwala także przewidywać powstanie mgły, obliczyć wysokość na jakiej są chmury lub stwierdzić czemu w kuchni odpada tynk z sufitu ;-).
Kondensator
Urządzenie dostępne w Nettigo jest pojemnościowym czujnikiem wilgotności HCH-1000. Pojemnościowy oznacza, że sensor jest kondensatorem w którym pojemność zależy wprost proporcjonalnie od wilgotności. Średnia pojemność tego kondensatora to około 330 pF.
Kondensator to w najprostszym tłumaczeniu element, który przechowuje ładunek elektryczny. Jeszcze prościej (wybaczcie prawdziwi elektronicy) to taki akumulator o bardzo małej pojemności.
Wyznaczanie pojemności kondensatora
Każdy kto miał do czynienia z akumulatorem (choćby w telefonie komórkowym) wie, że jego załadowanie i rozładowanie wymaga odpowiedniej ilości czasu. Ilość tego czasu zależy od pojemności akumulatora i zapotrzebowania na prąd przez urządzenie. Nie inaczej jest w przypadku kondensatorów.
Fachowo nazywamy to szeregowym obwodem RC (dlatego, że składa się z rezystora i kondensatora połączonych szeregowo).
Wykres ten przedstawia czas w jakim napięcie na kondensatorze (V kondensatora) w obwodzie RC osiągnie procent wartości napięcia zasilania obwodu (V zasilania). Można z niego wywnioskować, że 63,2% napięcia osiągnie w jednej jednostce czasu, którą można wyznaczyć ze wzoru:
t = RC
gdzie:
t – czas w sekundach
R – Rezystancja rezystora w Ω
C – Pojemność kondensatora w Faradach
Zakładając, że użyjemy rezystora 10 MΩ, a czujnik wilgotności ma około 330 pF, ładowanie do 63,2% napięcia będzie trwało:
t = RC = 10 MΩ * 330 pF = 10000000 Ω * 0,00000000033 F = 0,0033 s
Ładowanie do większych części napięcia zasilania to, zgodnie z wykresem wielokrotność tego czasu. Np. dla 95% jest to 3 razy dłuższy czas.
t = 3RC = 3 * 3300 * 10^-6 = 9900 µs
Rozładowywanie jest odwrotnym procesem, w którym przydział czasu rozładowania do wartości napięcia przebiega w ten sposób:
Realizacja w Arduino
Podstawowy model działania układu w projekcie będzie musiał realizować następujące punkty programu:
Ładowanie Kondensatora
Badanie stopnia naładowania
Mierzenie czasu ładowania
Rozładowywanie kondensatora
Układ elektryczny podstawowego modelu przedstawia poniższy rysunek.
PIN 3 odpowiada za ładowanie kondensatora, PIN 2 za rozładowywanie. Analogowy PIN 0 mierzy napięcie kondensatora. Do PIN 3 podłączony jest rezystor ładujący 10 MΩ, Do PIN 2 – rezystor rozładowujący 220 Ω.
Procedura pomiaru pojemności składa się z dwóch następujących po sobie podprogramów.
W ofercie Nettigo znajdują się czujniki nachylenia o zakresie pracy 30° oraz 60° (dokładniej od -30° do +30° od poziomu). Czujnik nachylenia to rodzaj przełącznika. Urządzenie to różni się od normalnych włączników tym, że zaczyna przewodzić prąd po przechyleniu. Skierowany wyprowadzeniami w górę nie przewodzi, natomiast skierowany wyprowadzeniem w dół przewodzi. Sensory takie najczęściej stosuje się w alarmach, gdzie badają położenie samochodu i włączają alarm podczas wciągania pojazdu na lawetę.
Sprzęt
Wykorzystanie czujnika nie jest trudne. Używa się go jak każdego włącznika. Potrzebny tylko wolny PIN cyfrowy w Arduino. Gdy PIN Arduino ustawiony jest na wejście, jego stan jest nieustalony (losowy) do chwili przyłączenia do niego jakiegoś napięcia. Przyłączenie “GND” wyzwala w nim stan “LOW”, natomiast podłączenie 5V wyzwala stan “HIGH”.
Gdy mamy podłączony czujnik do PINu cyfrowego jedną nogą i do “GND” drugą, wiemy że gdy zacznie przewodzić uaktywni się stan “LOW”. Gdy nie przewodzi oczekujemy, że będzie stan przeciwny czyli “HIGH”. W obecnej sytuacji jest to stan nieustalony. Dlatego aby ustalić stan podczas nieprzewodzenia czujnika zastosujemy wbudowany w procesor Arduino rezystor “Pull Up”. Powoduje on, że gdy nie doprowadzamy do PINu żadnego napięcia, automatycznie ustawia się on w stan “HIGH”.
Oprogramowanie
Korzystamy z sensora odczytując stan wybranego PINu cyfrowego. Najpierw w funkcji “setup” należy ustawić kierunek działania PINu na “INPUT” (wejście).
pinMode(numer_pinu, INPUT);
Oraz uaktywnić wbudowany rezystor “Pull Up”.
digitalWrite(numer_pinu, HIGH);
Następnie w funkcji “loop” możesz odczytywać stan PINu, a co za tym idzie położenie czujnika funkcją “digitalRead”.
zmienna = digitalRead(numer_pinu);
Przykładowy program użycia, świecący diodą “L” podczas przechyłu.
// Ustalenie pinu czujnika nachylenia
#define CZUJNIK_PIN 2
// Ustalenie pinu diody LED
#define LED_PIN 13
voidsetup()
{
// Ustawienie wejścia dla czujnika nachyleniapinMode(CZUJNIK_PIN, INPUT);
// Włączenie wbudowanego rezystora Pull Up.digitalWrite(CZUJNIK_PIN, HIGH);
pinMode(LED_PIN, OUTPUT);
}
voidloop()
{
// Sprawdzanie stanu czujnikaif (digitalRead(CZUJNIK_PIN) == HIGH)
{
// Zdarzenie jeśli wyłączonydigitalWrite(LED_PIN, HIGH); // Włączenie LED
}
else
{
// Zdarzenie jeśli włączonydigitalWrite(LED_PIN, LOW); // Wyłączenie LED
}
}
Zadanie
Jak każdy mężczyzna wie, kobieta przechowuje w swej torebce same skarby. Są to o tyle cenne trofea, że nikt nie ma prawa ich przeglądać. Chcąc ochronić biedne niewiasty, a raczej ich torby przed wścibskimi ludźmi postanowiłem skonstruować alarm torebkowy.
Elementy
Do alarmu potrzebne będą:
Czujnik nachylenia do badania pozycji w jakiej znajduje się torebka
Głośnik piezo do informowania o naruszaniu torebki
Elementy połączyłem jak na poniższym schemacie. Wykorzystałem PIN 2 jako wejście czujnika, PIN 3 jako wyjście dla głośnika piezo oraz PIN 13 dla diody LED.
Program nie różni się zbytnio od poprzedniego, za wyjątkiem dodatkowych funkcji generujących dźwięk.
Jak daje się zauważyć alarm jest zbyt wrażliwy i każdy wstrząs (nawet tupanie) powoduje "skrzeczenie" głośniczka. To się może właścicielce torby nie spodobać.
Czym się różnią wstrząsy od grzebania w torbie?
Najłatwiej można je odróżnić po tym jak szybko przełącza się sensor. Wstrząsy przełączają go co tysięczne części sekundy, natomiast poruszenie torby, albo grzebanie trwa od dziesiątych części sekundy do kilku sekund (wliczając przestrach i ucieczkę napastnika). Trzeba więc zmierzyć ile trwało włączenie sensora i jeśli trwało dłużej niż 0,1 sekundy (poruszenie torby) - włączyć alarm.
Użyłem do tego funkcji "millis", która podaje ile milisekund (setnych części sekundy) upłynęło od włączenia Arduino. Można użyć tej funkcji do zapamiętania czasu uruchomienia czujnika. Potem gdy upłynie większa ilość czasu niż mają wstrząsy uruchamia się alarm.
// Ustalenie pinu czujnika nachylenia
#define CZUJNIK_PIN 2
// Ustalenie pinu diody LED
#define LED_PIN 13
// Ustalenie pinu głośniczka piezo
#define PIEZO_PIN 3
// ustalenie czasu czułości czujnika
#define CZUJNIK_TIME 100
// zmienna przechowuje czas przełączenia czujnikaunsignedlong sensor_time;
// funkcja uruchamiana, gdy alarm jest włączonyvoid alarm_on()
{
digitalWrite(LED_PIN, HIGH); // Włączenie LEDtone(PIEZO_PIN, 600); // Dzwięk alarmu
}
// funkcja uruchamiana gdy alarm jest wyłączonyvoid alarm_off()
{
digitalWrite(LED_PIN, LOW); //Wyłączenie LEDnoTone(PIEZO_PIN); // Wyłączenie dźwięku alarmu
}
// funkcja sprawdzająca stan czujnikavoid check_sensor()
{
// Sprawdzanie stanu czujnikaif (digitalRead(CZUJNIK_PIN) == HIGH)
{
// Zdarzenie jeśli wyłączonyif (sensor_time == 0) // Sprawdzenie czy stan został zmieniony
{
sensor_time = millis(); // zapamiętanie czasu uaktywnienia czujnika
}
// Warunek czy stan czujnika trwa określony czaselseif (millis() - sensor_time > CZUJNIK_TIME)
{
alarm_on();
}
}
else
{
// Zdarzenie jeśli włączony
sensor_time = 0;
alarm_off();
}
}
voidsetup()
{
// Ustawienie wejścia dla czujnika nachyleniapinMode(CZUJNIK_PIN, INPUT);
// Włączenie wbudowanego rezystora Pull Up.digitalWrite(CZUJNIK_PIN, HIGH);
pinMode(LED_PIN, OUTPUT);
}
voidloop()
{
check_sensor();
}
Prawdziwy alarm
Nasz torebkowy alarm ma jeszcze jedną wadę. Wyłącza się od razu kiedy tylko torba wróci na swoją pozycję. Tak nie działają prawdziwe alarmy! Prawdziwe alarmy mają też bardziej urozmaicone dźwięki. Tu znowu wykorzystamy funkcję pomiaru czasu "millis". W pierwszej kolejności będziemy mierzyli ile czasu upłynęło od włączenia alarmu. Alarm będzie się wyłączał dopiero, gdy minie ustalona ilość czasu, tak by skutecznie odstraszyć i przyciągnąć uwagę.
W drugiej kolejności wykorzystałem pomiar czasu do sprawdzania długości trwania tonu sygnału dźwiękowego, tak by przełączał się cyklicznie między dwoma (wysokim i niskim). Pozwoli to odróżnić torebkowy alarm od innych hałasów.
// Ustalenie pinu czujnika nachylenia
#define CZUJNIK_PIN 2
// Ustalenie pinu diody LED
#define LED_PIN 13
// Ustalenie pinu głośniczka piezo
#define PIEZO_PIN 3
// ustalenie czasu czułości czujnika [ms]
#define CZUJNIK_TIME 100
// ustalenie czasu trwania alarmu [ms] (5000 ms = 5 s)
#define ALARM_TIME 5000
// zmienna przechowuje czas przełączenia czujnikaunsignedlong sensor_time;
// zmienna przechowuje czas włączenia alarmuunsignedlong alarm_time;
// zmienna przechowuje czas zmiany wysokości syrenyunsignedlong signal_time = 0;
// zmienna przechowuje stopień wysokości dzwięku// 0 - brak dzwięku// 1 - pierwszy ton// > 1 - drugi tonbyte sound_tone = 0;
// funkcja syreny alarmowejvoid alarm_signal()
{
if (sound_tone != 0) // sprawdzenie czy właczyć syrene
{
if (millis() - signal_time > 750) // sprawdzenie długości trwania tonu
{
signal_time = millis(); // zapamiętanie czasu włączenia tonu
sound_tone = ~sound_tone; // włączenie drugiego tonu
}
if (sound_tone == 1) // ton pierwszy
{
tone(PIEZO_PIN, 600);
}
else// ton drugi
{
tone(PIEZO_PIN, 1200);
}
}
else
{
noTone(PIEZO_PIN); // Wyłączenie dźwięku
}
}
// funkcja uruchamiana, gdy alarm jest włączonyvoid alarm_on()
{
alarm_time = millis(); // zapamiętanie czasu włączenia alarmudigitalWrite(LED_PIN, HIGH); // Włączenie LED
sound_tone = 1; // Włączenie syreny alarmowej
}
// funkcja uruchamiana gdy alarm jest wyłączonyvoid alarm_off()
{
if (millis() - alarm_time > ALARM_TIME) // sprawdzenie długości trwania alarmu
{
digitalWrite(LED_PIN, LOW); //Wyłączenie LED
sound_tone = 0; // Wyłączenie syreny alarmowej
}
}
// funkcja sprawdzająca stan czujnikavoid check_sensor()
{
// Sprawdzanie stanu czujnikaif (digitalRead(CZUJNIK_PIN) == HIGH)
{
// Zdarzenie jeśli wyłączonyif (sensor_time == 0) // Sprawdzenie czy stan został zmieniony
{
sensor_time = millis(); // zapamiętanie czasu uaktywnienia czujnika
}
// Warunek czy stan czujnika trwa określony czaselseif (millis() - sensor_time > CZUJNIK_TIME)
{
alarm_on();
}
}
else
{
// Zdarzenie jeśli włączony
sensor_time = 0;
alarm_off();
}
}
voidsetup()
{
// Ustawienie wejścia dla czujnika nachyleniapinMode(CZUJNIK_PIN, INPUT);
// Włączenie wbudowanego rezystora Pull Up.digitalWrite(CZUJNIK_PIN, HIGH);
pinMode(LED_PIN, OUTPUT);
}
voidloop()
{
check_sensor();
alarm_signal();
}
To tylko jedno z zastosowań czujnika nachylenia. Jeśli macie pomysły na inne zastosowania lub pytania - można zostawić komentarz lub skorzystać z maila.
Nasz blog dostał wsparcie w postaci nowego autora (kto uważny ten pewnie już wie kto to :) ), także nowe ciekawe wpisy się szykują a ja tymczasem przygotowuję jak zwykle jakieś kolorowe światełka :)
Zacznijmy od końca, czyli krótki filmik. Dzieło nie jest pasjonujące, bo komórkowa kamerka kolorów zbyt dobrze nie oddaje:
Co zrobić… No to może zdjęcie zmontowanego układu:
RGB LED
Teraz już wiadomo co zacz – dioda RGB – czyli tytułowe trzy diody w jednej – Red, Green, Blue. Czerwona, Zielona, Niebieska. Wspólna katoda, czyli z Arduino będzie łatwo taką diodą sterować – wystarczy wyjście cyfrowe podłączyć (przez rezystor 220 ohm) do odpowiedniej nóżki i już można sterować jednym kolorem.
Która nożka jest która? Pomocny będzie ten obrazek:
Wyprowadzenia diody RGB
Licząc od lewej mamy niebieski, zielony, masa, czerwony. Najdłuższa nóżka to właśnie masa i to pozwala się nam zorientować jak podłączyć diodę.
Co nam daje taka dioda? Otóż można nią uzyskać światło innych barw mieszając trzy kolory w różnym stopniu. Dla zilustrowania tego kod programu użytego w pierwszym przykładzie. Idea jest taka, że każdy z kolorów jest zapalany z różną intensywnością (korzystając z PWM) i różną częstotliwością. Uzyskujemy w ten sposób efekt mieszania się kolorów:
int LED1 = 9;
int s1 = 255;
int LED2 = 10;
int s2 = 255;
int LED3 = 11;
int s3 = 255;
unsignedlongint tme;
voidsetup() {
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
};
voidloop() {
analogWrite(LED1, s1);
s1 = sin(tme*tme/50000.0)*128+128;
analogWrite(LED3, s3);
s3 = sin(tme*tme/100000.0)*128+128;
analogWrite(LED2, s2);
s2 = sin(tme*tme/70000.0)*128+128;
delay(15);
tme++;
};
tme jest zmienną reprezentującą upływ czasu. Dzielimy kwadrat tej zmiennej w loop przez różne wartości i z nich obliczamy sinus. Dzięki temu mamy trzy różne fale (o różnej częstotliwości) każda z nich służy do sterowania jednym kolorem. Ponieważ funkcja kwadrat jest funkcją rosnącą nieliniowo więc przesunięcie w fazie poszczególnych fal powinno się zmieniać z czasem (tak sądzę, choć pewnie sprawdzić by to trzeba dokładniej). Dzięki temu kolory mieszają się różnie a nie w jednym cyklu.
Skutek uboczny jest taki, że z czasem cykle zmiany stają się coraz krótsze i dioda zaczyna migać coraz szybciej…
Jeżeli ktoś potrzebuje takiej diody – od teraz jest dostępna na Nettigo.
Arduino Bluetooth – czyli Arduino bez portu USB, a zamiast tego moduł Bluetooth. Rozwiązanie idealne gdy potrzebna jest komunikacja bezprzewodowa z Arduino.
Najpierw – kilka różnic w stosunku do zwykłego Arduino Duemilanove. Arduino BT jest oparte o ATmega168 – czyli mamy do dyspozycji trochę mniej pamięci. Nie ma portu USB, więc musimy zasilać Arduino BT we własnym zakresie. Jeśli już o zasilaniu mowa – Arduino BT jest wrażliwe na polaryzację zasilania, więc uważnie podłączajcie masę i Vcc do płytki. Na dodatek maksymalne napięcie zasilania płytki to tylko 5.5V!. Na osłodę – dzięki konwerterowi DC/DC minimalne napięcie zasilające to tylko 1.2V.
Arduino Bluetooth
Ponieważ nie ma portu USB, również programowanie odbywa się przez bluetooth. Krótka instrukcja jak to zrobić – system Ubuntu 9.10.
Nie korzystałem z GUI Ubuntu aby skonfigurować połączenie, możliwe że też zadziała ;)
Najpierw (oczywiście po włączeniu Arduino BT) szukamy dostępnych urządzeń:
Oto znaleziony moduł. 00:07:80:91:30:09 – to jest adres MAC urządzenia i oczywiście jest różny dla każdego modułu. Wszędzie gdzie wystąpi teraz ten adres należy zastąpić go właściwym dla Arduino, które wy macie.
Teraz podłączamy się do modułu:
$ sudo hcitool cc 00:07:80:91:30:09
$ sudo hcitool auth 00:07:80:91:30:09
Zapewne poprosi was o PIN – domyślny PIN to 12345.
Potrzebujemy informacji o urządzeniu:
$ sdptool browse 00:07:80:91:30:09
Browsing 00:07:80:91:30:09 ...
Service Name: Bluetooth Serial Port
Service RecHandle: 0x10000
Service Class ID List:
UUID 128: 00001101-0000-1000-8000-00805f9b34fb
Protocol Descriptor List:
"L2CAP" (0x0100)
"RFCOMM" (0x0003)
Channel: 1
Language Base Attr List:
code_ISO639: 0x656e
encoding: 0x6a
base_offset: 0x100
To co jest ważną informacją to RFCOMM i Channel 1. RFCOMM jest to protokół emulacji portu szeregowego w transmisji radiowej.
Teraz można wypisać do /etc/bluetooth/rfcomm.conf:
Oczywiście channel ma mieć taką samą wartość jak ten zwrócony przez sdptool. Mając wpisane powyższe w plik konfiguracyjny możemy się podłączyć:
$ sudo rfcomm connect 0
Connected /dev/rfcomm0 to 00:07:80:91:30:09 on channel 1
Press CTRL-C for hangup
Teraz wystarczyć powinno minicom -s ustawić port na /dev/rfcomm0 i powinniśmy być podłączeni do seriala Arduino.
Teoretycznie :) Arduino BT powinno być fabrycznie zaprogramowane z następującym programem (oryginał bez formatowania):
/* BT test 01 * —————— * Massimo Banzi * */
int LED = 13; // select the pin for the LED int RESET = 7;
voidsetup() { pinMode(LED,OUTPUT); // declare the LED’s pin as output pinMode(RESET,OUTPUT); // declare the LED’s pin as output Serial.begin(115200); // connect to the serial port digitalWrite(RESET, HIGH); delay(10); digitalWrite(RESET, LOW); delay(2000); Serial.println(“SET BT PAGEMODE 3 2000 1″); Serial.println(“SET BT NAME ARDUINOBT”); Serial.println(“SET BT ROLE 0 f 7d00″); Serial.println(“SET CONTROL ECHO 0″); Serial.println(“SET BT AUTH * 12345″); Serial.println(“SET CONTROL ESCAPE – 00 1″); Serial.println(“SET CONTROL BAUD 115200,8n1″); //first release 19200
}
Powinien – z moich skromnych doświadczeń wynika, że z fabryki przychodzi z klasycznym blink – cyfrowy pin 13 zapala się i gaśnie. Tak też jest w powyższym kodzie, ale powinien jeszcze pisać komunikat “ciao” na serial. Nie udało mi się na ‘świeżym’ Arduino BT uzyskać tego komunikatu na serialu (na /dev/rfcomm0 była cały czas cisza), choć pin 13 faktycznie się przełączał (Arduino BT nie ma na płytce diody podłączonej do 13 więc trzeba samemu podłączyć)
Pozostaje wgrać powyższy kod na płytkę. Najlepiej na stałe powiedzieć Arduino IDE, że chcemy korzystać z BT i do pliku ~/.arduino/preferences.txt dodać:
Teraz można bez problemu wgrać powyższy program. Uwaga – nawet jeżeli Arduion IDE pisze że korzysta z /dev/ttyS0 czy USB0 to przy powyższym wpisie do preferences.txt powinno wgrywać przez rfcomm0.
Wgrać bez problemu – jeżeli wie się jak to zrobić. Otóż obecne Arduino wyposażone w USB mają firmware pozwalający wgrać w każdej chwili nowy kod (przez USB jest robiony reset płytki po którym jest wgrywany nowy kod). Wersja firmware na Arduino BT nie wspiera tej wygodnej funkcji więc trzeba ręcznie zresetować moduł (przycisk S1) i w ciągu 1 sekundy nacisnąć ‘Upload’ w IDE.
Po takim zabiegu powyższy programik wgra się bez problemu i od teraz minicom nam będzie pokazywał ciao.
Ostatnim z elementów Arduino Starter Kitu, który jeszcze nie doczekał się opisu na tym blogu jest niepozorny układ scalony – rejestr przesuwny. Jest układ 74HC595, rejestr przesuwny typu SIPO (Serial-In, Parallel-Out) o 8 wyjściach szeregowych.
Rejestr przesuwny (ang. shift register) jest układem posiadającym wejście szeregowe i kilka (zazwyczaj 8) wyjść równoległych. Co to znaczy? Z każdą zmianą zegara na wejściu, stany wyjść są przesuwane o jeden. Czyli stan wyjścia 1 jest przepisywany do wyjścia 2, 2 do 3, itd. Stan wejścia 1 jest ustalany na podstawie stanu wejścia szeregowego.
Do czego można to zastosować w praktyce?
Każde miejsce które potrzebuje wielu wyjść cyfrowych, może być miejscem w którym można rozważyć zastosowanie rejestru przesuwnego. Można powiedzieć, że trzy piny mogą sterować znacznie większa ilością wyjść. Zobaczmy to na najprostszym przykładzie – diody LED.
Dzisiejszy artykuł jest oparty na przewodniku opublikowanym na stronach Arduino.cc, stanowi on źródło ilustracji i tekstu. Ilustracje wykorzystują więcej niż jedną płytkę stykową, ale zdecydowałem się je wykorzystać, aby przyspieszyć powstawanie tego wpisu – zrobienie dobrej ilustracji do tego wpisu we Fritzingu chyba nie jest możliwe (hint – czytelnej ilustracji :) )
Zacznijmy od podłączenia:
Schemat układu z rejestrem przesuwnym - zamontowany na płytce stykowej
Zasilanie jest rozprowadzone przez szyny na płytce stykowej. Na lewej płytce są podłączone diody LED wraz rezystorami. Na prawej jest podłączony sam układ scalony 74HC595. Jego wyprowadzenia:
Wyprowadzenia pinów 74HC595
Na powyższym diagramie przedstawione są wyprowadzenia pinów opisane zgodnie z danymi producenta (ST Microelectronics), którego to układy są w ofercie Nettigo i stanowią część Starter Kitu. Na stronie Arduino jest opis przystosowany dla układów z oznaczeniami zgodnymi z nomenklaturą Philipsa. Co to znaczy? Na szczęście w tym wypadku różnica polega tylko w nazwach sygnałów (np wyjścia w STM – QA do QH, w wersji Philipsa Q0-Q7), położenie i znaczenie pinów jest identyczne. W tym przewodniku będę używał nazewnictwa zgodnego z STM.
Najprostsze podłączenie rejestru przesuwnego do Arduino wygląda następująco:
Zasilanie +5V do pinu 16 rejestru
Masa do pinu 8 rejestru
Jeżeli nie przeszkadza nam to, że po włączeniu diody mogą się nam zapalić w losowym układzie a chcemy użyć mniej wyjść cyfrowych na Arduino podłączamy:
G – pin 13 na rejestrze do masy
SCLR – pin 10 na rejestrze do +5V
Minimalny zestaw podłączeń do sterowania rejestrem z Arduino przedstawia się następująco (wszystkie piny na Arduino to wejścia cyfrowe):
SI – pin 14 rejestru do pinu 11 na Arduino
SCK – pin 11 rejestru do pinu 12 na Arduino
RCK – pin 12 rejestru do pinu 8 na Arduino
Między pinem RCK a masą może być potrzebny mały kondensator (1 μF – nie jest częścią Starter Kitu). Z serii eksperymentów które przeprowadziłem wynika, że nie powinien być potrzebny :)
Oto schemat logiczny całego połączenia:
Schemat logiczny układu
Co nam pozostaje? Program:
//**************************************************************//
// Name : shiftOutCode, One By One //
// Author : Carlyn Maw, Tom Igoe //
// Date : 25 Oct, 2006 //
// Version : 1.0 //
// Notes : Code for using a 74HC595 Shift Register //
// : to count from 0 to 255 //
//****************************************************************
//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 11;
//holder for infromation you're going to pass to shifting function
byte data = 0;
void setup() {
//set pins to output because they are addressed in the main loop
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
void loop() {
//function that blinks all the LEDs
//gets passed the number of blinks and the pause time
blinkAll(1,500);
// light each pin one by one using a function A
for (int j = 0; j < 8; j++) {
lightShiftPinA(j);
delay(1000);
}
blinkAll(2,500);
// light each pin one by one using a function A
for (int j = 0; j < 8; j++) {
lightShiftPinB(j);
delay(1000);
}
}
//This function uses bitwise math to move the pins up
void lightShiftPinA(int p) {
//defines a local variable
int pin;
//this is line uses a bitwise operator
//shifting a bit left using << is the same
//as multiplying the decimal number by two.
pin = 1<< p;
//ground latchPin and hold low for as long as you are transmitting
digitalWrite(latchPin, LOW);
//move 'em out
shiftOut(dataPin, clockPin, MSBFIRST, pin);
//return the latch pin high to signal chip that it
//no longer needs to listen for information
digitalWrite(latchPin, HIGH);
}
//This function uses that fact that each bit in a byte
//is 2 times greater than the one before it to
//shift the bits higher
void lightShiftPinB(int p) {
//defines a local variable
int pin;
//start with the pin = 1 so that if 0 is passed to this
//function pin 0 will light.
pin = 1;
for (int x = 0; x < p; x++) {
pin = pin * 2;
}
//ground latchPin and hold low for as long as you are transmitting
digitalWrite(latchPin, LOW);
//move 'em out
shiftOut(dataPin, clockPin, MSBFIRST, pin);
//return the latch pin high to signal chip that it
//no longer needs to listen for information
digitalWrite(latchPin, HIGH);
}
//blinks the whole register based on the number of times you want to
//blink "n" and the pause between them "d"
//starts with a moment of darkness to make sure the first blink
//has its full visual effect.
void blinkAll(int n, int d) {
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, 0);
digitalWrite(latchPin, HIGH);
delay(200);
for (int x = 0; x < n; x++) {
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, 255);
digitalWrite(latchPin, HIGH);
delay(d);
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, 0);
digitalWrite(latchPin, HIGH);
delay(d);
}
}
Kod mignie wszystkimi diodami, potem zapali każdą po kolei diodę, mignie dwa razy wszystkimi i jeszcze raz zapali, korzystając z innej metody.
Najważniejsze wiadomości:
shiftOut to funkcja biblioteki Arduino, wysyłająca szeregowo wybrany bajt na wybrane wyjścia
ustawiając RCK (na Arduino podłaczony do 8) w stan niski możemy wysyłać dane do rejestru