czwartek, 22 listopada 2012

Overclocking raspberry pi

It is said to overclock Raspberry Pi one has to upgrade the system:


sudo apt-get update && sudo apt-get install raspberrypi* raspi-config

Then configure it with raspi-config utility:


sudo raspi-config

It is good anyhow to check the system version first:


uname -a
Linux raspberrystar.pinkaccordions.org 3.2.27+ #174 PREEMPT Wed Sep 26 14:09:47 BST 2012 armv6l GNU/Linux

The kernel is up to date. Inspecting raspi-config I have discovered it is not updated, but I prefer to configure the system via CLI (command line or console) interface rather than GUI one (no need to connect the RPi to a TV set which is in another room:-). So I decided not to upgrade the system but rather manually configure it. To achieve overclocking one has to add the following lines to /boot/config.txt file:


pi@raspberrystar ~ $ sudo vim /boot/config.txt
## add the following:
temp_limit=80
arm_freq=900
sdram_freq=500

Now reboot:


pi@raspberrystar ~ $ sudo reboot

Check the dmesg:


pi@raspberrystar ~ $ dmesg | grep 7000
[ 1.956412] bcm2835-cpufreq: min=700000 max=900000 cur=700000

CPU frequency is still 700Mhz. To increase it one has to edit scaling_governor file:


pi@raspberrystar ~ $ sudo bash
root@raspberrystar:/home/pi#
echo "performance" > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
## check if the above works:-)
pi@raspberrystar ~ $ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
performance
# display available options:
pi@raspberrystar ~ $ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors
conservative ondemand userspace powersave performance

The ondemand option allows for adjusting CPU frequency depending on CPU utilization.

Without any further reboot the new settings work:


# check current CPU frequency
pi@raspberrystar ~ $ cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
900000

There is even a temperature sensor available so one can check if the CPU is not overheated:


# check processor temperature:
pi@raspberrystar ~ $ /opt/vc/bin/vcgencmd measure_temp
temp=46.5'C

To boot the system with scaling_governor set to appropriate value one has to edit /etc/rc.local:


pi@raspberrystar ~ $ sudo vim /etc/rc.local
# Add the following line
# echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

I have performed a simple test:


#!/bin/bash
#
N=5
START=$(date +%s)

for ((i=1;i<=$N;i++ )) ; do

echo "**** Iteration $i ****"

STARTI=$(date +%s)
perl -e 'for ($i=0;$i<=10000000;$i++) { $s .= "xx"; }'
ENDI=$(date +%s) ; TOTALI=$(( $ENDI - $STARTI ))
echo "*** $TOTALI s."

done

END=$(date +%s)
TOTAL=$(( $END - $START ))
MEAN=`awk -v m=$TOTAL -v n=$N 'BEGIN { print m/n }'`

echo "total: " $TOTAL "mean: " $MEAN
##

The test uses the following perl program:


perl -e 'for ($i=0;$i<=10000000;$i++) { $s .= "xx"; }'

Because computing time can vary, the program has to be run N times and the mean time is reported.

My Rpi runs 28--29s at 700 Mhz, 25,8s at 800 Mhz and 21s at 900 Mhz.

So running at 900 Mhz results in almost 30% reduction of computing time.

środa, 14 listopada 2012

Raspberry Pi/czujnik DHT-22: rejestrowanie temperatury i wilgotności

Czujnik DHT-22
Rys. #1: DHT-22

Rys. #2: Testowanie DHT-22
Instalacja 2x czujnik DHT-22
Rys. #3: Okablowanie

Do wykonania instalacji potrzebne są:

Czujnik DHT-22 temperatury/wilgotności (ok. 30 zł za sztukę). Droga sprawa...

REZYSTOR 0,25W 10K OHM węglowy (1,00 zł za 100 sztuk na Allegro).

Do tego: przewody połączeniowe żeńskie, przewód telefoniczny czterożyłowy lub inny podobny, kostka elektryczna oraz rurka termokurczliwa do izolacji i wzmocnienia połączeń. (Por. Raspberry Pi: magistrala 1-Wire i rejestracja temperatury.)

UWAGA: tańszą wersja DHT-22 jest DHT-11 (aka SHT-11). Połasiłem się nawet na takowy, bo taniej ale nie polecam. Przede wszystkim mierzy temperaturę w przedziale od 0C do 50C (z kiepską dokładnością +/- 2C) więc nie nadaje się do pomiaru temperatury zewnętrznej. Do tego odczyt wilgotności jest zaniżony i nie działa podłączony do niektórych pinów GPIO (być może jest to problem oprogramowania, którego używam). Dla porównania DHT-22 mierzy temperaturę w przedziale od -40C do +80C z dokładnością +/- 0,5C.

Na stronie learn.adafruit.com znajduje się tutorial, z którego korzystałem...

Hardware

