>> wybierz styl >> es :: ns :: bs

Weblog Tomasza Przechlewskiego [Zdjęcie T. Przechlewskiego] [[Ikona]]


scrum
random image [Photo gallery]
Zestawienie tagów
1-wire | 18b20 | 1wire | 2140 | 3rz | alsamixer | amazon | anniversary | antypis | apache | api | arm | astronomy | asus | atom.xml | awk | aws | balcerowicz | balta | bash | berlin | bibtex | bieszczady | biznes | blogger | blogging | blosxom | borne-sulinowo | breugel | bt747 | canon | cedewu | chello | chown | chujowetaśmy | cmentarz | contour | cron | css | csv | curl | d54250wykh | debian | dejavu | dhcp | dht22 | dia | docbook | dom | ds18b20 | dyndns | dynia | ebay | economy | ekonomia | elka | elm | emacs | emacs23 | english | ess | eu | excel | exif | exiftool | f11 | fc | fc11 | fc15 | fc5 | fc8 | fedora | fedora21 | fenix | ffmpeg | finepix | firefox | flickr | fontforge | fontspec | fonty | fop | foto | france | francja | fripp | fuczki | fuji | fuse | gammu | garmin | gawk | gazwyb | gdańsk | gdynia | geo | georgia | gft | git | github | gmail | gnokii | gnus | google | googlecl | googleearth | googlemaps | gphoto | gphoto2 | gps | gpsbabel | gpsphoto | gpx | gpx-viewer | greasemonkey | gruzja | grzyby | haldaemon | handbrake | historia | history | hitler | holocaust | holokaust | hpmini | humour | iblue747 | ical | iiyama | ikea | imap | inkscape | inne | internet | j10i2 | javascript | jhead | k800i | kajak | kamera | kleinertest | kml | kmobiletools | knuth | kod | kolibki | komorowski | konwersja | krutynia | kuchnia | kurski | latex | latex2rtf | latex3 | lcd | legend | lenny | lesund | lewactwo | liberation | linux | lisp | lisrel | litwa | logika | ltr | lwp | m2wś | mapsource | marvell | math | mathjax | mazury | mbank | mediolan | mencoder | mh17 | michalak | microsoft | monitor | mp4box | mplayer | ms | msc | msw | mtkbabel | museum | muzyka | mymaps | mysql | nanopi | natbib | navin | neo | neopi | netbook | niemcy | niemieckie zbrodnie | nikon | nowazelandia | nuc | nxml | oauth | oauth2 | obituary | okular | olympus | ooffice | ooxml | opera | otf | otftotfm | other | overclocking | panoramio | pdf | pdfpages | pdftex | pdftk | perl | photo | photography | picasa | picasaweb | pim | pine | pit | plotly | pls | plugin | po | politics | polityka | polsat | postęp | powerpoint | prelink | problem | propaganda | pstoedit | putin | python | r | radio | random | raspberry pi | refugees | relaxng | ridley | router | rower | rowery | rpi | rsync | rtf | ruby | rugby | russia | rwc | rwc2007 | rwc2011 | rzym | samba | sem | sheevaplug | sienkiewicz | signature | sks | skype | skytraq | smoleńsk | sqlite | srtm | ssl | statistics | stats | statystyka | stix | suwałki | svg | svn | swornegacie | szwajcaria | terrorism | tex | texgyre | texlive | thunderbird | tomato | tourism | tramp | trang | truetype | ttf | turystyka | tusk | tv | tv5monde | twitter | typetools | ubuntu | uchodźcy | udev | umap | unix | upc | updmap | ups | utf8 | varia | video | vienna | virb edit | vostro | wammu | wdc | wdfs | webcam | webdav | wh2080 | wiedeń | wikicommons | wilno | windows | windows8 | wine | wioślarstwo | word | wordpress | wrt54gl | ws1080 | wtyczka | ww2 | www | wybory | wybory2015 | włochy | xemex | xetex | xft | xhtml | xine | xml | xmllint | xsd | xslt | xvidtune | youtube | yum | zakopane | zakupy | zdf | łeba | świdnica
Pobrania via google: [[Ikona]]
Archiwum
Inne blogi
N. Walsh | Morten H. Frederiksen | B. Clementson | prawo.vagla.pl | F. Hecker | M. Olson | J. Tennison | J. Clark | M. Nottingham | M. Shuttleworth | T. Isakowicz-Zalewski | J. Anglim | José A. Ortega Ruiz Modern Perl
Inne tematyczne
Ashwin Amanna | wiesia.nets.pl | Wojt | rwm.org.pl | DataBlog | Revolutions | Learning R | A. Gelman | C. Nel | J. Vogelgesang | ubl.xml.org/ | J.D. Long |
O stronie
wykorzystywany jest blosxom plus następujące wtyczki: tagging, flatarchives, rss10, lastbuilddatexhtmlmime. Niektóre musiałem dopasować nieco do swoich potrzeb. Więcej o blosxom jest tutaj
Subskrypcja
RSS 1.0
Stacja pogodowa WS1080

