Ich hatte ursprünglich in einem meiner aktuellen Projekte einen Attiny85
als Tiefentladungsschutz für meine Batterieversorgung zu nutzen. Der
Tiny schläft die meiste Zeit, wacht hin und wieder auf und misst dann
die Akkuspannung und sollte dann im Zweifelsfall den Rest der Schaltung
abdrehen. Der Plan war eigentlich einen P-Kanal Fet (TPH1R712MD um
gennau zu sein) dafür zu verwenden. Der Microcontroller zieht mir wenn
die Spannung zu niedrig wird PB4 auf Masse, das funktioniert soweit auch
einwandfrei (auch mit Hysterese). Allerdings ist das Verhalten extrem
seltsam sobald der FET dazugeschaltet wird. Ich bin noch nicht wirklich
dahinter gekommen was genau passiert. Manchmal läuft alles einwandfrei
und dann wiederum wird auf einmal ein anderer pin vom µc der eigentlich
mit internem pullup beschaltet ist auf Masse gezogen. Es fühlt sich ein
bisschen so als würde sich das Ding hin und wieder einfach reseten, ich
sehe da am Oszi aber auch gar keine Änderung am reset pin.
Spannungsversorgung ist auch stabil und bricht nie ein.
Ich wollte hier nur mal abklären, ob ich einen groben Fehler in meinem
Design habe der mir nicht aufgefallen ist. Ich bin ein bisschen verloren
in der Fehlersuche hier und dachte mir vielleicht hat ja jemand eine
Idee!
Ist eigentlich nicht ganz so dramatisch, wenn da keine Antenne dran
hängt.
Schließlich hat es ja einen internen Pullup.
Es liegt natürlich etwas an dem Dreck, welcher in der Luft liegt.
Aber 2cm bis zum ISP Stecker, würde ich schon als kleine Antenne
bezeichnen.
Ich habe ihn tatsächlich unbeschaltet gelassen weil ich davon
ausgegangen bin, dass der interne pullup das regelt. Is dem nicht so?
Wie sollte ich sonst vorgehen?
Sowas ähnliches habe ich schon ein paar mal gebaut - funktioniert
einwandfrei.
Ist zwar momentan noch ein Prototyp, aber ich habe schon ca. 20 Stück im
Einsatz.
Mal mit Fototransistor damit sich LEDs bei Dämmerung einschalten.
Mal um andere uCs einzuschalten um periodisch Messwerte zu senden.
Mal mit nachgeschaltetem Step-Up-Wandler.
Mal als "Powerbank" die sich nicht abschaltet bei zu geringem
Stromfluss.
Mal als Zeitschaltuhr.
Und noch zig andere Spielereien.
Bei nachgeschaltetem Step-Up-Wandeler muss aber noch zusätzlich ein
kleiner Elko vor den Step-Up-Wandler, sonst resettet sich der Tiny.
Gruß Daniel
Ein Tiny10 reicht dafür völlig aus. Auch dann hat man noch einen Pin
übrig um das Gerät via Taster regulär ein- und auszuschalten.
R102 ist auch zu klein. Wenn das Gate gegen GND geschaltet wird, fließen
da bei 5V immerhin 0.5mA.
Arduino Fanboy D. schrieb:> Weit verbreitet ist wohl ein 10K gegen Vcc und ein 100nF gegen GND.
+1
Jocobes S. schrieb:> Ich habe ihn tatsächlich unbeschaltet gelassen weil ich davon> ausgegangen bin, dass der interne pullup das regelt. Is dem nicht so?
Das ist (fast immer) so.
Wenn nicht, App-Note lesen.
Jocobes S. schrieb:> Der Plan war eigentlich einen P-Kanal Fet (TPH1R712MD um> gennau zu sein) dafür zu verwenden.
Sollte für 5V gehen.
> Der Microcontroller zieht mir wenn> die Spannung zu niedrig wird PB4 auf Masse, das funktioniert soweit auch> einwandfrei (auch mit Hysterese).
Wenn PB4 auf GND gezogen wird, ist der T102 aber eingeschaltet!
> Allerdings ist das Verhalten extrem> seltsam sobald der FET dazugeschaltet wird. Ich bin noch nicht wirklich> dahinter gekommen was genau passiert. Manchmal läuft alles einwandfrei> und dann wiederum wird auf einmal ein anderer pin vom µc der eigentlich> mit internem pullup beschaltet ist auf Masse gezogen. Es fühlt sich ein> bisschen so als würde sich das Ding hin und wieder einfach reseten, ich> sehe da am Oszi aber auch gar keine Änderung am reset pin.
Das könnte man leicht damit feststellen, dass man die LED101 bei Startup
mal blinken lässt. Sollte man jedenfalls klären, ob es ein Reset ist.
> Spannungsversorgung ist auch stabil und bricht nie ein.
Auch mit dem Oszi gemessen?
Falls er tatsächlich einen Reset macht, dann wäre mein Vorschlag, die
Spannung für den µC mit einer Diode abzutrennen und dem C101 nochmals
10µF parallel zu schalten. Die Spannungsmessung wird zwar etwas
ungenauer (nicht ganz stabiler Drop durch diese Diode), aber evtl. hast
du ja da ein wenig Toleranz.
Jocobes S. schrieb:> Der Plan war eigentlich einen P-Kanal Fet (TPH1R712MD um> genau zu sein) dafür zu verwenden. Der Microcontroller zieht mir wenn> die Spannung zu niedrig wird PB4 auf Masse, das funktioniert soweit auch> einwandfrei (auch mit Hysterese). Allerdings ist das Verhalten extrem> seltsam sobald der FET dazugeschaltet wird.
Der P-Kanal MOSFET schaltet aber genau anders herum, als du beschrieben
hast. Er schaltet ein, wenn zwischen Gate und Source ein paar Volt
liegen, und das ist der Fall, wenn PB4=LOW ist.
HildeK schrieb:> Wenn PB4 auf GND gezogen wird, ist der T102 aber eingeschaltet!
Ja stimmt, da hab ich mich vertan beim schreiben, sorry dafür!
Also reset passiert anscheinend doch keiner. Hab den Tipp von HildeK mal
probiert, die LED blink munter vor sich hin.
Andreas B. schrieb:> R102 ist auch zu klein. Wenn das Gate gegen GND geschaltet wird, fließen> da bei 5V immerhin 0.5mA.
Was würdest du für Größe empfehlen?
Daniel B. schrieb:> Sowas ähnliches habe ich schon ein paar mal gebaut - funktioniert> einwandfrei.
Schaut ziemlich gut aus was du da gemacht hast. Gibts eine Chance, dass
man die Firmware anschauen darf?
Jocobes S. schrieb:> Der Microcontroller zieht mir wenn die Spannung zu niedrig wird PB4 auf> Masse
Und schaltet damit den Mosfet ein.
> dachte mir vielleicht hat ja jemand eine Idee!
Vielleicht ist ja tatsächlich noch ein Fehler in der Software...
Andreas B. schrieb:> Arduino Fanboy D. schrieb:>> Weit verbreitet ist wohl ein 10K gegen Vcc und ein 100nF gegen GND.> +1
Ich danke dir für die Zustimmung, aber diese Beschaltung ist auch mit
Seiteneffekten verbunden.
Ohne jede Beschaltung ist der Resetpin sicher vor magnetischen Feldern.
Dadurch, dass da "jetzt" Bauteile dran hängen, ist Ende damit, jetzt
können Ströme fließen.
Jedes Fitzelchen, Draht/Leiterbahn machts empfindlich für elektrische
Felder.
Der Pullup kann bei HVSP, den Vcc, über die Nennspannung anheben.
Der Kondensator muss dann auch die 12V aushalten können.
Werte der Komponenten:
Ein kleiner Pullup beschleunigt den Start des µC
Ein großer Kondensator verzögert den Start des µC
---
Hier vielleicht nicht wichtig:
Der Kondensator belastet einen evtl. vorhandenen Reset Taster
Auch kann er bei manchen µC/Programmern dem Programmieren/Debuggen im
Wege rum stehen.
Setzen der ResetDisable Fuse und als Ausgang nutzen, macht ihn
mindestens ebenso stabil gegen die Wirkung von äußeren Einstreuungen.
-----
Hier ist ein Abwägen nötig.
Pauschale Ansagen müssen nicht auf alle Situationen passen.
Jocobes S. schrieb:> Andreas B. schrieb:>> R102 ist auch zu klein. Wenn das Gate gegen GND geschaltet wird, fließen>> da bei 5V immerhin 0.5mA.
Wenn da Strom fliesst, dann ist mal schon etwas nicht gut
Jocobes S. schrieb:> Gibts eine Chance, dass> man die Firmware anschauen darf?
Ähhhmmm....
Du möchtest die Software anderer Leute haben, bist aber nicht bereit
deine zu zeigen?
Hab ich das so richtig verstanden ....
Arduino Fanboy D. schrieb:> Setzen der ResetDisable Fuse und als Ausgang nutzen, macht ihn> mindestens ebenso stabil gegen die Wirkung von äußeren Einstreuungen.
Ist da nicht Vorsicht geboten?
Jocobes S. schrieb:> Also reset passiert anscheinend doch keiner. Hab den Tipp von HildeK mal> probiert, die LED blink munter vor sich hin.
Du solltest sie einmal einschalten und wieder aus und dann dein
eigentliches Programm ausführen. Dann darf sie auch nur einmal an- und
wieder ausgehen, wenn kein Reset erfolgt; beim Reset wiederholt sich das
und sie blinkt.
Ein Blinken zu programmieren ist nicht so hilfreich, höchstens wenn man
sieht, dass der Rhythmus nicht gleichmäßig wäre.
Arduino Fanboy D. schrieb:> Du möchtest die Software anderer Leute haben, bist aber nicht bereit> deine zu zeigen?
Ja, es wäre Zeit, den Code mal zu zeigen.
herba schrieb:> Arduino Fanboy D. schrieb:>> Setzen der ResetDisable Fuse und als Ausgang nutzen, macht ihn>> mindestens ebenso stabil gegen die Wirkung von äußeren Einstreuungen.> Ist da nicht Vorsicht geboten?
Eigentlich nicht!
Bis auf, dass man dann nur noch per HVSP (oder Bootloader) da drankommt.
Das sollte man schon wissen, bzw. in die Betrachtung einfügen.
Arduino Fanboy D. schrieb:> Bis auf, dass man dann nur noch per HVSP (oder Bootloader) da drankommt.> Das sollte man schon wissen, bzw. in die Betrachtung einfügen.
Genau das habe ich gemeint, wenn kein HV-Programmer, dann fährt der
Frust so so richtig ein.
herba schrieb:> Frust
Kommt, wenn man nicht weiß, welche Wirkung das hat...
Dabei dreht es sich nicht so sehr um "Vorsicht", sondern eher um
"Absicht"
Auch darf einen die Angst vor Frust nicht davon abhalten die "nötigen"
Fuses zu setzen.
Aus dem Nähkästchen:
Mein "AVR Fusesbit Doctor" hat seine Kosten schon längst wieder
eingespielt.
Ich habe hier einige Tinys seit mehreren Jahren im Dauerbetrieb und
teilweise mit wirklich jämmerlichen Stromquellen und beschalte die
Resetpins nie - ausser zum Programmieren.
Es ist sicher sinnvoll, auf Motorboating (rythmisches Ein- und
Ausschalten) der Schaltung zu prüfen, vor allem, wenn der Brownout
Detektor und der WD im Spiel sind. Dabei hilft, den Zustand von MCUSR
beim Start auf die LED zu blinken.
Matthias S. schrieb:> Ich habe hier einige Tinys seit mehreren Jahren im Dauerbetrieb und> teilweise mit wirklich jämmerlichen Stromquellen und beschalte die> Resetpins nie
Dann musst du mit deiner Schaltung mal zum EMV-Burst-Test. Du wirst nie
mehr guten Gewissens einen µC ohne mindestens 10nF am Reset-Pin aus der
Hand geben...
Mein "Bursttest für Anfänger" ist ein Viehtreiber für 20€, der diagonal
auf eine Metallplatte zündet (einer der Pins über einen Draht am
"anderen Eck" angeschlossen), auf der gut isoliert meine Schaltung
liegt. Wenn meine Schaltung diesen "Test" ohne Fehlverhalten und Reset
hinter sich bringt, dann gehe ich beruhigt ins EMV-Labor:
Lothar M. schrieb:> Vielleicht ist ja tatsächlich noch ein Fehler in der Software...
Ja das Gefühl bekomme ich langsam auch. Ich wer dmir dass nochmal in
ruhe anschauen, mal aufs Minimum reduzieren.
Arduino Fanboy D. schrieb:> Ähhhmmm....> Du möchtest die Software anderer Leute haben, bist aber nicht bereit> deine zu zeigen?> Hab ich das so richtig verstanden ....
Selbstverständlich teil ich meine gerne! Ich dachte mir nur ich habe ein
hardware problem.
Wozu ist der Kondensator an reset? Den pullup versteh ich, aber was
macht mir der Kondensator?
Lothar M. schrieb:> Mein "Bursttest für Anfänger" ist ein Viehtreiber für 20€
Sehr gute Idee!
Hast du das mal verglichen an einer Schaltung, mit der du sowieso ins
EMV-Labor musstest?
voltage_threshold und hysterese müssen volatile sein, weil sie sowohl
innerhalb der ISR als auch außerhalb verwendet werden. Sonst
funktioniert es nur mit Glück.
Jocobes S. schrieb:> Wozu ist der Kondensator an reset? Den pullup versteh ich, aber was> macht mir der Kondensator?
Hinzu zur Aussage von Stefan kommt, dass der Kondensator den Reset für
eine kurze Zeit auf LOW hält. Sollte so lange sein, bis die
Versorgungsspannung auf einem sinnvollen Wert angekommen ist.
Noch besser, aber meistens nicht notwendig, ist ein externer
Resetgenerator, der nach Erreichen einer Spannungsschwelle + einer
zusätzlichen Schutzzeit erst den Reset freigibt.
Stefan ⛄ F. schrieb:> voltage_threshold und hysterese müssen volatile sein, weil sie sowohl> innerhalb der ISR als auch außerhalb verwendet werden. Sonst> funktioniert es nur mit Glück.
Das gilt mit Sicherheit, wenn die ISR die Werte schreiben würde. Macht
sie aber hier nicht. Die ISR hat aber keine Möglichkeit anzunehmen, daß
sie den Wert noch in einem Register stehen hätte, muß also eh "volatile"
nachladen.
Manchmal hilft volatile schlicht Programmierfehler zu verstecken, in dem
man den Optimierer "ausschaltet". Nicht der beste Ansatz.
Interessanter wäre die Frage, warum man den Tiny mit double quält.
Stefan ⛄ F. schrieb:> double gibt es beim avr-gcc nicht, in Wirklichkeit nimmt er float. Ich> würde aber auch float vermeiden.
Echte 64-Bit double Unzerstützung wurde vor kurzem erst von Johann
eingebaut. Aber der weiter oben vorgeschlagene Schritt zum winzigen
Tiny10 könnte generell an floating Point scheitern.
Und einen 10-Bit ADC-Wert in FP Volt umzurechnen, um sie dann wieder mit
einem FP-Wert zu vergleichen, ist ungeschickt. Besser wäre es den
Initialen threshhold Wert als 10-Bit ADC Wert abzulegen. Um den zu
errechnen, kann man gerne FP verwenden, denn das läuft zur Compile-Zeit
auf einem (vermutlich) 64-Bit-Mehrkerner.
Jocobes S. schrieb:> Schaut ziemlich gut aus was du da gemacht hast. Gibts eine Chance, dass> man die Firmware anschauen darf?
Ja.
Ist allerdings noch ziemlich "prototypenmäßig" und mit jeder Menge
Kommentare an mich selbst als ich mich durch das Datenblatt gekämpft
habe.
Ich werde den Code die Tage bereinigen und besser kommentieren und dann
kannst du ihn nochmal haben. Bis dahin findest du im angehängten Code
vielleicht was Interessantes.
Ich habe mir auch extra Equipment besorgt um so geringe Ströme messen zu
können. Ist auch sehr interessant, da kann man am Oszi dem Tiny beim
arbeiten zuschauen.
Aber wie gesagt, gib mir ein paar Tage um das vorzeigbar zu machen.
Ich sehe hier auch keine Notwendigkeit für float oder double, zur
Laufzeit.
Auch nicht für das volatile, bei dem Programm von von Jocobes S.
(jocobes).
Carl D. schrieb:> Und einen 10-Bit ADC-Wert in FP Volt umzurechnen, um sie dann wieder mit> einem FP-Wert zu vergleichen, ist ungeschickt. Besser wäre es den> Initialen threshhold Wert als 10-Bit ADC Wert abzulegen. Um den zu> errechnen, kann man gerne FP verwenden, denn das läuft zur Compile-Zeit> auf einem (vermutlich) 64-Bit-Mehrkerner.
das klingt eigentlich ziemlich vernünftig, werd das gleich mal
ausprobieren.
Oben wurde noch geschriben, dass mein Pullup am Gate des ets zu klein
wäre. Gibts da Standardwerte die man verwednet? Gefühlsmäßig würd ich
ihn so groß machen wie geht, damit ich eben möglichst wenig Leistung
verlier.
Jocobes S. schrieb:> Gefühlsmäßig würd ich> ihn so groß machen wie geht, damit ich eben möglichst wenig Leistung> verlier.
Andererseits fängst du dir damit leicht Radiowellen ein, was den
Stromverbrauch erhöht.
Stefan ⛄ F. schrieb:> Andererseits fängst du dir damit leicht Radiowellen ein, was den> Stromverbrauch erhöht.
Inwiefern hängt das mit der Größe von meinem Widerstand zusammen? Also
woher kommt das?
Jocobes S. schrieb:> Inwiefern hängt das mit der Größe von meinem Widerstand zusammen? Also> woher kommt das?
Jede Leitung ist eine Antenne. Eine hochohmig belastete Antenne
"empfängt" höhere Spannungen, als eine niederohmig belastete Antenne.
Fass mal mit dem Finger den Line-Eingang einer Stereoanlage an: Brummt.
Fasse den Stecker eines Kopfhörers an: Brummt nicht (auch nicht, denn du
GND erdest). Der wesentliche Unterschied ist, dass die Stereoanlage ca.
50kΩ Eingangswiderstand hat, während der Kopfhörer 32Ω hat.
Wahrscheinlich melden sich gleich die Besserwisser mit ihren "ja aber".
Ich habe den Sachverhalt hier nämlich vereinfacht dargestellt. Wenn man
will, kann man darüber ein ganzes Buch schreiben.
Lothar M. schrieb:> Wenn meine Schaltung diesen "Test" ohne Fehlverhalten und Reset> hinter sich bringt, dann gehe ich beruhigt ins EMV-Labor
...wir haben "früher" eine grobe Feile auf den Labortisch gelegt und mit
einem Pol einer Steckdose verbunden. Den anderen Pol mit einer 1,5qmm
Litze verbunden und das abisolierte andere Ende über die Feile gezogen.
Wer das Feuerwerk überstanden hatte, der durfte raus in die raue, harte
Wirklichkeit (in unserem Fall Stahlwerk) :-)
Gruß Rainer
Arduino Fanboy D. schrieb:> Ich sehe hier auch keine Notwendigkeit für float oder double, zur> Laufzeit.
Zumal die interne Vref mit 1.1V auch toleranzbehaftet ist und zwischen
1.0V und 1.2V liegen kann.
Noch ein paar Bemerkungen.
- Statt "ISR(ADC_vect) {}" kann auch "EMPTY_INTERRUPT (ADC_vect);"
benutzt werden, spart (vermutlich) Prelog und Epilog in der ISR.
- ohne genau den Ablauf zu verfolgen: mir sind da zu viele sei(); drin
- auch sehe ich viele ADC-Dummyaufrufe. Die sind doch nur nach dem
Anschalten des ADC notwendig, nach dem REF-Wechsel und evtl. noch bei
Änderung des MUX-Wertes. Wobei ich dazu bei einem kurzen,
unvollständigen Check im Tiny85-Datenblatt nichts gefunden habe.
- In DIDR0 schaltet man doch nur den Pin ab, der als AD-Eingang benutzt
wird.
- ich weiß nicht, ob du den WD auch zum Überwachen des Programms nimmst,
wenn nicht: kein WDE setzten, nur einmal WDIE, Dann wird auch WDIE nicht
mehr gelöscht. Und die WD-ISR kann zu einer "EMPTY_INTERRUPT
(WDT_vect);" werden.
Wie gesagt: ich habe die Details nicht alle nachverfolgt, manche meiner
Bemerkungen kann deshalb unzutreffend sein.
Jocobes S. schrieb:> Oben wurde noch geschriben, dass mein Pullup am Gate des ets zu klein> wäre. Gibts da Standardwerte die man verwednet? Gefühlsmäßig würd ich> ihn so groß machen wie geht, damit ich eben möglichst wenig Leistung> verlier.
Wenn du den r102 meinst, den brauchst du nicht zu ändern, der zieht
keinen Strom.
Stefan ⛄ F. schrieb:> Jocobes S. schrieb:>> Inwiefern hängt das mit der Größe von meinem Widerstand zusammen? Also>> woher kommt das?>> Jede Leitung ist eine Antenne. Eine hochohmig belastete Antenne> "empfängt" höhere Spannungen, als eine niederohmig belastete Antenne.
Das spielt doch in dem Zusammenhang kaum eine Rolle. Der Tiny liefert
doch LOW oder HIGH, auch wenn er schläft. Nur während den paar µs/ms der
Resetphase ist der Pin hochohmig und da ist es sinnvoll, den FET auf OFF
zu halten. IMHO sind 100k und mehr kein Problem.
Man kann den Wert auch in Relation setzen zum nominalen Stromverbrauch,
wenn die Last aktiv ist. Der gewählte pMOS hat ID=60A bei den
Grenzdaten, es muss einen Grund haben, warum der TO so einen potenten
FET gewählt hat. Und dann ist im EIN-Zustand der Strom durch 10k an 5V
nicht mehr derjenige, der die Quelle leer macht.
MaWin schrieb:> herba schrieb:>> Wenn du den r102 meinst, den brauchst du nicht zu ändern, der zieht>> keinen Strom.>> Im eingeschalteten Zustand schon.
Sorry, hab zu wenig genau geschaut: im eingeschalteten Zustand 0,5mA.
HildeK schrieb:> Das spielt doch in dem Zusammenhang kaum eine Rolle.
Ich stimme dir zu, dass der Widerstandswert in dieser Schaltung nicht
wichtig ist. Meine Erklärung bezog sich auf die Frage nach dem
Unterschied zwischen einem niederohmigen und einem hochohmigen
Widerstand.
Stefan ⛄ F. schrieb:> Meine Erklärung bezog sich auf die Frage nach dem> Unterschied zwischen einem niederohmigen und einem hochohmigen> Widerstand.
Ja, damit hast du natürlich recht.
Die Diskussion gibt es immer wieder; mit Pullups, an Taster u.v.m.
Stefan ⛄ F. schrieb:> Wenn man> will, kann man darüber ein ganzes Buch schreiben.
Danke fürs erläutern, hast du vielleicht eine gute Buch Empfehlung zu
dem Thema? ;) Würde mich allgemein interessieren.
HildeK schrieb:> Statt "ISR(ADC_vect) {}" kann auch "EMPTY_INTERRUPT (ADC_vect);"> benutzt werden, spart (vermutlich) Prelog und Epilog in der ISR.
Was ist eine empty interrupt isr? Noch nie gehört in dem Zusammenhang.
HildeK schrieb:> auch sehe ich viele ADC-Dummyaufrufe
ich kann leider nicht ganz folgen, ich dachte ich rufe den nur einmal
auf
Jocobes S. schrieb:> HildeK schrieb:>> Statt "ISR(ADC_vect) {}" kann auch "EMPTY_INTERRUPT (ADC_vect);">> benutzt werden, spart (vermutlich) Prelog und Epilog in der ISR.>> Was ist eine empty interrupt isr? Noch nie gehört in dem Zusammenhang.>Genau das, was ich schrieb. Du hast eine ISR ohne Inhalt; ein EMPTY_INTERRUPT ist
genau das - (vermutlich) ohne die Push/Pop-Orgie in der ISR. War nur ein Hinweis,
es ist so auch kein Fehler!
> HildeK schrieb:>> auch sehe ich viele ADC-Dummyaufrufe>> ich kann leider nicht ganz folgen, ich dachte ich rufe den nur einmal> auf
Ich sehe an mehreren Stellen
1
(void)ADC;// erstes Dummy-Ergebnis verwerfen
imho rentiert sich das Abschalten vom ADC nur zum Sleep für die 2s.
Ich hatte jedoch auch erwähnt, dass ich deinen Code nicht analysiert
habe.
HildeK schrieb:> genau das - (vermutlich) ohne die Push/Pop-Orgie in der ISR. War nur ein> Hinweis,> es ist so auch kein Fehler!
Das habe ich mal so getestet....
1
EMPTY_INTERRUPT(ADC_vect);
2
80:1895reti
1
ISR(ADC_vect){}
2
80:1895reti
Macht also jetzt nicht wirklich den Unterschied in meiner kleinen
Arduino Welt.
Zwecks selbst dokumentierendem Code, kann das Sinn machen.
Im Betrieb ist das egal.
Arduino Fanboy D. schrieb:> Das habe ich mal so getestet....
Was hattest du im main()?
Wenn dort Register benutzt werden, fürchte ich, dass die gesichert
werden, egal ob sie in der ISR gebraucht werden oder nicht.
Aber ich sagte, dass ich es vermute ...
@HildeK
Du hast dir wohl meinen Code angesehen. Der TO und du geht aber wohl
davon aus, dass ihr über seinen Code sprecht.
Übrigens vielen Dank für die Tipps. Ich habe dazu später vielleicht
nochmal ein paar Fragen.
Daniel B. schrieb:> Du hast dir wohl meinen Code angesehen. Der TO und du geht aber wohl> davon aus, dass ihr über seinen Code sprecht.
LOL.
Ja, das ist das Problem :-)
Sorry, Jocobes S.!
HildeK schrieb:> Arduino Fanboy D. schrieb:>> Das habe ich mal so getestet....>> Was hattest du im main()?> Wenn dort Register benutzt werden, fürchte ich, dass die gesichert> werden, egal ob sie in der ISR gebraucht werden oder nicht.> Aber ich sagte, dass ich es vermute ...
Das habe ich natürlich auch geprüft!
Zudem: Arduino Umgebung.
Da ist genug sonstiges Gedönse unterwegs...
Es werden nur die Register gesichert, welche in der ISR verändert
werden.
Die volle Push Pop Orgie erhält man, wenn in der ISR eine CallBack
Funktion aufgerufen wird.
Hier mal die Variante mit Tiny 10 und Assembler.
Da hier alle I/Os verwendet werden, muß Reset ausgeknipst werden!
An PB1 muß eine externe Referenz angelegt werden. Ich habe hier die 1.8V
des angeschlossenen Bluetoothmodules verwendet. Notfalls tun es auch
irgendwelche heruntergeteilten 3V. Leider haben sie ja beim Tiny 10 auch
die Bandgapreferenz eingespart. :-(
Die Levels (Z 54-58 und 179) sollten dementsprechend angepasst werden.
Als Mosfet verwende ich da einen IRLML2502. Dann ist alles schön klein.
;-)
Lange drücken: Ein/Aus
Kurz im eingeschalteten Zustand drücken: blinkt bis 5x abhängig vom
Akkuzustand.
Da ist auch noch ein serieller Ausgang parallel zur Statusled
vorgesehen, um Befehle zum Bluetoothmodul zu schicken. Das habe ich aber
nicht getestet.
Arduino Fanboy D. schrieb:> Es werden nur die Register gesichert, welche in der ISR verändert> werden.
Ich habe das zwar anders in Erinnerung - es gab mal an anderer Stelle
eine Diskussion dazu. Da ging es genau darum, warum Register gesichert
werden, die in der ISR oder einer Funktion gar nicht benutzt werden.
Wäre gut, wenn sich deine Beobachtungen bestätigen würden.
Bei Gelegenheit untersuche ich das auch mal.
Aber wir sind leider etwas abgedriftet vom eigentlichen Thema, vor
allem, weil ich den falschen Code kommentiert habe.
Jocobes S. schrieb:> Danke fürs erläutern, hast du vielleicht eine gute Buch Empfehlung zu> dem Thema? ;) Würde mich allgemein interessieren.
Nein, leider nicht. Mein Antennenbuch ist schon 80 Jahre alt.
HildeK schrieb:> Was hattest du im main()?> Wenn dort Register benutzt werden, fürchte ich, dass die gesichert> werden, egal ob sie in der ISR gebraucht werden oder nicht.
Nein Hilde, so dumm ist der Compiler nicht. Er sichert nur die Register,
die in der ISR verändert werden. Anders kenne ich es nicht. Wenn das mal
anders war, muss es vor WinAvr2010 gewesen sein.
Stefan ⛄ F. schrieb:> Nein Hilde, so dumm ist der Compiler nicht.
1. HildeK! Oder K, nicht Hilde!
2. Meiner offenbar schon. So war auch das Ergebnis der genannten
Diskussion.
- normale, leere ISR zeigt den Code für eine WDT-ISR ohne Inhalt:
1
{
2
+00000020: 921F PUSH R1 Push register on stack
3
+00000021: 920F PUSH R0 Push register on stack
4
+00000022: B60F IN R0,0x3F In from I/O location
5
+00000023: 920F PUSH R0 Push register on stack
6
+00000024: 2411 CLR R1 Clear Register
7
}
8
+00000025: 900F POP R0 Pop register from stack
9
+00000026: BE0F OUT 0x3F,R0 Out to I/O location
10
+00000027: 900F POP R0 Pop register from stack
11
+00000028: 901F POP R1 Pop register from stack
12
+00000029: 9518 RETI Interrupt return
- EMPTY_INTERRUPT zeigt den Code im Disassembler
1
EMPTY_INTERRUPT (WDT_vect);
2
+00000020: 9518 RETI Interrupt return
Der C-Quelltext dazu
1
// entweder:
2
ISR(WDT_vect)
3
{
4
;
5
}
6
// oder:
7
EMPTY_INTERRUPT(WDT_vect);
Zugegeben, mein Compiler ist älter: WinAVR-20100110
Andreas B. schrieb:> Leider haben sie ja beim Tiny 10 auch> die Bandgapreferenz eingespart. :-(
Darum nimmt man besser einen PIC10LF322 der hat eine interne VRef und
noch vieles mehr!
HildeK schrieb:> normale, leere ISR zeigt den Code für eine WDT-ISR ohne Inhalt:
Der Code sieht ziemlich sinnlos aus. Hier wäre mal interessant, zu
erfahren, warum der Compiler das damals so gemacht hat. Weiß das jemand?
Offenbar traut der Compiler seinem eigenen Code nicht und stellt hier
doppelt gemoppelt sicher, dass R1=0 ist und sichert R1 vorsichtshalber
auf den Stack. Als Nebeneffekt muss er auch SREG und R0 sichern. Wobei
er anstelle von R0 auch R1 hätte benutzen können, um SREG zu lesen und
zu sichern.
Ziemlich dumm.
Arduino Fanboy D. schrieb:> Ich sehe hier auch keine Notwendigkeit für float oder double, zur> Laufzeit.
absolut richtig!
Ich nehme immer int oder uint und dann mV cV dV V als Ganzzahl, wozu bei
10-Bit float oder double?
Das Komma oder ein Dezimalpunkt kann man auch in den String einsetzen
und so vermeidet man die etwas größere floating point LIB.
HildeK schrieb:> Zugegeben, mein Compiler ist älter: WinAVR-20100110AVR GCC Tool Chain Gcc-10.2.0 binutils-2.35
Built: 19.8.2020
Die wichtigsten Einstellungen:
-std=gnu++20 -fno-sized-deallocation -Wall -Wno-volatile -mdouble=64
Die restlichen sind Arduino Standard. So wie z.B. -Os
Arduino Fanboy D. schrieb:> HildeK schrieb:>> Zugegeben, mein Compiler ist älter: WinAVR-20100110>> AVR GCC Tool Chain Gcc-10.2.0 binutils-2.35> Built: 19.8.2020
Danke für den Hinweis. Dann hat sich doch einiges getan in den letzten
10 Jahren.
Das, was ich oben als Ausschnitt gezeigt hatte, ist, betrachtet man das
ganze Progrämmchen*, eh nicht so ganz schlüssig gewesen. Z.B. wird im
restlichen Programm nirgends R0 und R1 verwendet, jedoch z.B. R24.
Sei es drum: für meine kleinen Programme war das bisher nur bei einem
Exemplar interessant.
* Ich hatte es als Demo für den WD-Timer hier schon mal gepostet,
allerdings mit Inhalt in der WD-ISR:
Beitrag "Re: ATtiny84 Pin Change Interrupt"
Zur ISR:
R0 wird vom Avr-GCC als temporäres Register verwendet, R1 erwartet der
GCC als "0". Beides muß beim Einstieg in eine ISR sichergestellt werden.
Zusätzlich erwartet der unterbrochene Code, daß R0,R1 und die Flags sich
(durch einen Interrupt) nicht einfach spontan verändern. R1 kann auch
mal ungleich "0" sein, wenn gerade eine HW-Multiplikation durchgeführt
wurde. Die liefert das 16-Bit Ergebnis nämlich in R0,R1. (Vielleicht
wäre z.B. R2 ein besseres Zero-Register gewesen, aber das ist wohl zu
spät).
Der Avr-GCC (und BinUtils, weil die mithelfen müssen) wurde kürzlich
(V8, oder so) bzgl. ISR geändert, so daß er leere ISRs immer zu einem
einzigen "RETI" übersetzt. Danke Johann!
Wobei, ob ich aus einem sleep per WD in 5 oder 20Takten (nur geraten)
aufwache, dürfte egal sein.
Carl D. schrieb:> Wobei, ob ich aus einem sleep per WD in 5 oder 20Takten (nur geraten)> aufwache, dürfte egal sein.
Ja, da hast du recht. WD war nur zufällig als Beispiel vorhanden, bei
anderen wäre es ja genauso.
Carl D. schrieb:> Der Avr-GCC (und BinUtils, weil die mithelfen müssen) wurde kürzlich> (V8, oder so) bzgl. ISR geändert, so daß er leere ISRs immer zu einem> einzigen "RETI" übersetzt. Danke Johann!
Danke. So genau verfolge ich diese Aktivitäten jedoch nicht 😀.
HildeK schrieb:> Carl D. schrieb:>> Der Avr-GCC (und BinUtils, weil die mithelfen müssen) wurde kürzlich>> (V8, oder so) bzgl. ISR geändert, so daß er leere ISRs immer zu einem>> einzigen "RETI" übersetzt. Danke Johann!>> Danke. So genau verfolge ich diese Aktivitäten jedoch nicht 😀.
Naja, da wurde von Maschinencodeästheten solange dran rumgenörgelt, bis
Johann den Nicht-(/kaum-)Fehler unorthodox bereinigt hat. Wenn also
jemand in einem Avr-GCC-Assembler-Output in einer ISR komischen Befehle
findet:
https://sourceware.org/binutils/docs/as/AVR-Pseudo-Instructions.html
Und wenn der Avr-AS aus den binutils bei diesen meckert, dann braucht
man eine neuere Version der binutils.
Carl D. schrieb:> R1 kann auch> mal ungleich "0" sein, wenn gerade eine HW-Multiplikation durchgeführt> wurde. Die liefert das 16-Bit Ergebnis nämlich in R0,R1.
Danke für diese aufschlussreiche Erklärung
Also hier nochmal ein Update: Ich habe beobachtet, dass der fet
offensichtlich nicht ganz durchgeschaltet hat, wenn ich dann manuell
einmal den dementsprechenden Pin des tinys mit einer Brücke auf Masse
gelegt hat funktionierte alles und es blieb stabil. Ich habe dann
einfach aus Neugierde dem Gate noch einen 1k Vorwiderstand verpasst und
voila, jetzt funktionierts einwandfrei. Jetzt wollte ich noch fragen ob
mir jemand erklären kann woran das gelegen hat? Nur damit ich in Zukunft
solche Fehler vermeiden kann. Ich nehme an das hat etwas mit den
parasitären Kapazitäten des fets zu tun?
Jocobes S. schrieb:> Jetzt wollte ich noch fragen ob> mir jemand erklären kann woran das gelegen hat?
Zeichne bitte den Schaltplan dazu auf, dann schaue ich mal.
Jocobes S. schrieb:> Ich habe dann einfach aus Neugierde dem Gate noch einen 1k Vorwiderstand> verpasst und voila, jetzt funktionierts einwandfrei.
Nun, wenn man 2 1uF Kondensatoren von denen der eine auf VCC, der
andete auf 0 geladen ist, schlagartig über einen niederohmigen MOSFET
zusammenschaltet, dann bricht VCC erst mal auf die Hälfte ein - bis der
Strom zum Nachladen kommt. Vorher spinnt aber der uC
Daher lohnt es sich, den MOSFET langsam aufzusteuern, was deine 1k
erreichen.
MaWin schrieb:> Nun, wenn man 2 1uF Kondensatoren von denen der eine auf VCC, der> andete auf 0 geladen ist, schlagartig über einen niederohmigen MOSFET> zusammenschaltet, dann bricht VCC erst mal auf die Hälfte ein
Es sind nicht nur zwei, sondern sogar drei 1uF Kondensatoren. Und die
sind nicht in Jocobes (dem TE) Schaltplan, sondern in meinem. Und
obgleich ich bisher keine Probleme hatte, klingt deine Erklärung
schlüssig.
Deswegen habe ich gerade direkt an den Pins des Tiny nachgemessen was
beim Schalten des Ausgangs-FETs und somit beim Laden des entladenen 1uF
Kerkos passiert. Man sieht einen Spannungseinbruch von knappen 1,5V.
Wie gesagt, bisher hatte ich keine Probleme, aber da werde ich beim
nächsten Layout nochmal drüber gehen.
Vielen Dank für den Hinweis.
Gruß Daniel