Forum: Mikrocontroller und Digitale Elektronik Atemega328p - schaffst du das?


von avrFanBoy 8-) (Gast)


Lesenswert?

Hallo zusammen, ich möchte zur Diskussionsrunde aufrufen oder eure 
Erfahrung/Meinung gerne hören, wird jetzt etwas länger, sorry.
Im Voraus vielen Dank fürs lesen!


Es geht um die Frage ob folgende Applikation mit einem: ATMEGA328P zu 
realisieren ist, oder ich mich besser von diesem µC verabschieden 
sollte.


Zusammengefasst soll er das machen:

1) PinX INPUT schalten, PinY OUTPUT HIGH, 1ms
   PinX OUTPUT High schalten, PinY INPUT, 25 ms


2)  5 x ADC Kanäle abtasten unter Nyquist berücksichtigt:

    1) Frequenz 4KHz , 8 Bit (Audio, soweit möglich, es interessiert 
nicht
       die Audiodatei, sondern "nur" der Amplitdenverlauf, also Dynamik
       nicht wichtig)

    2) Frequenz: 50Hz, 10 Bit


    3) Frequenz: 30 Hz, 8 Bit
    4) Frequenz: 30 Hz, 8 Bit
    5) Frequenz: 50 Hz, 8 Bit


3) 2 x G-Sensor auslesen via SPI, beide mit 50Hz je 3 Achsen. + 2CS Pin
   steuern ( es wird in einem Schwung alle 3 Achsen ausgelesen! 10Bit =
   1MSB + 2LSB)


4) Alle Daten über UART raussenden. + Eventuell zeitstempel.

   Verfügbare bluetooth kompatible Baudraten:

   115,2 K und 230,4 K

   F_CPU : 9.216MHz.
______________________________________________________________________ 
_
Zu 1) Würde ich einfach einen Timer verwenden, eventuell sogar den, der 
mir den Zeitstempel liefert.


2) Wie "stellt" man am besten eine Samplingsfrequenz ein?
von zB. 4K? Timer (ganz klein) verwenden und alle 1/4K [s] den Kanal 
losjagen? Oder besser gleich im Free Running Mode schauen was man 
erreichen kann?

Für eine korrekte Wandlung benötigt es eine eine ADC_Frequenz zwischen 
50KHz-200KHz, ausgehend von meiner CPU: 9.261MHz. kommt der Prescaler 64 
in Frage und die ADC_Frequenz beläuft sich auf 144KHz. Bei benötigten 13 
Take komme ich auf eine Samplingrate von: 144KHz/13 = 11KHz. Das alleine 
wäre ja dem ATMEGA noch zumutbar? Die Referenzspannung bleibt immer 
gleich und dadurch sollte jede Wandlung Ihre Gültigkeit haben (nach 13 
Takten), wenn die Einstellung stimmt.

Ansonsten würde ich die Routine wie folgt gestalten:

Channel 4K : 20 Samples,
1x ADC1
Channel 4K : 20 Samples,
1x Gsensor
Channel 4K : 20 Samples,
1xADC2
Channel 4K : 20 Samples, ....... usw mit einer
Switch abfrage? gesteuert entweder durch Interrupts oder Timer... ?




4) Dafür müsste ich mir ja eine FIFO schreiben.
Netto komme ich ja auf ca. 40kBaud. Angesichts des 2Kbyte Rams, wie und 
wann soll ich die FIFO losjagen?
Am besten gesteuert über Timer? Interrup-Routine? oder Array Größe?....
Dadurch dass keine zeit zum Puffern bleibt, sind da Jitter zu erwarten?


______________________________________________________________________
So, wer es bis hierhin geschafft hat, vielen dank fürs Lesen. Postet mir 
gerne eure Ideen und Meinungen.

Soll ich in einer Routine mich und den Atmega quälen oder meine Zeit 
besser in die Einarbeitung eines neuen µC investieren?

Alternativ, wenn es sein muss werde ich diesen mit einem STM32 ersetzen,
Vorschläge dürfen gerne gemacht werden (einarbeiten!):

-3V3 Vcc
-Klein/Kompakt
-DMA
-I²S
-Am besten mehrere ADC's
-evt Bluetooth integriert
-Viel RAM
-"viel Leistung und Billig"


Bitte keine verrückten Overkills mit FPGA's in asm vorschlagen, ich habe 
etwas Erfahrung in Atmegas, msp430 und sehr wenig in raspi, da hört es 
aber schon auf.


Vielen Dank fürs Lesen und eure Antworten.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Der Mega schafft das! Die Frage ist, ob Du es schaffst, ihm das 
vernünftig zu erklären ;-).

zu 4.: Die UART ist sendeseitig gepuffert, Du kannst am Anfang direkt 2 
Byte schreiben. Ist das erste Byte rausgerödelt, bekommst Du einen 
UDR-Empty Interrupt und kannst ein neues Byte schreiben. Dadurch kannst 
Du nahtlos senden. Einen Ringbuffer kannst Du Dir trotzdem bauen, in den 
das Programm dann zyklisch neue Blöcke einträgt. Der muss aber nicht 
größer als 2 volle Blöcke sein. Dein Programm sollte mehrere Schichten 
haben, die untere Interface-Ebene läuft quasi frei neben den oberen 
Organisationsschichten her und nichts kommt sich in's Gehege. Im Punkt 
des Jitters würde ich mir eher Sorgen bei der Bluetooth-Verbindung 
machen.

: Bearbeitet durch User
von avrFanBoy 8-) (Gast)


Lesenswert?

Guten Morgen Knut und Danke für dein Kommentar.

Knut B. schrieb:
> Der Mega schafft das! Die Frage ist, ob Du es schaffst, ihm das
> vernünftig zu erklären ;-).

Ich würde ihm am liebsten alles zeigen, bin jedoch kein Pointer ://..


Gut, 1:0 für den AVR. Brauche erst Bestätigung, dass es hinhaut :)

mit der FIFO prügel ich mich dann herum.

Knut B. schrieb:
> Im Punkt
> des Jitters würde ich mir eher Sorgen bei der Bluetooth-Verbindung
> machen.

warum?

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

avrFanBoy 8-) schrieb:
> warum?

Weil Bluetooth eine paketorientierte Übertragung ist, die auch mit 
Übertragungsfehlern zu kämpfen hat. Wenn Du Störungen hast oder den 
Empfangsbereich langsam verlässt, hast Du Aussetzer in der Übertragung. 
Da Bluetooth recht fehlersicher ist, stoppt der Stream halt einfach, 
Dein Controller rammelt dann noch den Puffer des BT-Modus voll und ab da 
wird's kritisch.

von avrFanBoy 8-) (Gast)


Lesenswert?

Empfangsbereich verlassen sollte ausgeschlossen sein, auf der anderen 
Seite hängt ein Handy. Nun gut.

von M. K. (sylaina)


Lesenswert?

avrFanBoy 8-) schrieb:
> Empfangsbereich verlassen sollte ausgeschlossen sein, auf der anderen
> Seite hängt ein Handy. Nun gut.

Also mein Handy hat keine Endlos-Reichweite mit Bluetooth...was hast du 
denn da für ein Handy?

von Karl M. (Gast)


Lesenswert?

Guten Morgen,

einen RX-TX FIFO-Steuerung für den Hardware-Uart gibt es schon fertig 
von Peter Dannegger (peda). Diese läuft zu 100%.

Es ist eher ein Verständnisproblem, so wie von Knut Ballhause 
ausführlich dargestellt, alle Progammierpfade zu verlassen und evtl. für 
Dich eine neuartige Problemanalyse und Programmierweise zu verwenden.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

avrFanBoy 8-) schrieb:
> F_CPU : 9.216MHz.

Das ist eine unnötige Einschränkung. So ein Mega darf auch mit 20MHz 
getaktet werden, oder, das bietet sich hier an, mit 18,432 MHz. Wimre 
ist das sogar ein Standard Quarz.

von Falk B. (falk)


Lesenswert?

@ avrFanBoy 8-) (Gast)

>1) PinX INPUT schalten, PinY OUTPUT HIGH, 1ms
>   PinX OUTPUT High schalten, PinY INPUT, 25 ms

Langweilig.


>2)  5 x ADC Kanäle abtasten unter Nyquist berücksichtigt:

>    1) Frequenz 4KHz , 8 Bit (Audio, soweit möglich, es interessiert
>nicht
>       die Audiodatei, sondern "nur" der Amplitdenverlauf, also Dynamik
>       nicht wichtig)

Was heißtm 4 kHz? Ist das die obere Grenzfrequenz des SIgnals oder die 
Abtastrate?
Wenn nur der "Amplitudenverlauf" interessiert (du meinst wohl die 
Hüllkurve?), kann man auch einen Hüllkurvendemodulator in Hardware 
davorsetzen, dann kann man mit DEUTLICH weniger Abtastrate arbeiten.

>    2) Frequenz: 50Hz, 10 Bit
>    3) Frequenz: 30 Hz, 8 Bit
>    4) Frequenz: 30 Hz, 8 Bit
>    5) Frequenz: 50 Hz, 8 Bit

Schön, aber auch hier ist die Frage nach der Abtastrate. Wie hoch soll 
sie sein?

Der ADC des AVRs kann bei voller 10ß Bit Auflösung offiziell 15ksmp/s, 
bei 5 Kanälen wären das nur noch 5ksmps/s / Kanal.

>3) 2 x G-Sensor auslesen via SPI, beide mit 50Hz je 3 Achsen. + 2CS Pin
>   steuern ( es wird in einem Schwung alle 3 Achsen ausgelesen! 10Bit =
>   1MSB + 2LSB)

Einfach.

>4) Alle Daten über UART raussenden. + Eventuell zeitstempel.

>   Verfügbare bluetooth kompatible Baudraten:

>   115,2 K und 230,4 K

Auch einfach.

>   F_CPU : 9.216MHz.

Nimm das Doppelte, ist auch eine Baudratenquarz frequenz.

>2) Wie "stellt" man am besten eine Samplingsfrequenz ein?

>von zB. 4K? Timer (ganz klein) verwenden und alle 1/4K [s] den Kanal
>losjagen?

Kann man machen.

>Oder besser gleich im Free Running Mode schauen was man
>erreichen kann?

Geht auch, ist ggf. besser.

>Take komme ich auf eine Samplingrate von: 144KHz/13 = 11KHz. Das alleine
>wäre ja dem ATMEGA noch zumutbar?

Sicher, aber was machst du mit deinen anderen 4 Kanälen?

>Channel 4K : 20 Samples,
>1x ADC1
>Channel 4K : 20 Samples,
>1x Gsensor
>Channel 4K : 20 Samples,
>1xADC2
>Channel 4K : 20 Samples, ....... usw mit einer
>Switch abfrage? gesteuert entweder durch Interrupts oder Timer... ?

so in etwa.

>4) Dafür müsste ich mir ja eine FIFO schreiben.

Siehe FIFO. Dort gibt es eine fertige Lib.

>Netto komme ich ja auf ca. 40kBaud. Angesichts des 2Kbyte Rams, wie und
>wann soll ich die FIFO losjagen?

Da reichen wahrscheinlich 100 Bytes.

>Soll ich in einer Routine mich und den Atmega quälen

Der AVR quält sich keine Sekunde. Ob der mit 20 MHz NOPs macht oder was 
sinnvolles ist dem egal.

> oder meine Zeit
>besser in die Einarbeitung eines neuen µC investieren?

Nicht zwingend.

>-Am besten mehrere ADC's

Das habt so gut wie kein uC, die haben alle nur einen + Multiplexer. Der 
PICCOLO hat auch nur einen, aber 2 Sample&Hold Stufen.

Die Aufgabe ist mit einem AVR lösbar, wenn man weiß was man tut. Ich hab 
mal einen DMX-Rekorder programmiert, dort wurden 22kB/s von SD-Karte 
gelesen/schreiben und per UART empfangen/gesendet. Die mittlere CPU-Last 
lag bei ~30% @16MHz.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