Zakupiłem używaną (z przeznaczeniem do rejestrowania parametrów pogody w innym miejscu BTW -- nie żebym chciał używać dwie różne stacje na raz w tym samym miejscu). Ponieważ akurat pod ręką był c.h.i.p (aka the world's first 9USD computer), podłączyłem na razie stację do chipa.

chip@chip:~/Crontab$ lsusb 
Bus 002 Device 003: ID 1941:8021 Dream Link WH1080 \
 Weather Station / USB Missile Launcher

root@chip:~# apt-get update 
root@chip:~# apt-get install python-pip
root@chip:~# pip install pywws
...
Successfully installed pywws tzlocal pytz
Cleaning up...
root@chip:~# pywws-hourly -v /home/chip/Logs/weather\
  >> /home/chip/Logs/weather/Hourly.log
cat /home/chip/Logs/weather/Hourly.log
Unknown weather station type. Please edit weather.ini
and set 'ws type' to '1080' or '3080', as appropriate.
Your station is probably a '1080' type.

# wpisać 1080 w weather.ini
# zmienić wpis dotyczący /tmp/weather w weather.ini

root@chip:~/Crontab#  pywws-hourly -v /home/chip/Logs/weather\
 >> /home/chip/Logs/weather/Hourly.log
03:07:00:pywws.Logger:pywws version 16.12.0, build 1367 (e917ba9)
03:07:00:pywws.Logger:Python version 2.7.9 (default, Mar  1 2015, 13:48:22) 
[GCC 4.9.2]
03:07:00:pywws.WeatherStation.CUSBDrive:using pywws.device_libusb1
03:07:02:pywws.DataLogger:Synchronising to weather station
03:09:00:pywws.weather_station:live_data missed
03:09:44:pywws.DataLogger:Fetching data
03:09:45:pywws.Process:Generating summary data
03:09:45:pywws.Calib:Using default calibration

I działa...

url | Mon, 12/06/2017 09:49 | tagi: , , ,
Installing Ubuntu in Asus X205TA

Ubuntu 16.04 @ X205TA

MS Windows broke down making the box unusable (no keybord/mouse/WiFi etc...) and as Google says it is not easy to recover the system on this particular machine I try Ubuntu, which was installed within 30 minutes (including 20 minutes for copying the files)

Sound is not working, but I suppose it is just a problem of installing proper drivers. After intalling the system 21Gb of 30Gb memory is free, while it was only 10Gb left on Windows (due to 10Gb non-removable recovery partition).

Still any doubts which system is better?

url | Fri, 31/03/2017 09:35 | tagi: , , , ,
Instalowanie Ubuntu na Asus X205TA

Ubuntu 16.04 @ X205TA

Popsuł się system. Nie mi tylko Jankowi, który usiłował go naprawiać (w jakimś serwisie). W rezultacie serwisant odtworzył system, który wszelako w zasadzie nie działał (klawiatura, touchpad, dźwięk, wskaźnik baterii i pewnie wiele innych rzeczy nie działały)...

Pisali kiedyś w Internetach, że Linuksa nie da się zainstalować, ale sprawdziłem czy stan rzeczy się nie zmienił. No i się zmienił, jest na przykład działająca wersja Ubuntu, której zainstalowanie zajęło mi 30 minut.

Wszystko działa za wyjątkiem dźwięku. Pewnie dźwięk też działa, potrzeba tylko pogimnastykowania się ze sterownikami. Na razie nie mam czasu...

inferior-systemie (czyli w Windows) z 32Gb dostępnej pamięci, po zainstalowaniu kilku aplikacji zostawało 10Gb wolnego miejsca, ponieważ 10 Gb zajęte było przez recovery partition (której nie dawało się usunąć/przenieść na przykład na pamięć USB bez uszkodzenia systemu--w tym Asusie tak było), podczas gdy w Ubuntu jest do dyspozycji całe 30 Gb, a po zainstalowaniu systemu zostaje aż 21 Gb (dwa razy tyle co w Windows)

Any questions?

PS: dla pewności kopiuję procedurę instalacyjną z podanej wyżej strony

# Write ISO to USB
# Assuming USB flashdrive assigned to /dev/sdb
sgdisk --zap-all /dev/sdb
sgdisk --new=1:0:0 --typecode=1:ef00 /dev/sdb
mkfs.vfat -F32 /dev/sdb1
mount -t vfat /dev/sdb1 /mnt
7z x ubuntu-16.04.2-desktop-amd64-asus-x205ta-4.10-kernel.iso -o/mnt/
umount /mnt

# Installation on X205TA
# BIOS setup
# Make sure the X205TA is off & plug in the USB flash drive
# Start the X205TA and continue to press F2 to get into BIOS.
# Under Advanced tab, USB Configuration -> USB Controller Select set to EHCI
#   otherwise mouse and keyboard will not work
# Under Security tab, Secure Boot menu -> Secure Boot Control set to Disabled.
#   Otherwise, you may get a SECURE BOOT VIOLATION on boot.
# Under Save & Exit tab, Save Changes (NOT Save Chances and Exit)
# Lastly, while still in Save & Exit tab, under Boot Override,
# select the USB flash drive.

PS2: WiFi działało z USB, po zainstalowaniu systemu do pamięci komputera (bo on nie ma dysku) przestało. Jak rozwiązać problem jest na przykład tutaj.

url | Fri, 31/03/2017 09:17 | tagi: , , , ,
Instalowanie skype w Fedora Linux

W zasadzie nie używam ale Elka chciała, w sumie też nie wiadomo po co. Okazało się że działa bezproblemowo, nie licząc problemu polegającego na blokowaniu ekranu logowania komunikatem o rzekomym błędzie nieprawidłowego adresu email (program nie czeka na wpisanie kompletnego emaila, tylko wyświetla okno z tekstem o błędzie i ni-chu-chu pozbyć się tego okna).

Skopiowane z tej strony.

## Doinstalowanie ew. brakujących zależności:
yum install alsa-lib.i686 fontconfig.i686 freetype.i686 \
  glib2.i686 libSM.i686 libXScrnSaver.i686 libXi.i686 \
  libXrandr.i686 libXrender.i686 libXv.i686 libstdc++.i686 \
  pulseaudio-libs.i686 qt.i686 qt-x11.i686 zlib.i686 qtwebkit.i686

## Ściągnięcie skype:
wget --trust-server-names http://www.skype.com/go/getskype-linux-dynamic

mkdir /opt/skype
tar xvf skype-4.3* -C /opt/skype --strip-components=1

## Link skype.desktop ##
ln -s /opt/skype/skype.desktop /usr/share/applications/skype.desktop

## Link icons (copy and paste all rows at once) ##
## Thank you Andrej Podzimek for this code and idea ##
for icon in /opt/skype/icons/*; do
ressuffix="${icon##*_}"
res="${ressuffix%%.*}"
ln -s "$icon" /usr/share/icons/hicolor/"$res"/apps/skype.png
done

## Update gtk icon cache (needed at least Gnome/GTK envorinments) ##
gtk-update-icon-cache /usr/share/icons/hicolor

## Create empty /usr/bin/skype file and set permissions ##
touch /usr/bin/skype
chmod 755 /usr/bin/skype

Teraz należy na przykład stworzyć plik skype w katalogu /usr/local/bin:

#!/bin/sh
export SKYPE_HOME="/opt/skype"
 
$SKYPE_HOME/skype --resources=$SKYPE_HOME $*

I to wszystko.

url | Thu, 22/12/2016 04:52 | tagi: , ,
Czujnik 1-Wire, USB-UART i nanoPi Neo

W ramach testowania nanoPi Neo podłączyłem do niego czujnik 18B20. Tym razem nie za pomocą układu MP00202 (FT232RL/DS2480B) który jest dość drogi (circa 60 PLN), ale wykorzystując USB-UART RS232 PL2303HX (za 4,40 PLN na Allegro + wysyłka.)

Podłączenie czujnika jest banalnie proste, mianowicie: styki oznaczone jako GND oraz +5V (na płytce układu USB-UART) łączy się z odpowiednimi stykami czujnika DS18B20, natomiast styki oznaczone jako RX oraz TX należy ze sobą połączyć a następnie połączyć ze stykiem DATA (środkowym) czujnika DS18B20.

I to wszystko. Korzystając z programu digitemp należy użyć digitemp_DS9097 (FT232RL/DS2480B działało z wariantem digitemp_DS9097U).

Nawiasem mówiąc nanoPi Neo działa tak średnio (wyrażając się oględnie), bo już go musiałem reistalować. Na dokładkę przy czytaniu dużych plików z pendrive'a USB się odłączał a system zgłaszał błędy -- powodem było być może zasilanie (jakiś super-wydajny zasilacz by pomógł/aktywny hub?).

Tak czy siak SheevaPlug działa mi bezawaryjnie a nanoPi Neo nie za bardzo.

url | Tue, 20/12/2016 05:46 | tagi: , , , , , , ,
Nowy ARM: NanoPi Neo

Działałem według opisu ze strony NanoPi NEO, tzn. ściągnąłem plik nanopi-neo-linux-rootfs-core-qte-sd4g-20160804.img.zip (BTW downloads: 1632, czyli jestem hipsterem/trendsetterem!). Rozpakowałem, wsadziłem kartę (micro SDHC 8Gb Toshiba, za +20 PLN BTW) do czytnika kart i za pomocą dd wykonałem obraz systemu:

NeoPo
NeoPi
dmesg
[10869.916710] sd 1:0:0:0: [sdb] 15196160 512-byte logical blocks: (7.78 GB/7.24 GiB)

Czyli karta jest w urządzeniu /dev/sdb. Zatem:

dd bs=4M if=nanopi-neo-linux-rootfs-core-qte-sd4g-20160804.img of=/dev/sdb

Kartę wyjąłem z czytnika, wsadziłem do Neo, urządzenie podłączyłem pod ładowarkę do smartfona i kabel sieciowy RJ45. W instrukcji jest napisane, że po podłączeniu zasilania nastąpi uruchomienie systemu sygnalizowane świeceniem się niebieskiej diody LED. I tak było w istocie: dioda świeci jak nie przymierzając kogut na radiowozie MO. Aby połączyć się z komputerkiem należy teraz wykonać (,,fabryczne'' hasło to fa):

  ssh -l root@192.168.1.123

Adres 192.168.1.123 ustaliłem łącząc się z routerem i oglądając device list (w instrukcji jest inny adres, pod którym urządzenie powinno być podłączone). Teraz:

apt-get update && apt-get upgrade
## dla pewności
apt-get install rsync less vim

Instalowanie mc

apt-get install mc # nie ma

apt-get install software-properties-common
## teraz zadziała

$add-apt-repository ppa:eugenesan/ppa
$ sudo apt-get update
$ sudo apt-get install mc

# dalej kicha 
$ apt-get install mc-data
# jakiś dziwny pakiet bez binarów, rzekomo zastępujący mc
# https://mail.gnome.org/archives/mc/2015-December/msg00020.html
# chyba jest problem z kompilacją na arma

Stay tuned

url | Sun, 30/10/2016 08:57 | tagi: , , , , ,
Asus X205TA

Asus X205TA

Kupiłem to cudo w celu używania na wyjazdach. W domu działam na PCie (bezwiatrakowy Intel NUC, opisany tutaj).

Z tego co piszą w Internetach Linuksa nie da się zainstalować (przed zakupem wydawało mi się, że się da, ale okazuje się, że są tylko jakieś alfa wersje, nie do końca działające). Z 32Gb dostępnej pamięci, 10Gb zajęte jest przez recovery partition, której nie da się usunąć/przenieść na przykład na pamięć USB. Po zainstalowaniu kilku aplikacji zostało 10Gb wolnego miejsca.

Teraz plusy

Na plus tego komputera bez wątpienia należy zaliczyć: 1. waży tylko 0,9kg (1,1kg z ładowarką); 2. potrafi ponad 10 godzin pracować na baterii; 3. jest całkiem szybki i wygodny (klawiatura).

Pewnie airBook byłby lepszy ale nie za 780 PLN no i trochę byłby cięższy (ten airBook).

Problem z pamięcią rozwiązałem (mam nadzieję -- na ile skutecznie, to wyjdzie w praniu) w taki sposób, że kupiłem kartę mikroSD 32Gb z przeznaczeniem na dane. Wsadziłem ją ,,na stałe'' do czytnika po sformatowaniu do NTFS. Gdzieś coś wyczytałem, że Windows10 pozwala na przeniesienie recovery partition, ale ja się boję tego Win10 i zostaję na razie z Win8.1 (być może niesłusznie). Zresztą przy instalowaniu byłem brutalnie zachęcany do zmiany domyślnego Win8.1 na Win10, co tylko pogłębiło moje obawy czy warto...

url | Mon, 22/02/2016 17:44 | tagi: , , , ,
Uploading pictures to Picasaweb with Perl/LWP::UserAgent

Previously described bash script allows for uploading a file to PicasaWeb only. With the following (simplified) Perl script one can upload pictures as well as upload with metadata (title description and tags) or create/list albums:

#!/usr/bin/perl

use strict;

use LWP::UserAgent;
use Getopt::Long;
use File::MimeInfo;
use XML::LibXML;

my $AlbumId ="6170354040646469009";
my $profileID="default";

my $Action = 'u'; ## x| u | c | l (default action is Upload)
my $entryTitle = ''; my $entryDescription = '';
my $entryKeywords = '';
my $ActionUpload =''; my $ActionList = '';
my $ActionCreate = ''; my $ActionXload = '';
my $ImageFile = '';
my $dummyReq='';

GetOptions("xload" => \$ActionXload, "upload" => \$ActionUpload,
  "list" => \$ActionList, "create" => \$ActionCreate,
  "title=s" => \$entryTitle, "description=s" => \$entryDescription,
  "keywords=s" => \$entryKeywords,
  "file=s" => \$ImageFile,
  "album=s" => \$AlbumId, ## UploadFile to Album
) ;

## Determine action:
if ( $ActionUpload ) {$Action = 'u'} elsif ( $ActionList ) { $Action = 'l'}
elsif ( $ActionCreate ) { $Action = 'c'}
elsif ( $ActionXload ) { $Action = 'x'}

OAuth 2.0 authorization is handled with Python script oauth2picasa.py. The script is an adapted/copy-pasted fragment of code borrowd from picasawebsync:

### Authenticate with external script (oauth2picasa.py):
my $ACCESS_TOKEN=`oauth2picasa.py`;
chomp($ACCESS_TOKEN);
print STDERR "*** AccessToken: $ACCESS_TOKEN [AlbumId: $AlbumId]\n";

my $req ; my $blog_entry ;

my $picasawebURL = "https://picasaweb.google.com/data/feed/api/user/$profileID";

if ( $Action eq 'c' ) {## Action: create album
  $req = HTTP::Request->new(POST => $picasawebURL );
  $req->header( 'Content-Type' => 'application/atom+xml' );

  $blog_entry = "<entry xmlns='http://www.w3.org/2005/Atom'
     xmlns:media='http://search.yahoo.com/mrss/'
     xmlns:gphoto='http://schemas.google.com/photos/2007'>"
  . "<title type='text'>$entryTitle</title>"
  . "<summary type='text'>$entryDescription</summary>"
  . "<media:group><media:keywords>$entryKeywords</media:keywords></media:group>"
  . "<category scheme='http://schemas.google.com/g/2005#kind'
     term='http://schemas.google.com/photos/2007#album'></category></entry>";

    $req->content($blog_entry);
} 
elsif ( $Action eq 'l' ) {## Action: list albums
  $req = HTTP::Request->new(GET => $picasawebURL );

} 
elsif ( $Action eq 'u' ) {## Action: Upload 1 photo w/o metadata
  my $mimeType = mimetype($ImageFile);

  ## https://developers.google.com/picasa-web/docs/2.0/developers_guide_protocol
  $req = HTTP::Request->new(POST => "$picasawebURL/albumid/$AlbumId" );
  $req->header( 'Content-Type' => "$mimeType" );
  $req->header( 'Slug' => "$ImageFile" );

  ## http://www.perlmonks.org/?node_id=131584
  open(FILE, $ImageFile);
  $req->content(join('',<FILE>));
  close(FILE);
}

To upload the binary image data along with its metadata, use MIME content type "multipart/related"; send photo metadata in one part of the POST body (Content-Type: application/atom+xml), and binary-encoded image data in another part. This is the preferred approach according to Picasa Web Albums Data API Picasa Web Albums Data API

elsif ( $Action eq 'x' ) {## Action: Upload 1 photo with metadata
  # https://groups.google.com/forum/#!topic/google-picasa-data-api/2qRfP0EIFhk
  my $mimeType = mimetype($ImageFile);

  $req = HTTP::Request->new(POST => "$picasawebURL/albumid/$AlbumId" );
  $req->header( 'Content-Type' => "multipart/related" );

  open(FILE, $ImageFile);
  my $add_photo_metadata = "<entry xmlns='http://www.w3.org/2005/Atom' 
     xmlns:media='http://search.yahoo.com/mrss/'>"
  . "<title type='text'>$entryTitle</title>"
  . "<summary type='text'>$entryDescription</summary>"
  . "<media:group><media:keywords>$entryKeywords</media:keywords></media:group>"
  . "<category scheme='http://schemas.google.com/g/2005#kind' 
     term='http://schemas.google.com/photos/2007#photo'></category></entry>";

  my $add_photo_data = join('',<FILE>); close(FILE);

  ## http://www.perlmonks.org/?node_id=131584
  $req->add_part(HTTP::Message->new(['Content-Type'
      => 'application/atom+xml'], $add_photo_metadata));
  $req->add_part(HTTP::Message->new(['Content-Type'
      => "$mimeType"], $add_photo_data));
}

$req->header( 'Authorization' => "Bearer $ACCESS_TOKEN" );
$req->header( 'GData-Version' => '2' );

## ### ###
my $res ;
my $ua = LWP::UserAgent->new;

$res = $ua->request($req);

if ($res->is_success) {
   my $decoded_response = $res->decoded_content;
   print "*** OK *** $decoded_response\n";
}

Usage:

Upload with metadata

picasaweb.pl -xload -title PICTURE-TITLE -descr DESCRIPTION \
  -keywords 'TAG1,TAG2' -file FILE.jpg -album ALBUMID

Upload w/o metadata:

picasaweb.pl -upload -file FILE.jpg -album 12345

Create album:

picasaweb.pl -create -title ALBUM-TITLE -descr DESCRIPTION \
   -keywords 'TAG1,TAG2'

List album:

picasaweb.pl -list

Source code: picasaweb.pl

url | Thu, 30/07/2015 09:48 | tagi: , , , ,
Mój nowy PCet
Intel NUC/Akasa case
Intel NUC/Obudowa Akasa

Niedawno zdecydowałem się na upgrade i stanęło na Intel NUC, konkretnie model D54250WYKH wyposażony w procesor Core i5-4250U/Haswell (nieobciążony pobiera podobno 6 watów!). Jak wiadomo NUC sprzedawany jest jako tzw. kadłubek/barebone zatem trzeba samodzielnie dokupić i zamontować dysk oraz pamięć RAM. Intel coś tam rekomenduje i jest dostępna na stosownej stronie (URL tej strony można znaleźć w kartonie z NUCem) lista zweryfikowanego sprzętu, ale ja wybrałem coś czego na liście nie było: pamięć 2x Kingston SODIMM PC-1600 DDR3L 4GB CL11 KVR16LS11/4 oraz dysk SSD Samsung 850 EVO (500 Gb) z interfejsem SATA bo taki miałem (domyślnym jest mSATA, z tym że obudowa D54250WYKH jest na tyle duża, że pozwala na instalację dwóch dysków, a system może być uruchamiany z obu).

NUC ma w środku wiatrak i do tego ten wiatrak całkiem wyraźnie słychać -- być może jestem przewrażliwiony bo są też opinie w stylu: jest praktycznie niesłyszalny gdy pracuje. Usiłowałem zmniejszyć prędkość wiatraka poprzez stosowne ustawienia BIOSa (zmiana control mode na manual plus zmniejszenie duty cycle z fabrycznych 40% na 30%, por. Intel NUC DN2820FYKH Bay Trail System Review) i wtedy faktycznie komputer działał ciszej, ale temperatura procesora (pod obciążeniem) potrafiła wzrosnąć do 85 stopni.

Nie po to kupowałem dysk SSD żeby coś mi się tam kręciło -- za następne 300 PLN kupiłem obudowę Akasa Newton X fanless case. Obudowa jest większa od oryginalnej i znacząco cięższa (1,3 kg wg producenta), ale faktycznie pozwala na wyłączenie wiatraka (podczas przekładania płyty do nowej obudowy wiatrak został odkręcony zresztą). Temperatura procesora jaką odnotowałem nigdy nie była wyższa od 55 stopni a zwykle znajduje się w przedziale 35--45 stopni.

Z instalacją Fedory 21 -- bo takiej wersji Linuksa używam, nie było żadnych problemów (z okładnością do błędów Fedory). Aby móc dalej korzystać z wiekowej drukarki HP6P kupiłem na Allegro za całe 9,90 PLN przejściówkę pn. konwerter kabel USB 2.0 wtyk--LPT gniazdo DB25 ponieważ NUC nie posiada gniazda LPT/IEEE 1284. Konwerter zadziałał od pierwszego strzału, co było miłym zaskoczeniem.

Drobny problem wystąpił z równie wiekowym skanerem Canon LIDE 25, który wieszał się po zeskanowaniu jednej strony. Się okazało, że powodem jest błąd w programie XSane/sane-backends w wersji 1.0.24. Rozwiązaniem było ściągnięcie z githuba i skompilowanie wersji 1.0.25.

Recenzji NUCa jest w Internecie multum, np. tutaj.

url | Tue, 23/06/2015 20:41 | tagi: , ,
Wysyłanie plików na Picasaweb za pomocą Curla

Taki oto (uproszczony) skrypt basha używałem do niedawna do wysyłania plików na konto Picasaweb (por. Using cURL to interact with Google Data services oraz PicasaUploader):

USERNAME=SomeUsername # GoogleAccountUsername
PASSWORD=SomePasswd # GoogleAccountPasswd
ALBUM_ID=6008849823888405298 # ID of picasaweb album

MY_PIC="$1" ## filename of the picture to upload ##
PIC_TITLE=`basename $MY_PIC` # filename w/o extension
PIC_TYPE=`file -b --mime-type "$MY_PIC"`

AUTH_KEY=$( curl -s https://www.google.com/accounts/ClientLogin -d Email="$USERNAME"@gmail.com \
  -d Passwd="$PASSWORD" -d accountType=GOOGLE \
  -d source=Google-cURL-Example -d service=lh2 | awk -F\= '/^Auth=/{print $2}' )
ALBUM_XML="http://picasaweb.google.com/data/feed/api/user/$USER_ID/albumid/$ALBUM_ID?authkey=$AUTH_KEY"

URL=`curl -s --request POST --data-binary "@$MY_PIC" --header "Slug: $PIC_TITLE" \
 --header "Content-Type: $PIC_TYPE" \
 --header "Authorization: GoogleLogin auth=$AUTH_KEY" "$ALBUM_XML" | \
sed 's/.*media:content url='"'"'\([^'"'"']*\).*media:thumbnail url='"'"'\([^'"'"']*\).*/\1/'`

Zmienna URL zawiera url wysłanego na Picasaweb obrazka (otrzymany przez zaaplikowanie w potoku odpowiedniego skryptu seda).

Skrypt przestał działać ostatnio, ponieważ Google nie obsługuje już protokołu OAuth 1.0 (por. Google Identity Platform). Na szczęście w łatwy sposób możliwe było dopasowanie skryptu nowszego protokołu OAuth 2.0:

ACCESS_TOKEN=$(oauth2picasa.py) ## Acces token is managed with Python's script now
## Note that ALBUM_XML URL starts now from https:// now
ALBUM_XML="https://picasaweb.google.com/data/feed/api/user/$USER_ID/albumid/$ALBUM_ID"

URL=`curl -s --request POST --data-binary "@$MY_PIC" \
--header "GData-Version: 2" --header "Slug: $PIC_TITLE" \
--header "Content-Type: $PIC_TYPE" -H "Authorization: Bearer $ACCESS_TOKEN" $ALBUM_XML |  \
sed 's/.*media:content url='"'"'\([^'"'"']*\).*media:thumbnail url='"'"'\([^'"'"']*\).*/\1/'`

Uwaga: Autoryzację OAuth 2.0 obsługuje Pythonowy skrypt oauth2picasa.py. Skrypt jest (zapożyczonym) fragmentem z projektu picasawebsync:

#!/usr/bin/python

import os
import time
import httplib2
## https://github.com/google/oauth2client
## installed with pip install --upgrade oauth2client (or some other way)
from oauth2client import client

def oauthLogin():
        # using http://stackoverflow.com/questions/20248555/list-of-spreadsheets-gdata-oauth2/29157967#29157967
        from oauth2client.file import Storage

        filename = os.path.join(os.path.expanduser('~'), ".picasawebsync")
        client_secrets = os.path.join(os.path.expanduser('~'), ".config", "picasawebsync.json")

	storage = Storage(filename)
        credentials = storage.get()
        if credentials is None or credentials.invalid:  
	        flow = client.flow_from_clientsecrets(client_secrets,
		       scope='https://picasaweb.google.com/data/',
		       redirect_uri='urn:ietf:wg:oauth:2.0:oob')     
                auth_uri = flow.step1_get_authorize_url()       
                print 'Authorization URL: %s' % auth_uri
                auth_code = raw_input('Enter the auth code: ')
                credentials = flow.step2_exchange(auth_code)
                storage.put(credentials)
        if credentials.access_token_expired:
                credentials.refresh(httplib2.Http())
                
        return credentials.access_token

# start of the program

gd_client = oauthLogin()

print '%s' % gd_client

Jak stworzyć OAuth 2.0 client ID opisano tutaj. Należy wybrać Client ID for native application. Następnie należy pobrać plik JSON, zmienić nazwę tego pliku na picasawebsync.json umieszczając go w katalogu .config swojego katalogu domowego (albo zmodyfikować skrypt, jeżeli plik ma być w innym miejscu).

Uruchomiony po raz pierwszy skrypt oauth2picasa.py wypisuje URL, który należy skopiować/wkleić do przeglądarki, celem uzyskania authcode. Pobrany authcode wklejamy w odpowiedzi na prompt Enter the auth code:.

Opisane skrypty są tutaj: picasa_upld.sh oraz oauth2picasa.py.

url | Tue, 23/06/2015 16:06 | tagi: , , , ,
Uploading pictures to Picasaweb with Curl

My (simplified) old bash script for uploading images to Picasaweb (cf. Using cURL to interact with Google Data services and PicasaUploader):

USERNAME=SomeUsername # GoogleAccountUsername
PASSWORD=SomePasswd # GoogleAccountPasswd
ALBUM_ID=6008849823888405298 # ID of picasaweb album

MY_PIC="$1" ## filename of the picture to upload ##
PIC_TITLE=`basename $MY_PIC` # filename w/o extension
PIC_TYPE=`file -b --mime-type "$MY_PIC"`

AUTH_KEY=$( curl -s https://www.google.com/accounts/ClientLogin -d Email="$USERNAME"@gmail.com \
  -d Passwd="$PASSWORD" -d accountType=GOOGLE \
  -d source=Google-cURL-Example -d service=lh2 | awk -F\= '/^Auth=/{print $2}' )
ALBUM_XML="http://picasaweb.google.com/data/feed/api/user/$USER_ID/albumid/$ALBUM_ID?authkey=$AUTH_KEY"

URL=`curl -s --request POST --data-binary "@$MY_PIC" --header "Slug: $PIC_TITLE" \
 --header "Content-Type: $PIC_TYPE" \
 --header "Authorization: GoogleLogin auth=$AUTH_KEY" "$ALBUM_XML" | \
sed 's/.*media:content url='"'"'\([^'"'"']*\).*media:thumbnail url='"'"'\([^'"'"']*\).*/\1/'`

URL contains url of uploaded picture (obtained with piping curl's output via sed).

This script stoped working recently as Google no longer supports OAuth 1.0 (cf. Google Identity Platform). Fortunately it was pretty easy to modify it to support OAuth 2.0:

ACCESS_TOKEN=$(oauth2picasa.py) ## Acces token is managed with Python's script now
## Note that ALBUM_XML URL starts now from https:// now
ALBUM_XML="https://picasaweb.google.com/data/feed/api/user/$USER_ID/albumid/$ALBUM_ID"

URL=`curl -s --request POST --data-binary "@$MY_PIC" \
--header "GData-Version: 2" --header "Slug: $PIC_TITLE" \
--header "Content-Type: $PIC_TYPE" -H "Authorization: Bearer $ACCESS_TOKEN" $ALBUM_XML |  \
sed 's/.*media:content url='"'"'\([^'"'"']*\).*media:thumbnail url='"'"'\([^'"'"']*\).*/\1/'`

NOTE: OAuth 2.0 authorization is handled with tiny Python script oauth2picasa.py. The script is an adapted/copy-pasted fragment of code borrowd from picasawebsync:

#!/usr/bin/python

import os
import time
import httplib2
## https://github.com/google/oauth2client
## installed with pip install --upgrade oauth2client (or some other way)
from oauth2client import client

def oauthLogin():
        # using http://stackoverflow.com/questions/20248555/list-of-spreadsheets-gdata-oauth2/29157967#29157967
        from oauth2client.file import Storage

        filename = os.path.join(os.path.expanduser('~'), ".picasawebsync")
        client_secrets = os.path.join(os.path.expanduser('~'), ".config", "picasawebsync.json")

	storage = Storage(filename)
        credentials = storage.get()
        if credentials is None or credentials.invalid:  
	        flow = client.flow_from_clientsecrets(client_secrets,
		       scope='https://picasaweb.google.com/data/',
		       redirect_uri='urn:ietf:wg:oauth:2.0:oob')     
                auth_uri = flow.step1_get_authorize_url()       
                print 'Authorization URL: %s' % auth_uri
                auth_code = raw_input('Enter the auth code: ')
                credentials = flow.step2_exchange(auth_code)
                storage.put(credentials)
        if credentials.access_token_expired:
                credentials.refresh(httplib2.Http())
                
        return credentials.access_token

# start of the program

gd_client = oauthLogin()

print '%s' % gd_client

How to create an OAuth 2.0 client ID in the Google Developers Console is described here. Choose Client ID for native application. Next download JSON file, rename it to picasawebsync.json and move it to .config directory in your HOME directory (or modify the script).

First time used oauth2picasa.py prompts to sign on to google and paste the link back to authenticate.

Source code: picasa_upld.sh and oauth2picasa.py.

url | Mon, 22/06/2015 11:40 | tagi: , , , , ,
My old Canon LIDE 25 scanner works only once

My old Canon CanoScan LIDE 25 scanner is not working properly with my new hardware (Intel NUC) and Fedora 21.

I suspected Fedora 21 bug, but the problem is with the hardware, exactly as describe here. Works once and got stuck when scanning next.

It is claimed problem is solved in version 1.025 of Sane. To compile Sane one has to install libusb-devel package first:

yum install libusb-devel

Then:

git clone git://git.debian.org/sane/sane-backends.git
cd sane-backends

# I would like to install whole stuff in /usr/local
# without removing original fedora package
./configure --prefix=/usr/local --sysconfdir=/usr/local/etc \
    --localstatedir=/var BACKENDS=plustek
make
make install

Sane works now.

I would like to avoid mixing original Sane files with the new ones, so I use --prefix and --sysconfdir options with appropriate values. New Sane will be installed in /usr/local and it will be run by default--no need to remove original Fedora packages.

url | Thu, 28/05/2015 08:33 | tagi: , , ,
Cron i ostatni dzień miesiąca

Wprawdzie nie wiadomo który dzień jest ostatnim w miesiącu, ale na pewno po nim będzie dzień z numerem 1. Numer dnia, który będzie jutro można zaś ustalić wykorzystując date:

$ date +%d -d tomorrow
$ 19

W dniach 28--31, o godzinie 23:55 sprawdź czy następny dzień ma numer jeden. Jeżeli tak, wykonaj SKRYPT.sh:

55 23 28-31 * * [ "$(date +%d -d tomorrow)" = "01" ] && SKRYPT.sh

url | Mon, 19/01/2015 17:25 | tagi: ,
Lista argumentów za długa

Ponieważ w przeciwieństwie do MSW w Linuksie długość wiersza poleceń jest absurdalnie duża zapomniałem, że jednak jest skończona:

system ("perl", "clickshop-delete.pl", "-items", join (',', @AllItems)) 

Program clickshop-delete.pl nie jest wykonywany. Żeby ustalić czemu dodaję:

system ("perl", "clickshop-delete.pl", "-items", join (',', @AllItems)) \
== 0 or warn "system failed: $? [$!]\n";

Teraz wiadomo czemu nie działa:

system failed: -1 [Lista argumentów za długa]

Poniższe ustala jak długi może być wiersz poleceń (Debian Lenny na Sheevaplug/ARM):

tomek@neptune:~$ getconf ARG_MAX
131072

Prosty sposób na zmodyfikowanie skryptu z wykorzystaniem splice:

my $max2process=6000; # każdy element @AllItems ma 12 znaków, więc 6000 jest OK
while ( my @items2process = splice @AllItems, 0, $max2process ) {
      system ("perl", "clickshop-delete.pl", "-items", join (',', @items2process)) == \
        0 or warn "system failed: $? [$!]\n";
   }

Powinno działać.

url | Thu, 12/06/2014 20:36 | tagi: ,
Ethernet connection drop on Raspberry Pi

From time to time internet connection to my Raspberry Pi disappears (AFAIK it is well known feature of Pi). Removing and reconnecting the ethernet cables did not work, so one has to reboot by pulling the plug (risking to corrupt file systems from improper shutdown).

To reconnect I use the following bash script (found here):

#!/bin/bash
# Check if Internet connection is still alive *** 
# Insert into crontab at *.16
LOGLOG="/home/pi/Logs/Cron/Reboot.log"
WLAN=eth0

if /sbin/ifconfig $WLAN | grep -q "inet addr:" ; then
  echo "Network connection up!"
else
  echo "Attempting reconnect [`date +%Y%m%d%H%M`]" >> $LOGLOG
  /usr/bin/sudo /sbin/ifup --force $WLAN
fi

Note: use ifconfig -a to identify relevant interface (WLAN):

pi@raspberryberrystar ~ $ ifconfig -a ifconfig -a
eth0      Link encap:Ethernet  HWaddr b8:27:eb:f5:9a:d7  
          inet addr:192.168.1.146  Bcast:192.168.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

My other Pi is connected to internet not through a cable but with WiFi dongle. The relevant interface is:

pi@blackberrystar ~ $ ifconfig -a
wlan2     Link encap:Ethernet  HWaddr 10:fe:ed:12:ef:2c  
          inet addr:192.168.1.144  Bcast:192.168.1.255  Mask:255.255.255.0

The connection is checked every 20 minutes with the following crontab entry:

## Check Internet connection every 7th, 27th, 47th minute:
7,27,47 * * * * /home/pi/bin/chk_www_alive.sh > /dev/null 2>&1

url | Sun, 09/02/2014 17:38 | tagi: , , ,
A newer version of the Raspberry Pi

I am using Raspberry Pi version A (256 Mb) for more than a year and now I bought one Pi more--model B (512 Mb) this time. I bought a TP-Link WiFi card (TL-WN725N) and a camera as well. The plan is:

Attaching everything to one single Pi is not an option--I want the camera-equipped Pi to be more portable.

Also I did not want to install a new system but just to use what I use so far (ie the system used on the old Pi):

uname-a 
Raspberrystar.pinkaccordions.org Linux 3.2.27 + # 174 PREEMPT ... 

Simple inserting the card from the old Pi into the new one did not work (the system did not start). An upgrade is needed probably:

sudo apt-get update 
sudo rpi-update 
uname-a 
Raspberrystar.pinkaccordions.org Linux 3.10.18 + 

Now 1-Wire bus stopped working. I also can not start the WiFi adapter TP-Link TL-WN725N. Inspecting Internet forums I discovered that version 3.6.11+ of the kernel may be less problematic in this respect. Therefore, I try to downgrade:

sudo rpi-update 8234d5148aded657760e9ecd622f324d140ae891 

The above means to downgrade to the latest of 3.6.11+ versions:

pi @ raspberrystar ~ $ uname-a 
Linux 3.6.11 + raspberrystar.pinkaccordions.org # 557 PREEMPT 

Now the 1-Wire bus magically started to work. Sensors DHT-22 also work. The program I have used to read data from pressure sensor BMP085 required minor modifications and recompilation (as GPIO layout is different on Pi model B).

WiFi card also works, but require to download an appropriate driver. This one works for me (a copy is here). Other drivers, such as available here or here do not work. Compilation from sources as described here (in Polish is here) ends with an error as well.

Module 8188eu.ko can be installed as follows:

wget http://www.mendrugox.net/downloads/13 -O 818188eu.ko
## albo https://dl.dropboxusercontent.com/u/61315145/PiStuff/8188eu.ko.gz
## after download: gunzip 8188eu.ko.gz

sudo install -p -m 644 8188eu.ko /lib/modules/`uname -r`/kernel/drivers/net/wireless
sudo depmod -a
sudo modprobe 8188eu

The contents of the file /etc/network/interfaces should look like:

auto lo 

iface lo inet loopback 
iface eth0 inet dhcp 

allow-hotplug wlan0 
auto wlan0 
iface wlan0 inet dhcp 
wpa-ssid "NAME OF-NETWORK" 
wpa-psk "PASSWORD" 

One have to provide correct values for the NAME-NET and PASSWORD of course. The above settings will automatically establish a connection when the system starts.

Changing the host name

Minor thing, but I want to know easily which Pi is which:

## in the last line of /etc/hosts change host name
sudo vi /etc/hosts 

## insert host name (this file contains only 1 line with a host name:)
sudo vi /etc/hostname

sudo /etc/init.d/hostname.sh
sudo reboot

The file /etc/hosts looks something like this:

127.0.0.1 localhost 
:: 1 localhost ip6-localhost ip6-loopback 
fe00 :: 0 ip6-localnet 
ff00 :: 0 ip6-mcastprefix 
ff02 :: 1 ip6-allnodes 
ff02 :: 2 ip6-allrouters 

127.0.1.1 blackberrystar 

Camera

Updated system was cloned on a second card (Btw. for years I use Toshiba SDHC 8GB Class 10. This card is advertised as SLC but on card packaging/casing there is no word about it. SLC or not SLC I had never any problem with this card.)

Pi + kamera
Pi + camera

First picture

How to connect a camera to the Pi can be seen at one of the many videos on YouTube.

I followed instructions from How to set up the camera hardware.

Since I have not done this before:

pi@blackberrystar ~ $ sudo apt-get update
pi@blackberrystar ~ $ sudo apt-get upgrade

Now:

pi@blackberrystar ~ $ sudo raspi-config

I Choose Enable/Disable camera addon support and Memory split. I have not decided on the suggested 128 Mb for the GPU, bearing in mind that all the memory in my Pi is 256 Mb. Perhaps I am wrong and recommended 128MBs is better.

Test if it works:

pi@blackberrystar ~ $ mkdir picam
pi@blackberrystar ~ $ cd picam 
pi@blackberrystar ~ $ raspistill -o image.jpg

The result (the first picture taken) is shown on the picture.

url | Tue, 10/12/2013 10:58 | tagi: , ,
Nowsza wersja Raspberry Pi

Do posiadanego Raspberry Pi w wersji A (256 Mb) dokupiłem parę dni temu drugi egzemplarz, tym razem w wersji B (512 Mb). Kupiłem też kartę WiFi TP-link TL-WN725N oraz kamerę. Plan jest taki:

Doczepienie wszystkiego do jednego komputerka nie wchodzi w grę bo docelowo kamera ma być mobilna.

Nie chciałem instalować nowego systemu tylko skorzystać z tego co używam do tej pory (tj. system używany na starym Pi):

uname -a
Linux raspberrystar.pinkaccordions.org 3.2.27+ #174 PREEMPT ...

Prosta wymiana karty nie działa (system się nie uruchamia). Potrzebny jest zapewne upgrade:

sudo apt-get update
sudo rpi-update
uname -a
Linux raspberrystar.pinkaccordions.org 3.10.18+ 

Teraz przestała działać magistrala 1-Wire. Nie mogę też uruchomić karty WiFi TP-link TL-WN725N. Gdzieś na forach doczytałem, że wersja 3.6.11+ może być pod tym względem mniej problematyczna. Zatem próbuję:

 sudo rpi-update 8234d5148aded657760e9ecd622f324d140ae891

Powyższe oznacza cofnięcie się do najstarszej wersji oznaczonej symbolem 3.6.11+:

pi@raspberrystar ~ $ uname -a
Linux raspberrystar.pinkaccordions.org 3.6.11+ #557 PREEMPT

Teraz magistrala 1-Wire magicznie zaczęła działać. Czujniki DHT-22 też działają. Czujnik ciśnienia BMP085, obsługiwany przez program opisany tutaj, wymagał drobnej modyfikacji i przekompilowania, bo zmienił się układ wejść GPIO.

Karta WiFi też działa, ale wymagała ściągnięcia stosownego sterownika. U mnie działa ten (kopia jest tutaj). Natomiast inne, np. udostępniane tu albo tutaj nie działają. Także kompilacja wg. sposobu opisanego tutaj (po polsku jest tutaj) kończy się błędem.

Moduł 8188eu.ko należy zainstalować w następujący sposób:

wget http://www.mendrugox.net/downloads/13 -O 818188eu.ko
## albo https://dl.dropboxusercontent.com/u/61315145/PiStuff/8188eu.ko.gz
## po ściągnięciu: gunzip 8188eu.ko.gz

sudo install -p -m 644 8188eu.ko /lib/modules/`uname -r`/kernel/drivers/net/wireless
sudo depmod -a
sudo modprobe 8188eu

Zawartość pliku /etc/network/interfaces powinna wyglądać następująco:

auto lo

iface lo inet loopback
iface eth0 inet dhcp

allow-hotplug wlan0
auto wlan0
iface wlan0 inet dhcp
wpa-ssid "NAZWA-SIECI"
wpa-psk "HASŁO"

Należy oczywiście podać prawidłowe wartości dla NAZWY-SIECI oraz HASŁA. Takie ustawienie powoduje automatyczne ustanowienie połączenia po uruchomieniu systemu.

Zmiana nazwy hosta

Sprawa drobna ale potrzebna żeby wiedzieć który jest który:

## w ostatnim wierszu /etc/hosts zmień nazwę hosta 
sudo vi /etc/hosts 

## wpisz nazwę hosta (ten plik zawiera jeden wiesz, nazwę hosta):
sudo vi /etc/hostname

sudo /etc/init.d/hostname.sh
sudo reboot

W rezultacie mój plik /etc/hosts wygląda jakoś tak:

127.0.0.1       localhost
::1             localhost ip6-localhost ip6-loopback
fe00::0         ip6-localnet
ff00::0         ip6-mcastprefix
ff02::1         ip6-allnodes
ff02::2         ip6-allrouters

127.0.1.1       blackberrystar

Kamera

Uaktualniony i działający na nowym Pi system sklonowałem na drugą kartę (BTW. Od lat używam kart Toshiba SDHC 8GB Class 10. Karta ta jest reklamowana jako typu SLC aczkolwiek na opakowaniu/karcie nie ma o tym ani słowa. SLC czy nie SLC nigdy nie miałem z tą kartą żadnych problemów.)

Pi + kamera
Pi + kamera

Pierwsze zdjęcie

Jak podłączyć kamerę do komputerka można obejrzeć na jednym z licznych filmów na YouTube.

Dalej postępowałem wg. instrukcji na stronie How to set up the camera hardware.

Ponieważ wcześniej tego nie robiłem:

pi@blackberrystar ~ $ sudo apt-get update # na wszelki wypadek
pi@blackberrystar ~ $ sudo apt-get upgrade

teraz:

pi@blackberrystar ~ $ sudo raspi-config

Wybieram Enable/Disable camera addon support a następnie Memory split. Nie zdecydowałem się na sugerowane wydzielenie 128 Mb na GPU, mając na uwadze, że cała pamięć w moim Pi to raptem 256 Mb. Być może niepotrzebnie się spłoszyłem -- doczytam jeszcze na ten temat.

Test czy działa:

pi@blackberrystar ~ $ mkdir picam
pi@blackberrystar ~ $ cd picam 
pi@blackberrystar ~ $ raspistill -o image.jpg

Wynik (pierwsze wykonane zdjęcie) jest zamieszczony obok.

url | Sat, 16/11/2013 21:33 | tagi: ,
Time lapse: end of first experiment

Because my tomatoes are growing unexpectedly fast I had to stop capturing pictures quicker than I have planned as they do not fit in the frame.

So 2664 pictures was taken from 16.03 to 23.04 at 20 minutes interval. The video size is about 715 Mb and the video length is 3min 43 seconds (at 12 fps or 1:47 at 25 fps).

The videos are available at YouTube: 25 fps | 12 fps

url | Wed, 24/04/2013 16:35 | tagi: , , , , , , , , ,
Pierwszy film poklatkowy

Ustaliłem empirycznie w jaki sposób podłączyć aparat do Raspberry Pi (do SheevaPlug zresztą też) żeby nic się nie zacinało. W skrócie:

  1. Używam kompakta Nikon S3000 (Canon A620 się zacinał/odłączał--sprzedałem go na Allegro).

  2. Podłączam aparat poprzez aktywny USB hub (kupiłem w tym celu cztero-portowy HUB firmy Vivanco).

  3. Po każdym zdjęciu wykonuję reset stosownego portu USB za pomocą programiku pn. usb_reset (zobacz tutaj oraz tutaj).

Kilka aparatów

Używam dwóch aparatów Nikon S3000 (kupionych na Allegro oczywiście), więc jest problem z ustaleniem który jest który:

$gphoto2 --auto-detect
Model                          Port                                            
----------------------------------------------------------
Nikon Coolpix S3000 (PTP mode) usb:001,022     
Nikon Coolpix S3000 (PTP mode) usb:001,021  

Można użyć opcji --port usb:001,022 aby wykonać coś z ,,pierwszym'' aparatem oraz --port usb:001,021, aby dostać się do drugiego. Oczywiście umieszczenie numerów portów na-zicher w skryptach byłoby kiepskim pomysłem ponieważ nie są one ustalone, ale się zmienią jeżeli urządzenie zostanie odłączone/przyłączone ponownie. Lepszym sposobem zidentyfikowania aparatów jest wykorzystanie numeru seryjnego:

## $gphoto2  --get-config serialnumber --port PORT
## example
$gphoto2  --get-config serialnumber --port usb:001,022
Label: Serial Number                                                           
Type: TEXT
Current: 000047514512

Mam czarnego Nikona o numerze 000041076602 oraz różowego o numerze 000047514512. Używam następującego skryptu do wykonania zdjęcia określonym aparatem:

#!/bin/bash
PINK_CAM_ID='000047514512'
BLACK_CAM_ID='000041076602'

while test $# -gt 0; do
  case "$1" in
    -b|--black)   REQ_CAM="$BLACK_CAM_ID";;
    -p|--pink)    REQ_CAM="$PINK_CAM_ID";;
  esac
  shift
