Pokazywanie postów oznaczonych etykietą hardware. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą hardware. Pokaż wszystkie posty

2013-01-17

Sygnały analogowe/cyfrowe. Potencjometr.


Sygnały analogowe i cyfrowe.

W świecie elektroniki powszechnie mamy do czynienia z sygnałami analogowymi i cyfrowymi. W internecie oczywiście możemy znaleźć masę informacji na ten temat. Ja tylko napiszę pokrótce, że sygnał cyfrowy przyjmuje wartość typu HIGH lub LOW, 1 lub 0, włączony lub wyłączony - czyli są 2 rodzaje wartości i nic pomiędzy nimi. Natomiast analogowe sygnały mogą przyjmować dowolną wartość w wybranym zakresie.
Przykładem (cyfrowym) jest tu np włącznik światła (który jest włączony lub wyłączony), czy np pokrętło głośności w radio (analogowy). Dobry do wyjaśnień jest również wspomniany już tu kiedyś kontroler PS3, który ma przyciski działające z sygnałem cyfrowym (wciśnięty, niewciśnięty), czy też analogową gałkę - mogącą przyjąć różne wartości.


Które są lepsze/bardziej przydatne? Oczywiście zależy od zastosowań.

Dlaczego o tym wspominam?
Do tej pory mieliśmy tu do czynienia z elementami cyfrowymi. I było to stosunkowo proste. Raspberry Pi samodzielnie nie potrafi jednak w żaden sposób "zrozumieć" sygnałów analogowych.  A co - jeśli będziemy chcieli (musieli) wykorzystać "coś" analogowego? (a nie chcemy korzystać np. z Arduino)

Wtedy przyda się nam dekoder analogowo - cyfrowy i właśnie tym się zajmiemy w tym poście.

Ja zakupiłem model PCF8591P. Koszt to niecałe 12zł.

Dane techniczne.

PCF8591P - Przetwornik A/C i C/A 8-bit DIP16

  •  Zasilanie: 2.5V - 6V
  •  Interfejs: I2C
  •  Obudowa: DIP16


Dokładniejsza dokumentacja TUTAJ

Opis slotów:





Przetwornik jest 8-bitowy, więc maksymalna wartość to 255. 

Zakupiłem też potencjometr obrotowy, który jest dobrym generatorem sygnałów analogowych :) Wraz z nakładką kosztował niecałe 2 zł. 

Dane techniczne.

Potencjometr obrotowy 10K:

  • Długość osi: 15mm
  • Średnica osi: 6mm
  • Kąt obrotu: 300°
  • charakterystyka: liniowa
  • tolerancja: +/- 20%
  • moc: 0,125W
  • temp. pracy: -10°C ÷ +70°C






Układ

potencjometr:
środkowy pin to OUT - czyli podłączamy do dekodera (tu mała uwaga - niektóre potencjometry mają dwie nóżki po jednej stronie i jedną nóżkę po drugiej stronie - wtedy "samotna" to OUT)

lewy pin do GND

prawy pin do 5V



dekoder:

AIN1 - analog input 1 - tu podłączamy środkowy pin potencjometru

AIN2 , 3, 4 - możemy podłączyć inne analogowe urządzenia - teraz nieużywane, więc do GND

A0-A2 - hardware address - też GND

VSS - negative supply - czyli też GND

Vdd - +5V

Aout - nie używany (nie podłączamy nigdzie)
Vref - + 5V
Agnd - analog ground - oczywiście GND
EXT - GND
OSC - nie używany (nie podłączamy nigdzie)
SCL - clock line - pin 5 w RPI GPIO 1 (I2C SCL)
SDA - data line - pin 3 w RPI GPIO 0 (I2C SDA)






Następnie musimy załadować odpowiednie moduły. W standardzie Raspbiana potrzebne nam moduły są "banowane", czyli nie można ich załadować. Tak więc edytujemy plik:
/etc/modprobe.d/raspi-blacklist.conf

i hashujemy:

#blacklist spi-bcm2708
#blacklist i2c-bcm2708

Następnie ładujemy moduły:
sudo modprobe spi-bcm2708
sudo modprobe i2c-bcm2708
sudo modprobe i2c-dev

W dmesg powinno pojawić się coś w tym stylu:

[270822.607823] bcm2708_spi bcm2708_spi.0: SPI Controller at 0x20204000 (irq 80)
[270828.657896] bcm2708_i2c bcm2708_i2c.0: BSC0 Controller at 0x20205000 (irq 79) (baudrate 100k)
[270828.658130] bcm2708_i2c bcm2708_i2c.1: BSC1 Controller at 0x20804000 (irq 79) (baudrate 100k)
[270875.242767] i2c /dev entries driver

Powinny pojawić się też 2 nowe urządzenia:
crw------- 1 root root 89, 0 Jan 14 23:32 /dev/i2c-0
crw------- 1 root root 89, 1 Jan 14 23:32 /dev/i2c-1

Kolejnym krokiem jest instalacja pakietów:
apt-get install python-smbus i2c-tools

I możemy przetestować czy wszystko jest w porządku. Sprawdzanie wykrycia urządzenia:

# i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

czy też sprawdzenie aktualnej wartości (na potencjometrze)
# i2cget -y 1 0x48
0x4c

Kod

Tu skorzystałem z zasobów forum LINK i pracy Grumpy Mike-a. Pozdrowienia :) Jako że dekoder pracuje przez interfejs i2c - kod wygląda nieco inaczej niż w poprzednich przypadkach.

#Read a value from analogue input 0
#in A/D in the PCF8591P @ address 0x48
from smbus import SMBus
import time

bus = SMBus(1)

print("Read the A/D")
print("Ctrl C to stop")
bus.write_byte(0x48, 0) # set control register to read channel 0
last_reading =-1

while(0 == 0): # do forever
   reading = bus.read_byte(0x48) # read A/D
   
   if(abs(last_reading - reading) > 2):
      print(last_reading - reading)
      last_reading = reading


2013-01-11

Czujnik odległości