avrFanBoy 8-) schrieb:
> Switch abfrage? gesteuert entweder durch Interrupts oder Timer... ?

 Wenn du 4KHz Samplingfrequenz nimmst, ergibt das 250us oder 2315 Takte
 zwischen zwei Messungen. Eine ISR braucht mindestens 11 Takte ohne
 überhaupt etwas zu machen. Mit ADC Registern lesen, Pointer erhöhen,
 Variablen vergleichen, evtl. ADC umschalten und Flags setzen macht
 der Compiler höchstens 250-500 Takte daraus.
 Das sind etwa 11-20% der Prozessorzeit fur Timer-ISR.
 Selbst wenn du aus der Timer-ISR auch deine Bytes rausjagst, gibt
 das nicht mehr als 100-200 Takte dazu.
 Die anderen Werte gehen höchstens mit 50Hz - uninteressant in diesem
 Zusammenhang.
 Genau 4KHz wird wohl nicht gehen, aber 4.019KHz schon, das ist ein
 Fehler von weniger als 0.5% .

 Für main() bleibt nur G-Sensor (bei entsprechend gesetztem Flag),
 diese Werte werden ins TxBuffer[80+G-Sensor] reingeschrieben, Flag
 zurückgesetzt und dann wieder Round-robin.

 Es sind also 80 Bytes für Audio + 8Byt andere Daten alle 20ms fällig.
 Mit Zeitstempel, FrameNr und CRC sind es etwa 94 Bytes = 8.16ms für
 Senden bei 115200B.

 Bleiben 20-8.16 = 11.84ms übrig, da kann die andere Seite sogar den
 Empfang bestätigen.

> 1) PinX INPUT schalten, PinY OUTPUT HIGH, 1ms
>    PinX OUTPUT High schalten, PinY INPUT, 25 ms

 Was ist das genau ?
 So etwas kann leicht schiefgehen, Pullup wäre besser.

: Bearbeitet durch User
von Ingo L. (corrtexx)


Lesenswert?

Falk B. schrieb:
> er ADC des AVRs kann bei voller 10ß Bit Auflösung offiziell 15ksmp/s,
> bei 5 Kanälen wären das nur noch 5ksmps/s / Kanal.
Du meinst sicher 3ksmps/s / Kanal oder?

von Falk B. (falk)


Lesenswert?

Ja, Kopfrechnen war wohl ausgeschaltet ;-)

von Jan H. (jan_m_h)


Lesenswert?

Falk B. schrieb:
> Ja, Kopfrechnen war wohl ausgeschaltet ;-)

War da nicht noch was, dass die ersten paar Messwerte nach dem 
Umschalten des Multiplexers kaum zu gebrauchen waren?

von avrFanBoy 8-) (Gast)


Lesenswert?

M. K. schrieb:
> Also mein Handy hat keine Endlos-Reichweite mit Bluetooth...was hast du
> denn da für ein Handy?

Ein Android hängt da, und BLE Adapter HC06, klasse 2? Jedenfalls ist die 
Reichweite ausreichend, Distanz <5m und ändert sich nicht.

Karl M. schrieb:
> einen RX-TX FIFO-Steuerung für den Hardware-Uart gibt es schon fertig
> von Peter Dannegger (peda). Diese läuft zu 100%.
>
> Es ist eher ein Verständnisproblem, so wie von Knut Ballhause
> ausführlich dargestellt, alle Progammierpfade zu verlassen und evtl. für
> Dich eine neuartige Problemanalyse und Programmierweise zu verwenden.

Hi Karl, hab ich schon gesehen. Vielen Dank!

Matthias S. schrieb:
> Das ist eine unnötige Einschränkung. So ein Mega darf auch mit 20MHz
> getaktet werden, oder, das bietet sich hier an, mit 18,432 MHz. Wimre
> ist das sogar ein Standard Quarz.

Hallo Matthias, mhh ich beziehe mich dabei auf meine Betriebsspannung 
Vcc = 3.3V als limitierenden Faktor.


Hi Falk und danke für deine ausführliche Antwort.

Falk B. schrieb:
> Was heißtm 4 kHz? Ist das die obere Grenzfrequenz des SIgnals oder die
> Abtastrate?

Abtastrate.

Falk B. schrieb:
> Wenn nur der "Amplitudenverlauf" interessiert (du meinst wohl die
> Hüllkurve?), kann man auch einen Hüllkurvendemodulator in Hardware
> davorsetzen, dann kann man mit DEUTLICH weniger Abtastrate arbeiten.

Muss ich mal anschauen. Merci

Falk B. schrieb:
> Schön, aber auch hier ist die Frage nach der Abtastrate. Wie hoch soll
> sie sein?

Das was dasteht, ist meine Abtastrate.

Falk B. schrieb:
>>von zB. 4K? Timer (ganz klein) verwenden und alle 1/4K [s] den Kanal
>>losjagen?
>
> Kann man machen.
>
>>Oder besser gleich im Free Running Mode schauen was man
>>erreichen kann?
>
> Geht auch, ist ggf. besser.

Denke ich auch. Entweder die Frequenz wird erreicht oder sowieso nicht, 
Oversampling tut ja nicht weh.

Kurze Frage, ja kann ich sicher im Datenblatt nachlesen, aber wenn ich 
meinen ADC Wert lese obwohl die Konvertierung nicht abgeschlossen ist, 
lese bis dahin das Konvertierte? Also wird der Wert ständig upgedatet?

Falk B. schrieb:
> Die Aufgabe ist mit einem AVR lösbar, wenn man weiß was man tut.

Allright! ich werde mein Konzept dann mal vorstellen...

von avrFanBoy 8-) (Gast)


Lesenswert?

@ Marc deine Antwort muss ich mir jetzt erst mal ausführlich durchlesen.

Jan H. schrieb:
> War da nicht noch was, dass die ersten paar Messwerte nach dem
> Umschalten des Multiplexers kaum zu gebrauchen waren

Lese ich oft in Foren, jedoch nichts im Datenblatt.

Der erste gelesene Wert ist unbrauchbar, wenn die Referenzspannung 
geändert wurde, nach dem Einschalten des ADC braucht die erste Wandlung 
25 Takte. Sonst habe ich nichts gelesen?

von MaWin (Gast)


Lesenswert?

avrFanBoy 8-) schrieb:
> es wird in einem Schwung alle 3 Achsen ausgelesen!

Nun ja, ein ATmega kann nicht simultan sampeln, da brauchst du einen 
externen ADC für.

Alles andere ist Kinderkram, da offenbar die Messwerte nicht komplex 
umgerechnet werden müssen.

von avrFanBoy 8-) (Gast)


Lesenswert?

MaWin schrieb:
> avrFanBoy 8-) schrieb:
>> es wird in einem Schwung alle 3 Achsen ausgelesen!
>
> Nun ja, ein ATmega kann nicht simultan sampeln, da brauchst du einen
> externen ADC für.
>
> Alles andere ist Kinderkram, da offenbar die Messwerte nicht komplex
> umgerechnet werden müssen.

Hallo MaWin,

Digitaler Sensor, via SPI!

Dabei kann CS durchgehen HIGH bleiben. Danke für dein Kommentar.

von avrFanBoy 8-) (Gast)


Lesenswert?

@Marc bevor ich mich von deinem Kommentar beeinflussen lasse, möchte ich 
eben schreiben wie ich es mir dachte. Danach wird er studiert :)

Also die ADC-Wandlung über Timer zu starten ist quatsch, und exakt 
treffe ich die Zeiten ja eh nicht. Dann wohl im Free-Running-Mode und 
über Interrupts und schauen wie hoch ich komme, Oversampling tut ja 
nicht weh.


>    1) Frequenz: 4KHz,  8 Bit <<--- das muss alles nicht exakt sein,
                                     Größenordnung ist wichtig
>    2) Frequenz: 50Hz,  10 Bit
>    3) Frequenz: 30 Hz, 8 Bit
>    4) Frequenz: 30 Hz, 8 Bit
>    5) Frequenz: 50 Hz, 8 Bit

     6&7)2x Sensor a 50 Hz = 100Hz

______________________________________________________________________ 
__

4000/260 = 15.

Daraus resultiert für einen Durchlauf:

uart_puts("|hh:mm:ss|15*1|1*2|15*1|1*3|15*1|1*4|15*1|1*5|15*1|1*6|15*1|1 
*7|                      \r\n");


|hh:mm:ss|stellt den Zeitstempel dar mit Auflösung 1/8s

|15*1| 15 Samples des Kanals 1 hintereinander.. usw

Durch die Zeitstempel könnte ich die tatstächliche Frequenz ca. 
bestimmen und dann mit Logicanalyzer kontrollieren. Der Zeitstempel 
dient aber eher der Auswertung und Markierung eines "Paketes"

Wie lange eine Wandlung dauert kann ich ja theoretisch berechnen.

Die Kanäle würde ich dann wohl über mehrere Variablen steuern, die 
abhängig von den ADC-Interrupts inkrementieren.

Danach wird der aktuelle Zeitstempel abgefragt (oder eben davor).

Dann hätte ich insgesamt Bytes:

6*15*8 = 720
1*10 =    10
5*8 =     40
____________

790 Byte. Ist meine Rechnung sinnvoll/korrekt?

+ die Reservierung der Zeichenkette Puffer Zeitstempel etc.. würde das 
hinhauen?

Das Leeren der FIFO  würde dann bei einer Baudrate von 230.4k

|hh:mm:ss| = 10 Zeichen?

1 Wert = 8 Bit = max 255 = 3 Zeichen? * ca 100 ( die 10 bit außer acht)

300/230.4K = xy [s] dauern?

Sind meine Gedanken halbwegs sinnvoll?


So jetzt an dein Kommentar ran, Marc :)

von avrFanBoy 8-) (Gast)


Lesenswert?

Aber da Ihr ja alle der selben Meinung seid:Machbar!, hat sich meine 
eigentliche Frage erledigt, danke dafür :) !!

von Falk B. (falk)


Lesenswert?

@  avrFanBoy 8-) (Gast)

>> War da nicht noch was, dass die ersten paar Messwerte nach dem
>> Umschalten des Multiplexers kaum zu gebrauchen waren

>Lese ich oft in Foren, jedoch nichts im Datenblatt.

>Der erste gelesene Wert ist unbrauchbar, wenn die Referenzspannung
>geändert wurde, nach dem Einschalten des ADC braucht die erste Wandlung
>25 Takte. Sonst habe ich nichts gelesen?

Stimmt. Danach kann man den MULTIPLEXER beliebig oft umschalten, die 
Werte stimmen immer.

Am Ende läuft es ja auf einen Abtastung mit 4kHz und weniger hinaus, da 
macht man mit einem einfachen 4 kHz Interrupt. Dort erfolgen dann 1-2 
Messungen. Wer sparsamer und eleganter arbeiten will nimmt einen 8 kHz 
Timer-Interrupt und packt dort das ADC-Multiplexing elegant rein. Damit 
wird kein einziger Wartetakt für die CPU erzeugt.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

avrFanBoy 8-) schrieb:
> Sind meine Gedanken halbwegs sinnvoll?
>
> So jetzt an dein Kommentar ran, Marc :)

 Ich glaube du kriegst das hin auch ohne meine Kommentare ;)

 Deine Berechnungen habe ich nicht überprüft, glaube schon, dass da
 alles stimmt, hier nur kurz mein Gedankengang:

 Timer2 läuft mit Prescaler=64 / OCR2A=36 (-1 natürlich) und feuert
 alle 248.785us. Kann auch Timer0 sein.
 4Khz = 250us    // Haut ungefähr hin
 50Hz = 20000us
 20000 / 250 = 80     // Also, 80 mal ADC auf Audio

 ADC in Free-Running-Mode, alle ADC-Channels ausser Audio mit 50Hz
 samplen - (du sagtest ja, dass oversampling nicht weh tut) ;)
