Hallo... Ich möchte mit einem Atmega8 folgendes erreichen: Ich habe 5
Pins zur Verfügugung, mit denen ich 4 Kabel kontrollieren möchte. Falls
ein Kabel durchgeschneidet wird, soll es der Mikrokontroller merken.
Also hab ich einfach 4 Pins als Ausgang gewählt und einen als Eingang,
alle Ausgänge sind mit dem Eingang verbunden (also sind sie auch
untereinander verbunden). Der Kontroller soll nacheinander an allen
Ausgängen eine Spannung anlegen und kontrollieren, ob am Eingang die
Spannung anliegt.
So sieht der Code aus:
1
PORTB&=~(1<<PB5);
2
if(PINB&(1<<PB1))
3
{
4
errors++;
5
}
6
PORTB|=(1<<PB5);
, und das 4 Mal (statt PB1 nehme ich danach halt PB2, PB3 und PB4, also
die Ausgänge).
Nur funktioniert das nicht, es zeigt immer Fehler an, obwohl die
Kontakte verbunden sind. Kann es sein, dass man nicht einfach die Pins
so verbinden kann, dass so der Strom "falsch" fließt? Wie könnte man das
lösen?
> Du solltest in deinem Fall immer nur ein Pin als Ausgang setzen.
Sorry ich hab mich vertippt. PB1, PB2, PB3 und PB4 sind die Eingänge,
PB5 ist der Ausgang, also hab ich nur eines.
>Dann dreh es um.
Hab ich auch schon versucht, jedoch brachte es nichts. Aber technisch
gesehen ist es möglich, die Ausgänge bzw. Eingänge zu verbinden, und es
sollte trotzdem funktionieren? Denn da könnte der Fehler auch irgendwo
anders im Programm liegen.
Die ganze Zeit ging es schon um die Datenrichtung, deswegen die Frage
von Kevin:
> Denn da könnte der Fehler auch irgendwo anders im Programm liegen.
Darauf deine Antwort:
Fhutdhb Ufzjjuz schrieb:> jep, vermutlich am DDRx
Toll!
Kevin Daverda schrieb:> Nur funktioniert das nicht
Immer diese Schnipseltaktik.
Häng das komplette Programm als Anhang an.
Wir sind hier doch nicht bei "Raten Sie mal".
Programmablauf:
- Alle Pins auf Eingang legen
- PB1 als Ausgang und auf Low schalten
- PB5 auf High? -> Fehler
- PB1 auf High schalten
- PB5 auf Low? -> Fehler
- PB1 als Eingang schalten.
- PB2 als Ausgang und auf Low schalten
- PB5 auf High? -> Fehler
- PB2 auf High schalten
- PB5 auf Low? -> Fehler
- PB2 als Eingang schalten.
- PB3 als Ausgang und auf Low schalten
- PB5 auf High? -> Fehler
- PB3 auf High schalten
- PB5 auf Low? -> Fehler
- PB3 als Eingang schalten.
- PB4 als Ausgang und auf Low schalten
- PB5 auf High? -> Fehler
- PB4 auf High schalten
- PB5 auf Low? -> Fehler
- PB4 als Eingang schalten.
- Hier angekommen? -> Alles ok.
PB5 braucht einen Pull-Up oder -Down Widerstand, sonst kann es zu
Fehlmessungen kommen!
Hallo!
es mag am Montag liegen, aber ich habe noch nicht ganz verstanden was du
geplant hast.
-Steuern deine 4 Leitungen noch irgendetwas oder ist es ehr eine art
Kabeltester?
-Wo genau sind die Pins den Verbunden? Am ende der Leitungen oder direkt
an den Pins (was keinen Sinn machen würde)?
Wenn du tatsächlich nur die Leitungen, welche an den Enden verbunden
sind (Sternpunkt) testen möchtest bietet es sich an deinen 5. Pin auf 5V
zu legen (oder Ausgang und High) und die Pins 1-4 einfach als Eingänge
zu schalten. Kein High an PinX = Leitung X Kaputt.
Am besten du erklärst nocheinal etwas "füllender" was es werden soll,
ich trink derweil noch einen Kaffee - vielleicht sehe ich was ich nicht
verstanden habe.
Gruß
Deathfun
Hallo...tut mir leid, dass ich für allgemeine Verwirrung sorgte :)...
Also, Sinn und Zweck besteht darin, dass ich mit 5 Pins so viele Kabel
wie möglich teste, also kontrolliere, ob sie noch ganz sind. Entweder
nehme ich 2 Pins als Ausgang und verbinde sie mit anderen 2 als Eingang
(mit dem Kabel dazwischen), und das funktioniert wunderbar, oder ich
nehme 1 Ausgang, mit dem ich alle Kabel an einem Ende verbinde, und 4
Eingänge und teste sie nacheinander. Bei der zweiten Möglichkeit würde
sich die Anzahl der Tests verdoppeln (von 2 auf 4). Nur funktioniert das
nicht mehr, das Programm zeigt manchmal Fehler, manchmal nicht, je nach
Laune. Da mein Programm sehr lang ist (es sind viel mehr Funktionen
dabei), habe ich hier die Ausschnitte, die mein Problem betreffen (Die
Pins werden ansonsten nie angesprochen):
1
DDRB&=~(1<<PB1);
2
DDRB&=~(1<<PB2);
3
DDRB&=~(1<<PB3);
4
DDRB&=~(1<<PB4);
5
PORTB|=(1<<PB1);
6
PORTB|=(1<<PB2);
7
PORTB|=(1<<PB3);
8
PORTB|=(1<<PB4);
9
DDRB|=(1<<PB5);
10
11
PORTB&=~(1<<PB5);
12
if(PINB&(1<<PB1))
13
{
14
errors++;
15
}
16
PORTB|=(1<<PB5);
17
PORTB&=~(1<<PB5);
18
if(PINB&(1<<PB2))
19
{
20
errors++;
21
}
22
PORTB|=(1<<PB5);
23
PORTB&=~(1<<PB5);
24
if(PINB&(1<<PB3))
25
{
26
errors++;
27
}
28
PORTB|=(1<<PB5);
29
PORTB&=~(1<<PB5);
30
if(PINB&(1<<PB4))
31
{
32
errors++;
33
}
34
PORTB|=(1<<PB5);
....wobei die Variable "errors" natürlich deklariert ist :).
P.s.: Den Vorschlag von Der konnte ich noch nicht testen, da ich zurzeit
keinen Kontroller zur Verfügung habe...
Hi, wiso schaltest du den Ausgang zwischen drin immer wieder auf high?
Es würde doch auch so gehen:
1
DDRB&=~((1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4));
2
PORTB|=(1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4);
3
DDRB|=(1<<PB5);
4
PORTB&=~(1<<PB5);
5
6
for(int8_ti=1;i<=4;i++)
7
{
8
if(PINB&(1<<i))errors++;
9
}
Was bei deinem Code ein Problem sein könnte: Du fragst die Eingänge
sofort ab nachdem du den Ausgang geschalten hast. Kann sein dass die
Ausgänge dafür zu langsam schalten. Vor allem wenn noch ne lange Leitung
mit entsprechend parasitären Kapazitäten dranhängen hast.
Wenn es irgend welche besonderen Gründen gibt, dass du den Ausgang immer
wieder auf high ziehen musst, dann versuchs mal mit Delays vor dem
Einlesen.
Gruß
Michael
Hi
Nnun, so ganz versteh ich dein Problem nicht...
>Hallo... Ich möchte mit einem Atmega8 folgendes erreichen: Ich habe 5>Pins zur Verfügugung, mit denen ich 4 Kabel kontrollieren möchte.
Um 4 Kabel zu überwachen brauchst du auch nur 4 Eingänge. Ein Ende kommt
an GND, die andere Seite auf den Eingang, natürlich bei eingeschaltetem
Pull Up Widerstand. Wird eine Leitung unterbrochen, geht der Eingang
dann automatisch auf High.
Programmablauf ist auch simpel:
Lese Eingänge
Prüfe mit Und-Maske
Ergebnis >0 dann ist eine Leitung offen und du kannst die Eingänge
einzeln prüfen.
Gruß oldmax
Hallo,
ich denke auch dass du hier vielleicht etwas zu komplex denkst.
Sollen wirklich nur 4 Leitungen getestet, Quasi "durchgepiepst", werden
reicht oldmax bzw. mein Vorschlag völlig aus.
An ein Problem führt aber bislang keiner der Lösungsansätze vorbei: Was
wenn eine der Leitungen beschädigt/durchtrennt ist aber bei dieser
Beschädigung auch die Nachbarleitung
"aufgescheuert"/angeschnitten/gequetscht wurde und eine Verbindung
zustande kommt?
|------------------- L1
|------------------- L2
|------------------- L3
.defekt \--------- L4
Obwohl durchtrennt melden die bisherigen Lösungen: Alles OK!
Durch den gemeinsamen Sternpunkt am Ende der Leitungen wird es generell
schwierig Beschädigungen sicher zu erkennen.
Je nachdem wie sicher es für dich sein muss hier ein Vorschlag für eine
relativ sichere wenn gleich deutlich komplexere Lösung:
An das Ende der Leitungen kommt eine weiter uC der in einem Takt immer
eine Leitung High schaltet. Dein jetziger uC wertet aus ob ein Takt
ankommt und auch immer nur eine Leitung High ist.
Also: ('-' = Takt)
L1 - L2 - L3 - L4 = OK!
L1 - - L3 - L4 = Error!
L1 - L2+L3 - L4 = Error! usw.
L1 - L3 - L2 - L4 = Error/Dreher aber Leitungen OK.
usw usw.
Weiter verbessen kannst du das ganze wenn du mit deinem 5. Pin und einer
GND Leitung einen One Wire Bus zwischen den Controllern aufbaust. Dies
müsste aber nicht unbedingt wenn du im 2. uC (dem Taktgeber) relativ
feste Zeiten einhältst.
Gruß
deathfun