Kolejnym moim testem jest ultradźwiękowy czujnik odległości - model HC - SR04.




Dane techniczne:

  • Zasilanie: DC 5 V
  • Częstotliwość: 40Hz
  • Max zasięg: 4m
  • Min zasięg: 2cm
  • Kąt działania: 15º 
  • Wymiary: 45*20*15mm
  • Waga: 90 gr
Dokumentacja TUTAJ, koszt takiego urządzenia to około 3 euro. Jak być może widać na rysunku czujnik posiada 4 piny: 5V, OUTPUT, TRIGGER, GND.


Sposób działania:

W stanie nieaktywnym na pinie OUTPUT jest zawsze 0V. Żeby aktywować czujnik (czyli, żeby wygenerowany został impuls ultradźwiękowy - a dokładniej 8 takich impulsów) wysyłany jest sygnał (co najmniej 10us) na port TRIGGER. Na porcie OUTPUT pojawia się wtedy stan wysoki (+5V) i pozostaje on w tym stanie dopóki sygnał ultradźwiękowy nie powróci do czujnika (czyli po odbiciu się od badanego obiektu). Żeby wyznaczyć odległość musimy zmierzyć ten czas, wziąść pod uwagę prędkość dźwięku i podzielić na 2 (bo droga jest do obiektu i z powrotem).
Tu niestety należy zwrócić uwagę na spore ograniczenie tego zestawu - czyli dużą niedokładność mierzenia czasu na RPI/Linuxie... Tak naprawdę powinniśmy zastosować dodatkowy hardware (albo wykorzystać np. Arduino), zapewniający nam dokładniejsze wyliczenia czasu. Dla zainteresowanych szczegółami proponuje poszukać zagadnienia "non realtime os".


OSTRZEŻENIE !
Przy podłączaniu wszelkich kabelków należy zachować ostrożność, gdyż może zakończyć się to uszkodzeniem sprzętu lub uszczerbkiem na zdrowiu. Robisz to na własną odpowiedzialność.


Układ:

Od razu zaznaczę, że tym razem znalazłem gotowe rozwiązanie i niezbyt wysilałem się intelektualnie. Za układ i kod możemy podziękować autorowi tej strony:

Jak możemy wyczytać na powyższej stronce - problemem tego czujnika (w przypadku współpracy z Malinką) jest fakt, że pracuje z napięciem 5V. Jak już wiemy (np. STĄD) porty GPIO mogą pracować z napięciem 3.3V, więc musimy wykorzystać prostą sztuczkę z rezystorami.

tak więc układ:

+5V - pin 2 w RPI
GND -  pin 6 w RPI
Trigger - GPIO 23
Echo - rezystor 330 Ω (lub 1K) -> GPIO 24 -> rezystor 470 Ω (lub 1K5) -> GND

Źródło: raspberrypi-spy.co.uk

wartości rezystorów mogą być oczywiście inne - tak jak zaleca autor - muszą spełniać zależność :
R1 < R2 < 2*R1

Przydałoby się jednak kupić kolorowe kabelki ;)

Kod:

kod wrzucam również w oryginale (szacunek dla autora), mimo, że ja go nieco zmodyfikowałem (np. wrzuciłem pętle, żeby odległość sprawdzana była co parę sekund - w ten sposób wygodniej mi było testować ;) ).

#!/usr/bin/python
#+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#|R|a|s|p|b|e|r|r|y|P|i|-|S|p|y|.|c|o|.|u|k|
#+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#
# ultrasonic_1.py
# Measure distance using an ultrasonic module
#
# Author : Matt Hawkins
# Date   : 09/01/2013

# Import required Python libraries
import time
import RPi.GPIO as GPIO

# Use BCM GPIO references
# instead of physical pin numbers
GPIO.setmode(GPIO.BCM)

# Define GPIO to use on Pi
GPIO_TRIGGER = 23
GPIO_ECHO = 24

print "Ultrasonic Measurement"

# Set pins as output and input
GPIO.setup(GPIO_TRIGGER,GPIO.OUT)  # Trigger
GPIO.setup(GPIO_ECHO,GPIO.IN)      # Echo

# Set trigger to False (Low)
GPIO.output(GPIO_TRIGGER, False)

# Allow module to settle
time.sleep(0.5)

# Send 10us pulse to trigger
GPIO.output(GPIO_TRIGGER, True)
time.sleep(0.00001)
GPIO.output(GPIO_TRIGGER, False)
start = time.time()

while GPIO.input(GPIO_ECHO)==0:
  start = time.time()

while GPIO.input(GPIO_ECHO)==1:
  stop = time.time()

# Calculate pulse length
elapsed = stop-start

# Distance pulse travelled in that time is time
# multiplied by the speed of sound (cm/s)
distance = elapsed * 34300

# That was the distance there and back so halve the value
distance = distance / 2

print "Distance : %.1f" % distance

# Reset GPIO settings
GPIO.cleanup()

A to mój profesjonalny zestaw do badań skuteczności czujnika ;) czyli pusta przestrzeń, miarka oraz ciemny przedmiot z prostym kształtem. 



Wg moich badań precyzja jest naprawdę dobra. Powtarzalność wyników jest bardzo dobra (nie skacze np o parę centymetrów), dokładność również całkiem niezła. Dla prostych zastosowań zdecydowanie wystarczająca.  
Zbadałem też układ z innymi przedmiotami i wyniki również są obiecujące. Ultradźwięk to jednak dobra opcja.

Podsumowując, mimo swoich ograniczeń czujnik + RPI to ciekawy zestaw. Jeśli w naszym projekcie niezbędna jest duża precyzja to zapewne warto poszukać innego rozwiązania, jeśli możemy przymknąć na to nieco oko - zdecydowanie polecam.

To już chyba mój ostatni czujnik na tą chwilę. Pora się zabrać za jakiś konkretny projekt. Mam pomysł (mam nadzieję, że starczy mi chęci i umiejętności) - ale do jego realizacji jeszcze dłuuuuga droga. W międzyczasie będę starał się wrzucać kolejne posty dotyczące RPI.    

