Forum: Mikrocontroller und Digitale Elektronik Arduino SD Card Modul


von Lukas D. (programmierer12)


Lesenswert?

Hallo zusammen,
ich habe ein wirkliches Problem: ich seit einiger Zeit einen Datenlogger 
in Planung, den ich gestern Abend auf eine Lochrasterplatine gelötet 
habe. Nun habe ich auch ein SD-Karten-Modul von 
Catalex(http://www.amazon.de/gp/product/B00QIKJP5W?psc=1&redirect=true&ref_=oh_aui_detailpage_o06_s00) 
direkt auf die Platine gelötet. Nach der Fertigstellung heute morgen hat 
das ganze noch wunderbar funktioniert, nachdem ich das ganze aber in ein 
Gehäuse gepackt habe ging Garnichts mehr! Also habe ich die Platine 
wieder aus dem Gehäuse genommen und nochmal alle Verbindungen geprüft - 
Alles in Ordnung und so wie zuvor. Jetzt probiere ich schon den ganzen 
Tag herum wie ich das SD-Modul wieder dazu bringen kann zu schreiben. 
Wenn ich den SDInfo Sketch von der sdFat-library ausführe bekomme ich 
immer entweder die Fehlermeldung
1
cardBegin failed
2
SD errorCode: 0X1
3
SD errorData: 0X0
oder
1
cardBegin failed
2
SD errorCode: 0X1 
3
SD errorData: 0XFF
Das Komische daran ist, dass ich an der Schaltung nichts verändert habe 
und es von jetzt auf gleich nicht mehr funktioniert hat!!!
Bitte helft mir ich bin echt am verzweifeln!

MFG
programmierer12

von Falk B. (falk)


Lesenswert?

Wackelkontakte?
Kalte Lötstellen?
Kurzschlüsse?

Siehe Fehlersuche.

von W.A. (Gast)


Lesenswert?

Lukas D. schrieb:
> Jetzt probiere ich schon den ganzen
> Tag herum wie ich das SD-Modul wieder dazu bringen kann zu schreiben.

Wenn die Hardware ok ist, die Versorgungsspannung stabil, die Karte 
richtig funktioniert/formatiert ist und die Software fehlerfrei ist:

Einfach einschalten.
An kreuzenden Wasseradern und Erdstrahlen wird es kaum liegen.

von Reto W. (Firma: Swissbit.com) (swissbit)


Lesenswert?

Hi,

Leider wird dir so niemand sagen können wo das Problem liegt.
Hast du ein Oszilloskop oder Logic Analyser um die Signale 
aufzuzeichnen?
Funktioniert die SD Karte in einem anderen Leser?

Gruss

: Bearbeitet durch User
von Lukas D. (programmierer12)


Lesenswert?

Erstmal sorry, dass ich erst jetzt wieder antworten kann ;)

Falk B. schrieb:
> Wackelkontakte?
> Kalte Lötstellen?
> Kurzschlüsse?

Danach habe ich schon geschaut und mein Durchgangsprüfer hat keine 
Anzeichen für einen Kurzschluss oder einen Wackelkontakt/Kalte Lötstelle 
gegeben. Die einzige Stelle die ich gefunden habe, habe ich sofort 
nachgelötet und somit einen guten Kontakt wiederhergestellt.

W.A. schrieb:
> Wenn die Hardware ok ist, die Versorgungsspannung stabil, die Karte
> richtig funktioniert/formatiert ist und die Software fehlerfrei ist:
>
> Einfach einschalten.
> An kreuzenden Wasseradern und Erdstrahlen wird es kaum liegen.

Ich bin nicht blöd, auch wenn du mich anscheinend dafür hältst !
Das Einschalten habe ich nicht vergessen und der LM7805 mit passenden 
Kondensatoren sollte eigentlich eine ausreichend stabile Stromversorgung 
garantieren.

Reto W. schrieb:
> Leider wird dir so niemand sagen können wo das Problem liegt.
> Hast du ein Oszilloskop oder Logic Analyser um die Signale
> aufzuzeichnen?
> Funktioniert die SD Karte in einem anderen Leser?

