Sida 1 av 1
LCD controllern och GPIO
Postat: 19 jan 2009, 10:46
av CirruZZ
Jag håller på och bygger in min LCD och LCD controller i en låda och har samtidigt kopplat 4 st externa tryck switchar till controllern. (Bilder kommer

)
Frågan jag har är, hur gör man för att på ett smidigt sätt hålla koll på om någon knapp är ned tryckt? Det jag menar är att det är ju en räknare som ändras när man trycker ned en knapp och således måste man hela tiden kolla om den har ändrats. Att göra detta via BASH script och crontab känns inte rätt väg då det i praktiken skulle behöva vara en konstant övervakning. Finns det någon annat sätt som man skulle kunna använda för att kolla om en förändering har skett och då trigga ett script eller annat kommando? Finns det något enkelt program som kan ligga i bakgrunden, kanske går att skriva ett simpelt i C (något som jag inte kan

)
Att skriva info till LCD tänkte jag lösa med vanligt script.
Re: LCD controllern och GPIO
Postat: 19 jan 2009, 11:38
av Plutonium
Det finns ett program som heter incron som "bevakar" nått som i sin tur triggar igång nått annat
http://inotify.aiken.cz/?section=incron ... ut&lang=en
Re: LCD controllern och GPIO
Postat: 19 jan 2009, 11:56
av CirruZZ
Ahaa!!!!! Det där verkar ju var PRECIS vad jag var ute efter, det skall jag kolla närmare på. TACKAR!

Re: LCD controllern och GPIO
Postat: 19 jan 2009, 12:17
av CirruZZ
Re: LCD controllern och GPIO
Postat: 12 feb 2009, 14:37
av CirruZZ
Då har jag gjort första testen men det verkar inte funka....

Kan vara så att det är jag som gjort fel också...
Men det jag undrar är lite hur OWFS (eller andra 1-wire program för den delen) jobbar. Allt som sker på 1-wire nätet initieras väl från början av det, dvs från datorn. En enhet som sitter på nätet kan väl inte på eget initiativ skicka information till datorn, utan det är datorn som läser av och alltså initierar informations flödet, eller? Det innebär ju i den här situationen med en GPIO att datorn eller rättare sagt, det styrande programmet, måste kolla om den har blivit nedtryckt (räknaren räknar upp).
I fallet med OWFS och incron så skulle ju det innebära att "filen" i OWFS inte uppdateras för ens den läs (av någon applikation), och först då kollar OWFS vad countern har för värde. Det skulle ju innebära att incron aldrig upptäcker en förändring.
Är jag helt ute och vimsar nu...igen...

Re: LCD controllern och GPIO
Postat: 12 feb 2009, 15:04
av elf98
Alla enheter är passiva och kan inte trigga interupt mot mastern.
Enda sättet att få ut värden är att aktivt läsa av nätet.
Re: LCD controllern och GPIO
Postat: 12 feb 2009, 15:47
av CirruZZ
elf98 skrev:Alla enheter är passiva och kan inte trigga interupt mot mastern.
Enda sättet att få ut värden är att aktivt läsa av nätet.
Misstänkte att det var så.

Men om man skall hålla koll på en sådan counter, med hur kort intervall törs man läsa av den eller de 4 counters som det är, via sig ett script som går hela tiden? Finns det risk att överbelasta nätet eller att man stör resterande läsningar på nätet? Säg att man vill kolla med 2 sek mellanrum, går det över huvud taget eller måste man upp på minuten?
Re: LCD controllern och GPIO
Postat: 12 feb 2009, 16:04
av elf98
Jag har byggt ett system där jag använde knapparna för att bläddra i menyer utan nämnvärt lagg.
När jag läste utan fördröjning blev det knas, men med XX ms paus mellan läsningar fungeradde det bra.
Re: LCD controllern och GPIO
Postat: 12 feb 2009, 16:42
av dali
elf, är det nåt du vill dela med dig av? Jag har börjat snickra på ett menybaserat system, men det vill sig inte riktigt.
Re: LCD controllern och GPIO
Postat: 12 feb 2009, 16:51
av Niklas
Jag vill också se!