2013-01-10

Detektor ruchu/PIR

Następny na mojej liście testów jest detektor ruchu PIR (czyli Passive Infra-Red sensor).
Zakupiłem model  HC-SR501, kosztował niecałe 4euro.





Dane techniczne:
  • Zasięg: 3 - 7 m
  • Kąt: 110º
  • Napięcie wyjścia: 3.3V
  • Temperatura działania: -20℃ - +50℃
  • Wymiary: 32*24 mm

Po wykryciu ruchu sensor podaje 3,3 V (idealnie dla RPI) na wyjściu. 
Posiada 2 potencjometry: SENSITIVE i TIME oraz jeden jumper.
TIME - czas "podawania" napięcia na wyjściu - definiowalny od 3 do 18 sekund.
SENSITIVE - dystans, na którym czujnik ma wykrywać ruch (3-7metrów)
JUMPER - stan H - po wykryciu ruchu działanie czujnika jest wstrzymane (na czas zdefiniowany przez TIME)
JUMPER - stan L - czujnik działa cały czas


OSTRZEŻENIE !
Przy podłączaniu wszelkich kabelków należy zachować ostrożność, gdyż może zakończyć się to uszkodzeniem sprzętu lub uszczerbkiem na zdrowiu. Robisz to na własną odpowiedzialność.


Układ:

pin 5V - do portu 2 w RPI
pin OUT - do GPIO 23 w RPI
pin GND - wiadomo
(podłączyłem to kabelkami męsko - żeńskimi, gdyż nie ma zbytnio opcji wpięcia bezpośrednio do płytki stykowej)
no i dodałem jeszcze diodę - podłączoną tak samo jak TUTAJ






Po podłączeniu napisałem prosty skrypt - który przy wykryciu napięcia na porcie OUT zapali diodę.

import RPi.GPIO as GPIO
 
PIR = 23
LED = 14
 
GPIO.setmode(GPIO.BCM)
GPIO.setup(PIR, GPIO.IN)
GPIO.setup(LED, GPIO.OUT)
 
while True:
    if GPIO.input(PIR):
        GPIO.output(LED, True)          
    else:
        GPIO.output(LED, False)         

no i działa.

Przemyślenia. 
Po testach stwierdzam, że czujnik jest dość precyzyjny, jego czas reakcji jest bardzo szybki, tylko nie do końca podoba mi się fakt, że minimalny czas podawania napięcia po wykryciu ruchu jest tak długi (3 sekundy - choć i tak dobrze, że jest sterowany), no ale można to było wyczytać w dokumentacji ;)


Zastosowanie.
Naprawdę przeróżne. Można stworzyć nawet automatycznie otwierane drzwi, czy system wykrywania obecności domowników + zapalanie światła albo np dla miłośników przyrody - system wykrywania obecności ptaków w karmniku + zrobienie zdjęcia przez kamerkę :)

Jako ciekawostkę wrzucam tu filmik dotyczący detekcji ruchu - żebyśmy bli przygotowani na różne możliwości;) (nie do końca ma to związek z "naszym" rodzajem detektora ruchu ale ten program zawsze warto obejrzeć ;) )





2013-01-09

Odbiornik podczerwieni/LIRC

Kolejnym moim testem jest podłączenie odbiornika podczerwieni.

Zakupiłem odbiornik IR typu TSOP4838.

Źródło: vishay.com

Nie mam dokładnej dokumentacji, ale z tego co wyczytałem pracuje na częstotliwości 38kHz, ma duży zasięg (niby do 35m), odbiór sygnału pod kątem do 45° i co najważniejsze dobrze pracuje na 3.3V. Można go dostać dość łatwo, mnie kosztował ~3 zł. 

UPDATE: dokumentacja TUTAJ


OSTRZEŻENIE !
Przy podłączaniu wszelkich kabelków należy zachować ostrożność, gdyż może zakończyć się to uszkodzeniem sprzętu lub uszczerbkiem na zdrowiu. Robisz to na własną odpowiedzialność.


UKŁAD
Podłączenie jest banalne, pierwszy pin do GPIO18 (6 z prawej), drugi pin to GND, trzeci pin to 3.3V.  


Instalujemy:
apt-get install lirc
Ładujemy moduł:
modprobe lirc_rpi
w syslogu powinno pojawić się
Dec 31 16:29:04 raspberrypi kernel: [11871.816457] lirc_rpi: auto-detected active low receiver on GPIO pin 18
powinno pojawić się też urzadzenie
# ls -la /dev/lirc0
crw-rw---T 1 root video 250, 0 Dec 31 16:29 /dev/lirc0
następnie
mode2 -d /dev/lirc0
bierzemy pilota (dowolnego - może być od telewizora) i każde wciśnięcie klawisza powinno generować komunikaty pulse space z numerkami...

Coś w tym stylu:
space 17826
pulse 129
space 803
pulse 174
space 790
pulse 100
space 18114
pulse 183
space 806
pulse 205
space 775
pulse 157
space 18484
pulse 222
space 1516
Są to "kody", które odpowiadają wciśnięciu poszczególnych klawiszy. Zamysł jest więc taki, żeby wychwycić taki kod i po jego wystąpieniu wywołać konkretne zdarzenie.

Skorzystamy więc z demona lirc.
LIRC to bardzo ciekawy projekt. Wiele mówiący skrót  Linux Infrared remote control. Polecam poczytanie dokumentacji i możliwości.
Projekt oferuje masę gotowych konfigów - lista supportowanych pilotów:
http://lirc.sourceforge.net/remotes/

Ja gdzieś wygrzebałem bardzo stary pilot, więc wygeneruję sobie plik konfiguracyjny sam.
Najpierw przyda się znajomość dostępnych nazw poszczególnych klawiszy.
irrecord --list-namespace
następnie odpalamy (tu zmiana (lircd.conf) dzięki komentarzom - dzięki:) )
irrecord -d /dev/lirc0 ~/lircd.conf
czyli generator konfiguracji. Każe nam powciskać różne klawisze, po czym mamy gotowy plik z kodami raw dla każdego klawisza pilota.
np dla klawisza 1 w moim pilocie raw_code wygląda tak:
          
