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.
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.
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?
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.
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?
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.
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.
@ 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.
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.
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?
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?
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...
@ 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?
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.
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.
@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 :)
@ 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.
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
InderISRzuerstADC-Wertauslesen,
3
inTxBuffer[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
KurzePause
9
Wenn(UDRE0==1)||(TXC0==1)
10
TxBuffer(TxPtr++]rausschicken.
11
12
WennSampleNr==60
13
ADC-Channelentspr.umschalten,kurzwarten
14
und10bitWertinTxBuffer[80]reinschreiben.
15
ADCzuruckschalten.
16
WennSampleNr==61
17
ADC-Channelentspr.umschalten,kurzwarten
18
und8bitWertinTxBuffer[80+2]reinschreiben.
19
ADCzuruckschalten.
20
WennSampleNr==62
21
ADC-Channelentspr.umschalten,kurzwarten
22
und8bitWertinTxBuffer[80+3]reinschreiben.
23
ADCzuruckschalten.
24
WennSampleNr==63
25
ADC-Channelentspr.umschalten,kurzwarten
26
und8bitWertinTxBuffer[80+4]reinschreiben.
27
ADCzuruckschalten.
28
29
WennSampleNr==65
30
// main soll Werte fur G-Sensor holen und reinschreiben
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 ?
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.
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.
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!
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 :)
@ 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.
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.
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 :)
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!
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?
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.
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.
@ 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.
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
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 :)
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.?
@ 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.
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 ?
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.
@ 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.
@ 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.
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.
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.
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.
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.
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^^?
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? ://
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).
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.
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.
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.
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...
@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.
@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.
@ 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);
@ 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.
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.
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.
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.
@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.
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)
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.
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.
@ 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
staticuint8_tcnt;
4
5
UDR0=ADCH;// Analogsignal senden
6
7
cnt++;
8
switch(cnt){
9
case25:// 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
case50:// Low Speed ADC Kanal 2 lesen
18
19
// wie oben
20
break;
21
22
case75:// Low Speed Sensor 1 per SPI lesen
23
// Sensor per SPI auslesen . . .
24
UDR0=sensorwert;
25
break;
26
27
case100:// 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.
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.
@ 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!
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?
@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.
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^^
@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.
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!!
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.
@ 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.
@ 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.
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?
@ 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.
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.