Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

RawWrite.ino 5.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*
  2. * This sketch illustrates raw write functions in SdFat that
  3. * can be used for high speed data logging. These functions
  4. * are used in the WaveRP library to record audio with the
  5. * Adafruit Wave Shield using the built-in Arduino ADC.
  6. *
  7. * The WaveRP library captures data from the ADC in an ISR
  8. * that is driven driven by timer one. Data is collected in
  9. * two 512 byte buffers and written to the SD card.
  10. *
  11. * This sketch simulates logging from a source that produces
  12. * data at a constant rate of one block every MICROS_PER_BLOCK.
  13. *
  14. * If a high quality SanDisk card is used with this sketch
  15. * no overruns occur and the maximum block write time is
  16. * under 2000 micros.
  17. *
  18. * Note: WaveRP creates a very large file then truncates it
  19. * to the length that is used for a recording. It only takes
  20. * a few seconds to erase a 500 MB file since the card only
  21. * marks the blocks as erased; no data transfer is required.
  22. */
  23. #include <SdFat.h>
  24. #include <SdFatUtil.h>
  25. // SD chip select pin
  26. const uint8_t chipSelect = SS;
  27. // number of blocks in the contiguous file
  28. const uint32_t BLOCK_COUNT = 10000UL;
  29. // time to produce a block of data
  30. const uint32_t MICROS_PER_BLOCK = 10000;
  31. // file system
  32. SdFat sd;
  33. // test file
  34. SdFile file;
  35. // file extent
  36. uint32_t bgnBlock, endBlock;
  37. // Serial output stream
  38. ArduinoOutStream cout(Serial);
  39. //------------------------------------------------------------------------------
  40. // store error strings in flash to save RAM
  41. #define error(s) sd.errorHalt_P(PSTR(s))
  42. //------------------------------------------------------------------------------
  43. // log of first overruns
  44. #define OVER_DIM 20
  45. struct {
  46. uint32_t block;
  47. uint32_t micros;
  48. } over[OVER_DIM];
  49. //------------------------------------------------------------------------------
  50. void setup(void) {
  51. Serial.begin(9600);
  52. while (!Serial) {} // wait for Leonardo
  53. }
  54. //------------------------------------------------------------------------------
  55. void loop(void) {
  56. while (Serial.read() >= 0) {}
  57. // pstr stores strings in flash to save RAM
  58. cout << pstr("Type any character to start\n");
  59. while (Serial.read() <= 0) {}
  60. delay(400); // catch Due reset problem
  61. cout << pstr("Free RAM: ") << FreeRam() << endl;
  62. // initialize the SD card at SPI_FULL_SPEED for best performance.
  63. // try SPI_HALF_SPEED if bus errors occur.
  64. if (!sd.begin(chipSelect, SPI_FULL_SPEED)) sd.initErrorHalt();
  65. // delete possible existing file
  66. sd.remove("RAW.TXT");
  67. // create a contiguous file
  68. if (!file.createContiguous(sd.vwd(), "RAW.TXT", 512UL*BLOCK_COUNT)) {
  69. error("createContiguous failed");
  70. }
  71. // get the location of the file's blocks
  72. if (!file.contiguousRange(&bgnBlock, &endBlock)) {
  73. error("contiguousRange failed");
  74. }
  75. //*********************NOTE**************************************
  76. // NO SdFile calls are allowed while cache is used for raw writes
  77. //***************************************************************
  78. // clear the cache and use it as a 512 byte buffer
  79. uint8_t* pCache = (uint8_t*)sd.vol()->cacheClear();
  80. // fill cache with eight lines of 64 bytes each
  81. memset(pCache, ' ', 512);
  82. for (uint16_t i = 0; i < 512; i += 64) {
  83. // put line number at end of line then CR/LF
  84. pCache[i + 61] = '0' + (i/64);
  85. pCache[i + 62] = '\r';
  86. pCache[i + 63] = '\n';
  87. }
  88. cout << pstr("Start raw write of ") << file.fileSize() << pstr(" bytes at\n");
  89. cout << 512000000UL/MICROS_PER_BLOCK << pstr(" bytes per second\n");
  90. cout << pstr("Please wait ") << (BLOCK_COUNT*MICROS_PER_BLOCK)/1000000UL;
  91. cout << pstr(" seconds\n");
  92. // tell card to setup for multiple block write with pre-erase
  93. if (!sd.card()->writeStart(bgnBlock, BLOCK_COUNT)) {
  94. error("writeStart failed");
  95. }
  96. // init stats
  97. uint16_t overruns = 0;
  98. uint32_t maxWriteTime = 0;
  99. uint32_t t = micros();
  100. uint32_t tNext = t;
  101. // write data
  102. for (uint32_t b = 0; b < BLOCK_COUNT; b++) {
  103. // write must be done by this time
  104. tNext += MICROS_PER_BLOCK;
  105. // put block number at start of first line in block
  106. uint32_t n = b;
  107. for (int8_t d = 5; d >= 0; d--){
  108. pCache[d] = n || d == 5 ? n % 10 + '0' : ' ';
  109. n /= 10;
  110. }
  111. // write a 512 byte block
  112. uint32_t tw = micros();
  113. if (!sd.card()->writeData(pCache)) error("writeData failed");
  114. tw = micros() - tw;
  115. // check for max write time
  116. if (tw > maxWriteTime) {
  117. maxWriteTime = tw;
  118. }
  119. // check for overrun
  120. if (micros() > tNext) {
  121. if (overruns < OVER_DIM) {
  122. over[overruns].block = b;
  123. over[overruns].micros = tw;
  124. }
  125. overruns++;
  126. // advance time to reflect overrun
  127. tNext = micros();
  128. }
  129. else {
  130. // wait for time to write next block
  131. while(micros() < tNext);
  132. }
  133. }
  134. // total write time
  135. t = micros() - t;
  136. // end multiple block write mode
  137. if (!sd.card()->writeStop()) error("writeStop failed");
  138. cout << pstr("Done\n");
  139. cout << pstr("Elapsed time: ") << setprecision(3)<< 1.e-6*t;
  140. cout << pstr(" seconds\n");
  141. cout << pstr("Max write time: ") << maxWriteTime << pstr(" micros\n");
  142. cout << pstr("Overruns: ") << overruns << endl;
  143. if (overruns) {
  144. uint8_t n = overruns > OVER_DIM ? OVER_DIM : overruns;
  145. cout << pstr("fileBlock,micros") << endl;
  146. for (uint8_t i = 0; i < n; i++) {
  147. cout << over[i].block << ',' << over[i].micros << endl;
  148. }
  149. }
  150. // close file for next pass of loop
  151. file.close();
  152. Serial.println();
  153. }