name KEY_1

             9096    4465     621     515     619     520

              601     512     625     519     585     546

              600     517     620     517     616     521

              598     516     625    1649     600    1662

              610    1632     623    1653     599    1655

              616    1634     631    1646     597     517

              625     512     595    1659     620     517

              617     521     597     520     627     510

              616     522     594    1655     595    1658

              619     520     616    1633     632    1644

              599    1654     618    1636     620    1654

              600

Kopiujemy wygenerowany plik do /etc/lirc. Następnie musimy przygotować kolejny plik:

# cat /etc/lirc/hardware.conf

# Arguments which will be used when launching lircd
LIRCD_ARGS="--uinput"

#Don't start lircmd even if there seems to be a good config file
#START_LIRCMD=false

#Don't start irexec, even if a good config file seems to exist.
#START_IREXEC=false

#Try to load appropriate kernel modules
LOAD_MODULES=true

# Run "lircd --driver=help" for a list of supported drivers.
DRIVER="default"

# usually /dev/lirc0 is the correct setting for systems using udev
DEVICE="/dev/lirc0"
MODULES="lirc_rpi"

# Default configuration files for your hardware if any
LIRCD_CONF=""
LIRCMD_CONF=""
i możemy wystartować demon
/etc/init.d/lirc start
Weryfikujemy działanie przez komendę:
irw
przy wciśnięciu każdego zdefiniowanego klawisza powinna pojawić się jego nazwa:
0000000000000001 00 KEY_1 pilotMOJ
0000000000000002 00 KEY_2 pilotMOJ
0000000000000003 00 KEY_3 pilotMOJ
000000000000000b 00 KEY_OK pilotMOJ
Tak więc teraz możemy zmapować przycisk do dowolnej komendy. Tworzymy w katalogu domowym plik .lircrc i umieszczamy w nim definicję:
# cat ~/.lircrc
begin
 prog = irexec
 button = KEY_1
 config = echo "Klawisz '1' wcisniety!"
end
uruchamiamy 
irexec
i wciskamy na pilocie przycisk 1, powinno się pojawić
Klawisz '1' wcisniety!
Inna opcja. Tworzymy skrypt, upewniamy się, że jest uruchamialny lub korzystamy z już utworzonego. Ja np po wciśnięciu OK chce mieć wyświetloną temperaturę na dworzu. Korzystam ze skryptu opisanego TUTAJ i dodaję:
begin
 prog = irexec
 button = KEY_OK
 config = echo "Temperatura w tym momencie:"; /projekty/temperatura/getTemp.sh
end

Możemy uruchomić irexec jako demon poprzez:
irexec -d

i aplikacja będzie działać na stałe w tle.

Dokumentacja z parametrami TUTAJ
Warto zwrócić uwagę na parametr repeat - czyli co się stanie jeśli drugi raz wciśniemy dany przycisk. Nieraz nie chcemy przecież, żeby dana aplikacja odpaliła się raz jeszcze, ale np chcemy żeby okno zrobiło się aktywne (np. wyskoczyło okno wcześniej zminimalizowane). Ogólnie jest to dość potężny projekt, więc da się z nim dużo zrobić.

No to teraz ogranicza nas już tylko wyobraźnia. Możemy podpiąć dowolną aplikację pod dowolny przycisk w pilocie i sterować różnymi zdarzeniami (np. uruchomienie XBMC, przeglądarki, wyłączenie systemu, zapalenie diody itp).

Jeszcze tylko dodam, że istnieje projekt umożliwiający współpracę z python-em. Więcej szczegółów http://pylirc.mccabe.nu/

Jest nawet w repozytorium Raspbian-a, więc można go zainstalować:
apt-get install python-pylirc

Inne zastosowanie. 
Np jeśli mamy problemy z libcec, a chcemy korzystać z pilota w XBMC (wspomniane TUTAJ), możemy podpiąć odbiornik i korzystać z dobrodziejstw pilota (jako, że sposób podłączenia jest banalny możemy to zrobić nawet bez płytki stykowej). Oczywiście nie musimy ograniczać się do XBMC - możemy wykorzystać pilota do innych aplikacji. Masa aplikacji multimedialnych ma gotowe konfigi dla pilotów.
Poza tym możemy podpiąć się do wielu domowych urządzeń (np. lampka nocna), czy całe systemy "home automation" i sterować nimi za pomocą zwykłego pilota. Tu prawie nie ma ograniczeń (aczkolwiek zazwyczaj przydaje się już nieco bardziej zaawansowana wiedza z zakresu elektroniki).


2012-12-27

Czujnik temperatury


Kolejnym krokiem w moich testach jest czujnik temperatury. Zakupiłem bardzo typowy, łatwo dostępny w Polsce czujnik DS18B20, kosztuje niecałe 4zł.

Dane techniczne:
DS18B20 - Czujnik temperatury TO92
  • Napięcie pracy: 3 - 5,5V
  • Mierzona temperatura: -55°C - + 125°C
  • Dokładność: 0,5°C
  • Interfejs: 1-Wire
  • Obudowa: TO92

Źródło: electropark.pl


Interfejs 1-wire powinien być możliwy do uruchomienia w każdym najnowszym jądrze...
Jeśli ktoś ma z problem z 1-wire polecam zajrzeć tutaj:

albo użyć systemu Adafruit - Occidentials:

W każdym razie na najnowszym Raspbianie również działa.

OSTRZEŻENIE !
Przy podłączaniu wszelkich kabelków należy zachować ostrożność, gdyż może zakończyć się to uszkodzeniem sprzętu lub uszczerbkiem na zdrowiu. Robisz to na własną odpowiedzialność.

UKŁAD

Tradycyjnie opis GPIO możemy znaleźć TUTAJ