Sensor DHT-22 ma cztery piny (por. rys #1). Podłączyłem linie danych (DQ) do pinów P22, P24 i P25 (każdy sensor musi mieć oddzielną linię danych). Vdd każdego sensora do pina P1 (zasilanie 3,3V). GND (masa) każdego czujnika do pina P6. Ponadto każde DQ należało połączyć za pomocą rezystora z linią zasilania Vdd.

Pin Null nie jest wykorzystywany.

Lutowanie i łączenie wszystkiego do kupy wykonałem w sposób identyczny (kostka elektryczna, rurka termokurczliwa itp.) z opisanym bardziej szczegółowo we wpisie Raspberry Pi: magistrala 1-Wire i rejestracja temperatury.

Software

Pobieram, kompiluję i instaluję niezbędną bibliotekę:


pi@raspberrystar $ wget http://www.open.com.au/mikem/bcm2835/bcm2835-1.8.tar.gz
pi@raspberrystar $ tar -zxvf bcm2835-1.8.tar.gz
pi@raspberrystar $ cd bcm2835-1.8
pi@raspberrystar $ ./configure && make && sudo make install

Pobieram program do obsługi czujników:


pi@raspberrystar $ git clone https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code.git
pi@raspberrystar $ cd Adafruit-Raspberry-Pi-Python-Code
pi@raspberrystar $ cd Adafruit_DHT_Driver

W pliku Makefile należy dopisać -l rt na końcu wiersza zaczynającego się od CFLAGS:


CFLAGS = -std=c99 -I. -lbcm2835 -l rt

teraz:


## w katalogu Adafruit_DHT_Driver
pi@raspberrystar $ make

Jeżeli wszystko działa, to:


# Uruchomienie ./Adafruit_DHT typ-czujnika nr-pina-DQ
pi@raspberrystar $ sudo ./Adafruit_DHT 22 25
Using pin #25
Data (40): 0x3 0xe7 0x0 0x17 0x1
Temp = 2.3 *C, Hum = 99.9 %

W katalogu Adafruit_DHT_Driver znajduje się też skrypt Pythona pn. Adafruit_DHT_googledocs.ex.py służący do wysyłania odczytanych danych do arkusza google.docs. Skrypt Adafruit_DHT_googledocs.ex.py do działania potrzebuje modułu gspread:


pi@raspberrystar $ wget http://pypi.python.org/packages/source/g/gspread/gspread-0.0.13.tar.gz
pi@raspberrystar $ tar -zxvf gspread-0.0.13.tar.gz
pi@raspberrystar $ cd gspread
pi@raspberrystar $ sudo python setup.py install

Skrypt Pythona Adafruit_DHT_googledocs.ex.py: 1) w nieskończonej pętli uruchamia co 30 sekund program Adafruit_DHT, 2) wyłuskuje z wydruku wartości temperatury/wilgotności, 3) wysyła co trzeba na google.docs. Fragment skryptu wygląda następująco:


while(True):
output = subprocess.check_output(["./Adafruit_DHT", "2302", "4"]);
print output
# search for humidity printout
matches = re.search("Hum =\s+([0-9.]+)", output)
if (not matches):
time.sleep(3)
continue
humidity = float(matches.group(1))
## pominięty kod ...

time.sleep(30)

Ponieważ ja chcę oprócz wysłania na google.docs coś tam jeszcze zrobić z danymi, to miałem do wyboru albo rozbudować Adafruit_DHT_googledocs.ex.py o dodatkową funkcjonalność albo go uprościć. Wybrałem to drugie: moja wersja Adafruit_DHT_googledocs.ex.py ogranicza się wyłącznie do wysłania na google.docs wartości przekazanych jako argumenty wywołania:


temp = float(sys.argv[1])
humidity = float(sys.argv[2])
## pominięty kod ...

Resztą zajmie się poniższy skrypt basha:


#!/bin/bash
#
LOG_DIR=/home/pi/Logs/DHT
BIN_DIR=/home/pi/bin
SENSTYPE=22
SLEEP_TIME=5

function ReadSensor() {
local sensorType="$1"
local sensorId="$2"
local WYNIK=""
local SUCCESS=""

## zwiększyłem powtórzenia do 5 (sleep zmniejszony do 5s/było 10)
for i in 1 2 3 4 5; do
WYNIK=`sudo $BIN_DIR/Adafruit_DHT $sensorType $sensorId | tr '\n' ' '`
SUCCESS=`echo $WYNIK | awk ' { if (NF > 10) {print "YES"} else { print "NO"}}'`

if [ "$SUCCESS" = "YES" ] ; then
echo "$sensorId=$i $WYNIK" >> $LOG_DIR/DHT22.log
DHT_CURR_TEMP=`echo $WYNIK | awk '{print $13}'`
DHT_CURR_HUM=`echo $WYNIK | awk '{print $17}'`
break
fi
sleep $SLEEP_TIME;
done

## Wszystkie próby okazały się nieudane
if [ $SUCCESS = "NO" ] ; then
echo "$sensorId=? $WYNIK" >> $LOG_DIR/DHT22.log
DHT_CURR_TEMP="999.9"
DHT_CURR_HUM="999.9"
fi
}
echo "@`date "+%Y%m%d%H%M%S"`" >> $LOG_DIR/DHT22.log

## Czujnik w pokoju:
ReadSensor $SENSTYPE "24"
READINGS="$DHT_CURR_TEMP $DHT_CURR_HUM"
sleep 12

## Czujnik na zewnątrz:
ReadSensor $SENSTYPE "25"
READINGS="$READINGS $DHT_CURR_TEMP $DHT_CURR_HUM"
sleep 12

## Czujnik weranda:
ReadSensor $SENSTYPE "22"
READINGS="$READINGS $DHT_CURR_TEMP $DHT_CURR_HUM"

## zamiana na HTML + wykres
/usr/bin/perl /home/pi/bin/dht2ht.pl > /var/www/stats/DHT22.html

# Wyslanie na google
/home/pi/bin/DHT_googledocs.ex.py $READINGS

Podobnie jak w przypadku magistrali 1-Wire zdarzają się problemy z odczytaniem wartości czujnika. Na tą okoliczność funkcja ReadSensor próbuje odczytu kilkukrotnie. Maksymalna nieudana liczba prób, którą zaobserwowałem w ciągu kilkudniowej eksploatacji to 3.

Skrypt jest uruchamiany co 30 min przez crona:


1,31 * * * * /home/pi/bin/dht2ht.sh

Plik LOG wygląda jakoś tak:


@20121113230101
24=1 Using pin #24 Data (40): 0x2 0x22 0x0 0xc9 0xed Temp = 20.1 *C, Hum = 54.6 %
25=1 Using pin #25 Data (40): 0x3 0xe7 0x0 0x1c 0x6 Temp = 2.8 *C, Hum = 99.9 %
22=4 Using pin #22 Data (40): 0x2 0x73 0x0 0xb0 0x25 Temp = 17.6 *C, Hum = 62.7 %

Wiersz zaczynający się od @ zawiera datę i czas odczytu. Wiersze zaczynające się od nn=m zawierają odczytane dane (nn to numer czujnika, m numer próby w której odczytano wartości lub ? jeżeli wszystkie próby były nieudane)

Uwaga: zauważyłem, że przy intensywnych operacjach I/O są duże problemy z odczytaniem wskazań czujników.

Skrypt dht2ht.pl

Perlowy skrypt dht2ht.pl tworzy tabelę oraz wykresy prezentujące odczytane wartości plus obliczoną na ich podstawie temperaturę punktu rosy. Rezultat działania można oglądać tutaj. Omawiane w tym wpisie skrypty są zaś tutaj.

Arkusz google.docs zawierający odczyty z moich trzech czujników jest dostępny tutaj. (Uwaga: z jakiś ważnych powodów skrypt Adafruit_DHT_googledocs.ex.py zaczął dopisywanie danych od 162 wiersza arkusza.)

wtorek, 13 listopada 2012

Raspberry Pi: tworzenie kopii systemu z wykorzystaniem rsync

W temacie kopii zapasowej na stronach poświęconych Raspberry Pi znaleźć można wyłącznie(?) opisy jak to zrobić za pomocą dd. Ten sposób nie podoba mi się na dłużą metę z uwagi na czas -- kopiowanie karty 8Gb z kompresją przez sshfs zajęło około 1 godziny. Tworzenie kopii przyrostowych (za pomocą rsync) wydaje się lepszym pomysłem...

Wariant #1: dysk USB podłączony do RPi

Załóżmy, że do /etc/fstab wpisano:


/dev/disk/by-id/usb-WD_5000AAV_External_57442D574341535535303634313031-0:0-part1 \
/mnt/external-disk ext4 noauto,user,rw 0 0

Utworzenie kopii systemu sprowadza się wykonania:


rsync -av --exclude=/proc/ --exclude=/sys/ --exclude=/tmp/ \
--exclude=/mnt/ --exclude=/home/pi/Dist/ --delete / /mnt/external-disk/backup/rpi

Opcja --exclude pomija wymienione pliki/katalogi. W szczególności należy koniecznie umieścić tam katalogi, w których są/mogą być montowane inne systemy plików, np. /mnt/ (uniknięcie pętli, bo przecież /mnt/ zawiera zamontowany dysk USB) oraz /home/pi/Dist/ (moje zwyczajowe miejsce montowania systemów plików przez sshfs)

Wariant #2: kopia systemu tworzona na innym komputerze

Kopia systemu z raspberry będzie tworzona na innym komputerze dostępnym poprzez sieć.

Konfigurowanie rsynca należy rozpocząć od jego zainstalowania na obu komputerach (źródłowym i odbiorcy):


apt-get install rsync

Zawartość pliku /etc/rsyncd.conf po stronie źródła (czyli raspberry):


uid = 0
gid = 0
hosts allow = 192.168.1.***
transfer logging = no
read only = yes

[wholefs]
path = /
comment whole root fs

W pliku /etc/default/rsync (także po stronie źródła, tj. raspberry) należy wpisać lub ,,odhaszować'':


RSYNC_ENABLE=true

Teraz trzeba wystartować rsync (po ustawnieniu RSYNC_ENABLE, rsync będzie już uruchamiany w momencie startu systemu -- nie potrzeba do tego żadnych dodatkowych zabiegów w konfiguracji)


# /etc/init.d/rsync restart

Można sprawdzić czy działa podając polecenie (moje raspberry nazywa się raspberrystar) na komputerze odbiorcy (jako root):


rsync raspberrystar::wholefs/

Jeżeli wszystko jest OK to wyświetlona zostanie zawartość katalogu / na raspberrystar (czyli źródle).

Utworzenie kopii systemu sprowadza się wykonania:


rsync -av --exclude=/proc/ --exclude=/sys/ --exclude=/tmp/ \
--exclude=/mnt/ --exclude=/home/pi/Dist/ --delete \
raspberrystar::wholefs/ /public/sheeva/backup/raspberrystar/rootfs

Przywracanie systemu z kopii zapasowej

W razie potrzeby kopia może być szybko przeniesiona na inną kartę SDHC.


# uwaga: nazwy katalogów odpowiadają wariantowi #2 tworzenia kopii:
rsync -av --log-file=rsync_`date +%Y%m%d%H`.log --delete \
/public/sheeva/backup/raspberrystar/rootfs/ /public/sdX

Gdzie /public/sdX oznacza miejsce zamontowania karty SDHC. Karta musi być wcześniej sklonowana z ,,pierwszej'' kopii systemu wykonanej za pomocą dd, tj.:


zcat sd_backup.img.gz > /dev/sdX

Teraz można gdybać czy użycie samego dd nie będzie prostsze. Być może -- ja wolę korzystać na co dzień z rsynca.

Zauważyłem, że przy intensywnych operacjach I/O są problemy z odczytem danych przez GPIO (temperatura/wilgotność). Problem nie jest duży, ponieważ tworzenie pierwszej kopii systemu zajęło mi jakieś 20 min (można się spodziewać, że kolejne będą tworzone w ciągu kilku minut), ale dla większej pewności dodałem ionice i --bwlimit (specjalnie tego nie testując, oprócz sprawdzenia, że działa)