1
 
2
 In der ISR zuerst ADC-Wert auslesen,
3
  in TxBuffer[SampleNr++] reinschreiben.
4
 
5
 Wenn (SampleNr < 60) && (SampleNr > 10) && (TxPtr < PktSize)
6
   Wenn (UDRE0==1) || (TXC0==1)     // hab vergessen was ich normal checke
7
       TxBuffer(TxPtr++] rausschicken. 
8
       Kurze Pause
9
       Wenn (UDRE0==1) || (TXC0==1)
10
            TxBuffer(TxPtr++] rausschicken. 
11
12
 Wenn SampleNr == 60
13
   ADC-Channel entspr. umschalten, kurz warten
14
   und 10bit Wert in TxBuffer[80] reinschreiben.
15
   ADC zuruckschalten.
16
 Wenn SampleNr == 61
17
   ADC-Channel entspr. umschalten, kurz warten
18
   und 8bit Wert in TxBuffer[80+2] reinschreiben.
19
   ADC zuruckschalten.
20
 Wenn SampleNr == 62
21
   ADC-Channel entspr. umschalten, kurz warten
22
   und 8bit Wert in TxBuffer[80+3] reinschreiben.
23
   ADC zuruckschalten.
24
 Wenn SampleNr == 63
25
   ADC-Channel entspr. umschalten, kurz warten
26
   und 8bit Wert in TxBuffer[80+4] reinschreiben.
27
   ADC zuruckschalten.
28
29
 Wenn SampleNr == 65
30
   // main soll Werte fur G-Sensor holen und reinschreiben
31
   Flag fur G-Sensor setzen.
32
 
33
 Wenn (SampleNr > 70) && (G-SensorFlag == 0) && (TS-Flag == 0)
34
   // main hat Werte fur G-Sensor reingeschrieben
35
   TimeStamp in TxBuffer reinschreiben
36
   TS-Flag = 1
37
 
38
 Wenn SampleNr == 80
39
   SampleNr = 0
40
   TxPtr = 0
41
   TS-Flag = 0
 Das wird einmal alle 20ms rausgeschickt.

 Aber meine Frage steht immer noch:

Marc V. schrieb:
>> 1) PinX INPUT schalten, PinY OUTPUT HIGH, 1ms
>>    PinX OUTPUT High schalten, PinY INPUT, 25 ms
>
>  Was ist das genau ?

: Bearbeitet durch User
von avrFanBoy 8-) (Gast)


Lesenswert?

Danke Mark für deine Beteiligung :) und allen hier!

Auf deine Kommentare werde ich noch antworten wenn ich mal alles 
durchdacht habe!

Marc V. schrieb:
> Marc V. schrieb:
>>> 1) PinX INPUT schalten, PinY OUTPUT HIGH, 1ms
>>>    PinX OUTPUT High schalten, PinY INPUT, 25 ms
>>
>>  Was ist das genau ?

Das sollte zur Erzeugung einer wechselnden Referenzspannung am 
nichtinvertierenden Eingang des OP's dienen, an den zwei Pins hängt ein 
belasteter Spannungsteiler.


X                  Y
I                  I
I                  I
R1                 R2
I                  I
--------------------------------------Input
        I
        I
        I
        R3
        I
       GND


So, wird aber anders gemacht nur durch Output low und high schalten, 
dient mir zu asynchronen Stromwechsel.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

avrFanBoy 8-) schrieb:
> Auf deine Kommentare werde ich noch antworten wenn ich mal alles
> durchdacht habe!

 Habs gerade gesehen, die ersten Samples werden vor der Ausgabe mit
 neuen Werten überschrieben, die oberste Abfrage muss auf jeden Fall
 geändert werden.
 Und vielleicht die anderen ADC-Werte ab SampleNr 40 reinschreiben,
 G-Sensor ab SampleNr 45, TimeStamp ab SampleNr 55 und ab SampleNr 61
 mit der Ausgabe beginnen. Sollte sich bei SampleNr 80 genau überdecken.

: Bearbeitet durch User
von avrFanBoy 8-) (Gast)


Lesenswert?

Marc V. schrieb:
> Habs gerade gesehen, die ersten Samples werden vor der Ausgabe mit
>  neuen Werten überschrieben, die oberste Abfrage muss auf jeden Fall
>  geändert werden.
>  Und vielleicht die anderen ADC-Werte ab SampleNr 40 reinschreiben,
>  G-Sensor ab SampleNr 45, TimeStamp ab SampleNr 55 und ab SampleNr 61
>  mit der Ausgabe beginnen. Sollte sich bei SampleNr 80 genau überdecken.

Nochmals Danke.

Ich habe gerade noch die Handy-App-Baustelle zu erledigen, danach ist 
der µC dran. Ich melde mich dann!

von avrFanBoy 8-) (Gast)


Lesenswert?

Marc V. schrieb:
> Timer2 läuft mit Prescaler=64 / OCR2A=36 (-1 natürlich) und feuert
>  alle 248.785us

Warum eigentlich? Ist das dann ein Takt abgezogen um in nächsten Takt 
dann die Anforderung zu erfüllen?

Meine (<<Student) Anforderungen wurden soeben erhöht.


8ksps für Audio, 30-50 ksp der rest, alles in 8 bit.

Sollte ja trotzdem machbar sein auch innerhalb der 50-200 KHz von ADC.

Habe noch diesen Input bekommen : Im Handbuch steht die Empfehlung, man 
möge dann zweimal abtasten und den ersten Wert verwerfen. Das muss aber 
dann doch nicht sein. Aber man sollte zwischen MUX-umschalten und 
Sampeln dann doch ein paar Takte was anderes machen.

Weiß jemand genaueres, ich kann nichts davon im Datenblatt finden.

Die SPI Schnittstelle wird dann untergebracht während die ADC 
Conversation erfolgt. Also kann man sich die theoretisch wegdenken.

Das Handy tut dann alle ankommenden Werte sortieren und "Sauber" 
speichern. Zeitstempel wird nicht erforderlich sein :)

von Falk B. (falk)


Lesenswert?

@  avrFanBoy 8-) (Gast)

>> Timer2 läuft mit Prescaler=64 / OCR2A=36 (-1 natürlich) und feuert
>>  alle 248.785us

>Warum eigentlich? Ist das dann ein Takt abgezogen um in nächsten Takt
>dann die Anforderung zu erfüllen?

Weil der Timer immer OCR2A+1 Takt als Periodendauer hat.

>8ksps für Audio, 30-50 ksp der rest, alles in 8 bit.

Ist da ein k zuviel? "30-50 ksp der rest" schafft der AVR definitiv 
nicht.

>Sollte ja trotzdem machbar sein auch innerhalb der 50-200 KHz von ADC.

Ja, wenn das 30-50 smps sind.

>Habe noch diesen Input bekommen : Im Handbuch steht die Empfehlung, man
>möge dann zweimal abtasten und den ersten Wert verwerfen.

Nein, das hast du faslch verstanden.

> Das muss aber
>dann doch nicht sein. Aber man sollte zwischen MUX-umschalten und
>Sampeln dann doch ein paar Takte was anderes machen.

Auch falsch. Nu die allererste Messung nach dem EInschalten des ADC ist 
Murks, dann kann man ganz normal den ADC-MUX umschalten und messen.

>Die SPI Schnittstelle wird dann untergebracht während die ADC
>Conversation erfolgt. Also kann man sich die theoretisch wegdenken.

So ungefähr.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

avrFanBoy 8-) schrieb:
> Marc V. schrieb:
>> Timer2 läuft mit Prescaler=64 / OCR2A=36 (-1 natürlich) und feuert
>>  alle 248.785us
>
> Warum eigentlich? Ist das dann ein Takt abgezogen um in nächsten Takt
> dann die Anforderung zu erfüllen?

 Weil der Flag für Interrupt erst beim nächsten Takt gesetzt wird.
 Nicht der CPU-Takt ist gemeint, sondern der Timertakt und deswegen
 muss man vom errechneten Wert 1 abziehen.

> 8ksps für Audio, 30-50 ksp der rest, alles in 8 bit.
 Um 50kSPS auf 4 Kanälen zu erreichen, muss M328P mindestens 200kSPS
 mit umschalten schaffen und das kann er nicht.

> Sollte ja trotzdem machbar sein auch innerhalb der 50-200 KHz von ADC.
 Wie kommst du auf 200KHz ?
 200KHz ist die Input Frequenz für ADC, nicht die ADC-Geschwindigkeit.
 Diese 200KHz werden dann mit nötigen ADC-Taktzyklen (13) geteilt,
 ergibt 15,384kSPS für maximale Auflösung (10 bit).
 Bei 8-bit kann man den Timerclock erhöhen, aber im DaBla steht, dass
 die max. Geschwindigkeit 76,9kSPS ist, ich würde mich tunlicht
 daran halten.

avrFanBoy 8-) schrieb:
> dann doch nicht sein. Aber man sollte zwischen MUX-umschalten und
> Sampeln dann doch ein paar Takte was anderes machen.
 Nicht paar Takte, sondern eine genau bestimmte Zeit.
 Selbst nach dem Umschalten wird zuerst die aktuelle Umwandlung
 abgearbeitet und erst dann die neue Messung gestartet. Bis zum Ende
 der neuen Messung gilt der Wert für vorigen Kanal.
 Und das kann im ungünstigstem Fall 13+13 = 26 ADC-Takte sein.
 Bei 8-bit Auflösung und CPU-Takt = 9.216MHz / 8 (max. ADC-Takt, um noch
 einigermassen (un)brauchbare Ergebnise zu kriegen), ergibt das 0.868us
 pro ADC-Takt.
 0.868us * 26 ADC-Takte = 22.57us ergibt max. 44kSPS und das auch
 noch sehr ungenau.

 Wenn das mit 30-50ksp kein Schreibfehler war, kannst es ruhig
 vergessen.

: Bearbeitet durch User
von avrFanBoy 8-) (Gast)


Lesenswert?

Hallo Falk,

Falk B. schrieb:
> Weil der Timer immer OCR2A+1 Takt als Periodendauer hat.

Merci, nochmal Datenblatt studieren.

Falk B. schrieb:
> Ist da ein k zuviel? "30-50 ksp der rest" schafft der AVR definitiv
> nicht.

richtig, der Schlafmangel war Schuld, ein k zu viel :)

Falk B. schrieb:
> Nein, das hast du faslch verstanden.

Hatte ich wohl richtig verstanden, darum nochmal die Frage.
Den Input hatte ich von einen Professor. Die kleine S&H Pause ist ja 
schon bei Marc vorgesehen.

Falk B. schrieb:
> So ungefähr.

Merci!





Hallo Marc,

Marc V. schrieb:
> Weil der Flag für Interrupt erst beim nächsten Takt gesetzt wird.
>  Nicht der CPU-Takt ist gemeint, sondern der Timertakt und deswegen
>  muss man vom errechneten Wert 1 abziehen.

ok. Danke.

Marc V. schrieb:
> Wie kommst du auf 200KHz ?
>  200KHz ist die Input Frequenz für ADC, nicht die ADC-Geschwindigkeit.
>  Diese 200KHz werden dann mit nötigen ADC-Taktzyklen (13) geteilt,
>  ergibt 15,384kSPS für maximale Auflösung (10 bit).
>  Bei 8-bit kann man den Timerclock erhöhen, aber im DaBla steht, dass
>  die max. Geschwindigkeit 76,9kSPS ist, ich würde mich tunlicht
>  daran halten.


Meinte ich auch. Die Frage ist nur ob ich über die 200Khz gehen sollte, 
da 8 bit, aber eigentlich sollte es auch in diesem Rahmen noch reichen.
Ahh ok 76KSps also dann.

