TimeLaps für Autonomen Einsatz mit RTC
Der Raspberry soll Timelapsaufnahmen von Sonnenauf-bis Sonnenuntergang machen. Fotos vom CAM-Modul sollen in guter Qualität in festgelegten Intervallen (min 30s) erstellt werden und anschließend in einen MP4 Film umgewandelt werden. Da der Raspberry ohne Netzwerkverbindung autonom arbeiten soll, hat er eine Echtzeituhr (RTC) bekommen. Zusätzlich einen 32GB großen USB-Stick zum Speichern der Filme.
Vorbereitung: Einbau des Raspberry und das CAM-Modul in ein Gehäuse. Ich habe ein Standardgehäuse in Schwarz genommen und in der Mitte der Frontseite im Gehäuses ein Loch für die Kamera gebohrt und unten ein Gewinde für ein kleines Stativ. Für die RTC muss im Gehäuse noch etwas Plastik entfernt werden, damit alles rein passt.
Software: Als Betriebssystem für den Raspberry benutze ich immer eine aktuelle Version von Raspbian lite weil ich keinen grafischen Desktop brauche.
Nachdem der Raspberry per SSH am Netz hängt kann die Einrichtung beginnen.
1 |
sudo raspi-config |
Hier die Cam und den I²C Bus für die RTC einschalten.
Das Einbinden eines USB-Sticks wird hier sehr gut erklärt.
Anschließend in der FSTAB Laufwerke (NAS und USB-Stick) für das Speichern der fertigen Filme einstellen.
1 2 3 4 5 6 7 8 |
Sudo nano /etc/fstab proc /proc proc defaults 0 0 PARTUUID=f6efd4df-01 /boot vfat defaults 0 2 PARTUUID=f6efd4df-02 / ext4 defaults,noatime 0 1 # a swapfile is not a swap partition, no line here # use dphys-swapfile swap[on|off] for that //192.168.178.1/web/www/mywebcams /mnt/camshare cifs vers=1.0,username=[name],password=[pass] UUID=[nnnn-nnnn] /media/usbstick/ vfat defaults,umask=000,users 0 0 |
Wir brauchen noch ein paar Softwaremodule für die Berechnung und Umwandlung von den Bilder in einen MP4 Film.
1 2 3 4 5 6 |
sudo apt-get update sudo apt-get upgrade sudo apt-get install bc sudo apt-get install mencoder sudo apt-get install libav-tools sudo apt-get install imagemagick |
Ablaufdiagramm:
Per Crontab wird das Script „photos.sh“ gestartet. Ich habe das nach dem Reboot festgelegt.
1 2 |
# Nach reboot nach 20 Sek Photos.sh starten @reboot sleep 20 && /home/pi/photos.sh & |
Im Script wird zum Berechnen eine Funktionserweiterung der Shell gebraucht: bc („Basic Calculator“) die vorher installiert wurde. Link
Quelle Berechnung Sonnen-auf und Untergang: www.anginf.de und ein paar Hintergründe zur Definition..
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
#--------------------- Sonnenauf und Untergang berechnen ----- #----------------------- Quelle //www.anginf.de--------------- !/bin/bash # Benoetigt apt-get install bc # Unsere Position # Roesrath posLaenge="7.183" posBreite="59.904" # Athlone #posLaenge="-7.942" #posBreite="53.423" # Notwendige Vorberechnungen zoneinfo=$(date +%z) # Zeitzone T=`date +%j` # Tag im Jahr pi="3.14159265358979323844" # pi=`echo "4*a(1)" | bc -l` rad=$(echo "${pi}/180" | bc -l) h=$(echo "-(5/6)*(${rad})" | bc -l) # Höhe des Sonnenmittelpunkts bei Aufgang: Radius+Refraktion BreiteRAD=$(echo "${posBreite}*${rad}" | bc -l) # Welcher Tag ist heute? echo "Heute ist $(date +%d.%m.%y), der $(date +%j). Tag im Jahr" echo -n "Wir nutzen die Zeitzone $(date +%Z), dies entspricht $(date +%z) und damit " echo "${zoneinfo:0:3}" sonnendekl=`echo "0.409526325277017*s(0.0169060504029192*(${T}-80.0856919827619))" | bc -l` sonnendeklDEG=$(echo "${sonnendekl} / ${rad}" | bc -l) arccosint=$(echo "(s(${h})-s(${BreiteRAD})*s(${sonnendekl}))/(c(${BreiteRAD})*c(${sonnendekl}))" | bc -l) arccosintsign=${arccosint:0:1} if [ ${arccosintsign} == "-" ]; then usesign="+" else usesign="-" fi arc2cosint=$(echo "(${arccosint}) * (${arccosint})" | bc -l) acoszeit=$(echo "${pi}/2 ${usesign} a(sqrt(${arc2cosint} / (1 - (${arc2cosint}) ) ) ) " | bc -l) zeitdiff=$(echo "12*${acoszeit}/${pi}" | bc -l) # KORREKT! zeitgleich=$(echo "-0.170869921174742*s(0.0336997028793971 * ${T} + 0.465419984181394) - 0.129890681040717*s(0.0178674832556871*${T} - 0.167936777524864)" | bc -l) aufgang=$(echo "12-(${zeitdiff})-(${zeitgleich})-(${posLaenge}/15)${zoneinfo:0:3}" | bc -l) untergang=$(echo "12+(${zeitdiff})-(${zeitgleich})-(${posLaenge}/15)${zoneinfo:0:3}" | bc -l) if [ ${aufgang:1:1} == "." ]; then # Ist ein einstelliges Ergebnis der Form x.xxxx, wir brauchen noch eine 0 vorne aufgang=$(echo 0${aufgang}) fi # Fuer unsere Breitengrade ueberfluessig, nur der Vollstaendigkeit halber: #if [ ${untergang:1:1} == "." ]; then # Ist ein einstelliges Ergebnis der Form x.xxxx, wir brauchen noch eine 0 vorne # untergang=$(echo 0${untergang}) #fi # Umrechnung in Stunden (trivial) und Minuten (runden!) AufgangMinute=$(echo "(${aufgang} - ${aufgang:0:2}) * 60" | bc | xargs printf "%02.0f\n") if [ ${AufgangMinute} == "60" ]; then AufgangMinute="00" AufgangStunde=$(echo "${aufgang:0:2} + 1" | bc | xargs printf "%02.0f") else AufgangStunde=${aufgang:0:2} fi echo "Aufgang (hh:mm): ${AufgangStunde}:${AufgangMinute}" # Immer ein zweistelliges Ergebnis aufgang=${AufgangStunde}:${AufgangMinute} UntergangMinute=$(echo "(${untergang} - ${untergang:0:2}) * 60" | bc | xargs printf "%02.0f\n") if [ ${UntergangMinute} == "60" ]; then UntergangMinute="00" UntergangStunde=$(echo "${untergang:0:2} + 1" | bc | xargs printf "%02.0f") else UntergangStunde=${untergang:0:2} fi echo "Untergang (hh:mm): ${UntergangStunde}:${UntergangMinute}" # Immer ein zweistelliges Ergebnis untergang=${UntergangStunde}:${UntergangMinute} AUFGANG=$aufgang UNTERGANG=$untergang export AUFGANG export UNTERGANG echo "--------------- sunset variable errechnet ----------------" >> /mnt/camshare/_RPi3_TLaps/log.txt echo "sunset AUFGANG=" $AUFGANG >> /etc/environment echo "sunset UNTERGANG=" $UNTERGANG >> /etc/environment #RTC stellen echo "sunset Aufgang :" $AUFGANG >> /mnt/camshare/_RPi3_TLaps/log.txt echo "sunset Untergang:" $UNTERGANG >> /mnt/camshare/_RPi3_TLaps/log.txt echo "------------------- sunset.sh end ------------------------" >> /mnt/camshare/_RPi3_TLaps/log.txt # ------------------------------------------------------------------------------------------------ # Timelaps script A.Schade 29.03.2019 INTERVAL=60 # Aufnahmeinterval in Sekunden AUFGANG_SEK=$(date -d $AUFGANG +%s) UNTERGANG_SEK=$(date -d $UNTERGANG +%s) AKTUAL_SEK=$(date +%s) nice_date="+%Y-%m-%d %H:%M:%S" nice_date=$(date "$nice_date") echo $nice_date "----------------- start photo.sh ----------------------" >>/mnt/camshare/_RPi3_TLaps/log.txt echo "Sonnenaufgang [SEK]:" $AUFGANG_SEK $AUFGANG >>/mnt/camshare/_RPi3_TLaps/log.txt echo "Sonnenuntergang [SEK]:" $UNTERGANG_SEK $UNTERGANG >>/mnt/camshare/_RPi3_TLaps/log.txt echo "Aktuelle Zeit [SEK]:" $AKTUAL_SEK $(date +%H:%M:%S) >>/mnt/camshare/_RPi3_TLaps/log.txt # Wenn die aktuelle Zeit später als Sonnenuntergang ist mach nix while [ $AKTUAL_SEK -gt $UNTERGANG_SEK ] do #nix done # Wenn die aktuelle Zeit vor Sonnenaufgang liegt mach nix while [ $AKTUAL_SEK -le $AUFGANG_SEK ] do #nix done # Wenn die aktuelle Zeit nach Sonnenaufgang liegt mach Photos while [ $AKTUAL_SEK -gt $AUFGANG_SEK ] do AKTUAL_SEK=$(date +%s) timestamp=$(date +%Y-%m-%d_%H-%M-%S) nice_date="+%Y-%m-%d %H:%M:%S" nice_date=$(date "$nice_date") sudo raspistill -o /home/pi/photos/$timestamp.jpg # Mache ein Photo und speichere auf die SD-Karte echo "Photo OK " $nice_date >>/mnt/camshare/_RPi3_TLaps/log.txt sudo convert -pointsize 64 -fill white -stroke black -draw "text 10,75 '$nice_date'" /home/pi/photos/$timestamp.jpg /home/pi/photos/$timestamp.jpg sudo cp /home/pi/photos/$timestamp.jpg /mnt/camshare/_RPi3_TLaps/live.jpg sudo cp /home/pi/photos/$timestamp.jpg /media/usbstick/photos/live.jpg if [ $AKTUAL_SEK -gt $UNTERGANG_SEK ] then echo "-------------- LASTPIC --------" $nice_date >>/mnt/camshare/_RPi3_TLaps/log.txt echo "------ finish photo.sh --------" $nice_date >>/mnt/camshare/_RPi3_TLaps/log.txt break # Skip entire rest of loop. fi sleep $INTERVAL done |
um den Bereich auf die Dämmerung auszudehnen kann man hierzu noch 2 weitere Werte erechnen:
1 2 3 4 5 6 7 |
auf=$(echo ${aufgang:0:2}:)$(echo „(${aufgang} – ${aufgang:0:2}) * 60“ | bc | xargs printf „%02.0f\n“) unter=$(echo ${untergang:0:2}:)$(echo „(${untergang} – ${untergang:0:2}) * 60“ | bc | xargs printf „%02.0f\n“) dawn=$(date -d „${auf//:/} – 32 minutes“ „+%k:%M“) dusk=$(date -d „${unter//:/} + 32 minutes“ „+%k:%M“) echo DAWN $dawn — DUSK $dusk |
Das Rendern des Films aus den vielen Einzelbilder kostet je nach Anzahl relativ viel Zeit, weil dem Raspberry etwas Rechenpower fehlt..
Das Script „makemovie.sh“ starte ich um 22:00 Uhr per Crontab. Abschließend startet der Raspberry neu und ist bereit für den nächten Tag.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#zeitstempel fuer dateiname generieren timestamp=$(date +%Y-%m-%d_%H-%M-%S) # Film aus den jpg's machen echo $(date +%Y-%m-%d_%H-%M-%S) "---------------------- Start makemovie.sh --------------------" >> /mnt/camshare/_RPi3_TLaps/log.txt # mencoder -nosound mf:///home/pi/photos/*.jpg -mf w=2592:h=1944:fps=10:type=jpg -ovc lavc -lavcopts vcodec=mpeg4:mbd=2:trell -oac copy -o //home/pi/movies/$timestamp.mp4 mencoder -nosound mf:///home/pi/photos/*.jpg -mf w=1920:h=1080:type=jpg:fps=15 -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=7000 :mbd=2:keyint=132:v4mv:vqmin=3:lumi_mask=0.07:dark_mask=0.2:mpeg_quant:scplx_mask=0.1:tcplx_mask=0.1:naq -o /home/pi/movies/$timestamp.mp4 echo $(date +%Y-%m-%d_%H-%M-%S) "---------------------- MP4 Movie erzeugt------------------------" >> /mnt/camshare/_RPi3_TLaps/log.txt exit # kopieren des Films auf Server echo $(date +%Y-%m-%d_%H-%M-%S) "----------------------- Copy Movie to Server -------------------" >> /mnt/camshare/_RPi3_TLaps/log.txt cp /home/pi/movies/*.mp4 /mnt/camshare/_RPi3_TLaps/ # kopieren den films auf USB-Stick echo $(date +%Y-%m-%d_%H-%M-%S) "---------------------- Copy Movie to USB-Stick -----------------" >> /mnt/camshare/_RPi3_TLaps/log.txt cp /home/pi/movies/*.mp4 /media/usbstick/movies/ # löschen der Photos und Filme auf der SD Karte echo $(date +%Y-%m-%d_%H-%M-%S) "------------------------- Clean SD-Card ----------------------" >> /mnt/camshare/_RPi3_TLaps/log.txt rm /home/pi/movies/*.mp4 rm /home/pi/photos/*.jpg echo $(date +%Y-%m-%d_%H-%M-%S) "------------------------- End Makemovie ----------------------" >> /mnt/camshare/_RPi3_TLaps/log.txt # reboot nach 20 s sleep 20 && sudo shutdown -r now |
Bei mir startet das script nicht..
Ich habe noch ein paar Zeilen ergänzt.. jetzt sollte es klappen.