Forum: Mikrocontroller und Digitale Elektronik dsPIC33F: Messung mit ADC und serielle Übertragung


von megagad (Gast)


Lesenswert?

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!

von (prx) A. K. (prx)


Lesenswert?

Da hängt wie üblich nix.

von Andreas T. (Gast)


Angehängte Dateien:

Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

Wieviel RAM?

von Benedikt K. (benedikt)


Lesenswert?

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.

von Andreas R. (blackpuma)


Lesenswert?

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?

von Andreas T. (Gast)


Angehängte Dateien:

Lesenswert?

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!!!

von Benedikt K. (benedikt)


Lesenswert?

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?

von Andreas T. (Gast)


Lesenswert?

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?

von Benedikt K. (benedikt)


Lesenswert?

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