Pierwszy pin czujnika to GND
Drugi pin do GPIO 4 (4 z lewej) oraz rezystor 4k7 do +
trzeci pin do +
no i + do 3.3V w RPI




Następnie ładujemy moduły (można je oczywiście dodać na stałe w /etc/modules)
sudo modprobe w1-gpio
sudo modprobe w1-therm

i weryfikujemy
cd  /sys/bus/w1/devices/

tu powinien być katalog zaczynający się na 28-...
# cat 28-000004458ce3/w1_slave 

3e 01 4b 46 7f ff 02 10 6c : crc=6c YES
3e 01 4b 46 7f ff 02 10 6c t=19875


czyli w moim przypadku temperatura to około 19,87 °C (wartość t= podzielona przez 1000)

MRTG
Jakiś czas temu napisałem krótkiego posta jak skonfigurować mrtg. Teraz jeden praktyczny pomysł jak to wykorzystać.
Podepniemy tu wyniki z czujnika, żeby rysowało nam wykresy.
Dodatkowo (dla większego bajeru;) ) jako porównanie dodamy drugą wartość - np temperaturę ze stolicy (to już oczywiście ściągane z internetu - np z www.wunderground.com)
Od razu zaznacze, że zapewne da się to zrobić inaczej/łatwiej, ale jako, że nie mam duszy programisty zrobiłem to właśnie tak.

Najpierw upewniamy się, że mamy zainstalowany pakiet links
Szukamy na www.wunderground.com miasta np Warszawa, klikamy na nazwie stacji pogodowej... na samym dole jest link do CDF (Comma Delimited File)
w przypadku Wawy ostateczny link to:
http://www.wunderground.com/history/airport/EPWA/2012/12/25/DailyHistory.html?format=1
ostatnia linia to najbardziej aktualny odczyt

W międzyczasie przypomniało mi się, że MRTG zaokrągla liczby (nie bierze pod uwagę wartości po przecinku, czyli 20,46°C to po prostu będzie 20). Dlatego postanowiłem zrobić małe obejście i pomnożyć każdy wynik * 10 - żeby mieć na wykresach nieco większą dokładność (czyli 20,46°C - to będzie 204 w moim przypadku). Tu tylko zaznaczę, że równie dobrze można wykorzystać czyste rrdtool, która ma dokładność do 3 miejsc po przecinku - ale szczerze mówiąc nie chciałem na to już zużywać zbyt dużo czasu.

Tak więc do /etc/mrtg.conf dodajemy

Title[temper]: Temperatura * 10
PageTop[temper]: Temperatura * 10
Target[temper]: `/projekty/temperatura/getTemp.sh`
MaxBytes[temper]: 500
Options[temper]: nopercent,growright,nobanner,nolegend,noinfo,gauge
ShortLegend[temper]: C
LegendI[temper]: Temperatura dom * 10
LegendO[temper]: Temperatura SF * 10
YLegend[temper]: Stopnie C

Tworzymy skrypt, który będzie weryfikował temperaturę lokalnie i z internetu.

#!/bin/bash

DATAdlaLINKSA=`date +%Y/%m/%d`
LINK_TEMP="http://www.wunderground.com/history/airport/EPWA/$DATAdlaLINKSA/DailyHistory.html?format=1"

# weryfikacja czy załadowany jest moduł
lsmod | grep w1_therm > /dev/null 2>/dev/null
if [ $? = 0 ]
then
        echo ok >/dev/null
else
        sudo modprobe w1_gpio
        sudo modprobe w1_therm
fi

TEMPczujnik=`cat "/sys/bus/w1/devices/28-000004458ce3/w1_slave"  | grep "t=" | cut -d "=" -f 2`
echo "scale=2;  $TEMPczujnik / 100" | bc

TEMPWAW=`links -width 150 -dump $LINK_TEMP | tail -1 | cut -d "," -f 2`
echo "scale=2; $TEMPWAW * 10" | bc


Przy zrzucie stronki przez links - ostatnia linia (zebrana przez tail -1) pokazuje standardowo tylko godzinę... pewnie jest na to inne rozwiązanie, ale nie chciałem za bardzo wnikać i poszerzyłem po prostu zakres dla linksa (-width 150).

Odpalamy jeszcze raz indexmaker i po jakimś czasie powinniśmy mieć wykresy.


Niebieska linia to wyniki z internetu, a zielone słupki to nasz czujnik.

Jeśli chodzi o już zupełnie praktyczne zastosowanie - myślę, że trochę tego jest - np. monitor temperatury w garażu, szklarni, pomieszczenia w którym szykujemy wino, serwerowni itp.
Można sięgnąć nieco (naprawdę tylko nieco) głębiej do kieszeni i zakupić wodoodporny czujnik i monitorować temperaturę płynów itp.

2012-12-24

Pierwsze kroki z elektroniką


WSTĘP

Zamówione części elektroniczne dotarły w końcu na miejsce, więc nadeszła pora na pierwsze testy.
Na początek zamówiłem min. :
trochę diod LED, 
trochę kabelków połączeniowych (na początek póki nie wykorzystam Cobbler-a szczególnie przydadzą się kabelki męsko - żeńskie), 
zestaw rezystorów,
wyświetlacz,
potencjometry,
przyciski,
kilka czujników (między innymi czujnik temperatury).
Dostałem też w prezencie używaną płytkę stykową (na 830 pól). Delikatnie stopiony kawałek ale działa :)

Z czasem przedstawię tu więcej szczegółów.

Do takich zabaw z RPI bardzo przydatna jest znajomość python-a, której na tą chwilę nie posiadam (a raczej znam tylko zupełne podstawy), więc ostatnio wolne chwile spędzam na dokształcaniu się z tego języka programowania. W międzyczasie - krótko mówiąc - wykorzystałem gotowce z internetu.

OSTRZEŻENIE !
Przy podłączaniu wszelkich kabelków należy zachować ostrożność, gdyż może zakończyć się to uszkodzeniem sprzętu lub uszczerbkiem na zdrowiu. Robisz to na własną odpowiedzialność.

