Forum: Mikrocontroller und Digitale Elektronik ADC-Kanäle sukzessive abfragen


von Veit D. (devil-elec)


Lesenswert?

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
von StefanK (stefanka)


Lesenswert?

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.
von Dergute W. (derguteweka)


Lesenswert?

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
von Rainer W. (rawi)


Lesenswert?

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.
von Torsten B. (butterbrotstern)


Lesenswert?

von Mi N. (msx)


Lesenswert?

StefanK schrieb:
> kleinen MPPT-Solarladereglers

... mit ATtiny13.
Ist das nur total blöd oder schon krank?
von StefanK (stefanka)


Lesenswert?

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
von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

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
von Achim H. (pluto25)


Lesenswert?

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  ;-)
von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

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.
von Falk B. (falk)


Lesenswert?

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!
von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Falk B. schrieb:
> Die Zuordnung der
> Kanäle ist falsch.

Richtig!
von Norbert (der_norbert)


Lesenswert?

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. ;-)
von Falk B. (falk)


Lesenswert?

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.
von Norbert (der_norbert)


Lesenswert?

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?
von Falk B. (falk)


Lesenswert?

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.
von Norbert (der_norbert)


Lesenswert?

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)
von Falk B. (falk)


Lesenswert?

Norbert schrieb:
> Ah, interessant. Dann muss das dieses Verhalten bei den neueren Typen
> geändert worden sein.

Glaub ich nicht so ganz.
von Norbert (der_norbert)


Lesenswert?

Falk B. schrieb:
> Glaub ich nicht so ganz.

Glauben heißt, nicht wissen. 8535.
von Falk B. (falk)


Lesenswert?

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
von Norbert (der_norbert)


Lesenswert?

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!
von StefanK (stefanka)


Lesenswert?

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
von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

StefanK schrieb:
> ...

Genau das ist in deinem zuletzt gezeigten Code falsch.
Damit ist der Code kaputt und das Tutorial dramatisch irreführend.
von StefanK (stefanka)


Lesenswert?

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.
von Falk B. (falk)


Lesenswert?

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!
von StefanK (stefanka)


Angehängte Dateien:

Lesenswert?

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
von Ob S. (Firma: 1984now) (observer)


Lesenswert?

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.
von StefanK (stefanka)


Lesenswert?

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!
von Ob S. (Firma: 1984now) (observer)


Lesenswert?

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
Noch kein Account? Hier anmelden.