LCD controllern och GPIO

OWFS - One Wire File System är en Linuxmjukvara som stödjer de flesta kommersiellt tillgängliga 1wire-enheterna. OWFS saknar helt möjligheter att presentera data - detta måste göras med tex RRDTool
Kategoriregler
Vill du visa bilder i ditt inlägg? Använd funktionen "Ladda upp bilaga" nedanför textrutan!
Användarvisningsbild
CirruZZ
Master Moderator
Inlägg: 1621
Blev medlem: 13 feb 2008, 16:46
Ort: Ystad

LCD controllern och GPIO

Inlägg 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 :wink: )

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.
Användarvisningsbild
Plutonium
Moderator
Inlägg: 1246
Blev medlem: 04 jan 2008, 02:34
Ort: Nossebro
Kontakt:

Re: LCD controllern och GPIO

Inlägg 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
http://essunga.org
Moderator - Temperatur.nu
Användarvisningsbild
CirruZZ
Master Moderator
Inlägg: 1621
Blev medlem: 13 feb 2008, 16:46
Ort: Ystad

Re: LCD controllern och GPIO

Inlägg av CirruZZ »

Ahaa!!!!! Det där verkar ju var PRECIS vad jag var ute efter, det skall jag kolla närmare på. TACKAR! :D
Användarvisningsbild
CirruZZ
Master Moderator
Inlägg: 1621
Blev medlem: 13 feb 2008, 16:46
Ort: Ystad

Re: LCD controllern och GPIO

Inlägg av CirruZZ »

Hittade en annan bra länk för info om incron...
http://www.howtoforge.com/triggering-co ... ith-incron :wink:
Användarvisningsbild
CirruZZ
Master Moderator
Inlägg: 1621
Blev medlem: 13 feb 2008, 16:46
Ort: Ystad

Re: LCD controllern och GPIO

Inlägg av CirruZZ »

Då har jag gjort första testen men det verkar inte funka.... :roll: 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... :?
Användarvisningsbild
elf98
Hemautomation - det är mer än en hobby
Inlägg: 5434
Blev medlem: 27 okt 2006, 13:49
Ort: Linköping
Kontakt:

Re: LCD controllern och GPIO

Inlägg 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.
Grundade m.nu & temperatur.nu

Driver temperatur.nu

Bild
Användarvisningsbild
CirruZZ
Master Moderator
Inlägg: 1621
Blev medlem: 13 feb 2008, 16:46
Ort: Ystad

Re: LCD controllern och GPIO

Inlägg 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?
Användarvisningsbild
elf98
Hemautomation - det är mer än en hobby
Inlägg: 5434
Blev medlem: 27 okt 2006, 13:49
Ort: Linköping
Kontakt:

Re: LCD controllern och GPIO

Inlägg 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.
Grundade m.nu & temperatur.nu

Driver temperatur.nu

Bild
dali
Gillar hemautomation
Inlägg: 38
Blev medlem: 22 nov 2007, 11:49
Ort: Habo

Re: LCD controllern och GPIO

Inlägg 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.
Niklas
Moderator
Inlägg: 1019
Blev medlem: 22 mar 2008, 21:13
Ort: Stockholm
Kontakt:

Re: LCD controllern och GPIO

Inlägg av Niklas »

Jag vill också se! :-)
Användarvisningsbild
CirruZZ
Master Moderator
Inlägg: 1621
Blev medlem: 13 feb 2008, 16:46
Ort: Ystad

Re: LCD controllern och GPIO

Inlägg 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?
Hoffan
Hemautomation - det är mer än en hobby
Inlägg: 352
Blev medlem: 13 maj 2007, 22:46
Ort: Mölndal

Re: LCD controllern och GPIO

Inlägg av Hoffan »

Tror nog vi e rätt många som vill se detta :)
Användarvisningsbild
elf98
Hemautomation - det är mer än en hobby
Inlägg: 5434
Blev medlem: 27 okt 2006, 13:49
Ort: Linköping
Kontakt:

Re: LCD controllern och GPIO

Inlägg 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.
Grundade m.nu & temperatur.nu

Driver temperatur.nu

Bild
Användarvisningsbild
CirruZZ
Master Moderator
Inlägg: 1621
Blev medlem: 13 feb 2008, 16:46
Ort: Ystad

Re: LCD controllern och GPIO

Inlägg av CirruZZ »

Du är alltså bara 5 år före oss dödliga....som precis har börjat få kläm på LCDn! :D

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?
Användarvisningsbild
HUSKii
Tar hemautomation på allvar
Inlägg: 270
Blev medlem: 16 jun 2008, 20:08
Ort: Oskarström

Re: LCD controllern och GPIO

Inlägg av HUSKii »

Hoffan skrev:Tror nog vi e rätt många som vill se detta :)
WORD!! :D
Skriv svar