done

## Nazwa pliku ze zdjęciem:
FILENAME="NIK`date +"%Y%m%d%H%M"`.jpg"

## Przejrzyj wszystkie podłączone aparaty:
while read PORT_ID 
do 
        ##echo $PORT_ID 
        ## -n means string is non-empty
        if [ -n "$PORT_ID" ] ; then
                CAM_ID=`gphoto2 --get-config serialnumber --port $PORT_ID | awk '/Current:/ { print $2 }' `
                if [ $CAM_ID = "$REQ_CAM" ] ; then
                        REQ_CAM_PORT="$PORT_ID"
                        ##echo "*** Req Camera ID: #$CAM_ID."
                fi
        fi
        
done <<< "`gphoto2 --auto-detect | grep usb | awk '{ print $6}'`"

# Na wypadek błędu wyślij alarmowego SMSa
if [ -z "$REQ_CAM_PORT" ] ; then
      echo "*** Error: Camera $REQ_CAM not found ***"
      ## sent a SMS cf http://pinkaccordions.homelinux.org/wblog/sms_alerts_with_google_calendar.html
      sms_reminder.sh
      exit 1   
fi

## reset USB 
REQ_CAM_PORT_DEVNAME=`echo $REQ_CAM_PORT | sed 's/^.*://' | sed 's/,/\//'`
usb_reset /dev/bus/usb/${REQ_CAM_PORT_DEVNAME}