Marc V. schrieb:
>> dann doch nicht sein. Aber man sollte zwischen MUX-umschalten und
>> Sampeln dann doch ein paar Takte was anderes machen.
>  Nicht paar Takte, sondern eine genau bestimmte Zeit.
>  Selbst nach dem Umschalten wird zuerst die aktuelle Umwandlung
>  abgearbeitet und erst dann die neue Messung gestartet. Bis zum Ende
>  der neuen Messung gilt der Wert für vorigen Kanal.

Richtig, waren auch meine Gedanken! Wie gesagt der Input stammt nicht 
von mir.

>  Und das kann im ungünstigstem Fall 13+13 = 26 ADC-Takte sein.
>  Bei 8-bit Auflösung und CPU-Takt = 9.216MHz / 8 (max. ADC-Takt, um noch
>  einigermassen (un)brauchbare Ergebnise zu kriegen), ergibt das 0.868us
>  pro ADC-Takt.
>  0.868us * 26 ADC-Takte = 22.57us ergibt max. 44kSPS und das auch
>  noch sehr ungenau

Da gilt aber auch lieber Samples als Auflösung.


Vielen, vielen Dank euch :)

von avrFanBoy 8-) (Gast)


Lesenswert?

Der Atmega328 scheitert bei mir am Punkt 4 :( ->Uart

Vom Timing her gebe ich euch Recht, ist machbar.

Habe 44Khz ADC_Frequenz gewählt, der ADC wurde autogetriggert 
(CTC-Modus,Timer0) mit 10Khz und der gleiche Timer dazu genutzt die 
ADC_Channel zu verwalten.

Audio alleine, kein Problem.


Eine Fifo hilft m.M.n. nicht aus, da einerseits sehr begrenzter 
Speicher, aber mehr noch, er auch ohne FIFO mit dem senden nicht 
hinterherkommt.

Wie gesagt bei Audio alleine, ist es kein Problem. Aber wenn man 
ADCaudio von ADCnichtaudio unterscheiden möchte, ist es vorbei, da kein 
Zeichen mehr gesendet werden kann.


Kurze Rechnung:

Baud= 230400

HexFormat= 2x 8 Bit= 16 Symbole


Baud/HexFormat = 14400 mögliche ADC Werte in der Sekunde.

Möchte ich die einzelnen Werte trennen sind es nur noch die Hälfte

= 7200

Möchte ich auch noch unterscheiden zwischen Nichtaudio und AUdioSample 
nicht unterbrechen, sind zusätzlich 3 weitere Bytes einzuplanen:

Audio(2Byte)|Trennwand(1Byte)|Nichtaudio(2Byte)|Trennwand(1Byte)

Das Feld für Nichtaudio ist nicht immer gefüllt.

Bei 6 bytes und der Baud, geht maximal eine Frequenz auf von 4k8sps auf.

(gut ich hatte anfangs auch nach 4ksps gefragt :) vielleicht bleibt es 
dann dabei.)


Außer Ihr kennt noch Tricks, wie man die Werte ohne Zeichen trennen 
kann?

Das Handy kann alles ja aufwändig sortieren..


Ansonsten schiele ich eventuell auch Richtung STFM32..., ist aber wohl 
nichts für Anfänger.


Danke!

von avrFanBoy 8-) (Gast)


Lesenswert?

Vlt nehme ich auch einen zweiten, der erste gibt dem zweiten ein HIGH 
Signal wenn es losgeht und der zweite legt gemütlich die Audio-Werte auf 
eine SD-Karte?

von avrFanBoy 8-) (Gast)


Angehängte Dateien:

Lesenswert?

Um mein Problem zu visualisieren.

Hier getriggert mit 9k6 (WAV-Format?)

dazwischen eine Trennung mit Symbol: |

Vom ADC-Wert ist immer einstellig, weil die Spannung da grad klein ist.

Sobald 2-Stellig, geht ja bis FF, haut es nicht mehr hin.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

avrFanBoy 8-) schrieb:
> Baud= 230400
> HexFormat= 2x 8 Bit= 16 Symbole
> Baud/HexFormat = 14400 mögliche ADC Werte in der Sekunde.

 Nein.
 Du sendest Startbit + 8bit + Stopbit  = 10bit oder 20bit fur 2 Byt.
 Ergibt 11520 Werte/s


> Möchte ich die einzelnen Werte trennen sind es nur noch die Hälfte
> = 7200
  Es sind immer noch 5760 + 5760 Werte.


> Möchte ich auch noch unterscheiden zwischen Nichtaudio und AUdioSample
> nicht unterbrechen, sind zusätzlich 3 weitere Bytes einzuplanen:
> Audio(2Byte)|Trennwand(1Byte)|Nichtaudio(2Byte)|Trennwand(1Byte)

 Warum ?
 2Byt Audio + 2 Byt Nichtaudio braucht man doch nicht trennen.

 EDIT:
 Es sei denn, du willst da eine Art Synchronisation haben, aber
 gerade deswegen schickt man Daten in Blocks mit SOF und EOF.

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

@  avrFanBoy 8-) (Gast)

>Habe 44Khz ADC_Frequenz gewählt,

Hmm, das wären dann max. 3,3kHz Abtsstrate.

>der ADC wurde autogetriggert
>(CTC-Modus,Timer0) mit 10Khz und der gleiche Timer dazu genutzt die
>ADC_Channel zu verwalten.

Also 10 kHz Abtastrate?

>Eine Fifo hilft m.M.n. nicht aus, da einerseits sehr begrenzter
>Speicher, aber mehr noch, er auch ohne FIFO mit dem senden nicht
>hinterherkommt.

Hmm.

>Wie gesagt bei Audio alleine, ist es kein Problem. Aber wenn man
>ADCaudio von ADCnichtaudio unterscheiden möchte, ist es vorbei, da kein
>Zeichen mehr gesendet werden kann.

Glaub ich nicht.

>Kurze Rechnung:

>Baud= 230400

= 23040 Byte/s

>HexFormat= 2x 8 Bit= 16 Symbole

>>Baud/HexFormat = 14400 mögliche ADC Werte in der Sekunde.

Nein, es sind nur 11.520

>Möchte ich die einzelnen Werte trennen sind es nur noch die Hälfte

>= 7200

Unsinn.

>Möchte ich auch noch unterscheiden zwischen Nichtaudio und AUdioSample
>nicht unterbrechen, sind zusätzlich 3 weitere Bytes einzuplanen:

Quark. Du wilslt doch nicht mehr Trennzeichen senden als Daten!!

>Audio(2Byte)|Trennwand(1Byte)|Nichtaudio(2Byte)|Trennwand(1Byte)

Trennwände gibt es auf den Scheißhaus, nicht in Datenpaketen!

>Außer Ihr kennt noch Tricks, wie man die Werte ohne Zeichen trennen
>kann?

Man definiert ein sinnvolles Datenpaket.

Bei 10 kHz Abtastrate willst du 5 kHz für die Audiodaten haben. Die 
andere Hälfte der 10 KHz (jedes 2. Sample) ist abwechslend für die 
niederfrequenten Datenkanäle gedacht. Sagen wir der Einfachheit halber 
50 smpl/s für alle anderen Kanäle.

D.h. Dein Datenpaket hat

Startzeichen, 1 Byte
100 Audiodaten, 200 Bytes
4x Low Speed Daten, 8 Bytes  ( d. h. bei jedem 25. 2. Sample werden die 
Low Speed Daten gemessen)

Macht in Summe 209 Bytes

Das Ganze mit einer Frequenz von 50 Hz gesendet, macht 10450 Byte/s
Da reicht sogar 115k2 als Baudrate.

Das Ganze kann man auch auf 5 kleinere Datenpakete aufteilen, wie du 
selbser schon vorgeschalgen hast, dann wird das mit dem Multiplexing des 
Datenstroms etwas einfacher. Ist aber eher nebensächlich.

Man kann auch noch etwas optimieren, denn du hast keine 16 Bit 
ADC-Werte, bestenfalls 10 Bit. Da kann man drei Meßwerte in 4 Byte 
packen, damit spart man 2 Bytes (30%). Oder man beschränkt sich gleich 
auf 8 Bit Audiodaten.

von avrFanBoy 8-) (Gast)


Lesenswert?

Hallo Marc,

Marc V. schrieb:
> Nein.
>  Du sendest Startbit + 8bit + Stopbit  = 10bit oder 20bit fur 2 Byt.
>  Ergibt 11520 Werte/s


richtig, habe ich nicht berücksichtigt.

Marc V. schrieb:
> Es sind immer noch 5760 + 5760 Werte.

ja, aber nur noch die Hälfte steht praktisch Audio zu.

Marc V. schrieb:
> 2Byt Audio + 2 Byt Nichtaudio braucht man doch nicht trennen.

wenn ich jetzt erhalte 111

ist dann Audio: 11
nichtAudio: 1 oder andersrum?

Marc V. schrieb:
> EDIT:
>  Es sei denn, du willst da eine Art Synchronisation haben, aber
>  gerade deswegen schickt man Daten in Blocks mit SOF und EOF.

Ja synchron muss es sein. Muss ich mich mal damit auseinandersetzen. 
Danke

von avrFanBoy 8-) (Gast)


Lesenswert?

Hallo Falk,

Falk B. schrieb:
>>Habe 44Khz ADC_Frequenz gewählt,
>
> Hmm, das wären dann max. 3,3kHz Abtsstrate.

Ne, das war schon dividiert :)

Falk B. schrieb:
> Also 10 kHz Abtastrate?

genau.

Falk B. schrieb:
> Quark. Du wilslt doch nicht mehr Trennzeichen senden als Daten!!

eigentlich nicht, nein.


Zum Rest, muss ich erst mal nachdenken. Danke :)

von avrFanBoy 8-) (Gast)


Lesenswert?

Falk B. schrieb:
> Bei 10 kHz Abtastrate willst du 5 kHz für die Audiodaten haben. Die
> andere Hälfte der 10 KHz (jedes 2. Sample) ist abwechslend für die
> niederfrequenten Datenkanäle gedacht. Sagen wir der Einfachheit halber
> 50 smpl/s für alle anderen Kanäle.

Die 10Khz, genauer 9k6 sollten alleine dem Audio gelten.

Die anderen ADC's sollen zwischen drinn konvertiert werden, so ist meine 
Aufgabenstellung. D.h. 9k6Khz für Audio ohne Unterbrechung.

Falk B. schrieb:
> Startzeichen, 1 Byte
> 100 Audiodaten, 200 Bytes
> 4x Low Speed Daten, 8 Bytes  ( d. h. bei jedem 25. 2. Sample werden die
> Low Speed Daten gemessen)

So war mein vorhaben. Aber es darf kein Audio-Wert ausgelassen werden.

D.h. der andere ADC-Wert muss innerhalb diese 9k6Hz gelesen (und 
gesendet)werden.

Falk B. schrieb:
> Man kann auch noch etwas optimieren, denn du hast keine 16 Bit
> ADC-Werte, bestenfalls 10 Bit. Da kann man drei Meßwerte in 4 Byte
> packen, damit spart man 2 Bytes (30%). Oder man beschränkt sich gleich
> auf 8 Bit Audiodaten.

mit 16 Bit meine ich die 2 Zeichen die für meine 8BitADC in Hex-Format 
geschickt werden. Pro zeichen 1 Byte.

Falk B. schrieb:
> Das Ganze kann man auch auf 5 kleinere Datenpakete aufteilen

ergibt sich dann aus dem Rest, dass Uart-Peripherie nicht 
hinterherkommt.?

von Falk B. (falk)


Lesenswert?

@  avrFanBoy 8-) (Gast)

>>>Habe 44Khz ADC_Frequenz gewählt,
>>
>> Hmm, das wären dann max. 3,3kHz Abtsstrate.

>Ne, das war schon dividiert :)

Das wären dann 44*13=572 kHz ADC-Takt. Hmm. Für 10 KHz Abtastrate 
braucht man das nicht. Da reichen etwas mehr als 130 kHz. Nimm einen CPU 
Takt von 18,xyz MHz (Baudratenquarz) und einen Prescaler von 64 für den 
ADC, da kommst du auf ca. 280 kHZ ADC-Takt. Das reicht. Damit hast du 
auch weniger Rauschen und Störungen in der Messung.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