ionice -c3 rsync -av --bwlimit=500 --exclude=/proc/ --exclude=/sys/ --exclude=/tmp/ \
--exclude=/mnt/ --exclude=/home/pi/Dist/ --delete \
raspberrystar::wholefs/ /public/sheeva/backup/raspberrystar/rootfs

Jeżeli powyższe zapisane zostanie do skryptu, np. o nazwie backup_raspberry.sh, to teraz aby ten skrypt był uruchamiany raz na tydzień, np. w niedzielę o 4:00 należy wpisac do pliku crontab (na komputerze odbiorcy) coś takiego:


0 4 * * 7 /root/bin/backup_raspberry.sh >> /root/logs/RSync/RSync.log 2>&1

wtorek, 9 października 2012

Zgranie filmu z płyty DVD do formatu AVI

Ponieważ zainstalowany frontend pn. k9copy kończy pracę błędem, zripowałem płytę DVD za pomocą czegoś takiego:


#!/bin/bash
if [ "$1" = "" ] ; then echo "*** Podaj numer ścieżki, np $0 3 ***" ; exit 1 ; fi
mencoder dvd://$1 -ovc lavc -lavcopts vcodec=mpeg4:vhq:vbitrate=2400:aspect=16/9 \
-vf scale=720:576 -oac mp3lame -lameopts br=128 -o Movie-$1.avi

czwartek, 4 października 2012

Raspberry Pi: magistrala 1-Wire i rejestracja temperatury

DS18B20
Rys. #1: Układ DS18B20
zdjęcie
Rys. #2
zdjęcie
Rys. #3
zdjęcie
Rys. #4
zdjęcie
Rys. #5: Kostka
DS18B20
Schemat #6: 2 czujniki

Poniższy opis w dużym stopniu jest oparty na tekście Raspberry Pi odczyt temperatury przez nodejs.

Podłączenie czujników DS18B20 do Raspberry Pi

Czujniki temperatury DS18B20 firmy Dallas należy dołączyć do portu GPIO (styki P1, P6 oraz P7)

Port GPIO

Do wykonania instalacji potrzeba:

Tzw. przewody połączeniowe żeńskie (4 zł za 10 sztuk); w oryginale to się nazywa jumper wire.

REZYSTOR 0,25W 4,7K OHM węglowy (1,50 zł za 100 sztuk).

DS18B20 termometr 1-wire (4,00--5,00 zł za sztukę).

Kostka elektryczna (około 3 zł za 10 sztuk).

Rurka termokurczliwa do izolacji i wzmocnienia połączeń.

Przewód telefoniczny czterożyłowy lub inny podobny.

