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.
:
Bearbeitet durch User
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.
Empfangsbereich verlassen sollte ausgeschlossen sein, auf der anderen Seite hängt ein Handy. Nun gut.
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.
:
Bearbeitet durch User
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 :)
Aber da Ihr ja alle der selben Meinung seid:Machbar!, hat sich meine eigentliche Frage erledigt, danke dafür :) !!
@ 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 | 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
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.
:
Bearbeitet durch User
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.
:
Bearbeitet durch User
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.
:
Bearbeitet durch User
@ 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).
:
Bearbeitet durch User
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.
:
Bearbeitet durch User
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: > Trotzdem ist es doch sinnvoller in HEX vorher zu wandeln oder nicht? Ich nehme die Aussage zurück^^ Hat grad klick gemacht.
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)
:
Bearbeitet durch User
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 | 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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.