You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ThreeCards.ino 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /*
  2. * Example use of three SD cards.
  3. */
  4. #include <SPI.h>
  5. #include <SdFat.h>
  6. #include <SdFatUtil.h>
  7. #if SD_SPI_CONFIGURATION >= 3 // Must be set in SdFat/SdFatConfig.h
  8. // SD1 is a microSD on hardware SPI pins 50-52
  9. // Using my fast custom SPI
  10. SdFat sd1;
  11. const uint8_t SD1_CS = 53;
  12. // SD2 is a Catalex shield on hardware SPI pins 50-52
  13. // Using the standard Arduino SPI library
  14. SdFatLibSpi sd2;
  15. const uint8_t SD2_CS = 4;
  16. // SD3 is a Adafruit data logging shield on pins 10-13
  17. // Using Software SPI
  18. SdFatSoftSpi<12, 11, 13> sd3;
  19. const uint8_t SD3_CS = 10;
  20. const uint8_t BUF_DIM = 100;
  21. uint8_t buf[BUF_DIM];
  22. const uint32_t FILE_SIZE = 1000000;
  23. const uint16_t NWRITE = FILE_SIZE/BUF_DIM;
  24. //------------------------------------------------------------------------------
  25. // print error msg, any SD error codes, and halt.
  26. // store messages in flash
  27. #define errorExit(msg) errorHalt(F(msg))
  28. #define initError(msg) initErrorHalt(F(msg))
  29. //------------------------------------------------------------------------------
  30. void list() {
  31. // list current directory on all cards
  32. Serial.println(F("------sd1-------"));
  33. sd1.ls("/", LS_SIZE|LS_R);
  34. Serial.println(F("------sd2-------"));
  35. sd2.ls("/", LS_SIZE|LS_R);
  36. Serial.println(F("------sd3-------"));
  37. sd3.ls("/", LS_SIZE|LS_R);
  38. Serial.println(F("---------------------"));
  39. }
  40. //------------------------------------------------------------------------------
  41. void setup() {
  42. Serial.begin(9600);
  43. while (!Serial) {} // wait for Leonardo
  44. Serial.print(F("FreeRam: "));
  45. Serial.println(FreeRam());
  46. // fill buffer with known data
  47. for (int i = 0; i < sizeof(buf); i++) {
  48. buf[i] = i;
  49. }
  50. Serial.println(F("type any character to start"));
  51. while (Serial.read() <= 0) {}
  52. // disable sd2 while initializing sd1
  53. pinMode(SD2_CS, OUTPUT);
  54. digitalWrite(SD2_CS, HIGH);
  55. // initialize the first card
  56. if (!sd1.begin(SD1_CS)) {
  57. sd1.initError("sd1:");
  58. }
  59. // initialize the second card
  60. if (!sd2.begin(SD2_CS)) {
  61. sd2.initError("sd2:");
  62. }
  63. // initialize the third card
  64. if (!sd3.begin(SD3_CS)) {
  65. sd3.initError("sd3:");
  66. }
  67. Serial.println(F("Cards OK - creating directories"));
  68. // create Dir1 on sd1 if it does not exist
  69. if (!sd1.exists("/Dir1")) {
  70. if (!sd1.mkdir("/Dir1")) {
  71. sd1.errorExit("sd1.mkdir");
  72. }
  73. }
  74. // make /Dir1 the default directory for sd1
  75. if (!sd1.chdir("/Dir1")) {
  76. sd1.errorExit("sd1.chdir");
  77. }
  78. // create Dir2 on sd2 if it does not exist
  79. if (!sd2.exists("/Dir2")) {
  80. if (!sd2.mkdir("/Dir2")) {
  81. sd2.errorExit("sd2.mkdir");
  82. }
  83. }
  84. // make /Dir2 the default directory for sd2
  85. if (!sd2.chdir("/Dir2")) {
  86. sd2.errorExit("sd2.chdir");
  87. }
  88. // create Dir3 on sd3 if it does not exist
  89. if (!sd3.exists("/Dir3")) {
  90. if (!sd3.mkdir("/Dir3")) {
  91. sd2.errorExit("sd3.mkdir");
  92. }
  93. }
  94. // make /Dir3 the default directory for sd3
  95. if (!sd3.chdir("/Dir3")) {
  96. sd3.errorExit("sd3.chdir");
  97. }
  98. Serial.println(F("Directories created - removing old files"));
  99. if (sd1.exists("TEST1.bin")) {
  100. if (!sd1.remove("TEST1.bin")) {
  101. sd1.errorExit("sd1.remove");
  102. }
  103. }
  104. if (sd2.exists("TEST2.bin")) {
  105. if (!sd2.remove("TEST2.bin")) {
  106. sd2.errorExit("sd2.remove");
  107. }
  108. }
  109. if (sd3.exists("TEST3.bin")) {
  110. if (!sd3.remove("TEST3.bin")) {
  111. sd2.errorExit("sd3.remove");
  112. }
  113. }
  114. Serial.println("Initial SD directories");
  115. list();
  116. // create or open /Dir1/TEST1.bin and truncate it to zero length
  117. SdFile file1;
  118. if (!file1.open(&sd1, "TEST1.bin", O_RDWR | O_CREAT | O_TRUNC)) {
  119. sd1.errorExit("file1");
  120. }
  121. Serial.println(F("Writing SD1:/Dir1/TEST1.bin"));
  122. // write data to /Dir1/TEST1.bin on sd1
  123. for (int i = 0; i < NWRITE; i++) {
  124. if (file1.write(buf, sizeof(buf)) != sizeof(buf)) {
  125. sd1.errorExit("sd1.write");
  126. }
  127. }
  128. file1.sync();
  129. list();
  130. // create or open /Dir2/TEST2.bin and truncate it to zero length
  131. SdFile file2;
  132. if (!file2.open(&sd2, "TEST2.bin", O_RDWR | O_CREAT | O_TRUNC)) {
  133. sd2.errorExit("file2");
  134. }
  135. Serial.println(F("Copying SD1:/Dir1/TEST1.bin to SD2::/Dir2/TEST2.bin"));
  136. // copy file1 to file2
  137. file1.rewind();
  138. uint32_t t = millis();
  139. while (1) {
  140. int n = file1.read(buf, sizeof(buf));
  141. if (n < 0) {
  142. sd1.errorExit("read1");
  143. }
  144. if (n == 0) {
  145. break;
  146. }
  147. if (file2.write(buf, n) != n) {
  148. sd2.errorExit("write3");
  149. }
  150. }
  151. t = millis() - t;
  152. file2.sync();
  153. Serial.print(F("File size: "));
  154. Serial.println(file2.fileSize());
  155. Serial.print(F("Copy time: "));
  156. Serial.print(t);
  157. Serial.println(F(" millis"));
  158. list();
  159. // create or open /Dir3/TEST3.bin and truncate it to zero length
  160. SdFile file3;
  161. if (!file3.open(&sd3, "TEST3.bin", O_RDWR | O_CREAT | O_TRUNC)) {
  162. sd3.errorExit("file3");
  163. }
  164. file2.rewind();
  165. Serial.println(F("Copying SD2:/Dir2/TEST2.bin to SD3:/Dir3/TEST3.bin"));
  166. while (1) {
  167. int n = file2.read(buf, sizeof(buf));
  168. if (n == 0) {
  169. break;
  170. }
  171. if (n != sizeof(buf)) {
  172. sd2.errorExit("read2");
  173. }
  174. if (file3.write(buf, n) != n) {
  175. sd3.errorExit("write2");
  176. }
  177. }
  178. file3.sync();
  179. list();
  180. // Verify content of file3
  181. file3.rewind();
  182. Serial.println(F("Verifying content of TEST3.bin"));
  183. for (int i = 0; i < NWRITE; i++) {
  184. if (file3.read(buf, sizeof(buf)) != sizeof(buf)) {
  185. sd3.errorExit("sd3.read");
  186. }
  187. for (int j = 0; j < sizeof(buf); j++) {
  188. if (j != buf[j]) {
  189. sd3.errorExit("Verify error");
  190. }
  191. }
  192. }
  193. Serial.println(F("Done - Verify OK"));
  194. file1.close();
  195. file2.close();
  196. file3.close();
  197. }
  198. //------------------------------------------------------------------------------
  199. void loop() {}
  200. #else // SD_SPI_CONFIGURATION >= 3
  201. #error SD_SPI_CONFIGURATION must be set to 3 in SdFat/SdFatConfig.h
  202. #endif //SD_SPI_CONFIGURATION >= 3