Trzy wyprowadzenia układu DS18B20 to: masa (GND), linia danych (DQ) i zasilanie (Vdd). Jeżeli położymy układ ,,napisem do góry''/,,stykami do dołu'' (por. rys. #1), to pierwszy styk od lewj (#1) to GND, środkowy (#2) to DQ a prawy (#3) to Vdd.

Styki DQ oraz Vdd należy złączyć za pomocą rezystora 4K7 (4k7 ohm resistor).

Ja to zrobiłem w ten sposób, że obciąłem złącza żeńskie po jednej stronie przewodów połączeniowych i wsadziłem je do kostki elektrycznej. Następnie dolutowałem dwa kilkucentymetrowe przewody po obu stronach rezystora i końce tych przewodów wsadziłem do odpowiednich styków w kostce elektrycznej. W ten sposób połączyłem DQ oraz Vdd za pomocą rezystora (rys. #5).

Styki czujnika DS18B20 dolutowuję do poszczególnych żył przewodu telefonicznego (jedna żyła jest zbędna). Ponieważ DS18B20 jest bardzo mały, to żeby piny się nie stykały izoluję każdą żyłę cienką rurką termokurczliwą (por. zdjęcie #2, umieszczone obok). Żeby ładniej wyglądało, ale przede wszystkim żeby połączenie czujnik-kabel było mocniejsze (żyły są bardzo cienkie) to na cały przewód naciągam szerszą rurkę (por. zdjęcie #3) i też zgrzewam (por. zdjęcie #4). Zgrzewam zapalniczką....

Odpowiednie żyły przewodu telefonicznego z dolutowanym na końcu układem DS18B20 łączę z kostką. Wydaje mi się, że tak jest lepiej--można łatwiej dodać kolejny termometr lub wydłużyć przewód. Układ jest gotowy i można go podłączyć: Vdd do pina P1, GND do pina P6 a DQ do pina P7. Który pin jest P1 jest jasno oznaczone na płytce.

Moja instalacja ma dwa układy DS18B20: jeden do mierzenia temperatury w pokoju a drugi do mierzenia temperatury na zewnątrz (por. rysunek #5/schemat #6).

Aktualizacja systemu (czyli po co robiłem kopię zapasową)

Aby Raspberry obsługiwał 1-Wire należy dokonać aktualizacji systemu, co można wykonać na kilka sposobów. Zgodnie z sugestią ze strony Raspberry Pi odczyt temperatury przez nodejs zdecydowałem się na Hexxeh's easy updater tool:


wget http://goo.gl/1BOfJ -O rpi-update
sudo mv rpi-update /usr/bin/rpi-update
sudo chmod +x /usr/bin/rpi-update

# Na wszelki wypadek:
sudo apt-get install ca-certificates

# rpi-update wymaga zainstalowania gita
sudo apt-get install git-core

Teraz można wykonać aktualizację (zabieg zawsze potencjalnie ryzykowny dlatego lepiej się zabezpieczyć wykonaniem kopii systemu, co opisano tutaj.)


pi@raspberrystar ~ $ sudo rpi-update
Raspberry Pi firmware updater by Hexxeh, enhanced by AndrewS
Performing self-update
Autodetecting memory split
Using ARM/GPU memory split of 192MB/64MB
We're running for the first time
Setting up firmware (this will take a few minutes)
Using HardFP libraries
If no errors appeared, your firmware was successfully setup
A reboot is needed to activate the new firmware

Teraz należy dodać do jądra moduły niezbędne do obsługi instalacji pomiaru temperatury:


sudo modprobe w1-gpio
sudo modprobe w1-therm

Uwaga: aby moduły były dodawana automatycznie, przy starcie systemu należy dodać w1-gpio oraz w1-therm do pliku /etc/modules. Mój plik /etc/modules wygląda następująco:


pi@raspberrystar ~ $ less /etc/modules
snd-bcm2835
w1-gpio
w1-therm

Odczyt temperatury

Po podłączeniu ,,magistrali 1-Wire'' (czytaj kabelków z czujnikami DS18B20 w opisany wyżej sposób) wykonanie polecenia ls w katalogu /sys/bus/w1/devices/ powinno ujawnić urządzenia dołączone do magistrali:


pi@raspberrystar ~ $ ls -l /sys/bus/w1/devices/
lrwxrwxrwx 1 root root 0 paź 3 13:45 w1_bus_master1 -> ../../../devices/w1_bus_master1
lrwxrwxrwx 1 root root 0 paź 3 13:58 28-0000032562aa -> ../../../devices/w1_bus_master1/28-0000032562aa
lrwxrwxrwx 1 root root 0 paź 3 19:27 10-000802012743 -> ../../../devices/w1_bus_master1/10-000802012743

W przypadku mojej ,,magistrali'' są to dwa termometry: 28-0000032562aa oraz 10-000802012743.

Do odczytania temperatury korzystamy z pliku w1_slave:


pi@raspberrystar ~ $ cat /sys/bus/w1/devices/28-0000032562aa/w1_slave
60 01 4b 46 7f ff 10 10 b5 : crc=b5 YES
60 01 4b 46 7f ff 10 10 b5 t=22000

Wielkość temperatury to 22,000 stopnie Celsjusza (t=22000).

Aby odczytać dwa termometry na raz, dodać datę i czas odczytu, a następnie zapisać wszystko do pliku LOG można zastosować następujący skrypt (,,prywatne'' skrypty umieszczam w katalogu ~/bin/):


#!/bin/bash
LOG_DIR=/home/pi/Logs/Digitemp
## Data/czas odczytu
echo "@`date "+%Y%m%d%H%M%S"`" >> $LOG_DIR/digitemp.log
## Czujnik nr1
echo "28-0000032562aa `cat /sys/bus/w1/devices/28-0000032562aa/w1_slave | tr '\n' ' '`" >> $LOG_DIR/digitemp.log
## Czujnik nr2
echo "10-000802012743 `cat /sys/bus/w1/devices/10-000802012743/w1_slave | tr '\n' ' '`" >> $LOG_DIR/digitemp.log

Zapis wygląda jakoś tak (przy założeniu, że powyższy skrypt znajduje się w pliku ~/bin/dt2ht.sh):


pi@raspberrystar ~ $ ~/bin/dt2ht.sh
@20121004100001
28-0000032562aa 5f 01 4b 46 7f ff 01 10 9b : crc=9b YES 5f 01 4b 46 7f ff 01 10 9b t=21937
10-000802012743 1e 00 4b 46 ff ff 0d 10 38 : crc=38 YES 1e 00 4b 46 ff ff 0d 10 38 t=14937

Gdzie: @20121004100001 oznacza datę i czas, 28-0000032562aa/10-000802012743 to identyfikatory czujników a zapis w stylu t=21937, to temperatura (21,937 stopni Celsjusza).

Teraz wystarczy dodać odpowiedni wpis do pliku crontab użytkownika pi, aby, przykładowo temperatura była rejestrowana co godzinę (dt2ht.sh to nazwa opisanego wyżej skryptu służącego odczytu temperatury i zapisania wyników do pliku LOG):


pi@raspberrystar ~ $ mkdir ~/Crontab
pi@raspberrystar ~ $ vi ~/Crontab/crontab
# do pliku ~/Crontab/crontab wpisuję jeden wiersz:
# 0 * * * * /home/pi/bin/dt2ht.sh
# zapisuję/kończę pracę vi

# dodanie zawartości ~/Crontab/crontab do zadań crona
pi@raspberrystar ~ $ crontab ~/Crontab/crontab

# sprawdzenie czy wszystko jest OK:
pi@raspberrystar ~ $ crontab -l
0 * * * * /home/pi/bin/dt2ht.sh

Pozostaje tylko wykonanie (np. za pomocą prostego skryptu PeHaPe) jakiś bardziej efektownego sposobu wyświetlania zawartości pliku LOG.

Dopisane 14 października 2012: W zasadzie działa, ale nie do końca. Czasami nie odczytuje temperatury wypisując CRC error, co wygląda następująco:


62 01 4b 46 7f ff 0e 10 03 : crc=03 NO 62 01 4b 46 7f ff 0e 10 03 t=-1250

Nie mam pojęcia czemu tak się dzieje. Jako workaround wymyśliłem kilkukrotny odczyt:


#!/bin/bash

LOG_DIR=/home/pi/Logs/Digitemp

function ReadSensor() {
local sensorId=$1
local WYNIK=""
local SUCCESS=""

## próbuj odczytać max 3 razy
for i in 1 2 3; do
WYNIK=`cat /sys/bus/w1/devices/$sensorId/w1_slave | tr '\n' ' '`
## pole 12 ($12) to wynik odczytu (YES albo NO):
SUCCESS=`echo $WYNIK | awk '{ print $12}'`

if [ "$SUCCESS" = "YES" ] ; then
## zapisuje numer próby oraz odczytaną informację :
echo "$sensorId=$i $WYNIK" >> $LOG_DIR/digitemp.log
## przerwij pętlę odczytano temperaturę:
break
fi
sleep 3;
done

## Trzy próby okazały się nieudane:
if [ $SUCCESS = "NO" ] ; then
echo "$sensorId=? $WYNIK" >> $LOG_DIR/digitemp.log
fi
}

echo "@`date "+%Y%m%d%H%M%S"`" >> $LOG_DIR/digitemp.log

## Czujnik w pokoju:
ReadSensor "28-0000032562aa"

## Czujnik na zewnątrz:
ReadSensor "10-000802012743"

Plik LOG wygląda jakoś tak:


@20121014220001
28-0000032562aa=1 62 01 4b 46 7f ff 0e 10 03 : crc=03 YES 62 01 4b 46 7f ff 0e 10 03 t=22125
10-000802012743=1 0e 00 4b 46 ff ff 0f 10 fd : crc=fd YES 0e 00 4b 46 ff ff 0f 10 fd t=6812

gdzie pierwszy wyraz to numer sensora, znak równości, numer próby w której odczytano temperaturę lub ?, jeżeli temperatury nie odczytano.

wtorek, 2 października 2012

Raspberry Pi: tworzenie kopii karty SDHC

Ustalamy jak nazywa się urządzenie, w którym jest zamontowana karta SDHC:


pi@raspberrypi ~ $ sudo fdisk -l

Disk /dev/mmcblk0: 7969 MB, 7969177600 bytes
4 heads, 16 sectors/track, 243200 cylinders, total 15564800 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000108cb

Device Boot Start End Blocks Id System
/dev/mmcblk0p1 8192 122879 57344 c W95 FAT32 (LBA)
/dev/mmcblk0p2 122880 15564799 7720960 83 Linux

Teraz można zamontować pendrive'a, na którym zostanie zapisana kopia:


pi@raspberrypi ~ $ mkdir /media/sda1
## zakładamy że pendrive jest oznaczony jako /dev/sda1
pi@raspberrypi ~ $ mount /dev/sda1 /media/sda1

Kopiowanie za pomocą dd


pi@raspberrypi ~ $ sudo dd if=/dev/mmcblk0 | gzip -1 > /media/sda1/sd_backup.img.gz
## bez kompresji będzie szybciej:
pi@raspberrypi ~ $ sudo dd if=/dev/mmcblk0 of=/media/sda1/sd_backup.img
## po sieci, w przypadku gdy nie mamy wolnego pendrive'a
ktos@inny-komputer ~ $ sudo ssh root@raspberrystar dd if=/dev/mmcblk0 | gzip -1 | dd of=sd_backup.img.gz

Uwaga: raspberrystar powinno być zamienione na odpowieni adres IP (lub nazwę).

Przywracanie systemu z kopii zapasowej:


pi@raspberrypi ~ $ zcat sd_backup.img.gz > /dev/sdX

Gdzie /dev/sdX to nazwa urządzenia z zamontowaną czystą kartą SDHC.

Więcej szczegółów i bardziej detalicznie jest tutaj.

Kopiowanie do pliku zamontowanego za pomocą sshfs:


pi@raspberrypi ~ $ sudo apt-get install sshfs fuse-utils

pi@raspberrypi ~ $ mkdir -p ~/Dist/jupiter

## montuję (jako użytkownik tomek) zdalny katalog /public/raspberry na
## komputerze jupiter; punkt montowania to ~/Dist/jupiter
pi@raspberrypi ~ $ sshfs tomek@jupiter:/public/raspberry/ ~/Dist/jupiter
failed to open /dev/fuse: Permission denied

# Za pierwszym strzałem (jak zwykle) nie wyszło, a to dlatego, że
# wyłącznie członkowie grupy "fuse" mogą czytać/pisać do/na /dev/fuse.
# Należy zatem dodać użytkownika pi do grupy "fuse":

pi@raspberrypi ~ $ sudo usermod -a -G fuse pi
## Teraz trzeba się wy/zalogować żeby zadziałały modyfikacje w /etc/group

pi@raspberrypi ~ $ sshfs tomek@jupiter:/public/raspberry/ ~/Dist/jupiter
pi@raspberrypi ~ $ ls -l /home/pi/Dist/jupiter
razem 0

## kopiowanie za pomocą dd (z kompresją `w locie'):
sudo dd if=/dev/mmcblk0 | gzip -1 > /home/pi/Dist/jupiter/raspberrystar.iso

poniedziałek, 24 września 2012

Jak obrócić plik AVI?

Umieszczony obok film przedstawiający dzięcioła dużego (Dendrocopos major) zaciekle borującego dziurę w płycie styropianowej na moim bloku został oryginalnie zarejestrowany przekręconym do pionu aparatem (być może nie był to dobry pomysł.)

Żeby ,,odkręcić'' dzięcioła z powrotem do pionu (proporcje obrazu wyszły takie sobie przyznaję) zastosowałem program mencoder:


mencoder -vf rotate=3 -o OUTPUT.AVI -oac copy -ovc lavc INPUT.AVI

Jeżeli obraz wyszedł odwrócony do góry nogami, to zamiast rotate=3 trzeba wstawić rotate=1.

Przy okazji: w jakim celu dzięcioł kuje dziury w styropianie? Nauka wskazuje trzy powody: szuka robaków (raczej nie w moim przypadku), znaczy terytorium hałasem (też nie, bo wtedy dziur jest dużo i są płytkie. Poza tym styropian słabo hałasuje przy kuciu), buduje dziuple lęgowe lub ,,wypoczynkowe'' (roosting cavity). Por. wyjaśnienia na ten temat tu oraz tu.

Jeżeli już, to ,,mój'' dzięcioł buduje sobie roosting cavity, tyle, że jakoś nie zaobserwowałem, żeby tam specjalnie przesiadywał.

poniedziałek, 17 września 2012

Uruchomienie Raspberry Pi

Urządzenie kupiłem w firmie Farnell. Z dostawą z UK wyszło 180 PLN. Do tego obudowa za ca 30 PLN (do kupienia np. na ebay.pl na aukcjach firmy A1 Items Ltd. Akrylowe obudowy oferowane na allegro.pl nie podobają mi się) i ładowarka z wyjściem mikroUSB, też za 30 PLN. No i karta 8GB Toshiba (do kupienia np. na Allegro.pl), przetestowana w Sheevaplugza -- 43 PLN.

Razem jak widać około 300 PLN. Dla porównania, Sheevaplug (plus karta) = 600 PLN.

Zainstalowanie systemu jest tak proste jak:

1. Ściągnięcie obrazu karty:


[tomek@darkstar ~]$ wget http://downloads.raspberrypi.org/images/raspbian/2012-08-16-wheezy-raspbian/2012-08-16-wheezy-raspbian.zip
[tomek@darkstar ~]$ sha1sum 2012-08-16-wheezy-raspbian.zip
[tomek@darkstar ~]$ unzip 2012-08-16-wheezy-raspbian.zip

2. Nagranie obrazu:


[root@darkstar]# df -h
## wsadzamy kartę do czytnika kart
## w moim przypadku się okazało że system `widzi' kartę jako /dev/sdc1
[root@darkstar]# umount /dev/sdc1
## w poniższym, koniecznie of=/dev/sdc a nie of=/dev/sdc1
[root@darkstar]# dd bs=1M if=2012-08-16-wheezy-raspbian.img of=/dev/sdc
1850+0 przeczytanych recordów
1850+0 zapisanych recordów
skopiowane 1939865600 bajtów (1,9 GB), 499,495 s, 3,9 MB/s

[root@darkstar]# sync

3. Powiększenie wielkości partycji w programie gparted (dla kart o pojemności większej od 2Gb):


[root@darkstar]# gparted
Rpi console
Rysunek #1
Rpi console
Rysunek #2
Rpi configuration tool
Rysunek #3

Example WWW page
Rysunek #4

Za pierwszym razem nie poszło -- nie wiem czemu. Gparted odmawiał stanowczo powiększenia partycji. Zamontowałem kartę niepowiększoną, uruchomiłem RPi, żeby sprawdzić czy w ogóle działa (Rysunek 1). Potem wyłączyłem urządzenie. Dla świętego spokoju spróbowałem drugi raz z gparted i tym razem poszło (Rysunek 2).

Połączyć się z RPi można przez ssh, ponieważ raspbian jest tak skonfigurowany, że demon ssh jest uruchamiany przy starcie systemu.


[tomek@darkstar ~]$ ssh -l pi 192.168.1.115

Aby dokończyć konfigurację zalecane jest uruchomienie raspi-config:


pi@raspberrypi ~ $ sudo raspi-config

Narzędzie to pozwala na (por. rys. 3): 1) powiększenie partycji, 2) ustawienie klawiatury, 3) zmianę hasła użytkownika o nazwie pi, 4) zmianę locale, 5) zmianę strefy czasu, 6) zmianę podziału pamięci (domyślnie 64Mb z dostępnych 256 Mb jest wykorzystywane przez GPU), 7) włączanie/wyłączanie serwera ssh, 8) start systemu w trybie graficznym lub tekstowym (domyślne).