Re: LCD controllern och GPIO
Postat: 12 feb 2009, 17:22
av CirruZZ
Som sagt jag har inte ens börjat snickar på mitt än men jag har många ideer.
Om man skriver ett script som loopar i oändlighet, räcker det med att köra det i början när datorn startar och sen så låta det stå och gå hela tiden? Eller hur lägger man smidigast upp en sån lösning?
Re: LCD controllern och GPIO
Postat: 12 feb 2009, 18:11
av Hoffan
Tror nog vi e rätt många som vill se detta

Re: LCD controllern och GPIO
Postat: 12 feb 2009, 20:30
av elf98
Sure!
Systemet är inte i drift längre, men jag har kvar filen.
Av någon anledning skrev jag mjukvaran i TCL.
Systemet kördes på en Asus WL500G Delux och någon tidig variant av OpenWRT.
I grund och botten är det ett system som utifrån configfiler för olika switchar sätter switcharnas status av/på.
Med menysystemet kan man ändra de schemalagda till/och frånslagen för switcharna - det var rätt praktiskt att med ett par knapptryckningar släcka alla akvarier i vardagsrummet när vi såg på film.
Systemet är "modulbaserat" dvs det finns en funktion för:
- varje "skärmbild" (en skärmbild var temperaturinfo, en skärmbild var schema för till/avslag, en skärmbild var för att ändra till/frånslag/ en skärmbild var för lite allmän info).
- Detektering av om någon knapp är tryckt
- Knapphantering. Knapparna skulle ju ge olika händelser beroende på vilken skärmbild som var aktiv och var i skärmbilden man var
- Till/frånslag av switchar
funktionen "button_action" och "skarm3" kan jag tänka mig att det är lite svårt att sätta sig in i....
Filerna är totalt okommenterade, jag hade nog inte i min vildaste fantasi kunnat gissa att någon skulle vilja se koden 5 år senare!
Kod: Markera allt
#!/usr/bin/tclsh
#include <tcl.h>
set timeout 20
set debug 0
set backlight 1
set 1wire "/mnt/1wire"
set LCDid "/mnt/1wire/uncached/FF.830200000100"
set root "/1wiresoft"
set configfiles "solspot.cfg terrarium.cfg akvarie1.cfg akvarie2.cfg"
set timelist "1 10 15 30 60 120 240"
set filesystem "/mnt/usb_stick"
set user "erik"
set version 1.2.0
set m1 1
set m2 0
set lastbutton 1
set todo 0
set done 0
set location 0
set i 0
set loop 59
set error -1
set odd 0
foreach cfg $configfiles {
set cfgfile [open "|tail -n 2 $root/$cfg" r]
set switch_name($i) [gets $cfgfile]
set switch_id($i) [gets $cfgfile]
close $cfgfile
set undantag($i) 0
set undantag_typ($i) 0
set next_event($i) 0
set next_event_typ($i) 0
incr i
}
set switch_name($i) "Alla"
proc errorhandler { } {
global odd root loop error m1 m2 switch_id switch_name
set m1 1
set m2 0
# if {$loop > 3} {
# set loop 0
# }
# if { $loop < 2 } {
writelcd "Switchfel! " 0
writelcd "$switch_name($error) ur" 1
writelcd "funkton! " 2
writelcd "($switch_id($error))" 3
# } else {
# writelcd "Tryck pa nagon knapp" 0
# writelcd "For att aterstalla!" 1
# writelcd "---------------------" 2
# writelcd "---------------------" 3
# }
}
proc check_lamps { } {
global debug switch_name switch_id error root configfiles 1wire undantag undantag_typ next_event next_event_typ
set i 0
set today_date [clock format [clock seconds] -format %d/%m]
foreach j $configfiles {
if { $undantag($i) < [clock seconds] } {
set undantag($i) 0
set data 0
set of2 [open "$root/$j" r]
set data [gets $of2]
while {![eof $of2]} {
if {[string match "*$today_date*" $data]} {
break
} else {
set data [gets $of2]
}
}
close $of2
if { ![string match $today_date [lindex $data 0]] } {
set of [open "|head -n 1 $root/$j" r]
set timeframe [gets $of]
close $of
} else {
set timeframe [string range $data 6 end]
}
if { [catch {set of [open "$1wire/$switch_id($i)/PIO.A" w]} err ]} {
set error $i
errorhandler
return
break
}
set next_event($i) [clock scan [lindex $timeframe 0]]
set next_event_typ($i) "1"
if { [clock scan [lindex $timeframe 0]] < [clock seconds] && [clock scan [lindex $timeframe 1]] > [clock seconds] } {
puts $of "1"
set next_event($i) [clock scan [lindex $timeframe 1]]
set next_event_typ($i) "0"
} else {
puts $of "0"
if {![clock seconds] > [clock scan [lindex $timeframe 0]]} {
set next_event($i) 0
}
}
close $of
} else {
set next_event($i) $undantag($i)
set next_event_typ($i) $undantag_typ($i)
}
incr i
}
}
proc backlight { backlight } {
global debug LCDid
if {![catch {set bl [open "$LCDid/backlight" w]} err ]} {
puts $bl $backlight
close $bl
}
}
proc get_temps { } {
global temp min max
set temp1 [open "/home/termo/ute.txt" r]
set temp [gets $temp1]
close $temp1
if { [catch {set of [open "/home/termo/minmax.txt" r]} err ]} {
set min "err"
set max "err"
} else {
set min [gets $of]
set min "[lindex $min 0]ßC [lindex $min 1]"
set max [gets $of]
set max "[lindex $max 0]ßC [lindex $max 1]"
close $of
}
}
proc get_temps2 { } {
global root user filesystem inne akv space mail
set of [open "/home/termo/lcd.txt"]
gets $of
set inne [gets $of]
set akv [gets $of]
# set of [open "|df -h $filesystem" r]
# gets $of
# gets $of
# set space [lindex [gets $of] 3]
# close $ofi
set space 0
# set of [open "|ls /home/$user/mail/new | wc -l" r]
# set of2 [open "|ls /home/$user/mail/cur | grep -v S | wc -l" r]
# set i [gets $of]
# set j [gets $of2]
# set mail [ expr $i + $j]
# close $of
#close $of2
set mail 0
}
proc checkbuttons { } {
global debug m1 m2 lastbutton LCDid
if {![catch {set buttons [open "$LCDid/counters.ALL" r]} err ]} {
if {[catch { set butt [gets $buttons] } err]} {
catch {close $buttons}
return 0
}
catch { close $buttons }
} else {
return 0
}
set butt [split [string map {" " ""} $butt] ","]
for { set k 0 } { $k < 4 } {incr k} {
if {[lindex $butt $k] > 0 } {
set i [expr floor([lindex $butt $k] / 2 ) ]
if { $i == 0 && $lastbutton == 0} {
set lastbutton 1
return 0
}
set lastbutton 0
if { $i != [expr [lindex $butt $k]/2]} {
return [expr $k +1][expr $i +1]
} else {
return [expr $k +1]$i
}
}
}
return 0
}
proc writelcd { data line } {
global LCDid
if {![catch {set lcd [open "$LCDid/line20.$line" w]} err ]} {
puts $lcd $data
close $lcd
}
}
proc correct_value { data } {
# puts $data
if {[string match "*n*" $data]} { return "NA" }
set i [string range $data [expr [string length $data] - 1] [string length $data] ]
set j 0
if { [string match "*-*" [string range $data 3 [string length $data]]] } {
set data [string range $data 0 6]
while { $j < $i } {
set data [expr $data / 10]
incr j
}
} else {
set data [string range $data 0 6]
while { $j < $i } {
set data [expr $data * 10]
incr j
}
}
return [string range $data 0 [expr [string first "." $data]+ 2]]
}
proc standard {} {
global temp min max
writelcd "Temperatur: $temp ßC" 0
writelcd "Max: $max" 1
writelcd "Min: $min" 2
writelcd "[clock format [clock seconds]]" 3
}
proc skarm2 {} {
global mail inne akv space
writelcd "Inne: $inne" 0
writelcd "Akvarium: $akv" 1
writelcd "Nya mail: ${mail}st" 2
writelcd "/gemensamt/ $space Free" 3
}
proc skarm3 {} {
global odd debug undantag undantag_typ switch_name next_event next_event_typ m2 location done todo andra tid timelist status
if { $m2 == 0 } {
for {set i 0} { $i <4 } {incr i} {
set msg "on"
if { [string match *e* $next_event_typ($i)] } { set msg "event" }
if { $next_event_typ($i) == 0 } { set msg "off" }
writelcd "$switch_name($i) [clock format $next_event($i) -format %H:%M] $msg" $i
}
} elseif { $m2 == 1 } {
if {$todo == 2} {
if { $location == 0 } {
set location 4
} else {
set location [expr $location -1 ]
}
} elseif {$todo == 1 } {
if {$location == 4} {
set location 0
} else {
incr location
}
}
set todo 0
for {set i 0} { $i <4 } {incr i} {
if {$location == 4} {
if { $i == 3 } {
if {$odd == 1 } {
writelcd " " $i
} else {
writelcd "ándra Alla" $i
}
} else {
set msg "on"
if { [string match *e* $next_event_typ($i)] } { set msg "event" }
if { $next_event_typ([expr $i + 1]) == 0 } { set msg "off" }
writelcd "$switch_name([expr $i +1]) [clock format $next_event([expr $i + 1]) -format %H:%M] $msg" $i
}
} else {
if {$location == $i && $odd == 1} {
writelcd " " $i
} else {
set msg "on"
if { [string match *e* $next_event_typ($i)] } { set msg "event" }
if { $next_event_typ($i) == 0 } { set msg "off" }
writelcd "$switch_name($i) [clock format $next_event($i) -format %H:%M] $msg" $i
}
}
}
} elseif {$m2 == 2 } {
writelcd $switch_name($location) 0
if { $done == 1} {
if {$andra == 0} {
incr andra
} else {
set_undantag $location [lindex $timelist $tid] $status
set done 0
set andra 0
return 0
}
set done 0
}
if {$andra == 0} {
if { $todo > 0 } {
if {[string match "*på*" $status] } {
set status "av"
} else {
set status "på"
}
set todo 0
}
if {$odd == 1} {
writelcd " " 1
} else {
writelcd "$status " 1
}
} else {
writelcd "$status " 1
}
if {$andra == 1 } {
if { $todo == 1 } {
if {$tid == 6 } {
set tid 0
} else {
incr tid
}
} elseif { $todo == 2 } {
if {$tid == 0 } {
set tid 6
} else {
set tid [expr $tid -1 ]
}
}
set todo 0
if {$odd == 1} {
writelcd " " 2
} else {
writelcd "[lindex $timelist $tid] Minuter " 2
}
} else {
writelcd "[lindex $timelist $tid] Minuter " 2
}
writelcd "-----------------------" 3
}
}
proc skarm4 {} {
global version
writelcd " Smart Home System" 0
writelcd " By elf98" 1
writelcd " version $version" 2
writelcd "--------------------" 3
}
proc set_undantag { id tid status } {
global 1wire root m1 m2 next_event error next_event_typ switch_name switch_id undantag undantag_typ
if { $id == 4 } {
set actionlist "0 1 2 3"
} else {
set actionlist "$id"
}
foreach id $actionlist {
set undantag($id) [expr [clock seconds] + [expr 60*$tid]]
if { [catch {set of [open "$1wire/$switch_id($id)/PIO.A" w]} err ]} {
set error $id
errorhandler
return
}
if {[string match "*på*" $status]} {
puts $of 1
set undantag_typ($id) 0e
} else {
puts $of 0
set undantag_typ($id) 1e
}
close $of
set next_event($id) $undantag($id)
set next_event_typ($id) $undantag_typ($id)
}
set m2 0
}
proc buttonaction { butt } {
global error debug m1 m2 todo loop undantag backlight andra tid status done
if { $butt < 1 || $butt > 100 } { return 0 }
set loop 0
if {$error >= 0 } {
set error -1
check_lamps
return
}
if { $m1 == 1 } {
if { $butt < 20 } {
for { set i 0 } { $i <4} {incr i} { set undantag($i) 0 }
check_lamps
backlight $backlight
} elseif { $butt < 30 } {
set m1 2
} elseif { $butt < 40 } {
set m1 4
} else {
if { $backlight == 0 } {
set backlight 1
} else {
set backlight 0
}
backlight $backlight
}
} elseif { $m1 == 2 || $m1 == 4} {
if { $butt < 20 } {
set m1 1
} elseif { $butt < 30 } {
if { $m1 == 4} {
set m1 1
} else {
set m1 3
}
set m2 0
} elseif { $butt <40 } {
if { $m1 == 4 } {
set m1 3
} else {
set m1 1
}
set m2 0
} else {
set m1 1
}
} elseif { $m1 == 3 } {
if { $m2 == 0 } {
if {$butt < 20 } {
set m1 1
} elseif { $butt < 30 } {
set m1 4
} elseif { $butt < 40 } {
set m1 2
} else {
set m2 1
}
} else {
if {$butt < 20 } {
set m2 [expr $m2 -1]
} elseif {$butt < 30} {
set todo 1
} elseif { $butt < 40 } {
set todo 2
} else {
if { $m2 == 2 } {
set done 1
} else {
set m2 2
set status "på"
set tid 0
set andra 0
}
}
}
}
return 1
}
if {![catch {set of [open "$LCDid/LCDon" w]} err ]} {
puts $of 1
close $of
}
get_temps
backlight $backlight
while {$loop <60} {
set state [buttonaction [checkbuttons]]
if {$state != 1} {
after $timeout
set state [buttonaction [checkbuttons]]
}
if {$state != 1} {
after $timeout
set state [buttonaction [checkbuttons]]
}
if {$state != 1} {
after $timeout
set state [buttonaction [checkbuttons]]
}
incr loop
if {$loop == 30 } {
set m1 1
set m2 0
}
if { $loop > 59 } {
set loop 0
get_temps
check_lamps
backlight $backlight
}
if {[string match "*.5" [expr $loop/2.0]] } {
set odd 0
} else {
set odd 1
}
if {[expr $undantag(0) + $undantag(1) + $undantag(2) + $undantag(3)] != 0 || $error >= 0 } {
backlight $odd
} else {
backlight $backlight
}
set error -1
if {$error >= 0 && $odd == 0} {
errorhandler
check_lamps
} elseif {$m1 == 1} {
standard
} elseif { $m1 == 2} {
if {$loop == 1} {
get_temps2
}
skarm2
} elseif {$m1 == 3 } {
skarm3
} elseif {$m1 == 4} {
skarm4
}
}
Ett exempel på hur en konfigfil kunde se ut:
Kod: Markera allt
12:00 18:30
27/01 10:02 23:59
Solspot
12.166B32000000
Den översta raden var standardinställningen.
Sedan följer X antal rader med datumspecifika till och frånslag.
Näst sista raden är aliaset för switchen
och sista raden är idnummer.
Re: LCD controllern och GPIO
Postat: 12 feb 2009, 21:56
av CirruZZ
Du är alltså bara 5 år före oss dödliga....som precis har börjat få kläm på LCDn!
Tackar för info!!
Fråga, nu kanske inte TLC är aktuellt som script språk, men om man ska börja från grunden, vad hade du valt idag? BASH, PERL, PHP eller något annat?
Re: LCD controllern och GPIO
Postat: 12 feb 2009, 23:09
av HUSKii
Hoffan skrev:Tror nog vi e rätt många som vill se detta

WORD!!