Na początek należy upewnić się, że mamy zainstalowane paczki:
python-rpi.gpio
python-dev

DIODA LED

Źródło: greenprophet.com

Dioda LED - czyli w tym przypadku odpowiednik "hello world" dla programistów. Niemal każdy zaczyna od właśnie tego kroku.
O czym należy pamiętać?
Anoda (negativ) - to ta krótsza nóżka - nieraz ma "flat spot" - czyli płaski bok.
Katoda (positiv) - ta dłuższa.

Diody pracują z odpowiednimi parametrami. W moim przypadku (dla diody zielonej) to 
Napięcie pracy: 2,3V
Prąd: 20mA

Jak wiemy porty GPIO w RPI działają z napięciem 3,3V. Gdybyśmy podłączyli bezpośrednio taką diodę do portu GPIO to najprawdopodobniej uległa by ona uszkodzeniu. Należy więc dobrać odpowiedni rezystor.

Wzór jest bardzo prosty: 

R=(V wyj - V led)/I led 

czyli w tym przypadku: 

R=(3,3-2,3)/0,02

0,02 - czyli 20mA
Wynik to 50 Ohm.

Najbliższa dostępna wartość (bezpiecznie trzeba brać wyższą) to 56Ohm i taki muszę dobrać rezystor.
Jeśli komuś niezbyt chc>e się liczyć może się posłużyć min. tym narzędziem: 

Rezystory po przesyłce są oczywiście opisane, ale jak gdyby ktoś nie wiedział który ma wymaganą wartość możemy się posłużyć oznaczeniami. Zazwyczaj rezystory mają 4 kolorowe paski i na ich podstawie możemy oszacować wartość. 

Oznaczenie kolorów:
0 - czarny
1 - brązowy
2 - czerwony
3 - pomarańczowy
4 - żółty
5 - zielony
6 - niebieski
7 - fioletowy
8 - szary
9 - biał
y

Pierwsze 2 wstęgi to wartość, trzecia to mnożnik, a czwarta to tolerancja (w tym przypadku najczęściej spotykany jest kolor złoty, oznaczający +/- 5%).

Czyli np rezystor z paskami :
brąz czarny czerwony i złoty

Wyliczamy:
brąz (1), czarny (0)  - czyli 10 
czerwony to 2 - czyli mnożnik 100 (2 zera)
złoty +/- 5%
czyli rezystor może mieć wartości (10*100 +/- 5% ) - czyli 950 - 1050 Ohm, czyli ogólnie 1kOhm.
Oczywiście (znów) są narzędzia dla leniwych, np.

OK. Mamy diodę, rezystor i płytkę stykową z kabelkami.

Podłączamy - w jednym rzędzie anoda diody oraz rezystor podłączony do minusa. Minus płytki należy podłączyć do GND (ground) w RPI - np port 3 w prawym rzędzie.
Przypomnę tylko że opis GPIO jest TUTAJ 

Następnie katodę diody podłączamy np do portu GPIO 14 w RPI - czyli 4 w prawym rzędzie.




Następnie musimy utworzyć/skopiować skrypt obsługujący porty (może być w różnych językach, ja wybrałem python-a).
Najpierw należy upewnić się, że mamy zainstalowane potrzebne pakiety:
apt-get install python-rpi.gpio python-dev


Przykładowy skrypt:
import RPi.GPIO as gpio
import time

#set up pin 14 as an output
gpio.setmode(gpio.BCM)
gpio.setup(14, gpio.OUT)

gpio.output(14, gpio.HIGH)
time.sleep(3)
gpio.output(14, gpio.LOW)

Ewentualnie zamiast 3 ostatnich linii możemy spróbować pętle:

while True: 
           gpio.output(14, gpio.HIGH) 
           time.sleep(3) 
           gpio.output(14, gpio.LOW) 
           time.sleep(3)


i dioda będzie migać dopóki nie przerwiemy.

TACT SWITCH


Źródło: toscos.com

Dorzuciłem również "momentary button", czyli przycisk powodujący przekazanie sygnału tylko na czas wciśnięcia... Tu trzeba się upewnić, że każda (z 4) nóżka jest w osobnym rzędzie na płytce stykowej.

Układ:
nóżka pierwsza tact-a - do GPIO.17 w RPI (6 port z lewej), następnie poprzez rezystor 10k podłączamy do 3.3V, czyli 1port z lewej w RPI
druga nóżka tact-a do GND w RPI



Skrypt:
import RPi.GPIO as gpio

#set up pin 17 as an input
gpio.setmode(gpio.BCM)
gpio.setup(17, gpio.IN)

while True:
        input_value = gpio.input(17)
        if input_value == False:
                print('Przycisk wcisniety...')
                while input_value == False:
                        input_value = gpio.input(17)


Przy każdym wciśnięciu przycisku na konsoli pojawi się napis...
Przy okazji wspomnę, że w ten oto sposób możemy zrobić wyłącznik dla naszej Malinki. Czyli zamiast odcinać zasilanie przez wyciągnięcie kabla (co nie jest do końca przyjazne np dla karty SD), możemy zdefiniować czyste i bezpieczne wyłączenie systemu po wciśnięciu przycisku.

DIODA + TACT

czyli łączymy jedno z drugim...
zostawiamy układ tak jak powyżej (przy tact)
oraz znów anoda diody z rezystorem do innego portu GND
a katoda diody do portu GPIO 14 w RPI



Skrypt:
import RPi.GPIO as gpio
import time

#set up pin 14 as an output and 17 as input
gpio.setmode(gpio.BCM)
gpio.setup(14, gpio.OUT)
gpio.setup(17, gpio.IN)

while True:
        input_value = gpio.input(17)
        if input_value == False:
                gpio.output(14, gpio.HIGH)
                time.sleep(3)
                gpio.output(14, gpio.LOW)
                while input_value == False:
                        input_value = gpio.input(17)

spowoduje zapalenie diody na 3 sekundy po wciśnięciu guzika. 