Als erstes einmal danke für den ersten richtig brauchbaren Beitrag auf 
meine Frage! Ja ich besitze seit ca. einer Woche ein Oszilloskop, womit 
ich jedoch deshalb noch nicht sooo gut umgehen kann bzw. ich weiß noch 
nicht so richtig wie ich jetzt aus den Signalen einen Fehler ablesen 
kann schäm. Einen Logic Analyser besitze ich nicht. Und ja die 
SD-Karte funktioniert in einem anderen Cardreader (am PC) hervorragend. 
Sie ist 4 GB groß und mit FAT32 formatiert, woran es eigentlich nicht 
liegen kann, da es vorher ja noch ging. Könntest du mit eventuell 
schildern wie welche Signale messen muss, um eine Aussage treffen zu 
können :).

von Jim M. (turboj)


Lesenswert?

Lukas D. schrieb:
> Ja ich besitze seit ca. einer Woche ein Oszilloskop, womit
> ich jedoch deshalb noch nicht sooo gut umgehen kann bzw. ich weiß noch
> nicht so richtig wie ich jetzt aus den Signalen einen Fehler ablesen
> kann

Das wird bei SD Karten auch schwierig, da die öffentlich einsehbaren 
Dokus AFAIK keine SPI Waveforms zum Vergleichen haben. Man könnte aber 
schauen ob der SPI Takt schön rechteckig ist, die Frequenz stimmt 
(Frequenz <400 kHz bei der Initialisierung, <=25 MHz danach) und ob der 
Pegelwandler funktioniert.


Ansonsten würde ich den Fehler immer zuerst in Quellcode suchen, den 
hast Du hier aber noch nicht gepostet.

von Lukas D. (programmierer12)


Lesenswert?

Jim M. schrieb:
> Das wird bei SD Karten auch schwierig, da die öffentlich einsehbaren
> Dokus AFAIK keine SPI Waveforms zum Vergleichen haben. Man könnte aber
> schauen ob der SPI Takt schön rechteckig ist, die Frequenz stimmt
> (Frequenz <400 kHz bei der Initialisierung, <=25 MHz danach) und ob der
> Pegelwandler funktioniert.
>
> Ansonsten würde ich den Fehler immer zuerst in Quellcode suchen, den
> hast Du hier aber noch nicht gepostet.

Wo soll ich denn meine Probes anschließen (hab ein 4-Kanal Oszi). An 
MISO, MOSI, SCK oder CS?

Sorry hier der Quellcode von der SDFat-library:
1
/*
2
 * This program attempts to initialize an SD card and analyze its structure.
3
 */
4
#include <SPI.h>
5
#include <SdFat.h>
6
/*
7
 * SD chip select pin.  Common values are:
8
 *
9
 * Arduino Ethernet shield, pin 4.
10
 * SparkFun SD shield, pin 8.
11
 * Adafruit SD shields and modules, pin 10.
12
 * Default SD chip select is the SPI SS pin.
13
 */
14
const uint8_t SD_CHIP_SELECT = 5;
15
/*
16
 * Set DISABLE_CHIP_SELECT to disable a second SPI device.
17
 * For example, with the Ethernet shield, set DISABLE_CHIP_SELECT
18
 * to 10 to disable the Ethernet controller.
19
 */