LANG=C gphoto2 --port "$REQ_CAM_PORT" --force-overwrite --set-config flashmode=1 \
   --set-config d002=4 \
   --capture-image-and-download --filename "$FILENAME"

## reset USB (powtórny) 
usb_reset /dev/bus/usb/${REQ_CAM_PORT_DEVNAME}

Właściwość d002 ustawia rozdzielczość zdjęcia (4 oznacza 2592x1944).

Wartość 1 właściwościflashmode wyłącza flash.

Z moich eksperymentów wynika, że bez wykonania usb_reset bateria aparatu nie jest doładowywana (czemu?) i po pewnym czasie z powodu braku zasilania aparat odłącza się.

Film

Po czterech tygodniach mam wystarczająco dużo zdjęć aby spróbować zrobić pierwszy film.

Najpierw konwertuję wszystkie zdjęcia do rozdzielczości 1920x1080 za pomocą programu convert (z zestawu ImageMagick) uruchamianego z ,,wewnątrz'' prostego skryptu Perla. Ponieważ nazwy plików wejściowych są konstruowane wg schematu NIKYYYYMMDDHHMM.jpg (gdzie YYY to rok, MM oznacza miesiąc, itd.) sortowanie alfabetyczne oznacza ustawienie ich także we właściwym porządku chronologicznym. Nazwy plików wynikowych są zaś konstruowane jako: hd1920_00001.jpg, hd1920_00002.jpg, itd.