avrFanBoy 8-) schrieb:
> Marc V. schrieb:
>> Es sind immer noch 5760 + 5760 Werte.
>
> ja, aber nur noch die Hälfte steht praktisch Audio zu.
 Nein.
 5760 Werte (16bit) fur Audio, 5760 Werte(16bit) Nichtaudio.


> Marc V. schrieb:
>> 2Byt Audio + 2 Byt Nichtaudio braucht man doch nicht trennen.
>
> wenn ich jetzt erhalte 111
>
> ist dann Audio: 11
> nichtAudio: 1 oder andersrum?

 111 kannst du gar nicht erhalten, vllt. 0111 oder 1110.

 Sowohl Falk als auch ich reden die ganze Zeit von Datenpaketen,
 du willst es aber unbedingt Byteweise senden.
 Warum ?

von avrFanBoy 8-) (Gast)


Lesenswert?

Falk B. schrieb:
> Das wären dann 44*13=572 kHz

genau.

Falk B. schrieb:
> Für 10 KHz Abtastrate
> braucht man das nicht.

aber insgesamt habe ich ja mehr als 10Khz, nicht viel.. aber das Spiel 
mit der ADC-Frequenz ist ja eine andere Baustelle :)

Falk B. schrieb:
> Nimm einen CPU
> Takt von 18,xyz MHz (Baudratenquarz)

geht nicht. 3V3 Vcc. Wurde mir so aufgesetzt.

von Falk B. (falk)


Lesenswert?

@ avrFanBoy 8-) (Gast)

>> Bei 10 kHz Abtastrate willst du 5 kHz für die Audiodaten haben. Die
>> andere Hälfte der 10 KHz (jedes 2. Sample) ist abwechslend für die
>> niederfrequenten Datenkanäle gedacht. Sagen wir der Einfachheit halber
>> 50 smpl/s für alle anderen Kanäle.

>Die 10Khz, genauer 9k6 sollten alleine dem Audio gelten.

Das geht so aber nicht. Denn die Abtastung sollte schon zeitlich 
gleichmäßig erfolgen. Man kann nicht 96 Samples für Audio nehmen und die 
letzten 4 für andere Sachen. Man kann da nur GANZZAHLIGE Teiler nutzen.

>Die anderen ADC's sollen zwischen drinn konvertiert werden, so ist meine
>Aufgabenstellung. D.h. 9k6Khz für Audio ohne Unterbrechung.

Denk mal drüber nach. So geht das nicht. Bzw. nicht direkt mit dem ADC. 
Wenn die andern Sachen nur die Sensoren sind und nicht mit dem ADC 
gemessen werden, DANN geht es!


>D.h. der andere ADC-Wert muss innerhalb diese 9k6Hz gelesen (und
>gesendet)werden.

Geht nicht. Siehe oben.

>mit 16 Bit meine ich die 2 Zeichen die für meine 8BitADC in Hex-Format
>geschickt werden. Pro zeichen 1 Byte.

Unsinn. Man sendet im Binärformat und nicht ASCII!!! Denn daruch 
verdoppelt sich das Datenvolumen!

>> Das Ganze kann man auch auf 5 kleinere Datenpakete aufteilen

>ergibt sich dann aus dem Rest, dass Uart-Peripherie nicht
>hinterherkommt.?

Nö, das vereinfacht nur ein wenig die Programmierung.

von Falk B. (falk)


Lesenswert?

@ avrFanBoy 8-) (Gast)

>> Nimm einen CPU
>> Takt von 18,xyz MHz (Baudratenquarz)

>geht nicht. 3V3 Vcc. Wurde mir so aufgesetzt.

Hmmm. Vielleicht reicht ja die Hälfte, muss man testen. Oder man nimmt 
einen ATXmega, die laufen auch bei 3,3V bis 32 MHz.

von c-hater (Gast)


Lesenswert?

avrFanBoy 8-) schrieb:

> Ansonsten schiele ich eventuell auch Richtung STFM32...

Wenn deine Rechnerei stimmen würde (was sie nicht tut), würde ein 
anderer Controller daran absolut NICHTS ändern können.

Wenn die Datenrate wirklich zu knapp für die Datenmenge und Codierung 
ist, dann wird sie das auch sein, wenn du mit einem anderen Controller 
versuchst, dieselben Daten in derselben Codierung mit derselben Rate zu 
senden. Selbst wenn dieser Controller millionen Mal schneller ist. Denn 
der begrenzende Faktor ist nicht die Rechengeschwindigkeit des 
Controllers, sondern die gewählte Datenrate für die Übertragung der 
Daten.

von avrFanBoy 8-) (Gast)


Angehängte Dateien:

Lesenswert?

Marc V. schrieb:
> 111 kannst du gar nicht erhalten, vllt. 0111 oder 1110.

Habe ich auch gedacht, vlt habe ich falsch gewandelt oder meine Timer 
überschneiden sich jetzt schon.

Siehe Anhang. Frequenz ADC-abtasten mit 9k6Hz

Marc V. schrieb:
> Sowohl Falk als auch ich reden die ganze Zeit von Datenpaketen,
>  du willst es aber unbedingt Byteweise senden.
>  Warum ?

Ich komm halt nicht so schnell mit ;)

Wie an auf dem Bild sieht, reicht m.M.n die Zeit langfristig nicht dafür 
die Daten auszusenden.

auf dem Logic Analyzer Bild ist nur 1Byte ADC und 1 Byte "Trennwand" und 
sonst würde durch interruptgesteuert noch 1 Zeichen reinpassen. Das 
ändert ja auch nicht viel wenn man die ADC-Abtastung auf z.B. 8 Khz 
runtersetzt. Und meine Frage ist ob er das schafft zu senden, egal ob 
Byteweise oder Päckchen.

von avrFanBoy 8-) (Gast)


Lesenswert?

Falk B. schrieb:
> Das geht so aber nicht. Denn die Abtastung sollte schon zeitlich
> gleichmäßig erfolgen. Man kann nicht 96 Samples für Audio nehmen und die
> letzten 4 für andere Sachen. Man kann da nur GANZZAHLIGE Teiler nutzen.

Nein der Timer startet den ADC(nennen wir es ADC1) alle 1/10Khz sekunden 
automatisch.

dazwischen kann ich aber doch auch manuell noch einen Wert herbeirufen.? 
Wenn ADC1 bei 30 samples ist, 1 mal anderen Kanal abholen, damit das 
zeitlich hinhauen könnte, habe ich die ADC frequenz 44Khz möglichst hoch 
gesetzt.

Falk B. schrieb:
> Unsinn. Man sendet im Binärformat und nicht ASCII!!! Denn daruch
> verdoppelt sich das Datenvolumen!

mhh ich poste am besten mal mein Code.

von avrFanBoy 8-) (Gast)


Lesenswert?

Hallo c-hater.

c-hater schrieb:
> Wenn deine Rechnerei stimmen würde (was sie nicht tut), würde ein
> anderer Controller daran absolut NICHTS ändern können.

ist eine grobe Überschlagung.

>
> Wenn die Datenrate wirklich zu knapp für die Datenmenge und Codierung
> ist, dann wird sie das auch sein, wenn du mit einem anderen Controller
> versuchst, dieselben Daten in derselben Codierung mit derselben Rate zu
> senden. Selbst wenn dieser Controller millionen Mal schneller ist. Denn
> der begrenzende Faktor ist nicht die Rechengeschwindigkeit des
> Controllers, sondern die gewählte Datenrate für die Übertragung der
> Daten.

Nicht wirklich oder. Mit einem MSP beispielsweise kann ich die Baudrate 
ungganzzahlig teilen und damit die 5-fache Baudrate erhalten.

von avrFanBoy 8-) (Gast)


Lesenswert?

Falk B. schrieb:
> Hmmm. Vielleicht reicht ja die Hälfte, muss man testen. Oder man nimmt
> einen ATXmega, die laufen auch bei 3,3V bis 32 MHz.

genau, ist die Frage. Aber dann ist es nicht mehr der Atmega328 :)

Was haltet Ihr davon einen zweiten Atmega nutzen der nichts anderes 
macht als auf SD-Karte Audio zu tippen und vom ersten angestupst wird^^?

von avrFanBoy 8-) (Gast)


Lesenswert?

Falk B. schrieb:
>>mit 16 Bit meine ich die 2 Zeichen die für meine 8BitADC in Hex-Format
>>geschickt werden. Pro zeichen 1 Byte.
>
> Unsinn. Man sendet im Binärformat und nicht ASCII!!! Denn daruch
> verdoppelt sich das Datenvolumen!


wie geht das?


ich hatte das so:

   uint8_t analog = (ADCH);

   itoa(analog,bufferadch,16);

   USART_putstring(bufferadch);


Ich hab gedacht Hex = 2 Zeichen.

bin = 8 Zeichen? Was muss ich statt itoa machen? ://

von B. S. (bestucki)


Lesenswert?

avrFanBoy 8-) schrieb:
> Was haltet Ihr davon einen zweiten Atmega nutzen der nichts anderes
> macht als auf SD-Karte Audio zu tippen und vom ersten angestupst wird^^?

Und was wird das bringen? Du musst die Daten so oder so loswerden. Falk 
hat ja bereits vorgerechnet, dass die Schnittstelle dafür reicht, wenn 
du die Daten binär und nicht als Zeichen sendest. Da hasst du sogar 
doppelt gemoppelt: Höherer Datendurchsatz und Zeitersparnis im 
Controller, da du die Werte nicht in einen String wandeln musst.

avrFanBoy 8-) schrieb:
> wie geht das?

Einfach den nackten Wert senden, den du vom ADC erhälst. Momentan 
sendest du Zeichen, die sind auch nichts anderes als 8bit-Zahlen. Du 
benötigst dann aber nicht USART_putstring sondern eine Funktion, die 
einen uint8_t als Übergabewert verlangt und diesen Wert sendet (meistens 
fast das gleiche wie USART_putchar).

: Bearbeitet durch User
von avrFanBoy 8-) (Gast)


Lesenswert?

Hi bestucki,

Be S. schrieb:
> Und was wird das bringen? Du musst die Daten so oder so loswerden.

Z.b. dass der sich nur ums Audio kümmert und über SPI schnell auf eine 
SD-karte legt.




Be S. schrieb:
> Einfach den nackten Wert senden, den du vom ADC erhälst. Momentan
> sendest du Zeichen, die sind auch 8 Bit breit. Du benötigst dann aber
> nicht USART_putstring sondern eine Funktion, die einen uint8_t als
> Übergabewert verlangt und diesen Wert sendet (meistens fast das gleiche
> wie USART_putchar).

Ich weiß dass ich den nackten Wert senden muss, aber nicht wie, ich 
schau mach mich mal schlau und schau dann was es ändert :)
Danke.

von B. S. (bestucki)


Lesenswert?

avrFanBoy 8-) schrieb:
> Be S. schrieb:
>> Und was wird das bringen? Du musst die Daten so oder so loswerden.
>
> Z.b. dass der sich nur ums Audio kümmert und über SPI schnell auf eine
> SD-karte legt.

Dann musst du aber auch beachten, dass beim Schreiben von SD-Karten 
Verzögerungen von mehreren 100ms auftreten können.

avrFanBoy 8-) schrieb:
> Ich weiß dass ich den nackten Wert senden muss, aber nicht wie, ich
> schau mach mich mal schlau und schau dann was es ändert :)
> Danke.

Vom Prinzip her kannst du die Funktion USART_putchar wiederverwenden. 
Diese macht meistens nichts anderes als das Zeichen in den Sendepuffer 
zu kopieren. Nun benötigst du eine Funktion, die das Selbe mit einem 
uint8_t macht. Im Idealfall kannst du die Funktion USART_putchar 
kopieren, ihr einen Namen geben und den Übergabedatentyp auf uint8_t 
ändern.

