Guten Tag!
Ich bin ganz neu auf dem Gebiet Elektronik und µCs und bin gerade dabei
die software für ein Board zu schreiben welches über I2c einen DS75
ausliest. Die gemmesene Temperatur in ASCII Zeichen umwandelt und an den
PC schickt (RS232). Je nach Temperatur wird eine PWM sohingehend
verändert dass über einen Spannungsteiler Lüfter mit 3-12 V versorgt
werden. Soweit habe ich das auch hinbekommen.
Jetz muss ich die Tachosignalleitungen der Lüfter (bzw versuche ich es
gerade nur mit einem) auswerten und wenn diese stehen oder zu langsam
laufen muss ich einen Error erzeugen und eine rote LED leuchten lassen.
Ich kriegs aber einfach nicht gebacken. Die LED blinkt entweder, ist
garnicht an oder die ganze zeit. außerdem verringert sich je langsamer
der lüfter läuft die geschwindigkeit der I2C kommunikation.
Anbei hab ich mein Programm mal reingestellt wenn jemand ne idee hat
warum die LED nicht anbleibt wenn der Lüfter steht bitte antworten. Ich
weiß echt nicht woran es liegt
MfG
ein blutiger Anfänger
PS: Schaltplan habe ich auch wenn benötigt
Hi
Ich bin mittlerweile etwas weiter aber nicht viel.
Die LED ist jetzt bei einem Fehler entweder an oder aus!?
Keine Ahnung wieso?? Hab auch nichts geändert nur ein paar befehle
auskommentiert die ich später für den Piezo Buzzer (siehe Schaltplan)
brauche.
Langsam macht mich das Teil verrückt
Ich hoffe hier kann mir jemand helfen.
PS: den Code hab ich mit ran ist aber wirklich nicht viel geändert (sbi
und cbi für die LEDs vertauscht (hab gemerkt dass sie bei cbi angehen
X-))) und ein paar befehle auskommentiert
Kannst du Vcc am Attiny oszilloskopieren? Bleibt die in dem zulässigen
Betriebsbereich oder sackt die ab? Wie hast du das Brownout am µC
eingestellt?
Hast du schon mal probiert alles was von dem LM2576 versorgt wird
galvanisch von dem µC-Teil zu trennen? Bzw. als Schnelltest: läuft die
Sache, wenn S2 offen ist und in den X5 bis X8 nix steckt?
Die Versorgung vom tiny ist stabil bei 5V. Dass kann ich zu 99,9%
ausschließen. Brownout ist deaktiviert.
Wie meinst du das mit galvanisch vom µC trennen?
Zu deiner Frage wenn du meinst ob die Temperaturauslesung funktioniert
wenn S2 offen ist und X5-8 unbelegt sind, ja die funktioniert.
Aber darum gehts ja nicht ich muss X5-X8 belegen da ich ja sonst keine
Lüfter habe zum auswerten. Hab jetzt nur X6 belegt damit es nicht gleich
zu kompliziert wird.
S2 kann man sich auch wegdenken. Hab den nur noch drin weil ich vorher
eine einfachere Schottky-Regelung drin hatte welche nur zwischen 3 und
12V geschaltet hat und nicht wie jetzt mittels PWM "stufenlos".
An was könnte es denn noch liegen.
Ich denke der Fehler müsste in der Abfrageroutine der Lüfter liegen weil
wenn ich diese rausnehme ist die LED aus, d.h. sie wird nur in der
Routine ein- bzw ausgeschaltet
ich vermute fast, daß vielleicht deine Warteschleifen waitfalling11 und
Konsorten etwas zu kurz warten, bis die auf Error gehen. Bei niedrigen
Drehzahlen gibt's also öfters mal einen Timeout. Bei waitfalling11
seltener als bei waitrising11, weil waitfalling11 irgendwo auf dem HIGH
Pegel anfängt zu zählen, waitrising11 aber immer komplett den LOW Pegel
erfaßt (also viel anfälliger für Timeouts).
Vielleicht solltest Du diese Warteschleifen via Timerinterupt bedienen,
wenn Du die Abhängigkeit weghaben willst (zumindest wirds nicht mehr
ganz so abhängig)
Diese Warteschleifen dürften auch die Ursache dafür sein, daß bei
höheren Drehzahlen diese Schleifen nicht mehr so viel mit Warten
verplembern müssen, und somit I2C öfters zum Zuge kommt.
Ich glaub zu kurz is das nicht. Müssten ja ca 40ms sein bei 4MHz takt.
Die signalleitung der Lüfter liefert mir folgende signale:
3V: Rechtecksignal mit ca. 33-35ms periodendauer
12V: Rechtecksignal mit ca. 17ms periodendauer
stillstand: ständiger HIGH-Pegel
Meine Vermutung ist dass die Abfrage irgendwie falsch läuft. Ich komm
aber einfach nicht drauf was.
Wenn ich den Lüfter während dem betrieb anhalte dann geht meine fehler
LED an oder aus und bleibt dann auch so. Wenn ich ihn dann wieder laufen
lasse, oder zu beginn blinkt meine LED am laufenden Band, das heißt doch
dass ständig Fehler erkannt werden. Aber warum? die Abfrage müsste doch
so passen.
Danke für die Hilfe bis jetzt und für die hoffentlich folgende
Den Watchdog hab ich nur zur Sicherheit rein falls sich der controller
mal aufhängen sollte. Der hat damit glaub ich nichts zu tun. Der
Watchdog-Reset wird ja auch erst nach 8s ausgelöst solange braucht das
Programm bei weitem nicht.
Verlängern oder Verkürzern der Schleifen bringt keine Veränderung. So
langsam bin ich mit meinem latein am Ende. Das mit den Timern ist etwas
schwierig, da ich Timer0 für die PWM benötige und Timer1 für die
Erzeugung einer 3,8kHz Frequenz die ich dann für nen Piezo Buzzer
brauche, welcher bei Fehlern pipst.
Hat denn keiner hier noch ne idee?
Wenn jemand eine bessere abfrageroutine hat bitte meldet euch. Bin offen
für alles!
@ Anfänger (Gast)
>Verlängern oder Verkürzern der Schleifen bringt keine Veränderung. So>langsam bin ich mit meinem latein am Ende.
Schalte den Watchdog aus! Mit dem arbeitet man nicht während der
Entwicklung.
Uuups, was ist denn das?
Erst die Interrupts freischalten und DANACH den Stackpointer
initialisieren. Tstststs, das macht ne Runde Freibier. Der Stack sollte
als ALLERERSTE Aktion im Programm gesetzt werden. Ausserdem ist dein
Resetvektor ungünstig bezeichnet. Das irritiert, vor allem bei grösseren
Programmen wirst du dir mit solchen Namensgebungen schnell ins Knie
schiessen. Reset ist Reset ist Reset.
MFG
Falk
Anfänger wrote:
> ...Timer1 für die> Erzeugung einer 3,8kHz Frequenz die ich dann für nen Piezo Buzzer> brauche, welcher bei Fehlern pipst...
Hmm, das kenne ich anders. Piezo bekommt stinknormale Gleichspannung und
der trötet dann munter. In der letzten Schaltung hatte ich einen Piezo
mit < 1 mA Stromaufnahme (Conrad Artikel-Nr.: 710143 - 62). Den müsste
man direkt an einem AVR-Port betreiben können (Lautstärke bei 5V
checken).
Genau, und nachdem Du Falks Hinweise umgesetzt hast (zumal Du den SP
permanent in der Start-Schleife sinnlos setzt - der Name Start ist
übrigens auch nicht gerade glücklich für eine Routine, die permanent
Runden dreht), wirst Du trotzdem noch sehen, daß der I2C schneller wird,
wenn der Lüfter schneller wird. Wobei "schneller" wohl nur bedeutet, daß
die einzelnen Datenpakete in geringerem Abstand gesendet werden dabei,
aber die Baudrate eines einzelnen Pakets wohl konstnt bleiben dürfte.
(die Fan-Warteschleife ist ja nur zw. den Paketen, nicht irgendwo
zwischendrin)
Wenn es Dir wirklich um weitgehend konstante I2C-Drehzahl geht, und
zustzliche Timer nicht möglich/gewollt sind, dann würde ich das
vielleicht nicht über Warteschleifen realisieren, sondern in der
Mainschleife (start) neben dem I2C Staff nur checken, ob sich nach x
Main-Runden mindestens einmal der Fan-Status geändert hat. Wenn nicht ->
Error. wie lang solch eine Main-Runde ist, kann man ja messen, oder
auszählen anhand der Takte pro Befehl.
Die Main-Schleifenzeit sollte dazu aber merklich kleiner sein als die
minimale Periodenzeit des Fansignals, sonst kanns passieren, daß der
Check immer nur "positive oder negative Halbwellen" erfaßt bei annähernd
gleicher Rundenzeit.
Beim UART haste auch noch solch Warteschleifen mit drin, deren Wartezeit
ebenfalls relativ unbestimmt ist, und somit den I2C beeinflußt.
Thema Buzzer,
wenns sozusagen nur ein Piezo-Lautsprecher wäre (ohne interne
Elektronik), dan muß er mit einer Frequenz angesteuert werden.
Wenns wirklich ein Buzzer ist, dann bedeutet Buzzer meines Wissens wohl,
daß er selbst aus eigener Kraft "buzzen" kann - also nur Gleichsspannung
nötig.
Jetzt mal langsam.
Den Piezo Buzzer bau ich erst später ein. Im Datenblatt steht, dass er
eine Frequenz von 3,8 kHz braucht. Ist ja jetzt auch erstmal egal.
Hab jetzt meine Abfrageroutine geändert und den SP gleich zu beginn
gesetzt und den Watchdog abgeschalten.
Das Problem ist aber weiterhin, dass ich nicht eindeutig einen Fehler
angezeigt bekomme. Wenn ich den Lüfter anhalte ist die FEHLER-LED an
oder aus.
Bei Betrieb mit richtiger Drezahl blinkt sie unregelmäßig.
Wie oft I2C zum Zuge kommt ist mir relativ egal so schnell ändert sich
die Temperatur im Normalfall ja nicht.
Hab den Code ma ran. Kann mir jemand erklären warum meine LED bei einem
Fehler an oder aus ist das würde mir glaube ich helfen.
Anfänger wrote:
> Jetzt mal langsam.> Den Piezo Buzzer bau ich erst später ein. Im Datenblatt steht, dass er> eine Frequenz von 3,8 kHz braucht. Ist ja jetzt auch erstmal egal.
Hmm, schau nach, ob es heisst "Der Buzzer trötet mit 3,8 kHz" oder "Der
Buzzer muss mit 3,8 kHz angesteuert werden". Ganz egal ist das nicht,
wenn wertvolle Resourcen vom µC durch einen Verständnisfehler gebunden
werden. Eine anständiger Zeitgeber ist wesentlich besser als die
bisherigen Warteschleifen.
@ Stefan B.
Er muss mit 3,8 kHz angesteuert werden.
Wie würdest du es denn mit timer machen? Kannst du mir das mal erklären?
Ich hab keine Ahnung wie ich die Abfrage mit nem Timer hinbekomme. Mit
Iinput Capture?? da hab ich ja dann nur 2 Pins ich hab aber 4 Lüfter.
Hat keiner eine Ahnung warum meine LED bei einem Fehler an oder aus ist?
Das leuchtet mir einfach nicht ein.
ich wollte dir den Zusammenhang I2C und Lüfterdrehzahl nur erklären,
weil das in deiner Frage ebenfalls mit drin stand !
Hast Du mal das Fan-Signal oszillografiert? Kann ja sein, daß da
kompletter Müll ankommt.
So auf die Schnelle sehe ich im neuen Code keinen Denkfehler, aber wenn
ich mich mit der AVR Assembler Syntax noch richtig auskenne (ist schon
zwei Jahre her,daß ich mal damit ne zetlang zu tun hatte), dann
schaltest Du den Interupt wohl immer während der Fanprüfung relativ
lange ab . Hat zwar mit dem eigentlichen Problem sicherlich nix zu tun,
aber ich weiß nicht, ob da dein ISR Handler noch zeitlich exakt genug
ist. Sehe ich als sinnlos an. Denn die ISR tut doch kaum die
Fan-Routine stören - oder?
@ JensG:
Also das Signal das vom Fan kommt ist in Ordnung:
Rechtecksignal von 0-5V. Daran liegt es nicht. Maximal zulassige
Periodendauer: bei 3V ca 17ms HIGH-Pegel und 17ms LOW-Pegel.
^^genau das ist mein Problem ich finde den Fehler nicht irgendwo muss
etwas schief laufen. Wenn der Lüfter steht sollte meine LED ja
eigentlich immer an sein. Ist sie aber nicht: Sie ist entweder an oder
aus.
Wenn ich die Ints die ganze Zeit über zulasse bringt das keine
Veränderung.
Hab noch ne Idee: Muss ich die Abfrage erst synchronisieren? Dürfte
eigentlich nicht daran liegen, da ich ja nur auf fehler springe wenn es
zu lange dauert bis die flanke kommt --> also müsste es auch egal sein
ob ich kurz vor Ende der HIGH oder LOW Phase mit der Abfrage beginne.
Ich werd jetz mal nen andern µC probieren. Wenn noch jemandem etwas
auffällt bitte melden.
Warum bist du so sparsam mit dem Kommentieren deines Codes?
Ich sehe im Moment auch keinen Denkfehler, musste mir aber das
Codefragment zuerst in ein Pseudo-C fummeln, bevor ich verstehe, was du
vor hast.
Läuft der µC noch in der aktuellen Instanz (d.h. nicht nach
Watchdog-Reset), auch wenn der Lüfter gestanden hat? Bzw. wenn der
Lüfter wieder anläuft, geht die LED irgendwann wieder aus?
Es ist essentiell, dass die globale Variable hilfe (genauer das
Register) sonst nirgends verändert wird. Ist das im Restprogramm
sichergestellt? Nirgends eine Doppelbelegung bei der Variablenbenennung
oder die direkte Registerbezeichnung in einer Anweisung?
1
; void i2cabfrage(void)
2
; {
3
; while(1)
4
; {
5
; cli();
6
; fansignal(); // Seiteneffekt: manipuliert hilfe
7
; // Pegelwechsel in 0,5ms bleiben aus (hilfe!=0)
8
; // Pegelwechsel in 0,5ms kommen (hilfe==0)
9
; if (hilfe)
10
; LEDein();
11
; else
12
; LEDaus();
13
; sei();
14
; wdr();
15
; }
16
; }
17
loop:
18
I2C-Abfrage:
19
cli
20
rcall fansignal
21
tst hilfe
22
brne LEDein ; Pegelwechsel innerhalb 0,5ms bleiben aus (hilfe!=0)
23
breq LEDaus ; Pegelwechsel innerhalb 0,5ms kommen (hilfe==0)
24
weiter:
25
sei
26
wdr
27
rjmp loop
28
29
LEDein:
30
cbi PINB,FEHLER
31
rjmp weiter
32
33
LEDaus:
34
sbi PINB,FEHLER
35
rjmp weiter
36
37
; void fansignal(void)
38
; {
39
; hilfe = 0;
40
; if (!(PINB & (1<<4)))
41
; waitrising(); // setzt hilfe|=1, wenn PINB.4
42
; // nicht innerhalb ~0,5 ms Null wird
43
; waitfalling(); // setzt hilfe|=1, wenn PINB.4
44
; // nicht innerhalb ~0,5 ms Eins wird
45
; waitrising(); // setzt hilfe|=1, wenn PINB.4
46
; // nicht innerhalb ~0,5 ms Null wird
47
; }
48
fansignal:
49
clr hilfe
50
sbis PINB,4 ; Springe, wenn Bit 4 im Port B Eins ist
51
; PINB.4 == 0
52
rcall waitrising
53
; PINB.4 == 1 || PINB.4 == 0
54
rcall waitfalling
55
rcall waitrising
56
ret
57
58
; void waitrising(void)
59
; {
60
; unsigned char temp2 = 50;
61
; while(temp2)
62
; {
63
; if ((PINB & (1<<4)))
64
; return;
65
; else {
66
; delay2();
67
; temp2--;
68
; }
69
; }
70
; hilfe |= 1;
71
; }
72
waitrising:
73
ldi temp2,50
74
waitrisingloop:
75
sbic PINB,4 ; Springe, wenn Bit 4 im Port B Null ist
76
; PINB.4 == 1
77
ret
78
; PINB.4 == 0
79
rcall delay2
80
dec temp2
81
brne waitrisingloop
82
ori hilfe,1
83
ret
84
85
; void waitfalling(void)
86
; {
87
; unsigned char temp2 = 50;
88
; while(temp2)
89
; {
90
; if (!(PINB & (1<<4)))
91
; return;
92
; else {
93
; delay2();
94
; temp2--;
95
; }
96
; }
97
; hilfe |= 1;
98
; }
99
waitfalling:
100
ldi temp2,50
101
waitfallingloop:
102
sbis PINB,4 ; Springe, wenn Bit 4 im Port B Eins ist
Der µC läuft noch wenn der lüfter steht. Auch wenn er wieder anläuft
fängt die LED wieder das blinken an. -->ständige Fehler + nicht-Fehler
Diagnose.
Ich versteh aber nicht warum die LED bei einem Fehler entweder an oder
aus ist.
Das Register Hilfe hab ich jetzt überall durch ein anderes ersetzt -->es
wird nur noch in der lüfterabfrage verwendet. Immer noch das selbe
verhalten!??
Langsam aber Sicher bringt mich das Ding zur Verzweiflung.
Kann mir jemand erklären warum meine LED bei einem Fehler an oder aus
ist?
Ich habe jetzt den letzten Komplettcode von dir geprüft. Dort findet
sich dieser Abschnitt:
1
sendtemp:
2
ldi hilfe,'-' ; - in register laden-->wenn temp<0
Und auch sonstwo ist 'hilfe' im Programm häufig benutzt. Das ist nicht
einfach zu kontrollieren. Benutze mal ein Register nur für die Variable
in der OK/Nicht-OK gespeichert wird.
ADD: Ich sehe gerade, das hast du bereits ausgeschlossen.
In welchem Frequenzbereich bewegt sich das Lüftersignal? Du hast das mit
dem Oszilloskop an PINB.4 kontrolliert? Die grosse Abweichung Messzeit
0,5ms zu 17ms@3V kommt mir spanisch vor. Funktionieren tut die Routine
ja nur, wenn Halbwellen <= 0,5ms dauern.
Ok hier mein Code den ich zur Zeit geproggt hab. Ich lass mir jetzt die
Art des Fehlers an den PC schicken. Wenn der Lüfter läuft bekomme ich
eine 0 -->kein Fehler festgestell und trotzdem blinkt die LED
Hab jetzt auch mal die Interrupts ausgeschalten sodass ich diese als
Fehlerquelle ausschließen kann.
@ stefan b.
Hab das mit den registern jetzt geändert. Hilfe wird jetzt nur noch in
der Abfrageroutine verwendet.
LOOOOOOOOOOOOOOOOOL
Wie kann das sein!? Hab es zuvor schonmal mit PORTB probiert da hat es
garnicht funktioniert. Kann mir jemand mal sagen wann man PORT und wann
PIN nimmt? Ich glaube das war die Lösung des Problems.
Nochmals DANKE an alle die mir geholfen haben!!!
@ Anfänger (Gast)
>garnicht funktioniert. Kann mir jemand mal sagen wann man PORT und wann>PIN nimmt? Ich glaube das war die Lösung des Problems.AVR-Tutorial: IO-Grundlagen
MfG
Falk