#!/usr/bin/perl

opendir (DIR, ".");
my  @files = sort { $a cmp $b } readdir(DIR);

while (my $file = shift @files ) {
   if ($file =~ /.jpg$/) {  $fileNo++;
      $file_out = sprintf "hd1920_%05d.jpg", $fileNo;
      print "$file -> $file_out\n";
      system ("convert", $file, "-geometry", "1920x1080", "$file_out");
   }
}

Okazało się, że jest dokładnie 1784 zdjęć:

$ls -l hd1920_0* | wc -l
1784

Konwersja trwała około 30 min na moim przeciętnym zupełnie PC-cie. Każdy plik wynikowy miał około 0,5Mb; wszystkie razem zajmowały około 0,85Gb:

$ls -l hd1920_0* | awk '{t+=$5}; END{print t}'
853332231

Film został wykonany za pomocą programu ffmpeg:

ffmpeg -r 12 -qscale 2 -i hd1920_%05d.jpg Tomato_12.mp4

Gdzie -r 12 oznacza liczbę klatek na sekundę (12 fps) a -qscale określa jakość (1 oznacza najlepszą, 32 najgorszą jakość).

Film ma około 450 Mb. Konwersja zajmuje około 3min (on my decent PC) a długość filmu to 2min i 29 sekundy.