Z powyższych interesowało mnie jedynie 2--5, reszta jest albo wykonana (punkt jeden wykonałem za pomocą gparted) albo domyślne nastawy mnie satysfakcjonują (serwer ssh chcę mieć włączony, start systemu ma być w trybie tekstowym). Narzędzie raspi-config można uruchomić zresztą w każdej chwili.

Ponieważ wiem jak ustawić klawiaturę, locale, zmienić strefę czasu oraz hasło w Debianie ,,tak w ogóle'', bez uciekania się do konfiguratorów, ostatecznie nie uruchamiałem raspi-config, tylko wykonałem następujące polecenia:


pi@raspberrypi ~ $ sudo apt-get update
pi@raspberrypi ~ $ sudo apt-get install debconf

## zmiana stefy czasowej
pi@raspberrypi ~ $ sudo dpkg-reconfigure tzdata

## zmiana locale na pl_PL.UTF-8
pi@raspberrypi ~ $ sudo dpkg-reconfigure locales

## zmiana hasła:
pi@raspberrypi ~ $ sudo passwd pi

## klawiatura (nie przewiduję na razie podłączenia klawiatury)
pi@raspberrypi ~ $ sudo vi /etc/default/keyboard

Instalowanie serwera apache


pi@raspberrypi ~ $ sudo groupadd www-data
groupadd: group 'www-data' already exists
pi@raspberrypi ~ $ sudo apt-get install apache2