20
const int8_t DISABLE_CHIP_SELECT = -1;
21
SdFat sd;
22
23
// serial output steam
24
ArduinoOutStream cout(Serial);
25
26
// global for card size
27
uint32_t cardSize;
28
29
// global for card erase size
30
uint32_t eraseSize;
31
//------------------------------------------------------------------------------
32
// store error strings in flash
33
#define sdErrorMsg(msg) sdErrorMsg_F(F(msg));
34
void sdErrorMsg_F(const __FlashStringHelper* str) {
35
  cout << str << endl;
36
  if (sd.card()->errorCode()) {
37
    cout << F("SD errorCode: ");
38
    cout << hex << int(sd.card()->errorCode()) << endl;
39
    cout << F("SD errorData: ");
40
    cout << int(sd.card()->errorData()) << dec << endl;
41
  }
42
}
43
//------------------------------------------------------------------------------
44
uint8_t cidDmp() {
45
  cid_t cid;
46
  if (!sd.card()->readCID(&cid)) {
47
    sdErrorMsg("readCID failed");
48
    return false;
49
  }
50
  cout << F("\nManufacturer ID: ");
51
  cout << hex << int(cid.mid) << dec << endl;
52
  cout << F("OEM ID: ") << cid.oid[0] << cid.oid[1] << endl;
53
  cout << F("Product: ");
54
  for (uint8_t i = 0; i < 5; i++) {
55
    cout << cid.pnm[i];
56
  }
57
  cout << F("\nVersion: ");
58
  cout << int(cid.prv_n) << '.' << int(cid.prv_m) << endl;
59
  cout << F("Serial number: ") << hex << cid.psn << dec << endl;
60
  cout << F("Manufacturing date: ");
61
  cout << int(cid.mdt_month) << '/';
62
  cout << (2000 + cid.mdt_year_low + 10 * cid.mdt_year_high) << endl;
63
  cout << endl;
64
  return true;
65
}
66
//------------------------------------------------------------------------------
67
uint8_t csdDmp() {
68
  csd_t csd;
69
  uint8_t eraseSingleBlock;
70
  if (!sd.card()->readCSD(&csd)) {
71
    sdErrorMsg("readCSD failed");
72
    return false;
73
  }
74
  if (csd.v1.csd_ver == 0) {
75
    eraseSingleBlock = csd.v1.erase_blk_en;
76
    eraseSize = (csd.v1.sector_size_high << 1) | csd.v1.sector_size_low;
77
  } else if (csd.v2.csd_ver == 1) {
78
    eraseSingleBlock = csd.v2.erase_blk_en;
79
    eraseSize = (csd.v2.sector_size_high << 1) | csd.v2.sector_size_low;
80
  } else {
81
    cout << F("csd version error\n");
82
    return false;
83
  }
84
  eraseSize++;
85
  cout << F("cardSize: ") << 0.000512*cardSize;
86
  cout << F(" MB (MB = 1,000,000 bytes)\n");
87
88
  cout << F("flashEraseSize: ") << int(eraseSize) << F(" blocks\n");
89
  cout << F("eraseSingleBlock: ");
90
  if (eraseSingleBlock) {
91
    cout << F("true\n");
92
  } else {
93
    cout << F("false\n");
94
  }
95
  return true;
96
}
97
//------------------------------------------------------------------------------
98
// print partition table
99
uint8_t partDmp() {
100
  cache_t *p = sd.vol()->cacheClear();
101
  if (!p) {
102
    sdErrorMsg("cacheClear failed");
103
    return false;
104
  }
105
  if (!sd.card()->readBlock(0, p->data)) {
106
    sdErrorMsg("read MBR failed");
107
    return false;
108
  }
109
  for (uint8_t ip = 1; ip < 5; ip++) {
110
    part_t *pt = &p->mbr.part[ip - 1];
111
    if ((pt->boot & 0X7F) != 0 || pt->firstSector > cardSize) {
112
      cout << F("\nNo MBR. Assuming Super Floppy format.\n");
113
      return true;
114
    }
115
  }
116
  cout << F("\nSD Partition Table\n");
117
  cout << F("part,boot,type,start,length\n");
118
  for (uint8_t ip = 1; ip < 5; ip++) {
119
    part_t *pt = &p->mbr.part[ip - 1];
120
    cout << int(ip) << ',' << hex << int(pt->boot) << ',' << int(pt->type);
121
    cout << dec << ',' << pt->firstSector <<',' << pt->totalSectors << endl;
122
  }
123
  return true;
124
}
125
//------------------------------------------------------------------------------
126
void volDmp() {
127
  cout << F("\nVolume is FAT") << int(sd.vol()->fatType()) << endl;
128
  cout << F("blocksPerCluster: ") << int(sd.vol()->blocksPerCluster()) << endl;
129
  cout << F("clusterCount: ") << sd.vol()->clusterCount() << endl;
130
  cout << F("freeClusters: ");
131
  uint32_t volFree = sd.vol()->freeClusterCount();
132
  cout <<  volFree << endl;
133
  float fs = 0.000512*volFree*sd.vol()->blocksPerCluster();
134
  cout << F("freeSpace: ") << fs << F(" MB (MB = 1,000,000 bytes)\n");
135
  cout << F("fatStartBlock: ") << sd.vol()->fatStartBlock() << endl;
136
  cout << F("fatCount: ") << int(sd.vol()->fatCount()) << endl;
137
  cout << F("blocksPerFat: ") << sd.vol()->blocksPerFat() << endl;
138
  cout << F("rootDirStart: ") << sd.vol()->rootDirStart() << endl;
139
  cout << F("dataStartBlock: ") << sd.vol()->dataStartBlock() << endl;
140
  if (sd.vol()->dataStartBlock() % eraseSize) {
141
    cout << F("Data area is not aligned on flash erase boundaries!\n");
142
    cout << F("Download and use formatter from www.sdsd.card()->org/consumer!\n");
143
  }
144
}
145
//------------------------------------------------------------------------------
146
void setup() {
147
  Serial.begin(9600);
148
  while(!Serial) {}  // wait for Leonardo
149
150
  // use uppercase in hex and use 0X base prefix
151
  cout << uppercase << showbase << endl;
152
153
  // pstr stores strings in flash to save RAM
154
  cout << F("SdFat version: ") << SD_FAT_VERSION << endl;
155
  if (DISABLE_CHIP_SELECT < 0) {
156
    cout << F(
157
           "\nAssuming the SD is the only SPI device.\n"
158
           "Edit DISABLE_CHIP_SELECT to disable another device.\n");
159
  } else {
160
    cout << F("\nDisabling SPI device on pin ");
161
    cout << int(DISABLE_CHIP_SELECT) << endl;
162
    pinMode(DISABLE_CHIP_SELECT, OUTPUT);
163
    digitalWrite(DISABLE_CHIP_SELECT, HIGH);
164
  }
165
  cout << F("\nAssuming the SD chip select pin is: ") <<int(SD_CHIP_SELECT);
166
  cout << F("\nEdit SD_CHIP_SELECT to change the SD chip select pin.\n");
167
}
168
//------------------------------------------------------------------------------
169
void loop() {
170
  // read any existing Serial data
171
  while (Serial.read() >= 0) {}
172
173
  // pstr stores strings in flash to save RAM
174
  cout << F("\ntype any character to start\n");
175
  while (Serial.read() <= 0) {}
176
  delay(400);  // catch Due reset problem
177
178
  uint32_t t = millis();
179
  // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with
180
  // breadboards.  use SPI_FULL_SPEED for better performance.
181
  if (!sd.cardBegin(SD_CHIP_SELECT, SPI_HALF_SPEED)) {
182
    sdErrorMsg("\ncardBegin failed");
183
    return;
184
  }
185
  t = millis() - t;
186
187
  cardSize = sd.card()->cardSize();
188
  if (cardSize == 0) {
189
    sdErrorMsg("cardSize failed");
190
    return;
191
  }
192
  cout << F("\ninit time: ") << t << " ms" << endl;
193
  cout << F("\nCard type: ");
194
  switch (sd.card()->type()) {
195
  case SD_CARD_TYPE_SD1:
196
    cout << F("SD1\n");
197
    break;
198
199
  case SD_CARD_TYPE_SD2:
200
    cout << F("SD2\n");
201
    break;
202
203
  case SD_CARD_TYPE_SDHC:
204
    if (cardSize < 70000000) {
205
      cout << F("SDHC\n");
206
    } else {
207
      cout << F("SDXC\n");
208
    }
209
    break;
210
211
  default:
212
    cout << F("Unknown\n");
213
  }
214
  if (!cidDmp()) {
215
    return;
216
  }
217
  if (!csdDmp()) {
218
    return;
219
  }
220
  uint32_t ocr;
221
  if (!sd.card()->readOCR(&ocr)) {
222
    sdErrorMsg("\nreadOCR failed");
223
    return;
224
  }
225
  cout << F("OCR: ") << hex << ocr << dec << endl;
226
  if (!partDmp()) {
227
    return;
228
  }
229
  if (!sd.fsBegin()) {
230
    sdErrorMsg("\nFile System initialization failed.\n");
231
    return;
232
  }
233
  volDmp();
234
}

Tut mir leid wenn das zu viel war ;) aber ich habe das Example so 
gelassen ausßer den CS-Pin, den ich auf 5 gesetzt habe.

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.