Film przedstawia sadzonkę pomidora (Pinkaccordion oczywiście :-). Zdjęcia były robione co 20 minut od 16 marca do 11 kwietnia.

Są także wersje na 25 fps oraz 6 fps.

url | Mon, 15/04/2013 17:05 | tagi: , , , , , , , ,
Time lapse: first production

After almost 4 weeks I have enough pictures to create my first video production. (How to capture images with a still camera attached to Raspberry Pi is described here and here.)

I started from converting all pictures to 1920x1080 resolution with convert run from a simple Perl script. As the input file names are constructed as NIKYYYYMMDDHHMM.jpg (where YYY denotes year, MM denotes month etc) alphabetic sorting is OK. The resulting files are named as hd1920_00001.jpg, hd1920_00002.jpg, etc.

#!/usr/bin/perl

opendir (DIR, ".");
my  @files = sort { $a cmp $b } readdir(DIR);

while (my $file = shift @files ) {
   if ($file =~ /.jpg$/) {  $fileNo++;
      $file_out = sprintf "hd1920_%05d.jpg", $fileNo;
      print "$file -> $file_out\n";
      system ("convert", $file, "-geometry", "1920x1080", "$file_out");
   }
}

There are exactly 1784 pictures:

$ls -l hd1920_0* | wc -l
1784

