Forum: Mikrocontroller und Digitale Elektronik ADC Atmega32 Werte auslesen und auf MMC speichern


von Michael (Gast)


Lesenswert?

Hallo Leute,

ich habe einen Atmega32 (16MHz) mit einer MMC-Karte verbunden und 
benutze die Library von Roland Riegel um mit der MMC-Karte zu 
kommunizieren.

Nun würde ich gerne die Werte, die ich von dem AD-Wandler bekomme auf 
die MMC-Karte speichern.

Wenn ich das folgendermaßen mache, funktioniert das auch einwandfrei:
1
uint16_t analog;
2
char buffer[24];
3
uint8_t data_len;
4
5
ADCSRA |= (1<<ADSC);
6
while (ADCSRA & (1<<ADSC) ) {}
7
analog = ADCL;
8
analog += (ADCH<<8);
9
itoa(analog,buffer,10);
10
strcat(buffer," ");



Und dann wird das ganze mit der Funktion von Roland Riegel auf die 
MMC-Karte geschrieben. Ich erhalte dann Werte zwischen 0 und 1023...


Jetzt möchte ich aber die Effizienz etwas steigern. Um das zu erreichen 
habe ich folgenden Code geschrieben:
1
for(i=0;i<24;i+=2) //in 23 Bytes Daten speichern ins 24te \0
2
  {
3
  ADCSRA |= (1<<ADSC);
4
  while (ADCSRA & (1<<ADSC) ) {}
5
  low = ADCL;
6
  high = ADCH;
7
  buffer[i] = low;
8
  buffer[i+1] = high;
9
}



Und dann wird das ganze wieder auf die MMC-Karte geschrieben.


Wenn ich die MMC-Karte dann auslese soll der Wert wieder in eine 
Dezimalzahl umgewandelt werden.
Das habe ich so realisiert:
1
while(i<zeile.length())
2
{
3
  wert = zeile[i];
4
  res << wert ; // res ist ein File-Handle
5
  wert += (zeile[i+1]<<8);       
6
        
7
  res << "+" << (int)zeile[i+1] ;
8
  cout << "WERT:" << wert << "| " ;       
9
  res << "=" << wert << "|" << endl;
10
          
11
 i+=2;
12
}




Ich habe das so verstanden, dass wenn ich den Wert 544 vom ADC bekomme, 
dass dann 0000 0010 im ADCH und 0010 0000 im ADCL stehen sollte


Kann mir jemand sagen, was ich falsch mache?!?!
Stimmt das Auslesen, stimmt die Wertzuweisung...
Wird der Wert aus ADCH auch richtig in "high" abgespeichert?
(es kommt mir manchmal so vor, als ob das high byte immer das gleiche 
wie am Start einer ganzen Messung wäre.)
Teilweise kommen Werte (umgewandelt) vor, die sich in Regionen von 2 
hoch 32 ansiedeln...

Ich hoffe ich habe mein Problem gut schildern können, alle wichtigen 
Code-Teile und und Spezifikationen geliefert.

Viele Grüße
Michael

von Karl H. (kbuchegg)


Lesenswert?

Michael schrieb:

> Kann mir jemand sagen, was ich falsch mache?!?!

Nicht wirklich.
Vor allen Dingen, weil du dch nicht darüber auslässt, was denn anstelle 
des von dir erhofften passiert.

Aber über eines musst du dir im klaren sein:
Du hast soeben dein MMC File von einem reinen Textfile zu einem 
Binärfile mutiert. Daher kann die Leseroutine nicht so bleiben wie sie 
ist.
Insbesondere ist interessant, ob du diese Tatsache beim Öffnen der Datei 
am PC bzw. beim Lesen vom File berücksichtigen musst. Auch der Datentyp 
von zeile ist dabei nicht uninteressant.

Um erst mal ruszukriegen ob der AVR die Datei so geschrieben hat, wie ds 
so sein soll: Es gibt auch Tools mit denen man die Bytes auf einer MMC 
direkt ansehen kann.

von Michael (Gast)


Lesenswert?

Gute Idee: die Bytes direkt auf der MMC anschauen.
Werd ich gleich mal machen...

>Vor allen Dingen, weil du dch nicht darüber auslässt, was denn anstelle
>des von dir erhofften passiert.

