Hallo,
irgendwie bin ich im Moment blockiert und sehe den Fehler nicht.
Folgende Situation:
An einem Pin ist ein Taster angeschlossen - und die Verarbeitung klappte
bislang auch ganz gut.
Jetzt soll über den gleichen Pin noch ein Relais gesteuert werden.
Während der Schaltphase des Relais brauche ich den Taster nicht.
Dafür gibt es folgende Saucen:
Erstmal der Bereich aus config.h
1
/*
2
* Inputs
3
*/
4
#define PORT_T1 PIND
5
#define DDR_T1 DDRD
6
#define PIN_T1 PD2
7
8
#define PORT_T2 PIND
9
#define DDR_T2 DDRD
10
#define PIN_T2 PD3
Im Timer-Interrupt wird der Taster überprüft:
1
if(PORT_T1&(1<<PIN_T1))
2
state.btT1++;
3
else
4
state.btT1=0;
Solange der Taster alleine am Pin war - kein Problem.
Jetzt im Doppel dachte ich, wenn ich das Richtungsregister mit abfrage,
kann ich abfangen, wenn/ob das Relais geschaltet ist und werte das nicht
als Eingabe.
Das wollte ich folgendermaßen umsetzen:
Hallo,
man kann solche Tricks zwar machen, aber hast Du auch in der Schaltung
bedacht, was mit dem Relais oder dem auf Ausgang programmierten Pin
passiert, wenn der Taster gedrückt wird?
Im Programm sehe ich da weniger ein Problem, Du weißt ja dort, wann Dein
Relais angesteuert wird, also irgendein Flag setzen und wenn das gesetzt
ist, die Tastenabfrage komplett übergehen.
Gruß aus Berlin
Michael
Hallo Michael,
danke für Deine Aufmerksamkeit.
> man kann solche Tricks zwar machen, aber hast Du auch in der Schaltung> bedacht, was mit dem Relais oder dem auf Ausgang programmierten Pin> passiert, wenn der Taster gedrückt wird?
Bedacht schon - ob ich das Richtige gedacht habe, muss sich dann zeigen.
Der Taster ist über Pulldown-Widerstand angeschlossen und das Relais
(auf einer anderen Platine) hat vor dem Schalt-Transistor noch einen
Vorwiderstand.
Ich hätte gedacht, dass das klappen könnte.
> Im Programm sehe ich da weniger ein Problem, Du weißt ja dort, wann Dein> Relais angesteuert wird, also irgendein Flag setzen und wenn das gesetzt> ist, die Tastenabfrage komplett übergehen.
Getreu dem Motto: "und fällt dem Programmierer nix mehr ein, dann setzt
er halt ein Schalterlein"?
Mir nehmen die Stellen, an denen wertvoller Speicher verschwendet wird
zu schnell zu. Die Information ist doch im Chip drin. Das DDR-Register
darf auch gelesen werden - warum klappt dann meine Abfrage von oben
nicht?
Wo sitzt denn genau mein Denkfehler (und jetzt bitte net sagen: vor der
Tastatur :( )
Das ist tricky.
Ich würde sowas nur manche, wenn z.B. schon ein Kabel liegt und da eben
nur noch ein Draht frei ist.
Wie es geht, steht hier:
Beitrag "Taster + LED am selben Draht (4*)"
Ansonsten würde ich einen (oder 2, 3, ..) 74HC595 nehmen.
Kostet unter Verwendung des SPI nur einen Portpin zusätzlich und Du hast
8 (oder 16, 24, ..) zusätzliche Ausgänge.
Peter
Santiago wrote:
> Ich hätte gedacht, dass das klappen könnte.
Sollte so gehen.
>...> Getreu dem Motto: "und fällt dem Programmierer nix mehr ein, dann setzt> er halt ein Schalterlein"?> Mir nehmen die Stellen, an denen wertvoller Speicher verschwendet wird> zu schnell zu. Die Information ist doch im Chip drin. Das DDR-Register> darf auch gelesen werden - warum klappt dann meine Abfrage von oben> nicht?
Na gut, in ASM gibt es sowieso bei mir immer ein FLAG-Register und da
wäre es ein belegtes Bit mehr...
> Wo sitzt denn genau mein Denkfehler (und jetzt bitte net sagen: vor der> Tastatur :( )
Ich denke aber doch. ;)
Im Ernst: muß mal ein C-Programmierer über die Zeile schauen...
Schönen warmen Sonntag aus Berlin
Michael
Hallo,
> Ich würde sowas nur manche, wenn z.B. schon ein Kabel liegt und da eben> nur noch ein Draht frei ist.
Sehe ich bei mir mal als gegeben :)
Ich habe ein Bild meines Testaufbaus beigefügt.
Basis ist das Evalboard des bayrischen Resteverwerters, aufgebohrt mit
einem parallelen Programmieradapter (erst zu spät entdeckt, dass mein PC
nix mehr seriell mag), und einem 40pol Adapter, welcher mir jeweils
einen halben Port auf eine 10pol Wanne legt (10pol Flachkabel sind meine
Standardkabel).
Daneben ist eine IO-Testplatine mit dem Drehencoder, einem vollen Port
auf LED gelegt (wählbar zu schalten gegen Masse oder gegen Vcc) und
durchgeschleift und eben das Relais.
Das Relais geht über den freien Kanal des Drehencoderkabels und auf dem
Pin liegt der Taster des Evalboards.
Oben sieht man noch ein 7segment Element über Schieberegister und 10pol
Steckbrettadapter und fliegender Verkabelung angeschlossen.
Die Ports sind so belegt:
Port B low nibble: low nibble LED-port Anzeige
Port B high: Schieberegister zu Segment-Anzeige
Port D low: Drehencoder, onboard Taster und Relais
Port D high: high nibble LED-port Anzeige (es fehlt das höchste Bit)
Bislang hatte ich keine Probleme, den Taster abzufragen, deshalb suche
ich auch kein Problem in der Hardware.
> Wie es geht, steht hier:
Sorry, Peter, aber das ist mir zu hoch. Warum sollte ich eine Komparator
nehmen? Wie gesagt, der Taster funktioniert mit der einfachen Abfrage
problemlos.
Die Tasterprüfung läuft in einem Timer-ISR, die Verarbeitung der
erkannten Tasten wird in main() durchgeführt.
>> Ich hätte gedacht, dass das klappen könnte.> Sollte so gehen.
Hm - das ist genau mein Dilemma. Mit dem "Trivialcode" wird der Schalter
erkannt. Frage ich aber zusätzlich das Pin-Richtungs-Register ab, wird
kein Taster mehr erkannt (ohne jetzt das Relais geschaltet zu haben -
also gleiche HW-Voraussetzungen).
> Na gut, in ASM gibt es sowieso bei mir immer ein FLAG-Register und da> wäre es ein belegtes Bit mehr...
Klar! Ich komme auch nicht ohne zentralen Variablenpool aus. Nur sehe
ich es nicht wirklich ein, warum ich einen Wert, der aus dem µC ablesbar
sein sollte, nochmal selber speicheln sollte.
Santiago wrote:
> Sorry, Peter, aber das ist mir zu hoch. Warum sollte ich eine Komparator> nehmen? Wie gesagt, der Taster funktioniert mit der einfachen Abfrage> problemlos.
Daß das eine geht, hilft nicht weiter, wenn man was ganz anderes will.
Du willst ja keine einfache Taste, sondern den Pin gleichzeitig als
Ausgang nehmen. Daher ist es wurscht, obs nur mit der Taste geht.
Wie schon gesagt, es ist und bleibt tricky.
Aber ich will Dich zu nichts überreden.
Peter
Hallo Peter,
> Daß das eine geht, hilft nicht weiter, wenn man was ganz anderes will.
Hm, könnten wir dann vielleicht erst das eine Problem abhandeln, bevor
wir uns dem zweiten Problem zuwenden?
> Du willst ja keine einfache Taste, sondern den Pin gleichzeitig als> Ausgang nehmen. Daher ist es wurscht, obs nur mit der Taste geht.
Hier bitte ich um etwas Nachsicht für meine fehlende HW-Kenntnisse.
Für mich sieht es so aus, dass ich schaltungstechnisch Taste und Pin als
Ausgang gleichzeitig nehmen will.
Softwareseitig natürlich nicht gleichzeitig.
So wie ich Deine Beschreibung bei der Komparator Geschichte verstanden
habe, ist der Taster durch die LED nimmer auf High gekommen.
Das Problem liegt ja bei mir nicht vor. Schaltungstechnisch sind beide
ja schon von Anfang an auf der gleichen Leitung. Und der Taster wird
zuverlässig erkannt (geht also auf high).
Dürfte ich Dich einmal bitten, die Schaltung beiseite zu lassen und Dir
meine Codezeilen im ersten Post anzuschauen?
Ich würde gerne verstehen, warum ich mit der zweiten Abfrage keine
Tastendrucke mehr erkennen kann.
Die vier Zeilen sind völlig in Ordnung. Entweder ist vorher was im
Programm verkehrt, oder der Pin erreicht trotz gedrückter Taste den
high-level nicht.
Wenn du das nicht debuggen kannst (JTAG, oder z.B. in der ISR eine LED
high setzen, wenn PIN_T1 high ist), häng mal die gesamte
Relais-Schaltung ab, und schau, was dann passiert.
Oliver
Santiago wrote:
> Ich würde gerne verstehen, warum ich mit der zweiten Abfrage keine> Tastendrucke mehr erkennen kann.
Dann mußt Du schon einen compilierbaren Code schicken.
Mit den 4 Zeilen kann keiner was anfangen.
Ich weiß ja nicht, wie das DDR_T1 steht und was das state.btT1 für ne
Funktion hat und woran Du die Fehlfunktion erkennst (was der Unterschied
zwischen Fehlfunktion und Funktion ist).
Die Schaltung wäre auch wichtig.
Peter
Oliver wrote:
> Die vier Zeilen sind völlig in Ordnung.
Würde mich mal interessieren, wie Du das feststellst.
Die 4 Zeilen sind syntaktisch in Ordnung.
Ob sie auch von der Logik her das tun, was der Fragesteller sich
wünscht, kann man nicht feststellen.
Peter
Hallo zusammen,
vielleicht kann ich mich ja einfach nicht richtig ausdrücken?
Ich bitte also nochmals um Nachsicht.
> Die vier Zeilen sind völlig in Ordnung. Entweder ist vorher was im> Programm verkehrt, oder der Pin erreicht trotz gedrückter Taste den> high-level nicht.>> Wenn du das nicht debuggen kannst (JTAG, oder z.B. in der ISR eine LED> high setzen, wenn PIN_T1 high ist), häng mal die gesamte> Relais-Schaltung ab, und schau, was dann passiert.
Nochmal - es gibt kein Problem mit der Relais-Schaltung, oder wie ich
schrieb - mit der Hardware.
Ich habe 2 Firmware - eine verwendet den ersten 4Zeiler vom ersten Post,
die 2. verwendet den zweiten 4Zeiler vom ersten Beitrag.
Die erste Variante tut, die 2. net - ohne dass ich an der Schaltung oder
im Rest des Programmes irgendwas verändere (das Relais ist in beiden
Firmwares noch garnicht aktiv)
> Ich weiß ja nicht, wie das DDR_T1 steht und was das state.btT1 für ne> Funktion hat und woran Du die Fehlfunktion erkennst (was der Unterschied> zwischen Fehlfunktion und Funktion ist).
aus dem Grunde hatte ich den Auszug aus der config.h mit gepostet
(erster unterlegter Bereich). DDR_T1 entspricht DDRD und state ist eine
Struktur mit globalen Variablen, von denen eine btT1 heißt und ein
Zähler ist.
Die betreffenden 4Zeiler werden im Timer-ISR abgearbeitet und haben den
Sinn, für jeden Knopf einen Zähler hoch zu zählen, solange er gedrückt
ist. Sobald der Knopf losgelassen wird (oder ein Low vom Prellen kommt),
geht der Zähler auf 0.
In der Hauptprogramm-Schleife prüfe ich für jeden Taster, ob der Zähler
einen (vorher festgelegten) Wert übersteigt. Wenn dies zutrifft, gilt
die Taste als gedrückt und der entsprechende Zweig wird abgearbeitet.
> Die Schaltung wäre auch wichtig.
Ich habe die Schaltung mal nur für den Pin, um den es geht, gemalt
(hatte keine Lust, das ganze Evalboard abzupinseln).
Wie durch die gestrichelten Ränder angedeutet, handelt es sich um 2
Platinen, die über Flachbandkabel verbunden sind.
Bei dem 40pol-Adapter ist noch ein 100n-Blocker pro Stecker zwischen Vcc
und Masse.
Sorry, gerade erst entdeckt:
> Die 4 Zeilen sind syntaktisch in Ordnung.
wenn das so ist, könnte es sein, dass der 2. 4Zeiler zu lange braucht
und der Timer nicht mehr richtig abgearbeitet werden kann?
Dann zur Klarstellung:
Im zweiten Vierzeiler wird "state.btT1++;" ausgeführt, wenn das
entsprechende Bit im DDR-Reg nicht 1 und der Tastereingang high ist,
sonst "state.btT1 = 0;". Das wolltest du wohl auch so.
Mehr kann man den vier Zeilen nicht entnehmen, aber das beschriebene tun
die ganz bestimmt.
Oliver
P.S. volatile ?
Santiago wrote:
> aus dem Grunde hatte ich den Auszug aus der config.h mit gepostet> (erster unterlegter Bereich). DDR_T1 entspricht DDRD
Ja, aber wann werden sie denn gesetzt/ausgewertet?
> und state ist eine> Struktur mit globalen Variablen, von denen eine btT1 heißt und ein> Zähler ist.
Das ging aber nicht aus dem config.h-Auszug hervor.
Ob Dein Code funktioniert, hängt davon ab, wann vor dem Abfragen der
Taste das DDRD wie gesetzt wird. Und genau das sieht man immer noch
nicht.
> Ich habe die Schaltung mal nur für den Pin, um den es geht, gemalt
Da sieht man schon viel klarer.
Der Taster ist also high-aktiv, was man vorher auch nicht wußte (Taster
sind meistens low aktiv, um den Pullup zu sparen).
Ein Kondensater an nem Ausgang ist ein ganz böses Foul, da fließen dann
immer riesige Umladeströme.
Und sobald man den Taster drückt, muß erstmal der Kondensator geladen
werden, dieser Spannungseinbruch auf VCC könnte den brownout-reset
auslösen.
Solange der Taster gedrückt ist, zieht das Relais, da ists wurscht, was
der AVR macht.
Peter
Hallo,
dank Euch beiden!
Die Bestätigung, dass mein 4Zeiler richtig ist, hat mich dann auf die
Spur des Fehlers gebracht :)
Ich hatte in den letzten Tagen die Entwicklungsumgebung unter Linux
eingerichtet und den Kwältext nur noch mit vim und make bearbeitet.
So hat sich ein Fehler eingeschlichen.
Und zwar geschah der Fehler bei der Initialisierung eines noch
unbenutzten Tasters als Eingang:
1
DDR_T3|=(uint8_t)~(1<<PIN_T3);
Ich habe zwar schon viel mit C gemacht, aber die ganzen Bitschiebereien
habe ich seit der Ausbildung kaum verwendet. Deshalb ist an der Stelle
wieder etwas Unsicherheit aufgekommen.
> Solange der Taster gedrückt ist, zieht das Relais, da ists wurscht, was> der AVR macht.
Da muss ich dann wohl noch etwas in mich gehen ;)