Hallo! Ich möchte eine große Menge von Messwerten mit dem ADC aufnehmen und diese dann an den PC über die serielle Schnittstelle senden. Mein Vorgehen sieht so aus: Ich lege ein großes Array an und schreibe nacheinander alle Werte des ADC per Busy-Waiting dort hinein. Wenn das Array voll ist sende ich diese per UART an den PC. Für Messungen bis 1000 Werte funktioniert dieses gut. Wenn ich allerdings die größe des Array darüberhinaus erhöhe, erhalte ich da Ergebnis, das in dem anghängten Bild zu sehen. Ich habe dort eine Art Sinus aufgenommen bzw. versucht. Wie zu erkennen ist, ist dort ein zeitlicher Sprung vorhanden. Habe ich einen grundlegenden Fehler bei der Herangehensweise gemacht? Vielen Dank schon mal!
ich hoffe, dass nun der Anhang erscheint.... Noch weitere Infos: Die Samplingrate ist auf 300 ksps eingestellt und der Controller läuft mit F_cy = 40 MHz. Ich fülle das Array wie folgt
1 | #define ANZ 1000
|
2 | ...
|
3 | |
4 | unsigned short Werte_arr[ANZ]; |
5 | ...
|
6 | |
7 | while (i<ANZ){ |
8 | // Auf ende der Konvertierung warte
|
9 | while (AD1CON1bits.DONE){ |
10 | |
11 | // Wert ins Array schreiben
|
12 | Werte_arr[i] = ADC1BUF0; |
13 | |
14 | // Status-Bit des ADC auf "busy" setzen
|
15 | AD1CON1bits.DONE=0; |
16 | i++; |
17 | };
|
18 | };
|
Vielleicht kann jemand etwas dazu sagen. Vielen Dank schon mal
Probier mal das aus: Werte_arr[i]=i; Wenn du dann keine Gerade hast, dann dürfte das Problem irgendwo beim Übertragen der Daten in den PC liegen.
Ich denke das Problem ist das du vermutlich die Daten an den PC sendest aber in der Zeit keine Messungen mehr gemacht werden. Erst wenn der mit senden Fertig ist werden wieder Werte gemessen und in das Array geschrieben. Kann das sein?
Der Controller hat laut Datenblatt 32kB RAM. Der Build Bericht des Projekts gibt eine Data Memory Usage von 13% aus. Die angehängte Datei zeigt die Ausgabe von
1 | Werte_arr[i]=i; |
i läuft dabei von 0 bis 2000. Wie zu sehen macht die Gerade einen Sprung. Mit dem Debugger konnte ich mir den Speicher anschauen. Das Array wird korrekt mit Werten von 0 bis 1999 gefüllt. Also muss es ja irgendwie an der Datenübertragung oder -konvertierung liegen. Abhängig von der Anzahl der zu übertragneden Daten findet der Sprung entweder früher oder später statt. Der Code zum Übertragen der Daten zum PC sieht wie folgt aus:
1 | char s[10]; // Stringbuffer |
2 | .
|
3 | .
|
4 | .
|
5 | |
6 | while(i<ANZ){ |
7 | |
8 | // Konvertierung von Zahl in String
|
9 | sprintf(s,"%d",Werte_arr[i]); |
10 | |
11 | // Schreibe String an UART
|
12 | mywriteUART((char *)s); |
13 | |
14 | // warte bis UART frei ist bzw. überprüfe Status Bit
|
15 | while(U2STAbits.UTXBF); |
16 | |
17 | // Schreibe an UART
|
18 | // 59 = Semikolon
|
19 | U2TXREG = 59; |
20 | |
21 | i++; |
22 | };
|
Die Funktion mywriteUART((char *)s) sieht so aus:
1 | void mywriteUART(char * temp_ptr){ |
2 | |
3 | while(*temp_ptr != '\0'){ |
4 | |
5 | while(U2STAbits.UTXBF); |
6 | |
7 | U2TXREG = *temp_ptr++; |
8 | |
9 | }
|
10 | }
|
Ich kann da leider kein Problem entdecken. Ich hoffe es kann mir jemand da helfen. Vielen Dank schon mal!!!
Schau dir mal die Daten auf der PC Seite an, z.B. damit: http://www.der-hammer.info/terminal/ Der Code sieht nämlich OK aus, vielleicht liegt das Problem ja auch auf der PC Seite?
Das Problem ist gelöst. Es lag tatsächlich am verwendeten Terminalprogramm. Ich habe nun man das Windows-eigene Tool verwendet. Damit funktioniert es problemlos auch mit großen Werten. Vielen Dank nochmal für die schnelle Hilfe. Eine weitere kleine Frage habe ich allerdings noch: Kann ich mir die Konvertierung in String eigentlich irgendwie sparen? Ich meine, kann ich die reinen binär bzw. integer Werte auf dem PC empfangen?
Matthias H. wrote: > Kann ich mir die Konvertierung in String eigentlich irgendwie sparen? > Ich meine, kann ich die reinen binär bzw. integer Werte auf dem PC > empfangen? Ja und ja. Sende am besten vor dem ersten Byte eine Startsequenz wie sie in den eigentlichen Daten nie vorkommen kann (z.B. 0xFF, 0xFF, da der ADC nur 12bit hat und der Wert daher nie größer als 0x0FFF werden kann). Dann sind die Pakete eindeutig voneinander abgegrenzt. Dann sendest du einfach die beiden Bytes eines Wertes: while(U2STAbits.UTXBF); U2TXREG = Werte_arr[i]>>8; while(U2STAbits.UTXBF); U2TXREG = Werte_arr[i]&255; Am PC suchst du nun die beiden 0xFF und dahinter beginnen dann die Daten. Die Frage ist halt nur wie du die Daten dann am besten in deine Software einliest, mit einem kleinen C Programm auf dem PC sollte das kein Problem sein.
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.