River Cam (6 / 8 steg)
Steg 6: Ljus nivåkontroll
Auto ljusstyrkan kontrollen är inte så bra för att styra kameran som på Pi efter ett tag du finna det bara pendlande mellan ytterligheterna. Ursprungligen jag hade råd att vända motioneye automatisk ljusstyrka på och bort skulle kalibrera saker-vilket den gjorde – åtminstone tills juni 2016 uppgraderingen!
Det ursprungliga manuset som jag placerade i cron var:
ECHO "---Start level_ligt.sh---"
datum
sed -I's / auto_brightness off/auto_brightness på / g' /data/etc/thread-1.conf
sed -I's / # på / # off / g' /data/etc/thread-1.conf
/etc/init.d/S85motioneye restart
sömn 30
sed -I's / auto_brightness på/auto_brightness off / g' /data/etc/thread-1.conf
sed -I's / # off / # på / g' /data/etc/thread-1.conf
/etc/init.d/S85motioneye restart
Den fil som redigeras är effektivt motion.conf filen som motioneye har bytt namn med en rad för varje kamera (så om du som jag bara har en kommer att vara thead-1.conf.
Som sagt, detta fungerade grad tills MotionEyeOs uppgraderas och resulterade i ljuset nivå lämnas på en random inställning (oftast i ena änden av spektrumet) lyckligtvis som jag hade beslutat att flytta till en vanilj Raspbian installation, jag fått tillgång till v4l2 kontrollerna och funnit att följande kommandorad arbetade samtidigt motion var igång :
v4l2-ctl--set-ctrl = ljusstyrka = 50, kontrast = 50
Så min nästa strategi var att placera ovanstående uttalande (med värden av 50/50 för dagtid, och 100/100 för natt) i python IRfilter_control.py script (dessa har lagts ovan), värden men kruxet är att nu IR-filter är bort ljuset in i kameran dubbel, så ställer in det till natten på denna punkt resultat i virtuella mörker före solnedgången , och utbränd bild efter.
Något mer intensiv krävdes, så nästa steg var att skapa en sqlite konfigurationsdata som har värden för endera sidan av solen händelsen och styr även IR-filter.
IRfilter_control.py (detta är en upprepning av de tidigare avsnitten kod och behov sunset.py att köra)
#-----------------------------------------------------------#
# bibliotek #
#-----------------------------------------------------------#
importera RPi.GPIO som GPIO
från att importera sömn, localtime, mktime
från datetime import datetime, datum
importera sunset
importera underprocess
importera re
importera sqlite3
importera sys
#-----------------------------------------------------------#
# time2sec #
#-----------------------------------------------------------#
def time2sec (t):
skriva ut t
l = re.split(':',t)
återgå int(l[0]) * 3600 + int(l[1]) * 60 +float(l[2])
#-----------------------------------------------------------#
# exposure_level #
#-----------------------------------------------------------#
def exposure_level (sr, ss, t):
TS = time2sec(str(t))
skriva ut ts
SRS = time2sec(str(sr))
SSS = time2sec(str(ss))
om ts > sss: # då iit är efter solnedgången
period = 4 # efter solnedgången
gap = ts - sss
annat:
om ts < srs:
period = 1 # före gryningen
gap = srs - ts
annat:
mitt på dagen = (sss - srs) / 2 # inte riktigt men tillräckligt bra
om ts < middagar:
period = 2 # efter gryningen
gap = ts - srs
annat:
period = 3 # före solnedgången
gap = sss - ts
# Nu använder han gap och period arbetet ut nivåerna.
Skriv ut period
gap = gap / 60 #convert till mminutes
skriva ut gap
försök:
dbconnect = ingen
dbconnect = sqlite3.connect('light_levels.db')
markören = dbconnect.cursor()
cursor.Execute ("SELECT * FROM nivåer där period = %d och gap > %d ORDER BY gap ASC" % (period, gap))
rad = cursor.fetchone() # förhoppningsvis är nästa en i ordning som vi strategi/moveaway från sr/ss
Om raden:
ljusstyrka = rad [2]
kontrast = rad [3]
filtret = rad [4]
annat:
skriva ut "Ingen data availalble - ange standardinställningar"
ljusstyrka = 50
kontrast = 50
filtret = 1
utom sqlite3. Fel, e:
skriva ut "Fel % s:" % e.args[0]
sys.Exit(1)
Slutligen:
om dbconnect:
dbconnect.Close
skriva ut "ljusstyrka", ljusstyrka
skriva ut "kontrast", kontrast
Print "Filtrera", filtrera
skriva ut "gap", raden [1]
tillbaka (ljusstyrka, kontrast, filter)
#-----------------------------------------------------------#
# Allmänna parametrar #
#-----------------------------------------------------------#
#display inga varningar (på kommandoraden)
GPIO.setwarnings(False)
#use RPi styrelsen pin-koder
GPIO.setmode (GPIO. STYRELSEN)
#set pin 16, 18 och 22 som utgång
GPIO.setup (16, GPIO. OUT)
GPIO.setup (18, GPIO. OUT)
GPIO.setup (22, GPIO. OUT)
delay_s = 60 #delay i sekunder
# Ställ in latitud och longitud (det är möjligt att få detta på nätet,
# men jag föredrog fasta som kameran är inte rörliga)
home_lat = "51.83"
home_long = "-1.40"
welcome_mess = "From Dusk Till Dawn v2.1 (08/2014)"
skriva ut "\n"
skriva ut welcome_mess
#-----------------------------------------------------------#
# main loop #
#-----------------------------------------------------------#
medan 1:
#-----------------------------------------------------------#
# Avgöra soluppgång/solnedgång #
#-----------------------------------------------------------#
#determine föregående/nästa solnedgången och -upphov
#define solen som anmärker av intresserar
s=Sunset.Sun()
SR = s.sunrise()
SS = s.sunset()
t = datetime.utcnow().time()
skriva ut "solnedgång:", ss
skriva ut "soluppgång:", sr
# Lookup databas att få nivåer för tiden på dagen i förhållande till solen
light_level = exposure_level (sr, ss, t)
om light_level [2]: # värdet av filter är sanna och filtret måste vara på
skriva ut "Slå på IR-filter"
GPIO.output (16, GPIO. LÅG)
GPIO.output (18, GPIO. HÖG)
GPIO.output (22, GPIO. HÖG)
annat:
skriva ut "Stänga av IR-filter"
GPIO.output (16, GPIO. HÖG)
GPIO.output (18, GPIO. LÅG)
GPIO.output (22, GPIO. HÖG)
# Justera digital vinst på kameran med hjälp av databasdata
subprocess.Call ("v4l2-ctl--set-ctrl = ljusstyrka = %d kontrast = %d ' % (light_level [0], light_level[1]), skal = True)
Sleep(delay_s) #wait
Själva koden använder en sqlite databas "light_levels.db" som från början innehöll följande data (detta kommer att förfinas med tiden att göra resultaten matchar de generiska ljusförhållandena:
DROP TABLE nivåer. Skapa tabell nivåer (perioden INT, gap INT, ljusstyrka INT, kontrast INT, filtrera INT);
INSERT INTO nivåer värden (1,5,75,60,0);
INSERT INTO nivåer värden (1,10,80,65,0);
INSERT INTO nivåer värden (1,15,85,70,0);
INSERT INTO nivåer värden (1,20,90,75,0);
INSERT INTO nivåer värden (1,25,95,80,0);
INSERT INTO nivåer värden (1,30,100,100,0);
INSERT INTO nivåer värden (1,999999,100,100,0);
INSERT INTO nivåer värden (2,5,75,60,0);
INSERT INTO nivåer värden (2,10,65,60,0);
INSERT INTO nivåer värden (2,15,55,60,0);
INSERT INTO nivåer värden (2,20,70,70,1);
INSERT INTO nivåer värden (2,25,60,60,1);
INSERT INTO nivåer värden (2,30,50,50,1);
INSERT INTO nivåer värden (2,999999,50,50,1);
INSERT INTO nivåer värden (3,5,60,60,0);
INSERT INTO nivåer värden (3,10,60,60,0);
INSERT INTO nivåer värden (3,15,75,75,1);
INSERT INTO nivåer värden (3,20,65,65,1);
INSERT INTO nivåer värden (3,25,60,60,1);
INSERT INTO nivåer värden (3,30,50,50,1);
INSERT INTO nivåer värden (3,999999,50,50,1);
INSERT INTO nivåer värden (4,5,60,60,0);
INSERT INTO nivåer värden (4,10,70,70,0);
INSERT INTO nivåer värden (4,15,80,80,0);
INSERT INTO nivåer värden (4,20,90,90,0);
INSERT INTO nivåer värden (4,25,90,90,0);
INSERT INTO nivåer värden (4,30,100,90,0);
INSERT INTO nivåer värden (4,999999,100,90,0);
Fungerar genom att bryta dagen på 4 perioder bryts upp av solen händelserna och då med ett dataelement för varje 10 minuters fönster (detta kunde minskas) i zonen 30 minuter och sedan en standardpost som koden plockar utanför "zone". Skriptet ovan kan förresten klistras som en klump i en sqlite för att skapa databasinnehållet.
En del jag förväntar att åtgärda undertrycka rörelsedetektorn när vända ljusnivåer. Men har inte jag ännu bestämt om att behålla Motion detection elementet på YouTube sänder Pi som jag inte vill att bildfrekvensen att släppa när något intressant händer. Mer att följa om jag kan räkna ut hur man gör detta arbete av de verkliga ljusförhållandena utan en ljussensor (som det finns inte plats för mer kretsar)...