: Bearbeitet durch User
von avrFanBoy 8-) (Gast)


Lesenswert?

Be S. schrieb:
> Dann musst du aber auch beachten, dass beim Schreiben von SD-Karten
> Verzögerungen von mehreren 100ms auftreten können.

also unbrauchbar, gut zu wissen.

Be S. schrieb:
> Vom Prinzip her kannst du die Funktion USART_putchar wiederverwenden.
> Diese macht meistens nichts anderes als das Zeichen in den Sendepuffer
> zu kopieren. Nun benötigst du eine Funktion, die das Selbe mit einem
> uint8_t macht. Im Idealfall kannst du die Funktion USART_putchar
> kopieren, ihr einen Namen geben und den Übergabedatentyp auf uint8_t
> ändern.

Danke, ich probiere mal rum und schau mir Falks Berechnung genauer an.

Ist schwierig wenn Ihr schneller antwortet als ich denken kann :D.

von c-hater (Gast)


Lesenswert?

avrFanBoy 8-) schrieb:

> Mit einem MSP beispielsweise kann ich die Baudrate
> ungganzzahlig teilen und damit die 5-fache Baudrate erhalten.

Ich verstehe, was du meinst. Das Problem liesse sich aber für den AVR 
auch ganz simpel durch eine geeignetere Wahl des Quarzes erschlagen. 
Statt 9,216MHz einfach 9,8304MHz verwenden und der Drops ist gelutscht.
Ich sehe jedenfalls in deinem ganzen Projekt wirklich absolut nix, was 
die Wahl dieser schrägen Quarzfrequenz in irgendeiner Form sinnvoll 
erscheinen ließe.

Und selbst, wenn es irgendeinen Grund gäbe, der tatsächlich diese 
Quarzfrequenz zwingend erfordern würde, gibt es mit einem Mega328 sogar 
mehrere Möglichkeiten, auch "unrund geteilte" typische Bitraten zu 
erreichen.

Kostet bei sinnvoller Nutzung der verfügbaren Hardware und kompetenter 
Programmierung nur zusätzliche Rechenzeit in einem durchaus akzeptablem 
Umfang. Der Trick ist: betreibe die UART als SPI-Master bei deutlich 
höherer Bitrate und benutze mehrere ihrer Bits (wobei "mehrere" nach 
einem sinnvollen Muster um +-1 variiert) für ein effektives Bit auf der 
Leitung.

Ziemlicher Kinderkram für Leute, die wirklich programmieren können, aber 
für FanBoys natürlich...

von Falk B. (falk)


Lesenswert?

@avrFanBoy 8-) (Gast)

>> Das geht so aber nicht. Denn die Abtastung sollte schon zeitlich
>> gleichmäßig erfolgen. Man kann nicht 96 Samples für Audio nehmen und die
>> letzten 4 für andere Sachen. Man kann da nur GANZZAHLIGE Teiler nutzen.

>Nein der Timer startet den ADC(nennen wir es ADC1) alle 1/10Khz sekunden
>automatisch.

Geht das wirklich mit dem Timer? Oder meinst du vielmehr, daß die CPU 
das im Timer-Interrupt macht.

>dazwischen kann ich aber doch auch manuell noch einen Wert herbeirufen.?

Nö. Du hast nur einen ADC.

>Wenn ADC1 bei 30 samples ist, 1 mal anderen Kanal abholen, damit das
>zeitlich hinhauen könnte, habe ich die ADC frequenz 44Khz möglichst hoch
>gesetzt.

Das funktioniert so nicht.

>> Unsinn. Man sendet im Binärformat und nicht ASCII!!! Denn daruch
>> verdoppelt sich das Datenvolumen!

>mhh ich poste am besten mal mein Code.

Nö, du solltest mal etwas über die Grundlagen lernen.

von Falk B. (falk)


Lesenswert?

@avrFanBoy 8-) (Gast)

>> Hmmm. Vielleicht reicht ja die Hälfte, muss man testen. Oder man nimmt
>> einen ATXmega, die laufen auch bei 3,3V bis 32 MHz.

>genau, ist die Frage. Aber dann ist es nicht mehr der Atmega328 :)

>Was haltet Ihr davon einen zweiten Atmega nutzen

Gar  nichts. Du bist mit einem schon mehr als gefordert.

>der nichts anderes
>macht als auf SD-Karte Audio zu tippen und vom ersten angestupst wird^^?

Das kann EIN AVR allein. Sagte ich bereits. Mein DMX512 Recorder 
schreibt/liest mit 22kB/s dauerhaft auf SD-Karte, und das bei einer 
MITTLEREN CPU-Last von 30%, allerdings bei 16 MHz Takt.

von Falk B. (falk)


Lesenswert?

@ avrFanBoy 8-) (Gast)

>> Unsinn. Man sendet im Binärformat und nicht ASCII!!! Denn daruch
>> verdoppelt sich das Datenvolumen!

>wie geht das?

Grundlagen und so . . .

>ich hatte das so:

>   uint8_t analog = (ADCH);

>   itoa(analog,bufferadch,16);

>   USART_putstring(bufferadch);

Ist Unsinn, denn ASCII macht man nur, wenn es menschenlesbar sein muss. 
Das sind dein Datenpakete aber nicht, müssen sie auch gar nicht sein.

>Ich hab gedacht Hex = 2 Zeichen.

Lies mal was zum Thema ASCII-Kodierung von Zahlen

>bin = 8 Zeichen? Was muss ich statt itoa machen? ://

AUA!!!!

GRUNDLAGEN!!!!

uint8_t analog = ADCH;
USART_putc(analog);

von Falk B. (falk)


Lesenswert?

@ Be Stucki (bestucki)

>> Z.b. dass der sich nur ums Audio kümmert und über SPI schnell auf eine
>> SD-karte legt.

>Dann musst du aber auch beachten, dass beim Schreiben von SD-Karten
>Verzögerungen von mehreren 100ms auftreten können.

Richtig, und dafür braucht man einen recht großen FIFO, so 0,5-1s. Hab 
ich damals mit 60kB SRAM am ATmega64 gemacht.

>Vom Prinzip her kannst du die Funktion USART_putchar wiederverwenden.
>Diese macht meistens nichts anderes als das Zeichen in den Sendepuffer
>zu kopieren. Nun benötigst du eine Funktion, die das Selbe mit einem
>uint8_t macht. Im Idealfall kannst du die Funktion USART_putchar
>kopieren, ihr einen Namen geben und den Übergabedatentyp auf uint8_t
>ändern.

Bei der Datenrate schreibt man das alles direkt in die Register, 
Funktionen sind da weder sonderlich sinnvoll noch nötig. Letztendlich 
läuft nahezu das gesamte Programm im 10 kHz Timer-Interrupt.

von M. K. (sylaina)


Lesenswert?

Falk B. schrieb:
> Trennwände gibt es auf den Scheißhaus, nicht in Datenpaketen!

ymmd :D

von avrFanBoy 8-) (Gast)


Lesenswert?

c-hater schrieb:
> Ich sehe jedenfalls in deinem ganzen Projekt wirklich absolut nix, was
> die Wahl dieser schrägen Quarzfrequenz in irgendeiner Form sinnvoll
> erscheinen ließe.

für die bluetoothkompatible Baudraten.

c-hater schrieb:
> Der Trick ist: betreibe die UART als SPI-Master bei deutlich
> höherer Bitrate und benutze mehrere ihrer Bits (wobei "mehrere" nach
> einem sinnvollen Muster um +-1 variiert) für ein effektives Bit auf der
> Leitung

interessant.

c-hater schrieb:
> Ziemlicher Kinderkram für Leute, die wirklich programmieren können, aber
> für FanBoys natürlich...

Das erste Mal, dass ich mich damit auseinandersetze.

von avrFanBoy 8-) (Gast)


Lesenswert?

Falk B. schrieb:
> Geht das wirklich mit dem Timer? Oder meinst du vielmehr, daß die CPU
> das im Timer-Interrupt macht.

Autotrigger mit CTC Timer0. Dieser löst einen ADC-Start aus beim 
Erreichen des Compare-Wertes. Dann kann ich den CTC Timer0 noch ein 
weiteres mal nutzen für andere Zwecke und weiß ganz genau, dass gerade 
eine ADC-Wandlung gestartet wird, dessen benötigte Dauer ich ja auch 
kenne.

Falk B. schrieb:
> Nö. Du hast nur einen ADC.

...Den ich switchen kann. Die Zeit müsste da sein.

Falk B. schrieb:
> uint8_t analog = ADCH;
> USART_putc(analog);

Diese Funktion ist mir nicht unbekannt. Es wollte mir aber nichts 
ausspucken darum meine umständliche Formatierung. (ist bisher ja alles 
nur zum testen).

Trotzdem ist es doch sinnvoller in HEX vorher zu wandeln oder nicht?

Falk B. schrieb:
>>> Z.b. dass der sich nur ums Audio kümmert und über SPI schnell auf eine
>>> SD-karte legt.
>
>>Dann musst du aber auch beachten, dass beim Schreiben von SD-Karten
>>Verzögerungen von mehreren 100ms auftreten können.
>
> Richtig, und dafür braucht man einen recht großen FIFO, so 0,5-1s. Hab
> ich damals mit 60kB SRAM am ATmega64 gemacht.

Gut, ist dann abgehackt.

Falk B. schrieb:
> Bei der Datenrate schreibt man das alles direkt in die Register,
> Funktionen sind da weder sonderlich sinnvoll noch nötig. Letztendlich
> läuft nahezu das gesamte Programm im 10 kHz Timer-Interrupt.

Wird alles gemacht. Ich spiele grad eher rum und mache mir Gedanken und 
probiere rum.

von avrFanBoy 8-) (Gast)


Lesenswert?

avrFanBoy 8-) schrieb:
> Trotzdem ist es doch sinnvoller in HEX vorher zu wandeln oder nicht?

Ich nehme die Aussage zurück^^ Hat grad klick gemacht.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

avrFanBoy 8-) schrieb:
>>>Dann musst du aber auch beachten, dass beim Schreiben von SD-Karten
>>>Verzögerungen von mehreren 100ms auftreten können.
>>
>> Richtig, und dafür braucht man einen recht großen FIFO, so 0,5-1s. Hab
>> ich damals mit 60kB SRAM am ATmega64 gemacht.
>
> Gut, ist dann abgehackt.

 Nö, brauchst du nicht. Mit -- direktem -- beschreiben der Sektors auf
 der SD-Karte schaffst du 150-200KB ohne irgendwelche Verzögerungen.
 Wenn es über FAT geht, kann es (meistens ist es aber nicht der Fall bei
 einer frisch formatierter Karte) zu Verzögerungen kommen.

 -- direkt -- Auch so kannst du nicht auf physikalische Sektoren
 zugreifen, aber zumindest den Umweg uber FAT kannst du dir sparen.

von Falk B. (falk)


Lesenswert?

@avrFanBoy 8-) (Gast)

>Autotrigger mit CTC Timer0.

OK.


>> Nö. Du hast nur einen ADC.

>...Den ich switchen kann.

Früher nannte man das umschalten.

>Die Zeit müsste da sein.

Das passt aber mit dem Gesamtkonzept nicht!!! Vor allem, da du die 
Audiodaten WIRKLICH äquidistant, sprich, zeitich absolut gleichmäßig 
abtasten mußt. Lösung -> 20 kHz Timer-Interrupt.

>Trotzdem ist es doch sinnvoller in HEX vorher zu wandeln oder nicht?

NEIN!!!!!
(mein Gott sind die Leute lernresistent)

>> Richtig, und dafür braucht man einen recht großen FIFO, so 0,5-1s. Hab
>> ich damals mit 60kB SRAM am ATmega64 gemacht.

>Gut, ist dann abgehackt.