Es werden wilde ZahlenWerte zwischen 300 und 700 ausgegeben. Obwohl es 
ja Werte zwischen 0 und 1023 sein sollten.
Es ist auch keinen Zusammenhang zwischen Sollwert und Istwert 
festzustellen.
(will heißen: wenn der eigentlich 1023 erscheinen sollte erscheint nicht 
700...)



>Aber über eines musst du dir im klaren sein:
>Du hast soeben dein MMC File von einem reinen Textfile zu einem
>Binärfile mutiert.

Wie kann ich den direkt ein Binärfile anlegen, bzw. im Textfile die 
Bytes richtig ablegen



>Daher kann die Leseroutine nicht so bleiben wie sie
>ist.

Was müsste geändert werden?



>Insbesondere ist interessant, ob du diese Tatsache beim Öffnen der Datei
>am PC bzw. beim Lesen vom File berücksichtigen musst.

Hab ich bis jetzt mal nicht gemacht. Wusste davon ja nichts :)



>Auch der Datentyp von zeile ist dabei nicht uninteressant.

es ist ein String.



Also ich versuche dann mal die MMC Karte Byte für Byte anzuschauen.
Ich meld mich dann wieder.

Aber danke schonmal für die schnelle Antwort!!

Grüße

von Michael (Gast)


Lesenswert?

Hey,
also ich hab jetzt mal die MMC-Karte Byte per Byte ausgelesen und 
festgestellt, dass dort die richtigen Werte stehen....

Ich hab am ADC ein Poti hängen und starte bei Vollausschalag
-> es steht auf der MMC-Karte: 0xFF 0x03    (erst low dann high)
wie erwartet!
nun dreh ich langsam gegen Null
-> auf der MMC-Karte gehts über 0xCA 0x02 und 0x93 0x01 nach 0x00 0x00



Da passt also alles.

Wie schreib ich nun die Bytes richtig auf die MMC-Karte, und wie lese 
ich sie richtig aus?
Ich dachte nämlich, dass ich die Bytes einfach so auf die Karte 
(Textdatei) schreiben kann da die Werte ja nur von 0x00 bis 0xFF gehen 
-> kommen ja alle in der ASCII-Tabelle vor...

Grüße

von Karl H. (kbuchegg)


Lesenswert?

Michael schrieb:

> Da passt also alles.
>
> Wie schreib ich nun die Bytes richtig auf die MMC-Karte,

auf der MMC ist alles richtig drauf, so wie du das geschrieben hast, 
Byte für Byte.

> und wie lese
> ich sie richtig aus?

die Umkehrung vom scheiben. Aber Achtung: Das sind jetzt keine Texte 
mehr. Das sind einfach nur Bytes. Daher ist String der falsche Datentyp, 
bzw ReadLine oder was auch immer du zum Lesen benutzt hast. Du hast 
jetzt Bytes und keine Texte mehr.

> -> kommen ja alle in der ASCII-Tabelle vor...

ASCII ist schon lange aus dem Rennen und hat nichts mehr damit zu tun.

von Michael (Gast)


Lesenswert?

Sodale,
habs mit der Hilfe eines Kollegens hinbekommen.
Die Fehler:
 - nicht readline sondern read benutzen
 - gcount verwendet, sonst wird teilweise Müll ausgegeben.

So sieht der Code nun komplett aus:
1
#include <iostream>
2
#include <fstream>
3
#include <string>
4
5
using namespace std;
6
7
int main(int argc, char* argv[]) {
8
    if(argc!=3) {
9
         cout << "Usage: " << argv[0] << " <Eingabedatei> <Ausgabedatei>" << endl; 
10
         return 1;
11
    }
12
13
    ifstream in(argv[1], ios::binary);
14
    ofstream res(argv[2]);
15
16
    if (!in) {
17
         cout << "Fehler beim oeffnen der Datei:" << argv[1] << endl;
18
         return 1;
19
    }
20
    if (!res) {
21
         cout << "Fehler beim erstellen der Datei:" << argv[2] << endl;
22
         return 1;
23
    }
24
    
25
    while(!in.eof()) {
26
       unsigned char buf[256];
27
       in.read((char*)buf, sizeof buf);
28
       size_t size = in.gcount();
29
       for(unsigned char* p = buf; p < &(buf[size]); p += 2) {
30
          unsigned int val = *(p+1) << 8 | *p;
31
          cout << val << endl;
32
          res << val << endl;
33
       }
34
   } 
35
   return 0;
36
}


Grüße
Michael

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.