StefanK schrieb: > Veit D. schrieb: >> StefanK schrieb: >>> @Veit D. > >> Ein bool Datentyp hat immer die kleinste Byte Größe. Beim 8Bit AVR 1 >> Byte. Lasse dir auf deiner Zielplattform von allen Datentypen die Größe >> mittels sizeof() ausgeben. bool kann nur Werte von true/false annehmen. >> Das ist die Eigenschaft des Datentyps. > > Dann bedeutet das, dass mehrere bools in so einer Struct nicht in ein > Byte gepackt werden? Nein. > D.h. man muß sich ein Byte anlegen, dieses als > Bit-Basis verwenden und auf seine bits einzeln zugreifen, wenn man nicht > für jedes bool ein ganzes Byte spendieren will. Du kannst bei Bedarf mit Bitfelder rumspielen. https://en.cppreference.com/w/cpp/language/bit_field.html
Dergute W. schrieb: > Moin, > > StefanK schrieb: >> was >> hätten denn mehr Details zu Anfang Ihrer Meinung nach daran geändert, >> die Methode zu finden, wie man am schnellsten ohne im Hauptprogramm zu >> warten mehrere ADC-Kanäle mißt? > > Dann waere z.b. mir voellig klar gewesen, dass das mit dem "am > schnellsten" natuerlich Quatsch ist. Ja, das wäre wohl so gekommen und wir hätten Ihre Ideen verloren, wenn Sie sich aus der Diskussion verabschiedet hätten. Das finde ich eben schade. @Rainer W. (rawi) >Möchtest du die Flügelschläge einzelner überfliegender Insekten >ausregeln oder warum so schnell? Das vielleicht nicht gerade, es gibt ja auch immer weniger Insekten ;-) Es gibt von Microchip eine interessante Application Note dazu. Sie verwenden natürlich einen PIC. Der mißt 4 Kanäle * 4 Messungen und Mittelwert mit 1000Hz (wir schaffen immerhin 600Hz mit Atmega328/ATtiny bei 16MHz Systemtakt). Die 1000 Datensätze pro Sekunde gehen in einen PI-Regler, der den MPP 40 mal pro Sekunde anpasst. Bei allen MPP-Suchalgorithmen von P&O, Hill-Climbing über Incremental Condutance bis hin zu Fire Flies etc. steigt der MPP-Wirkungsgrad, also den richtigen Punkt zu finden und zu halten mit der Frequenz. Daher ist es gut schnell zu sein.
Moin, StefanK schrieb: > Ja, das wäre wohl so gekommen und wir hätten Ihre Ideen verloren, wenn > Sie sich aus der Diskussion verabschiedet hätten. Das finde ich eben > schade. Bullshit. Wenn du gleich am Anfang auch noch erwaehnt haettest, dass du ja auch noch einen UART brauchst, den aber mangels Vorhandensein in HW unbedingt in SW machen musst, dann waere ziemlich sicher nicht nur bei mir die Idee aufgekommen, eben den zeitkritischen Teil des UARTs im Timerinterrupt zu machen und dann eher so "nebenbei" den ollen ADC zu triggern und dessen Eingang umzuschalten. Und nich ewig rumzukaspern ob der ADC jetzt 13.5 oder 14.3 Takte braucht... Und wenn du dann auch noch erwaehnt haettest, dass dein Wissen von seriellen Protokollen in C auch noch durchaus Potential nach oben hat... Naja, waere sicherlich schneller gegangen, da was wirklich halbwegs durchdachtes fuer's Gesamtproblem vorzuschlagen, kann mir ja aber eher auch wurscht sein :-) Gruss WK
StefanK schrieb: > Es gibt von Microchip eine interessante Application Note dazu. AN???? > Sie verwenden natürlich einen PIC Dann muss die Application Note schon älter sein. Inzwischen kommen auch die AVR von Microchip.
https://ww1.microchip.com/downloads/en/appnotes/00001521a.pdf https://ww1.microchip.com/downloads/en/Appnotes/00002321A.pdf https://ww1.microchip.com/downloads/en/appnotes/pv_appnotes.pdf https://www.microchip.com/content/dam/mchp/documents/OTH/ApplicationNotes/ApplicationNotes/01444A.pdf
StefanK schrieb: > kleinen MPPT-Solarladereglers ... mit ATtiny13. Ist das nur total blöd oder schon krank?
Nachtrag: 10 Jahre vor diesem Beitrag hatte Sebastian Foerster die gleiche Projektidee. Er löste die Messung von 4 Spannungen mit dem ADC im Freerunning Modus so:
1 | ISR(ADC_vect) |
2 | {
|
3 | switch(ADMUX) |
4 | {
|
5 | case ADCMUX_CELL_VOLTAGE: |
6 | //ADCSRB = 0; //change conversation to free running;
|
7 | cell_voltage = ADCW; |
8 | ADMUX = ADCMUX_CELL_CURRENT; |
9 | break; |
10 | |
11 | case ADCMUX_CELL_CURRENT: |
12 | cell_current = ADCW; |
13 | ADMUX = ADCMUX_ACCU_VOLTAGE; |
14 | break; |
15 | |
16 | case ADCMUX_ACCU_VOLTAGE: |
17 | accu_voltage = ADCW; |
18 | ADMUX = ADCMUX_CELL_VOLTAGE; |
19 | adc_ready = true; |
20 | //ADCSRB = (1<<ADTS2); //trigger adc read with timer in sync
|
21 | break; |
22 | }
|
23 | }
|
https://sebastianfoerster86.wordpress.com/2016/01/02/attiny13-solar-cell-charger-hardware/
:
Bearbeitet durch User
StefanK schrieb: > Er löste die Messung von 4 Spannungen mit dem ADC > im Freerunning Modus so: Bedenklicher Ansatz! Die Kanalumschaltung in der ISR kommt zu einem undefiniertem Zeitpukt. Also weiß man nicht sicher zu welchem Kanal die nächste Messung gehört. Will man das unterbinden, muss man jede 2te Messung verwerfen. Und damit ist der freerunning Mode nicht mehr die schnellste Variante.
:
Bearbeitet durch User
Die Umschaltung passiert erst nach der Konvertierung. So ist das Ergebnis in der nächsten Isr noch von dem vorher ausgewähltem Kanal / der Konvertierung die lief als die Mux geändert wurde. Unzuverlässig kann das nur werden wenn man einen Int verpasst. Aber dazu müssten andere Isr viel zu lang sein. Oder in der ADC-Isr zu viel passieren bevor der Wert ausgelesen wird ;-)
Achim H. schrieb: > Die Umschaltung passiert erst nach der Konvertierung. So ist das > Ergebnis in der nächsten Isr noch von dem vorher ausgewähltem Kanal / > der Konvertierung die lief als die Mux geändert wurde. Davon ist im dem gezeigten Code nichts zu sehen. Im Gegenteil! Der Code geht davon aus, dass die Mux Umstellung VOR der S&H Phase, und damit auch vor der Wandlung, stattfindet.
Arduino F. schrieb: > Im Gegenteil! > Der Code geht davon aus, dass die Mux Umstellung VOR der S&H Phase, und > damit auch vor der Wandlung, stattfindet. Das tut es ja auch. Lies mal das Datenblatt. Beitrag "Re: ADC-Kanäle sukzessive abfragen" Beitrag "Re: ADC-Kanäle sukzessive abfragen" Ok, ich sehe das Problem, denn ich hatte es auch. Die Zuordnung der Kanäle ist falsch. Denn wenn man in der ISR ADMUX ausliest ist das die aktuell laufende Wandlung aber NICHT das Ergebnis in ADCW. Das ist von der vorhergehenden Wandlung!
Das einzige was man weiß wenn man in der ISR aufschlägt, ist dass ein IRQ stattgefunden hat. Nach dem Eintreten des IRQ hat man 1,5 ADC Takte Zeit um den MUX für die nächste Messung umzustellen. Ob und wo man sich in diesem schmalen Zeitfenster aufhält weiß man nicht. Also muss man eine Laufzeit/Reaktionszeit Analyse des kompletten Systems durchführen. Wenn nichts anderes einen IRQ erzeugen kann UND man auch sonst sicher ist, dass kein IRQ temporär disabled wird, ist man bei hohen CPU Taktraten (ADC DIV 64 od. 128) auf der sicheren Seite. Sonst heißt es Zyklen zählen und worst case Szenarien rechnen. Sobald man auch nur einmal den MUX (unwissentlich) etwas zu spät umschaltet, ist die nächste Messung versaut. Das aber garantiert. ;-)
Norbert schrieb: > Das einzige was man weiß wenn man in der ISR aufschlägt, ist dass ein > IRQ stattgefunden hat. Nach dem Eintreten des IRQ hat man 1,5 ADC Takte > Zeit um den MUX für die nächste Messung umzustellen. Nein! Das ist längst passiert! Das macht der ADC im free run mode selber! Und wenn man den Single shot mode nutzt, ist es egal, denn dann steht der ADC. > Also muss man eine Laufzeit/Reaktionszeit Analyse des kompletten Systems > durchführen. Nö, das wäre ziemlich doof. Ist aber gar nicht nötig.
Falk B. schrieb: > Das macht der ADC im free run mode > selber! Der schaltet selbstständig auf den nächsten Kanal? In welcher Reihenfolge? Welche Kanäle? Wo konfigurierbar?
Norbert schrieb: >> Das macht der ADC im free run mode >> selber! > > Der schaltet selbstständig auf den nächsten Kanal? Ja. > In welcher Reihenfolge? Den, der in ADMUX steht. Dahinter liegt ein 2. aus Softwaresicht unsichtbares Register, das beim Start der AD-Wandlung gespeichert wird. > Welche Kanäle? > Wo konfigurierbar? Den nächsten Kanal kann man per ADMUX festlegen, mehr nicht. Siehe mein Link oben, da gibt es vollständige, getestete Software.
Falk B. schrieb: > Dahinter liegt ein 2. aus Softwaresicht > unsichtbares Register, Ah, interessant. Dann muss das dieses Verhalten bei den neueren Typen geändert worden sein. (Hab' lange nichts mehr mit AVR gemacht)
Norbert schrieb: > Ah, interessant. Dann muss das dieses Verhalten bei den neueren Typen > geändert worden sein. Glaub ich nicht so ganz.
Norbert schrieb: >> Glaub ich nicht so ganz. > > Glauben heißt, nicht wissen. Stimmt. > 8535. Das ist bei dir einer der "neueren Typen"? ;-) Aber es gibt Berichte, daß einige Typen an der Stelle einen Bug hatten und die interne Verriegelung von ADMUX nicht ganz wie gewünscht funktionierte.
:
Bearbeitet durch User
Falk B. schrieb: > Das ist bei dir einer der "neueren Typen"? ;-) Nein. Genau so wie ich es geschrieben habe ist es einer der älteren Typen!
Arduino F. schrieb: > Falk B. schrieb: >> Die Zuordnung der >> Kanäle ist falsch. > > Richtig! Das sollte schon klappen. Wenn die ISR kommt, liefert sie den ADC-Wert aus der vorletzten ADMUX Beauftragung. Liest man in dieser ISR ADMUX, erhält man den Kanal der bereits jetzt auto-getriggerten Messung. Wenn man jetzt ADMUX um eins erhöht, passt es. Dann geht ADMUX ggü dem in dieser ISR gelieferten ADC-Wert um genau +2 vor. In der Main.c muss das schon so vorbereitet werden, wenn der ADC mit Kanal 0 gestartet wird. Dann ADMUX++. Ist verzwickt, aber geht.
:
Bearbeitet durch User
StefanK schrieb: > ... Genau das ist in deinem zuletzt gezeigten Code falsch. Damit ist der Code kaputt und das Tutorial dramatisch irreführend.
Ich baue das Sebastian Foerster Verfahren mal nach und vergleiche es mit meinem erprobten Verfahren. Bin gespannt was rauskommt. Intetessiert mich auch, wie gross/schnell der Code im Vgl ist. Werde dann berichten.
StefanK schrieb: > In der Main.c muss das schon so vorbereitet werden, wenn der ADC mit > Kanal 0 gestartet wird. Dann ADMUX++. Ist verzwickt, aber geht. Nö, es ist falsch, denn die defines sind dann irreführend!
Arduino F. schrieb im Beitrag > Genau das ist in deinem zuletzt gezeigten Code falsch. > Damit ist der Code kaputt und das Tutorial dramatisch irreführend. Der Code ist weder kaputt noch irreführend, er funktioniert. Falk B. schrieb: > Nö, es ist falsch, denn die defines sind dann irreführend! Selber nö. Seit wann lässt Du Dich so leicht in die Irre führen? Das passt schon, hast Du doch selbst in Deinen Code gezeigt. Also ich finde die Methode von Sebastian Foerster gut. Sie erzeugt zwar etwas mehr Code, ist aber flexibel und intuitiv. Das hätte ich gern schon vor einem Jahr gewusst. Hätte mir ne Menge Nerven gespart. Übrigens Schreck Gpt beatwortet die Frage nach Freerunning inzwischen mit genau dieser Methode... Mein 👍 hoch für Sebastian.
:
Bearbeitet durch User
StefanK schrieb: > Übrigens Schreck Gpt beatwortet die Frage nach Freerunning inzwischen > mit genau dieser Methode... Ist ein deutlicher Hinweis, dass KI eigentlich bedeutet: konkurrenzlos inkompentent.
Ob S. schrieb: > Ist ein deutlicher Hinweis, dass KI eigentlich bedeutet: konkurrenzlos > inkompentent. Dem widerspreche ich jetzt mal nicht, bin aber trotzdem gespannt auf Deine Methode. Zeig her!
StefanK schrieb: > Ob S. schrieb: >> Ist ein deutlicher Hinweis, dass KI eigentlich bedeutet: konkurrenzlos >> inkompentent. > > Dem widerspreche ich jetzt mal nicht, bin aber trotzdem gespannt auf > Deine Methode. Zeig her! Wieso, alles was es dazu zu sagen gab ist doch bereits in den einschlägigen Threads gesagt worden. Die korrekte Umsetzung kannst du ja der KI überlassen. Ähemm... Blöderweise ist die auf Wichsvorlage angewiesen, weil ihr jegliches Verständnis für die Inhalte fehlt. Tja, dumm gelaufen...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.