Wer wird abgehackt? Der Kopf? Oder der Arm? Oder nur abgehakt?

>Wird alles gemacht. Ich spiele grad eher rum und mache mir Gedanken und
>probiere rum.

Du träumst. Denken ist was anderes.

von B. S. (bestucki)


Lesenswert?

Marc V. schrieb:
> Nö, brauchst du nicht. Mit -- direktem -- beschreiben der Sektors auf
>  der SD-Karte schaffst du 150-200KB ohne irgendwelche Verzögerungen.
>  Wenn es über FAT geht, kann es (meistens ist es aber nicht der Fall bei
>  einer frisch formatierter Karte) zu Verzögerungen kommen.
>
>  -- direkt -- Auch so kannst du nicht auf physikalische Sektoren
>  zugreifen, aber zumindest den Umweg uber FAT kannst du dir sparen.

Schön wärs. SD-Karte betreiben Wear-Leveling und automatische 
Fehlerkorrekturen, bei denen ganze Sektoren verschoben werden. Das alles 
benötigt Zeit und führt zu Verzögerungen. Du kannst zwar direkt einen 
Sektor beschreiben, aber physikalisch wird sich dieser irgendwo auf der 
Karte befinden. Das hat auch nichts mit FAT zu tun, eine SD-Karte weiss 
nichts über FAT.

Schau dir mal ein Datenblatt eine solchen Karte an:
http://www.datasheetarchive.com/dl/Datasheets-SL6/DSASL00100495.pdf

Seite 2-2:
Block Write Access Time: 250ms (Maximum Value)

: Bearbeitet durch User
von avrFanBoy 8-) (Gast)


Lesenswert?

Falk B. schrieb:
> Das passt aber mit dem Gesamtkonzept nicht!!!


Also ich träume Folgendes:

Timer O-->Startet Automatisch ADC.


ISR(TIMERO)
i++;
for i = 25; //Sample&Hold-takt abwarten
{
ADMUX=1;

}


ISR(ADC)
i++;

wenn i ungleich 25 und 26
{
analogAudio = ADCH(ADC0);
}

for i = 25;
{
 ADCSTART; //"manuell"
 }

for i = 26;
{
analog2 = ADCH(ADC1);

ADMUX=0;

}

Da 44Khz schneller sind als die 10Khz interrupt Routine.

Wenn das nicht geht-->

Falk B. schrieb:
> 20 kHz Timer-Interrupt.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Be S. schrieb:
> Schön wärs. SD-Karte betreiben Wear-Leveling und automatische
> Fehlerkorrekturen, bei denen ganze Sektoren verschoben werden. Das alles
> benötigt Zeit und führt zu Verzögerungen.
 Ja, nur fängt eine Karte nicht gleich damit an, es braucht schon
 einige Schreibvorgänge. Es ist schon ein Unterschied zwischen alten
 und neuen Karten.

> Du kannst zwar direkt einen
> Sektor beschreiben, aber physikalisch wird sich dieser irgendwo auf der
> Karte befinden.
 Habe ich etwas anderes geschrieben ?

> Das hat auch nichts mit FAT zu tun, eine SD-Karte weiss
> nichts über FAT.
 Nein, aber wegen Wear-Leveling wird mit einem Filesystem auf der
 SD-Card gerade FAT am meisten herumgeschoben. Ohne Filesystem, mit
 neuen Karten und mit geradeaus schreiben habe ich nie Verzögerungen
 größer 5ms gehabt. An der Sektorengrenze gibt es meistens etwas
 längere Verzögerungen aber nichts drastisches.

> Seite 2-2:
> Block Write Access Time: 250ms (Maximum Value)

 Die 250ms max. BWAT ist für Karten die schon am Ende sind, kommt
 bei neuen Karten niemals vor.

 Mit 2 * FIFO a 512Byt fährt man diese Aufgabe absolut ohne Probleme.

von Falk B. (falk)


Lesenswert?

@ avrFanBoy 8-) (Gast)

>> Das passt aber mit dem Gesamtkonzept nicht!!!


>Also ich träume Folgendes:

>Timer O-->Startet Automatisch ADC.

Nö. Sinnvollerweise startet man den ADC mittels Compare VOR der 
Timer-ISR, sodas bei deren Aufruf die Umwandlung schon abgeschlossen 
ist. Dann kann man das Ergebnis einfach auslesen und 
/verarbeiten/senden. Dann könnte man den ADC noch einmal starten und die 
langsamen Kanäle sampeln, das muss ja nur jeder 25. ISR sein. Allerdings 
muss man dan in der ISR auf das Ende der ADC-Wandlung warten. Nicht 
schön, aber hier OK.

Etwa so.
1
ISR(TIMERO_OVF_vect) {
2
3
  static uint8_t cnt;
4
5
  UDR0 = ADCH;    // Analogsignal senden
6
7
  cnt++;
8
    switch (cnt) {
9
    case 25:            // Low Speed ADC Kanal 1 lesen
10
        ADMUX = ADMUX & ~0xF | 1;  // AD-Kanal auswählen
11
      ADCSRA |= 1<<ADSC;      // start ADC
12
      while (ADCSCR & (1<<ADSC));  // auf Ende der AD-Wandlung warten
13
      UDR0=ADCH;          // Daten senden
14
        ADMUX = ADMUX & ~0xF | 0;  // wieder auf Audiokanal umstellen
15
    break;
16
17
    case 50:            // Low Speed ADC Kanal 2 lesen
18
19
      // wie oben
20
    break;
21
22
    case 75:            // Low Speed Sensor 1 per SPI lesen
23
      // Sensor per SPI auslesen . . .
24
      UDR0 = sensorwert;
25
    break;
26
27
    case 100:            // Low Speed Sensor 2 per SPI lesen
28
      // wie oben
29
      cnt =0;            // Zyklus neu starten
30
    break;
31
    }
32
}

>Da 44Khz schneller sind als die 10Khz interrupt Routine.

Sicher, aber dein Konzept ist immer noch nicht brauchbar. Die ADC 
conversion complete ISR nutzt man nicht. In der ISR nutzt man auch keine 
Schleife, um mehrfache AD-Wandlungen vorzunehmen! Pro Aufruf wird 
bestenfalls EINE zusätzliche AD-Wandlung druchgeführt, siehe oben.

von avrFanBoy 8-) (Gast)


Lesenswert?

ok danke schon mal für deine Hilfe Frank.

Falk B. schrieb:
> Nö. Sinnvollerweise startet man den ADC mittels Compare VOR der
> Timer-ISR

Das tut Sie doch automatisch => Autotrigger.

Wenn ich Timer-ISR aufrufe, weiß ich dann, dass gerade eine ADC-Konvert 
läuft.

Oder liege ich da falsch?

void InitTimer0(void)
{

  OCR0A=(119);                //9k6Hz
    TCCR0A |= (1<<WGM01);  //Set CTC mode
}


und

ADCSRB |= (1<<ADTS1)|(1<<ADTS0);    //Autotrigger Timer0/Counter Compare 
Match A

Habe ich meine ADC-Start an den Timer gebunden, welcher ohne weiteres 
Hinzutun automatisch läuft. Dadurch erst stelle ich ja meine 9,X KHz 
Abtastung sicher. Und mit


ISR(ADC_vect)
{

  kann ich mein Wert rechtzeitig auslesen. Und eben gegebenfalls nochmal 
starten.. & auslesen. Darum habe ich die ADC-Frequenz auf maximal. 44Khz 
gesetzt. }


ISR (TIMER0_COMPA_vect)
{


plus zusätzlich meinen Timer0 Während ein Sample läuft, switchen und 
beim nächsten ADC-Kanal rechtzeitig auf ein Niveau laden lassen. Ich 
hätte das als mein Grundgerüst für den Code genommen.

}


Falk B. schrieb:
> In der ISR nutzt man auch keine
> Schleife, um mehrfache AD-Wandlungen vorzunehmen!

Gewiss. Aber dadurch, dass ich die Zeiten kenne, kommen sich die 
Interrupts nicht in die Quere?

Falk B. schrieb:
> Pro Aufruf wird
> bestenfalls EINE zusätzliche AD-Wandlung druchgeführt,

Mehr brauche ich ja auch nicht. Eine reicht.

Dann hätte ich einen Timer für alle ADC'S.

Würde einen Nichtaudio(immer der erste Wert) und ca. 70 ADC-Werte dann 
als päckchen verpacken und versenden. Da es ja Binär bleibt :)) (ist 
angekommen, ich weiß auch nicht wie ich auf die Idee gekommen bin, dass 
jedes Bit als Zeichen verschickt wird..)

Zumindest war so meine Vorstellung. Ich komme gerade nicht dazu alles 
auszuprobieren.

von Falk B. (falk)


Lesenswert?

@ avrFanBoy 8-) (Gast)

>> Nö. Sinnvollerweise startet man den ADC mittels Compare VOR der
>> Timer-ISR

>Das tut Sie doch automatisch => Autotrigger.

Ja, aber nicht beim Timer Overflow, sondern vorher!

>Wenn ich Timer-ISR aufrufe, weiß ich dann, dass gerade eine ADC-Konvert
>läuft.

Stimmt, aber dann kannst du nichts mit dem ADC machen! Willst du gern 
lange warten?

>void InitTimer0(void)
>{

>  OCR0A=(119);                //9k6Hz
>    TCCR0A |= (1<<WGM01);  //Set CTC mode
>}

Warum diese krumme Abtastfrequenz?

>ADCSRB |= (1<<ADTS1)|(1<<ADTS0);    //Autotrigger Timer0/Counter Compare
>Match A

OK. Aber dann muss man den Compare Match passend einstellen.

>Habe ich meine ADC-Start an den Timer gebunden, welcher ohne weiteres
>Hinzutun automatisch läuft. Dadurch erst stelle ich ja meine 9,X KHz
>Abtastung sicher. Und mit

Das ist OK.

>ISR(ADC_vect)
>{

>  kann ich mein Wert rechtzeitig auslesen. Und eben gegebenfalls nochmal
>starten.. & auslesen. Darum habe ich die ADC-Frequenz auf maximal. 44Khz
>gesetzt. }

NEIN!!! Das willst du nicht wirklich. Denn bei 10kHz Interruptfrequenz 
will man nicht noch mehr Interrups als nötig erzeugen. Du erzeugst 
doppelt so viele wie nötig. -> Schlechtes Konzept.

>ISR (TIMER0_COMPA_vect)
>{

>plus zusätzlich meinen Timer0 Während ein Sample läuft, switchen und
>beim nächsten ADC-Kanal rechtzeitig auf ein Niveau laden lassen.

???

> Ich
>hätte das als mein Grundgerüst für den Code genommen.

Ich wiederhole mich. Das ist ein schlechtes Konzept.

>Dann hätte ich einen Timer für alle ADC'S.

Und KEINEN ADC-Interrupt!

von avrFanBoy 8-) (Gast)


Lesenswert?

Falk B. schrieb:
> Ja, aber nicht beim Timer Overflow, sondern vorher!

Mit ihm dachte ich, wo ist denn das Problem? Ich will da nur meinen MUX 
umschalten, damit ich paar Takte auf dem anderen Kanal weilen lassen 
kann.

Falk B. schrieb:
> Stimmt, aber dann kannst du nichts mit dem ADC machen! Willst du gern
> lange warten?

Solange mache ich was anderes.

Falk B. schrieb:
> Warum diese krumme Abtastfrequenz?

Wie gesagt ich teste grad, weil ich keinerlei Erfahrung habe. Habe mir 
sagen lassen 9k6 Hz entspricht einem WAV-Format, kann aber noch runter 
gehen auf 8 Khz.

Falk B. schrieb:
> NEIN!!! Das willst du nicht wirklich. Denn bei 10kHz Interruptfrequenz
> will man nicht noch mehr Interrups als nötig erzeugen. Du erzeugst
> doppelt so viele wie nötig. -> Schlechtes Konzept.

