Hallo,
auf der Suche nach Steuerungsmöglichkeiten für Fensterheber bin ich über
Atmel Mikrocontroller gestolpert und war doch sehr überrascht, wie
einfach es gehen kann (könnte). Momentan beschränken sich meine Versuche
auf AVRStudio4 und einen emulierten AT90S8515 (was wohl auch erst mal
reicht...).
Folgende Vorstellung geistert durch meinen Kopf: Einmal auf hoch oder
runter tippen (t<0,5s) und der Motor wird für 8s angesteuert (hoch bzw.
runter), es sei denn es wird in die andere richtung getippt, dann stoppt
der Antrieb.
Liegt das Eingangssignal länger als 0,5s an, wird der Motor so lange
angesteuert, wie das Signal anliegt.
Das Ganze sollte auch mit allen Ein- und Ausgängen simultan
funktionieren, da ansonsten die Fenster nur der Reihe nach bedient
werden könnten.
Ist sowas generell mit einem Controller möglich (kann ich einzelne Bits
ansprechen oder nur das komplette Byte), oder braucht es da vier Stück?
Wo finde ich denn den Befehlssatz samt einer kurzen Beschreibung für
einen MC?
Gruß,
Matthias
Hallo Matthias!
Sowas ist mit einem Microcontroller problemlos möglich, Datenblätter von
den einzellnen Controller bekommst du direkt bei ATMEL oder ganz bequem
von http://www.avrfreaks.net/.
Natürlich kannst du auch einzellne Bits von einem Port auf high/low
ziehen, ich weiss nicht auf welcher Platform du deinen Controller
programmieren willst (C, ASM, Pascal, BASCOM) aber jedenfalls gibt es
dafür Befehle und Möglichkeiten.
Hallo...
Bitte bedenke das: Wenn ein Kind usw. seinen Arm aus dem Fenster hält,
muss der Motor abgeschaltet werden bzw wieder herunter gefahren werden.
Da gab es mal div. Tests mit Äpfeln ...
Das Abschalten kann man z.B. über die Stromaufnahme des Motors machen. -
Nur - dazu muss man sie messen und verarbeiten.
Es hängt da also noch mehr drann.
Gruß
Holger
Hallo,
naja, ASM sieht ganz nett aus. Irgendwann hab' ich damit mal auf meiner
CPU rumgespielt und es kam mir mal nicht sooo schwer vor...
Mit welchem MC wäre sowas denn möglich? Ich hätte da Bedenken wegen der
gleichzeitigen Ansteuerung im Bezug auf die Anzahl der Verfügbaren
Timer. IMHO bräuchte ich für jedes Fenster einen, da er unter Umständen
bis zu acht sekunden "belegt" ist, oder gibt es da eine andere Lösung?
Gruß,
Matthias
@Howey
Aber an die Strommessung habe ich schon gedacht und möchte mir dafür
entweder einen Port des MCs freihalten oder den Motor extern abschalten.
lassen wir vorerst mal die Kirche im Dorf, ich bin Froh wenn ich das
erste Problem mal gelöst bekomme. Bis jetzt hab' ich da noch keinen
blassen Schimmer... wenn also jemand ne idee hat??
gruß,
matthias
Vielleicht klappt das:
Du nimmst einen Timer und stellst ihn so ein, dass er z.B. alle 0,1s
einen Interrupt auslöst. Wenn der Interrupt ausgelöst wird, schaust Du
welche Motoren alle für 8s laufen sollen (z.B. könnte in einem
bestimmten Register jeweils ein Bit für einen Motor gesetzt werden, wenn
die Taste weniger als 0,5s gedrückt wurde; um die betreffenden Bits zu
setzen könntest Du einen zweiten Timer Interrupt verwenden). Für jeden
Deiner Motoren zählst Du einfach ein Register hoch und schaltest den
entsprechenden Motor ab, wenn sein Register 80 erreicht hat (und setzt
natürlich Bit und Register zurück und verlässt den Interrupt).
Schöne Grüße
Stefan
klingt gut, aber dafür brauche ich zwei große Zähler (2Byte). Bei 'nem
kleinen Timer liegt die längste Zeit bei 0,06528 (4MHz), oder irre ich
mich da?
Vielleicht kann jemand ein paar Code-Beispiele posten, die die
Interrupts und Timer behandeln...
Vielen Dank,
Matthias
Du könntest als Zeitbasis genauso auch 0,05 Sekunden nehmen und bis 160
zählen.
Aber das Prinzip müsste auch mit nur einem Timer funktionieren. Wenn der
Interrupt auslöst, wird zuerst geguckt, welche Tasten gedrückt sind. Die
Motoren dieser Tasten werden angeschaltet (falls notwendig) und für jede
dieser Tasten wird ein Register um eins erhöht.
Bei den nichtgedrückten Tasten wird geguckt, ob der Wert der jeweiligen
Register kleiner 10 (bei 0,05s Zeitbasis) und ungleich null ist. Falls
nein Motor abschalten und Register zurücksetzen, falls ja Motor
laufenlassen und Register um eins erhöhen.
Zuletzt muss noch überprüft werden, ob eines der Register 160 erreicht
hat. Falls ja, Motor abschalten. Anschließend wird der Interrupt
verlassen.
Ein AVR Code-Beispiel kann ich Dir leider nicht anbieten, weil ich
bisher nicht für AVRs sondern für 8051er programmiert habe. Im Moment
bin ich damit beschäftigt Pony Prog (www.lancos.com/prog.html)
nachzubauen und dann werde ich wohl umsteigen. Aber ein Beispiel für
8051 kann ich Dir schicken, falls es Dir etwas nützt.
hallo stefan,
daran sitze ich schon den halben tag. momentan verzweifle ich gerade an
der richtigen INT-Adresse für Timer0, da ja fast jeder Controller eine
andere tabelle hat...
auf dein angebot mit "code-häppchen" komme ich gerne zurück, denn noch
habe ich ja keinen mc, sondern nur das avrstudio4 - bin also noch
völligst offen. welcher wäre denn für diese anwendung am besten
geeignet? mir wäre halt eine am liebsten, der pro port acht nutzbare
ein/ausgänge hat und das ganze mal 3 (für die sicherheitsschaltung), da
ich so bei meinen momentanen Kenntnissen leichter den überblick behalte:
eine reihe eingänge, eine reihe ausgänge...
gruß,
matthias
Hi!
Tja, da erwischst Du mich ein wenig auf dem falschen Fuß, schließlich
habe ich, wie gesagt, bisher überhaupt keine Erfahrung mit AVRs. Ich
kann Dir also nur meine ehrliche, wenn auch möglicherweise
unqualifizierte Meinung anbieten.
Du könntest natürlich einen 8051er verwenden, die gibts auch als
Flash-Controller von Atmel ;-)) (AT89S8252).
Aber ich denke mit dem 90S8515 hast Du schon eine gute Wahl getroffen.
Der hat schließlich vier 8 Bit Ports und dürfte ansonsten schon über
mehr Peripherie verfügen, als Du in Deinem Fall brauchst. In der PLCC
Version ist er z.B. bei Reichelt auch mit 8,10 Euro recht günstig. An
Deiner Stelle würde ich es einfach mal mit dem versuchen.
Tschüss
Stefan
Hi!
Mit einem 8 Bit Timer ist bei 4MHz eine max. Verzögerung von 65,563 ms
für einen TOV = Timerüberlauf zu erreichen.
Du must nur den Vorteiler (TCCR0) auf 5 (Bit0+2=1)setzen dann wird der
Timer aller 256 mys um 1 erhöht. Wenn das 195 mal gemacht wurde sind
49,92ms vergangen also ~50ms.
Das ist doch eine gute Zeitbasis. Die 195 kannst du einfach in's TCNT0
eintragen indem du schreibst:
(ich nehme jetzt mal r16 als tmp)
.def tmp =r16
.def Fe_1 =r17 ;Fenster 1
.def Fe_2 =r18 ;Fenster 2
.equ 8s =160 ;Zählwert für 8sek
TOV_ISR:
ldi tmp,0-195 ;Überlauf ist von $FF nach 0(~50ms)
out TCNT0,tmp ;Ausgabe in's Timerreg.
tst Fe_1 ;Zeit Fenster 1 schon abgelaufen?
breq cls1 ;wenn 0 Fenster 1 abschalten
dec Fe_1 ;sonst Zeit Fe_1 - 1
brne F2 ;jetzt 0?, bei nein -> F2
cls1: "Befehl für Reset Fensterbit,kann mit"cbi Port,Bit" ein Ausgang
sein"
F2:tst Fe_2 ;Zeit Fenster 2 schon abgelaufen?
breq cls2 ;wenn 0 Fenster 2 abschalten
dec Fe_2 ;sonst Zeit Fe_2 - 1
brne ende ;jetzt 0?, bei nein -> ende
cls2: "Befehl für Reset Fensterbit,kann mit"cbi Port,Bit" ein Ausgang
sein"
ende: reti ;TOV_ISR ende
Im Hauptprog. stellst du mit den Tasten fest was gemacht werden soll
zb.:
Fenster1 stop = clr Fe_1
oder Fenster1 8sek ein = ldi Fe_1,8s ;Wert 160->Fe_1
Alles andere erledigt dann die TOV_ISR
Als Anregung sollte das erstmal reichen, viel Spass
Uwe
Ps.:hoffentlich kann man's lesen, Anhang wäre vermutlich besser.
hallo uwe,
das waren schon mal ein paar sehr hilfreiche tipps - danke! ich habe mal
versucht sie umzusetzen, scheitere allerdings immernoch an den
Interrupts. Wenn ich den Cursor in die erste Zeile der INT-Routine setze
(unter TOVISR:) und dann auf "run to cursor" klicke, kommt er nie dort
an. Der Counter rennt aber munter weiter, auch über den Overflow
drüber...
Code liegt im Anhang, vielleicht hat jemand nen Tipp.
Gruß,
Matthias
Hi!
Habe zwar nicht alles geprüft aber:
1. wo ist denn dein Stackinit???? Ganz wichtig!
2. Zeit für Fenster 2 wird nicht geladen, nur Fe_1.
3. wenn eine Zeit gesetzt wurde, auf 0 warten, nicht neu
laden
4. rjmp F1
F1: Das sind unsinnige Befehle,verschwenden Platz
5. Eingänge brauchst du nicht def.,alle Pin's sind das
nach Reset
Ansonsten sollte es klappen.
Ich habe aber gestern nochwas vergessen. Du solltest in der TOV_ISR das
S-Reg. sichern und zurückschreiben, es kann sonst zu Fehlern im "MEIN"
kommen.
Das kann so aussehen:
.def isr_tmp=r19 ;zum SREG sichern in allen ISR's
...
...
TOV_ISR:
in isr_tmp,SREG
...
...
...
...
ende:out SREG,isr_tmp
reti
Viel Spass
Uwe
hi,
ich habe deine punkte soweit umgesetzt, nr.3 müsstest du mir aber
nochmal erläutern. Die Interrupts funktionieren immer noch nicht, den
geänderten code hab' ich nochmal angehängt.
gruß,
matthias
Hi!
Auf ein neues. Habe jetzt mal genau hingeschaut, die
Int.Einsprungadresse war falsch es ist noch ein
Timer1 compareB Handler vorhanden. Die TOV_ISR konnte also per timer0
nicht gefunden werden.
Den Cursor solltest du aber nicht in die ISR setzen, das gibt bei "reti"
Stackfehler. Setze besser TCNT0 auf 255 und mache 1024 Step's oder setze
einen Breakpoint vor TOV_ISR und lasse mit Run laufen.
Jetzt zu deiner Frage. Wenn du dein Progr.so lässt,läuft die Zeit von 8s
ab dem loslassen der jeweiligen Taste, ist bestimmt nicht gewollt. Habe
es mal für Fe_1 umgeschr. Dabei ist mir was aufgefallen. Du setzt deine
Ausgänge alle einzeln, wenn du aber den neuen Merker am Ende deiner
TOV_ISR auf das Port schreibst hast du das selbe Ergebnis. Genauso
könnte man natürlich auch die entspr. Portpin's abfragen um mehrfaches
laden der Zeit zu vermeiden. Der Möglichkeiten gibt es halt viele.
Ich hoff du verstehst was ich meine.
Gruss Uwe
Ich hänge die Änderungen an.
Mist habe Müll geschrieben.
Die Zeile
andi merke_Fe,$2 ;F1DN-Bit löschen
bitte ändern in
andi merke_Fe,0b1111100
Mache es doch überall im Bin Format, das ist übersichtlicher.
Wenn mein Tag schon 18 Stunden alt ist darf das mal sein.
Gruss Uwe
hallo zusammen,
ich möchte mich an dieser stelle mal für die doch sehr umfangreiche
hilfe von euch bedanken... insgesamt geht es schneller und einfacher
vorwärts als ich mir das anfangs gedacht habe. da ich in diesen tagen
umziehen muss, werde ich den "starthilfe-thread" erst mal schließen
(wenn man das so sagen kann) und dann bei gelegenheit einen neuen
fensterheber-thread öffnen.
gruß,
matthias