Podstawy więc zaliczone. Łatwizna.

2012-12-17

Proces produkcji RPI

Ciekawostka.
Jeśli chcesz się dowiedzieć jak powstaje raspberry - a także np jak to możliwe, że dziennie fabryka wytwarza 4000 RPI (sztuka co 7.5 sekundy) proponuję zajrzeć tutaj:


A także obejrzeć poniższy filmik:



2012-12-16

Żywotność karty SD a Linux

Używanie karty SD w RPI ma sporo plusów, ale oczywiście karty te mają ograniczoną żywotność (np. ilość zapisów) . Dlatego ważne są backupy ważnych plików no i trzeba być przygotowanym, że za jakiś czas trzeba będzie kupić kolejną kartę.

Źródło: raspberrypi.org


Jak nieco opóźnić ten proces? 

Ważnym czynnikiem jest posiadanie, w miarę możliwości, sporej ilości wolnego miejsca, żeby zapisy nie były ciągle na tych samych sektorach.
Innym sposobem jest ograniczenie ilości zapisów na kartę. 
Co generuje największą ilość takich operacji?  
Najczęściej są to logi. 
Co możemy zatem zrobić?
Możemy /var/log umieścić na zewnętrznym dysku (lokalnym/sieciowym) albo utworzyć do tego celu mały ramdisk. 
Każde z rozwiązań ma swoje plusy i minusy - teraz opiszę ostatnią opcję.

Możemy utworzyć oczywiście ręcznie ramdisk i zamontować /var/log na nim, ale ja wykorzystam gotowe rozwiązanie LINK 

Wg dokumentacji pliki będą zapisywane na wygenerowanym ramdisku do momentu restartu systemu lub serwisu (wtedy pliki zostaną przeniesione na dysk (przez rsync)). Jeśli skończy się miejsce to serwer niestety zacznie swapować więc musimy albo wcześniej zrestartować serwis ramdisk albo usunąć pliki.

Instalacja jest prosta, najpierw należy pobrać pakiet lsof (zależność)
apt-get install lsof
następnie:
wget http://www.tremende.com/ramlog/download/ramlog_2.0.0_all.deb
sudo dpkg -i ramlog_2.0.0_all.deb
Jeszcze definiujemy ile pamięci ma być przeznaczone:
sudo vi /etc/default/ramlog
TMPFS_RAMFS_SIZE=25m
I restartujemy :
sudo reboot

Teraz cały katalog /var/log powinien znajdować się na ramdisku.
# df -h | grep ramlog

ramlog-tmpfs     25M  5.2M   20M  18% /var/log 

UPDATE.
W związku z tym, że uruchomiłem MRTG i wrzuciłem jeszcze parę dodatków do monitorowania (opis TUTAJ), postanowiłem rozszerzyć nieco ideę ramdisku i ograniczyć kolejne zapisy na kartę. Popracowałem bowiem z katalogiem /var/www/mrtg (w końcu to kilkanaście zapisów co 5 minut). 
Można oczywiście stworzyć oddzielny ramdisk (np wykorzystując TEN opis), ale należy pamiętać, że po reboocie stracimy wszystkie pliki, więc trzeba by było stworzyć skrypt synchronizujący pliki (np przez rsync). Jako, że mamy tu gotowe rozwiązanie - poszedłem drogą na skróty i utworzyłem link dla katalogu mrtg na /var/log. W ten sposób ramlog również zajmie się plikami mrtg.
Na szybko:
mkdir /var/log/mrtg_pliki

cp -rapv /var/www/mrtg /var/log/mrtg_pliki

cd /var/www

mv mrtg mrtg.BACKUP

ln -s /var/log/mrtg_pliki/mrtg/ /var/www/mrtg

UPDATE.2.
Po pewnym czasie dodałem wpis do cron-a
15 * * * * root /etc/init.d/ramlog reload
spowoduje to, że jeśli malinka straci dostęp do sieci lub się np zawiesi, nie stracimy zbyt dużej ilości danych. W ten sposób bowiem co godzinę logi z ramdisku będą zapisywane na karcie SD.

Tak tylko dodam, że ta idea przydatna jest również wtedy, gdy chcemy przyspieszyć odczyt często używanych plików - np przy udostępnianiu plików przez apache.

2012-12-11

raspberry pi + bluetooth + dualshock 3

Jak wspomniałem TUTAJ zakupiłem klucz bluetooth na USB. Co zrobić żeby go uruchomić?




Podobnie jak z wifi sprawdzamy czy został poprawnie wykryty (np przez lsusb). W moim przypadku:
Bus 001 Device 006: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
Następnie należy zainstalować wymagane paczki
apt-get install bluetooth bluez-utils blueman
upewniamy się, że uruchomiony jest demon
/etc/init.d/bluetooth status
po czym możemy włączyć bluetooth w telefonie czy laptopie i zweryfikować, czy da się go wykryć z RPI
# hcitool scan
Scanning ...

        xx:xx:xx:xx:xx:xx      n/a
U mnie szybko wykryło mojego laptopa.

Ponadto możemy zweryfikować czy wszystko w porządku w:
# hciconfig -a
hci0:   Type: BR/EDR  Bus: USB
        BD Address: xx:xx:xx:xx:xx:xx  ACL MTU: 384:8  SCO MTU: 64:8
        UP RUNNING PSCAN
        RX bytes:1520 acl:0 sco:0 events:47 errors:0
        TX bytes:458 acl:0 sco:0 commands:47 errors:0
        Features: 0xff 0xff 0x8f 0xfe 0x9b 0xf9 0x00 0x80
        Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3
        Link policy: RSWITCH HOLD SNIFF PARK
        Link mode: SLAVE ACCEPT
        Name: 'raspberrypi-0'
        Class: 0x420100
        Service Classes: Networking, Telephony
        Device Class: Computer, Uncategorized
        HCI Version: 2.0 (0x3)  Revision: 0x7a6
        LMP Version: 2.0 (0x3)  Subversion: 0x7a6
        Manufacturer: Cambridge Silicon Radio (10)