Instalowanie serwera MySQL


pi@raspberrypi ~ $ sudo apt-get install mysql-server mysql-client php5-mysql

Instalowanie PHP


pi@raspberrypi ~ $ sudo sudo apt-get install php5-cgi php5-mysql \
php5-curl php5-gd php5-idn php-pear php5-imagick php5-imap \
php5-mcrypt php5-memcache php5-mhash php5-ming php5-pspell \
php5-recode php5-snmp php5-sqlite php5-tidy php5-xmlrpc \
php5-xsl php5-fpm php5-cgi php5-cli php5-common

Instalowanie różnych przydatnych rzeczy:


pi@raspberrypi ~ $ sudo apt-get install fuse-utils
pi@raspberrypi ~ $ sudo apt-get install make zip unzip
## digitemp -- program do obsługi sensorów temperatury DS18B20
pi@raspberrypi ~ $ sudo apt-get install digitemp
pi@raspberrypi ~ $ sudo apt-get install vim

pi@raspberrypi ~ $ sudo apt-cache search emacs | grep 23
pi@raspberrypi ~ $ sudo apt-get install emacs23-nox

Apache działa o czym świadczy rysunek 4.

Sprawdzam też czy demon ntpd (synchronizacja czasu) jest uruchomiony:


ps aux | grep ntpd
ntp 1840 0.0 0.8 5424 1544 ? \
Ss 20:04 0:03 /usr/sbin/ntpd -p /var/run/ntpd.pid -g -u 102:104

