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.
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.
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 :-)
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
caseADCMUX_CELL_VOLTAGE:
6
//ADCSRB = 0; //change conversation to free running;
7
cell_voltage=ADCW;
8
ADMUX=ADCMUX_CELL_CURRENT;
9
break;
10
11
caseADCMUX_CELL_CURRENT:
12
cell_current=ADCW;
13
ADMUX=ADCMUX_ACCU_VOLTAGE;
14
break;
15
16
caseADCMUX_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
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.
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 ;-)
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.
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. ;-)
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.
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.
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.
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.
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.
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...