Oczywiście bardzo istotne jest tu zasilanie, którego jakości bardzo potrzebuje ten klucz. Przypadkiem wysunęła mi się wtyczka zasilania od powered huba i bluetooth niezbyt chciał działać. Pojawiały się błędy I/O error, connection timeout i hciconfig też lekko szalał.

Z działającym bluetooth można podłączyć np klawiaturę i mysz lub jeśli mamy problem z wifi lub nie mamy internetu w domu - teoretycznie możemy udostępnić internet z telefonu poprzez bluetooth i umożliwić dostęp dla RPI. 

Ja mam plan związany z kontrolerem do PlayStation - Dualshock 3.

Źródło: productreview.com

Znalazłem fajny, krótki opis TUTAJ
Pokrótce podstawowe kroki:

Ściągamy kod i kompilujemy:
wget http://www.pabr.org/sixlinux/sixpair.c
gcc -o sixpair sixpair.c -lusb
Podłączamy Dualshock kablem USB do RPI i odpalamy:
sudo ./sixpair

Current Bluetooth master: xx:xx:xx:xx:xx:xx 
Setting master bd_addr to: xx:xx:xx:xx:xx:xx
W ten sposób parujemy DS3 i RPI. 

Następnie:
wget http://sourceforge.net/projects/qtsixa/files/QtSixA%201.5.1/QtSixA-1.5.1-src.tar.gz
tar xfvz QtSixA-1.5.1-src.tar.gz
cd QtSixA-1.5.1/sixad
make
sudo mkdir -p /var/lib/sixad/profiles
sudo checkinstall
czyli ściągamy pakiet qtsixa i kompilujemy moduł sixad.
Po czym uruchamiamy jednorazowo:
sudo sixad --start
lub startujemy demon sixad.

Już oczywiście możemy odłączyć kabel Dualshock (potrzebny tylko do parowania) i po wciśnięciu przycisku PS - diody powinny radośnie zaświecić i kontroler powinien przez chwilę wibrować.

W syslog widać będzie coś w tym stylu:
Dec  10 17:14:18 raspberrypi kernel: [  188.457540] input: PLAYSTATION(R)3 Controller (xx:xx:xx:xx:xx:xx) as /devices/virtual/input/input2
Dec  10 17:14:22 raspberrypi sixad-sixaxis[2407]: Connected 'PLAYSTATION(R)3 Controller (xx:xx:xx:xx:xx:xx)' [Battery 05]
Czyli misja zakończona sukcesem (szczególnie fajnie, że przy wykorzystaniu klucza za 1€)
Co teraz z tym zrobić? Mam mały plan - ale szczegóły wkrótce.

W międzyczasie polecam przejrzeć jeszcze linki na temat bluetooth i raspberry:
czy też ogólnie o współpracy Dualshock z Linuxem : 

Przy okazji - jeśli ktoś nie ma PS3, a ma np Wii - może również podpiąć ich kontroler. Szczegóły np. http://www.brianhensley.net/2012/08/wii-controller-raspberry-pi-python.html.

2012-12-09

Już jest!!!

A więc zamówiony sprzęcik dotarł...






Myślę więc że nieaktualne jest już to stwierdzenie:

Źródło: qkme.me
ale cały czas zgodzę się z tym:

Źródło: memecrunch.com

;)

Jak wspomniałem TUTAJ zamówiłem również obudowę (przezroczystą) oraz USB hub z zewnętrznym zasilaniem. Resztę starałem się zdobyć sam. 

Jeśli chodzi o obudowę to nie popisałem się - w momencie zamówienia nie pomyślałem, że bardzo przyda się łatwy dostęp do portów GPIO, a w tej wersji obudowy nie ma możliwości wykorzystać mojej przejściówki z adafruit. Będę coś musiał wymyśleć.
W każdym razie na obudowę można znaleźć wiele pomysłów w sieci - np. z klocków lego, wersję DIY (podoba mi się TEN pomysł), itp. Jest tego sporo.

Zasilacz "pożyczyłem" od IPhone. Na wyjściu ma 5V, 1A - więc jest niemal w sam raz dla RPI.  Kabelek USB - micro usb wziąłem z Kindle.
Kartę SD też miałem w domu jako backup do aparatu. 

Jako, że domowy router mam daleko od RPI musiałem kupić również kartę wifi. Znalazłem całkiem fajną na ebayu (za ok 7 €). Pod linuxem przedstawia się następująco:

Bus 001 Device 007: ID 0bda:8176 Realtek Semiconductor Corp. RTL8188CUS 802.11n WLAN Adapter


Źródło: amazon.com
Ponadto mam plan jeśli chodzi o bluetooth więc kupiłem takie cudo (znów na ebay - łącznie z przesyłką całe 2 € ).

Bus 001 Device 006: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)

Źródło: dreamgreenhouse.com

Co ciekawe przetestowałem klucz wifi i bluetooth razem wpięte bezpośrednio do RPI (bez powered hub) i działało dobrze (wykorzystując wifi całkiem intensywnie). Przypominam, że mam zasilacz 1A.     

Ponadto postanowiłem również pożyczyć ze swojego PlayStation kamerkę PS EYE, która może służyć również jako mikrofon.
Źródło: amazon.com

Tak informacyjnie wspomnę tylko, że jeśli komuś bardzo zależy na prawidłowym wyświetlaniu czasu to musi zakupić hardware-owy zegar RTC, gdyż RPI nie ma takiego na pokładzie. W moim przypadku - jako, że mam zamiar używać wifi - wystarczy mi klient ntp.

W przypadku wątpliwości co do sprzętu proponuję przejrzeć listę już przetestowanego przez  użytkowników. 


No i na koniec - w razie jakichkolwiek problemów polecam przeczytać najpierw:


i z mojego "krótkiego" doświadczenia - jeśli coś przestaje działać (np HDMI albo całe RPI) - proponuję wszystko odłączyć i odczekać parę minut, po czym na spokojnie spróbować ponownie.