Conversion of all images lasted circa half an hour on my decent PC. Each picture size is about 0,5Mb, while the total size is 0,85Gb:

$ls -l hd1920_0* | awk '{t+=$5}; END{print t}'
853332231

To create a video from the images I run ffmpeg now:

ffmpeg -r 12 -qscale 2 -i hd1920_%05d.jpg Tomato_12.mp4

Where -r 12 means frames ratio (12 fps) and -qscale determines video quality (1 denotes best quality and 32 is the lowest one).

The video size is about 450 Mb. The conversion takes circa 3min (on my decent PC) and the video length is 2min 29 seconds.

The movie's subject is a growing tomato (Pinkaccordion variety of course:-). The photographs were taken every 20 minutes from March 16th to April 11th.

There are versions at 25 fps and 6 fps as well.

url | Fri, 12/04/2013 12:15 | tagi: , , , , , , , , ,
Raspberry Pi: some progress with time-lapse photography

I have made some progress in accessing still camera with gphoto2 (cf. here). The detailed description of my set-up will be disclosed within a few weeks (as I am still not sure if it is 100% success:-). In short:

I changed camera from Canon A620 to Nikon S3000.

I connected camera with active USB hub.

On every capture USB port is reset with usb_reset utility (cf here and here)

Multiple cameras