Okazuje się, że jest...

poniedziałek, 10 września 2012

Ambernia Obywatelska

Ambernia Obywatelska -- główna kwatera polowa
Hauptquartier

Dziś pojechałem do pracy Elki instalować jej mój ,,super program'' (org-mode + TeX).

Po drodze, przechodząc koło opuszczonej siedziby spółki mającej od niedawna jedną z bardziej rozpoznawalnych nazw w Polsce:-), czyli Amber Gold (zwanej także złośliwie Ambernią Obywatelską), zrobiłem kilka zdjęć.

czwartek, 6 września 2012

Zamiana kolorowego PDFa na czarno-biały za pomocą ghostscripta

Taką zamianę można wykonać za pomocą komercyjnej i do tego windzianej aplikacji Acrobat Pro. Zamiast Acrobata Pro można też użyć ghostscripta:


#!/bin/bash
INPUT=$1
OUTPUT=`basename $1 .pdf`_grayscale.pdf
gs -sOutputFile=$OUTPUT -sDEVICE=pdfwrite \
-sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray \
-dCompatibilityLevel=1.4 $INPUT < /dev/null

Sprawdziłem -- na dużym pliku -- i wygląda, że działa.

Tutaj piszą, że nie zawsze.

poniedziałek, 3 września 2012

Państwo polskie zdało egzamin

,,Państwo polskie zdało egzamin'' oświadczył ówczesny marszałek i PO prezydenta B. Komorowski w kwietniu 2010 r. Teraz też zdało, ale już nie tak celująco, jak wtedy więc zamiast awansu (którego wtedy doświadczył przykładowo gen. Be-O-eR Janicki) paru funkcjonariuszy ma dostać dymisję.

Co jest najważniejsze w ,,aferze Amber-Gold''? Nie jest nim bynajmniej oszukanie kilku tysięcy ludzi na kilkaset milionów złotych. Takie rzeczy były, są i będą. IMHO najważniejsze i najbardziej bolesne jest ujawnienie fasadowości instytucji państwa zwanego 3Rp (tego które zdało egzamin):

Prokuratura i sądy nie były w stanie egzekwować obowiązującego prawa w przypadku 28 letniego cffaniaczka, który przywłaszczył sobie utarg z kasy dla emerytów (Multikasa) i wyłudzał od banków kredyty na podstawionych figurantów. Skoro od takiego nie jest w stanie, to co dopiero w bardziej skomplikowanych sprawach i/lub przypadkach bardziej ,,finezyjnych'' przestępców?

Służby skarbowe wykazały się zdumiewającą bezradnością. NO COMMENTS po prostu, bo co tu komentować? Można się tylko zapytać, czy kontrola w/s ministra P. Grasia dot. jego ew. przestępstw karno-skarbowych (słynne cieciowanie) trwa dalej?

Komisja Nadzoru Finansowego (KNF), ta która rzekomo nie zawiodła, zajmuje się bzdurami. Słynna lista ostrzeżeń publicznych jest tworzona w oparciu o nie wiadomo jakie kryteria. Pomijając wszystkie inne, w ten sposób zarządzana `czarna lista' może być np. instrumentem do udupienia firmy. Dobrze jest zatem (a nie źle, jak się usiłuje teraz wmówić), że nikt się tą listą nie przejmuje.

KNF nie powinna się zajmować wszystkim, tylko wyłącznie swoją ,,białą listą'', tj. bankami, czyli podmiotami działającymi na podstawie udzielonej licencji (jest tam sporo do poprawienia BTW). Reszta nie ma licencji, a co za tym idzie, gwarancji na wypadek niewypłacalności, a jak ktoś chce próbować szczęścia i tam lokować oszczędności -- to wolny wybór.

Agencja Bezpieczeństwa Wewnętrznego (ABW) -- wg. słów D. Tuska -- nie zajmuje się takimi sprawami jak rozkręcenie w 2 lata biznesu wartego kilkaset milionów (jeżeli nie więcej) przez człowieka znikąd, który nie stroni od kontaktów z władzą, w tym z najbliższą rodziną premiera. Jeżeli w podobnie profesjonalny sposób działały służby specjalne w kwietniu 2010, to także NO COMMENTS.

Czwarta władza, czyli media dostały w pierwszym półroczu od A-G 20 mln PLN (tytułem reklam). Jeżeli czwarta władza bierze pieniądze od każdego, kto je ma, to potem pisze to, co jej każą. To chyba oczywiste...

Reszta to mgła propagandowa mająca odwrócić uwagą od istoty.

PS: Czym zajmuje się ABW można się było dowiedzieć oglądając zdjęcia (przykładowo tutaj) z konwojowania Marcina P. z aresztu do sądu, otoczonego chmarą ubranych na czarno osiłków oznaczonych stosownymi naszywkami. ABW to po prostu służba konwojowa, tyle, że wysoko opłacana, a nie żadna Agencja Bezpieczeństwa Wewnętrznego.