Das ist der Versuch, einen Wert "dazwischen" (zwischen 10Khz, zu 
messen).
Wie gesagt, ich lasse mich gerne eines besseren belehren, wenn das 
Schwachsinn ist, so ist aber meine Aufgabenstellung. Ansonsten verdoppel 
ich wie du schon gesagt hast die Frequenz.

Falk B. schrieb:
>>plus zusätzlich meinen Timer0 Während ein Sample läuft, switchen und
>>beim nächsten ADC-Kanal rechtzeitig auf ein Niveau laden lassen.
>
> ???

Ich weiß nicht worauf sich die Fragezeichen beziehen. So wurde es mir 
von jemand gesagt, der mehr Erfahrung hat als ich, dass man nicht sofort 
mit einer Messung beginnen soll..

Im Datenblatt finde ich zwar nichts davon, (die 2.5 Takte Sample und 
Hold gehören ja sowieso zur Messung).

Falk B. schrieb:
> Ich wiederhole mich. Das ist ein schlechtes Konzept.

OKAY

Falk B. schrieb:
> Und KEINEN ADC-Interrupt!

Falk B. schrieb:
>>ISR(ADC_vect)

Hab ich doch? Einen für alle? Wie soll ich sonst die Werte auslesen?

von Falk B. (falk)


Lesenswert?

@avrFanBoy 8-) (Gast)

>> Ja, aber nicht beim Timer Overflow, sondern vorher!

>Mit ihm dachte ich, wo ist denn das Problem? Ich will da nur meinen MUX
>umschalten, damit ich paar Takte auf dem anderen Kanal weilen lassen
>kann.

Kannst oder willst du es nicht verstehen?

>> Stimmt, aber dann kannst du nichts mit dem ADC machen! Willst du gern
>> lange warten?

>Solange mache ich was anderes.

Was denn?

>> Warum diese krumme Abtastfrequenz?

>Wie gesagt ich teste grad, weil ich keinerlei Erfahrung habe. Habe mir
>sagen lassen 9k6 Hz entspricht einem WAV-Format,

Quark. 9600 Hz ist keine Standardfrequenz. WAV kann jede beliebige 
Frequenz speichern.

> kann aber noch runter gehen auf 8 Khz.

Ist auch egal, das ist eine einfache Einstellung.

>Das ist der Versuch, einen Wert "dazwischen" (zwischen 10Khz, zu
>messen).

Wie man das besser macht, habe ich dir skizziert.

Beitrag "Re: Atemega328p - schaffst du das?"

>Wie gesagt, ich lasse mich gerne eines besseren belehren, wenn das
>Schwachsinn ist, so ist aber meine Aufgabenstellung. Ansonsten verdoppel
>ich wie du schon gesagt hast die Frequenz.

Kann man machen, verbrät aber unnötig viel CPU Leistung.

>>plus zusätzlich meinen Timer0 Während ein Sample läuft, switchen und
>>beim nächsten ADC-Kanal rechtzeitig auf ein Niveau laden lassen.
>
> ???

>Ich weiß nicht worauf sich die Fragezeichen beziehen.

Auf deinen komischen Satz. Der ist gramatikalisch als auch inhaltlich 
äußerst irritierend.

>So wurde es mir
>von jemand gesagt, der mehr Erfahrung hat als ich, dass man nicht sofort
>mit einer Messung beginnen soll..

Unsinn. Das macht der ADC schon richtig. Lediglich das allererste 
Messung nach dem Einschalten des ADC bzw. Umschalten der 
Referenzspannung ist Murks. Danach kann man am Stück beliebig messen.

>Hab ich doch? Einen für alle? Wie soll ich sonst die Werte auslesen?

Den ADC liest du im Timer-Interrupt aus. Siehe mein Beispiel.

von avrFanBoy 8-) (Gast)


Lesenswert?

Falk B. schrieb:
> Wie man das besser macht, habe ich dir skizziert.

Dann werde ich mich daran orientieren. Danke Vielmals!!

Falk B. schrieb:
> Kann man machen, verbrät aber unnötig viel CPU Leistung.

Eine Frage aus Neugier, woher kennt man diese, bzw. wie misst man die? 
Oder ist die dann berechnet? Weil du mit der Angabe von 30% weiter oben 
ankamst.

Falk B. schrieb:
>>Wie gesagt ich teste grad, weil ich keinerlei Erfahrung habe. Habe mir
>>sagen lassen 9k6 Hz entspricht einem WAV-Format,
>
> Quark.

OKAY. Wusste es nicht besser.

Falk B. schrieb:
> Unsinn. Das macht der ADC schon richtig. Lediglich das allererste
> Messung nach dem Einschalten des ADC bzw. Umschalten der
> Referenzspannung ist Murks. Danach kann man am Stück beliebig messen.

Ok, so hatte ich es auch in Kopf. Eine Initial-Messung habe ich in den 
Voreinstellung eingeführt.

Falk B. schrieb:
> Den ADC liest du im Timer-Interrupt aus. Siehe mein Beispiel.

Werde ich dann so machen.

Vielen lieben Dank Frank und sorry wenn ich dich teilweise auf die Palme 
gebracht habe^^

von avrFanBoy 8-) (Gast)


Lesenswert?

Ich meine natürlich Falk!! Sorry.

von Falk B. (falk)


Lesenswert?

@avrFanBoy 8-) (Gast)

>> Kann man machen, verbrät aber unnötig viel CPU Leistung.

>Eine Frage aus Neugier, woher kennt man diese, bzw. wie misst man die?

Kann man simulieren und die Takte vom Simulator zählen lassen bzw. real 
messen. Am Anfang der ISR ein Pin einschalten am Ende wieder 
ausschalten.
Das kann man mit dem Oszi messen.

von avrFanBoy 8-) (Gast)


Lesenswert?

Dankeschön.

von avrFanBoy 8-) (Gast)


Lesenswert?

Hi Falk Brunner.

Nur nochmal kurz hier um dir

for (i=0, i>255, i++)

{

print("DANKE");

i=0;

}

zu sagen, wenn du verstehst :)


Danke, dass du mich nicht aufgegeben hast :)


Es hat alles super funktioniert.

Dein Gerüst war genial und hat mich meinen Code mit Leichtigkeit 
vollenden lassen :)


DANKE! und super Forum!!

von avrFanBoy 8-) (Gast)


Lesenswert?

Und allen anderen selbstverständlich auch tausend Dank!!!

von Florian W. (florian_w77)


Lesenswert?

Ich hab gesehen, dass das Thema eigentlich erledigt ist und habe den 
Thread auch nur bis etwa zur Hälfte aufmerksam gelesen, mir ist aber 
eine Idee zu deinen Trennern gekommen, die du bis zu dem Zeitpunkt noch 
eingesetzt hast, um die einzelnen Daten voneinander zu trennen. Du hast 
dabei immer | benutzt und konntest somit nicht unterscheiden, ob du 
Audiodaten oder anderes Zeug sendest.
Meine Idee dazu wäre, dass du vor jedes 2-Byte-Paket einen Identifier 
stellst, bei dir Trenner genannt. Für Audio stellst du also | für die 
erste 50-Hz-Abtastung ein * , dann evtl noch eine ~ und ein # oder jedes 
andere beliebige Zeichen voran, das nicht in deinen Daten vorkommt.

So kannst du folgendes Senden:

|2Byte-Audio*2Byte-50-Hz
|2Byte-Audio
|2Byte-Audio~2Byte-anderes

Damit sparst du dir die 3 Byte im mittleren Block, die du senden 
wolltest, als du noch alles in 6-Byte-Pakete aufteilen wolltest.

Evtl kannst du auf diese Weise nicht nur Daten einsparen, sondern die 
gesendeten Daten beim Empfänger auch noch einfacher kategorisieren.

MfG
Florian W.

von Falk B. (falk)


Lesenswert?

@ Florian W. (florian_w77)

>Meine Idee dazu wäre, dass du vor jedes 2-Byte-Paket einen Identifier
>stellst, bei dir Trenner genannt. Für Audio stellst du also | für die
>erste 50-Hz-Abtastung ein * , dann evtl noch eine ~ und ein # oder jedes
>andere beliebige Zeichen voran, das nicht in deinen Daten vorkommt.

Das ist eine schlechte Idee. Denn erstens hast du damit 33% Overhead, 
der keine Daten transportiert und 2. bist du dann auf eine 
ASCII-Kodierung angewiesen, die wiederum bestenfalls 50% Effizienz hat 
(1 Nutzbyte = 2 ASCII Bytes). Gesamteffizienz 2 / 5 = 40%. Prost 
Mahlzeit.

von Falk B. (falk)


Lesenswert?

@ avrFanBoy 8-) (Gast)

>Nur nochmal kurz hier um dir

1
for (i=0, i>255, i++)
2
{
3
  print("DANKE");
4
  i=0;
5
}

>zu sagen, wenn du verstehst :)

Hmm, diese Schleife sagt nicht ein einziges Mal Danke und ist nicht 
compilierbar. Bug oder Feature? ;-)

Aber schön daß es funktioniert und, noch viel wichtiger, daß du es 
verstanden hast.

von Florian W. (florian_w77)


Lesenswert?

Hallo Falk,

was schlägst du denn vor, wie die einzelnen 2-Byte-Datenpakete 
voneinander getrennt werden, so dass sie am Handy auch den einzelnen 
Quellen wieder zugeordnet werden können?

von Falk B. (falk)


Lesenswert?

@ Florian W. (florian_w77)

>was schlägst du denn vor, wie die einzelnen 2-Byte-Datenpakete
>voneinander getrennt werden, so dass sie am Handy auch den einzelnen
>Quellen wieder zugeordnet werden können?

Mal den Thread gelesen?

Auf jeden Fall KEINE 2er Datenpakete, sonder DEUTLICH größere mit 20-100 
Byte Nutzdaten und nur EINEM Startzeichen. Das Ganze auch in einfacher 
Binärkodierung. Ja, das macht die Dekodierung schwieriger, aber das ist 
ein lösbares Problem.

von avrFanBoy 8-) (Gast)


Lesenswert?

Falk B. schrieb:
> Hmm, diese Schleife sagt nicht ein einziges Mal Danke

Das Gegenteil war natürlich gemeint, Hauptsache mein Danke ist bei dir 
angekommen :)

Florian W. schrieb:
> was schlägst du denn vor, wie die einzelnen 2-Byte-Datenpakete
> voneinander getrennt werden, so dass sie am Handy auch den einzelnen
> Quellen wieder zugeordnet werden können?

Falk B. schrieb:
> Auf jeden Fall KEINE 2er Datenpakete, sonder DEUTLICH größere mit 20-100
> Byte Nutzdaten und nur EINEM Startzeichen. Das Ganze auch in einfacher
> Binärkodierung. Ja, das macht die Dekodierung schwieriger, aber das ist
> ein lösbares Problem.

Ich habe es bisher so gelöst :


Ich habe 25 analoge Werte für Audio zwischengespeichert und dann 
sortiert (der richtigen Reihe nach) gesendet. D.h. erst folgen meine 
langsamen Signale, dann 56*Werte für Audio. Dies geschieht schon alles 
auf der µC-Ebene.


Getrennt habe ich es bisher immer noch durch meine 2 "ScheißWände"

D.h. ein Start wird dadurch gekennzeichnet durch: |Counter|

| entspricht glaub DEC 124, dadurch habe ich dann immer stehen: 124 Counter-Wert 
124. So kann ich jeden Counter-Wert(Zyklus) prüfen & da ich die Anzahl der Werte 
kenne, ist das gar nicht notwendig.

Ob das überhaupt notwendig ist prüfe ich grad da ich meine App optimiere 
und z.B. weiß, dass jeder 56e Wert jetzt mal von 3 Startzeichen 
abgesehen meinem ersten Wert entspricht.

von Avrfanboy (Gast)


Lesenswert?

Der Counter-wert für  mein Startpaket  inkrementiert nur bei Case:1

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.