I use two Nikon S3000 compact cameras so there is a problem how to identify which is which.

$gphoto2 --auto-detect
Model                          Port                                            
----------------------------------------------------------
Nikon Coolpix S3000 (PTP mode) usb:001,022     
Nikon Coolpix S3000 (PTP mode) usb:001,021  

So one can use --port usb:001,022 option to access first attached camera and --port usb:001,021 to access the second one. Of course hard-coded port numbers are troublesome as they are not fixed and change if the device is disconnected/connected again. Better way to identify the camera is to use it's serial number:

## $gphoto2  --get-config serialnumber --port PORT
## example
$gphoto2  --get-config serialnumber --port usb:001,022
Label: Serial Number                                                           
Type: TEXT
Current: 000047514512

I have black Nikon with 000041076602 serial number and pink one with 000047514512 serial number. I use the following bash script to access the cameras:

#!/bin/bash
PINK_CAM_ID='000047514512'
BLACK_CAM_ID='000041076602'

while test $# -gt 0; do
  case "$1" in
    -b|--black)   REQ_CAM="$BLACK_CAM_ID";;
    -p|--pink)    REQ_CAM="$PINK_CAM_ID";;
  esac
  shift
done

## Picture filename:
FILENAME="NIK`date +"%Y%m%d%H%M"`.jpg"

## Scan all attached cameras:
while read PORT_ID 
do 
        ##echo $PORT_ID 
        ## -n means string is non-empty
        if [ -n "$PORT_ID" ] ; then
                CAM_ID=`gphoto2 --get-config serialnumber --port $PORT_ID | awk '/Current:/ { print $2 }' `
                if [ $CAM_ID = "$REQ_CAM" ] ; then
                        REQ_CAM_PORT="$PORT_ID"
                        ##echo "*** Req Camera ID: #$CAM_ID."
                fi
        fi
        
done <<< "`gphoto2 --auto-detect | grep usb | awk '{ print $6}'`"


if [ -z "$REQ_CAM_PORT" ] ; then
      echo "*** Error: Camera $REQ_CAM not found ***"
      ## sent a SMS cf http://pinkaccordions.homelinux.org/wblog/sms_alerts_with_google_calendar.html
      sms_reminder.sh
      exit 1   
fi

## reset the USB device
REQ_CAM_PORT_DEVNAME=`echo $REQ_CAM_PORT | sed 's/^.*://' | sed 's/,/\//'`
usb_reset /dev/bus/usb/${REQ_CAM_PORT_DEVNAME}

LANG=C gphoto2 --port "$REQ_CAM_PORT" --force-overwrite --set-config flashmode=1 \
   --set-config d002=4 \
   --capture-image-and-download --filename "$FILENAME"

## reset the USB device again
usb_reset /dev/bus/usb/${REQ_CAM_PORT_DEVNAME}

Property d002 sets picture resolution (4 means 2592x1944).

Value 1 of flashmode turns-off flash.

It seems that without usb_reset there are problems with battery charging (why?)

url | Thu, 04/04/2013 21:26 | tagi: , , , , , , , , ,