voltloggera0000.ino 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. #include <SPI.h>
  2. #include <TimerOne.h>
  3. #include <digitalWriteFast.h>
  4. #define FASTADC 1
  5. #define CHANNELS 3 /* possible values: 1, 3, 7 */
  6. #define ETHERNET 1
  7. #define SDCARD 2
  8. #define STORETO ETHERNET
  9. //#define STORETO SDCARD
  10. #define HAVE_LEDS
  11. //#define LOCKS
  12. #define DEBUG
  13. #if STORETO == ETHERNET
  14. #include <EthernetV2_0.h>
  15. //#define UDP_BUFSIZE UDP_TX_PACKET_MAX_SIZE
  16. #define UDP_BUFSIZE 768
  17. #define STORAGE_LATENCY 25
  18. #define BUFSIZE UDP_BUFSIZE
  19. #endif
  20. #if STORETO == SDCARD
  21. #include <SdFat.h>
  22. #include <SdFatUtil.h>
  23. Sd2Card sdCard;
  24. #define SD_BLOCKSIZE 512
  25. #define SD_BUFSIZE (SD_BLOCKSIZE + 512)
  26. #define SD_HEADERS "\000voltlogger\000\001\000\000\000VoltloggerA0000\0000"
  27. #define STORAGE_LATENCY 25
  28. #define BUFSIZE SD_BUFSIZE
  29. uint32_t sdWriteBlockAddress;
  30. uint32_t sdCardSizeBlocks;
  31. #endif
  32. #ifdef LOCKS
  33. volatile uint8_t WriteBufferLock_loop = 0;
  34. volatile uint8_t WriteBufferLock_pushValue = 0;
  35. #endif
  36. #if STORETO != ETHERNET
  37. # if STORETO != SDCARD
  38. # error STORETO is not defined
  39. # endif
  40. #endif
  41. #if STORETO == ETHERNET
  42. byte mac[] = {
  43. 0xfe, 0x00, 0x00, 0x00, 0x01, 0x00
  44. };
  45. unsigned int port_local = 30319;
  46. IPAddress ip_remote;
  47. unsigned int port_remote = 30319;
  48. EthernetClient eth;
  49. EthernetUDP udp;
  50. #endif
  51. #if STORETO == SDCARD
  52. File sddumpfile;
  53. #endif
  54. // defines for setting and clearing register bits
  55. #ifndef cbi
  56. #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
  57. #endif
  58. #ifndef sbi
  59. #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
  60. #endif
  61. #define W5200_CS 10
  62. #define SDCARD_CS 4
  63. #define LED_GREEN 2
  64. #define LED_RED 5
  65. #define SS 10
  66. #define nRST 8
  67. #define nPWDN 9
  68. #define nINT 3
  69. /*
  70. extern volatile unsigned long timer0_overflow_count;
  71. unsigned long ticks()
  72. {
  73. return timer0_overflow_count;
  74. }
  75. */
  76. /*
  77. void resetFunc() {
  78. delay(1000000);
  79. }
  80. */
  81. void (*resetFunc)(void) = 0;
  82. unsigned char WriteBuffer[BUFSIZE];
  83. volatile uint16_t WriteBufferFilled;
  84. void pushValue()
  85. {
  86. if (WriteBufferFilled >= BUFSIZE - (1+CHANNELS)*2) {
  87. return;
  88. }
  89. #ifdef LOCKS
  90. WriteBufferLock_pushValue = 1;
  91. if (WriteBufferLock_loop) {
  92. WriteBufferLock_pushValue = 0;
  93. return;
  94. }
  95. #endif
  96. //volatile uint16_t newWriteBufferFilled = WriteBufferFilled;
  97. uint16_t value;
  98. uint16_t timestamp;
  99. timestamp = micros();
  100. WriteBuffer[WriteBufferFilled++] = timestamp;
  101. WriteBuffer[WriteBufferFilled++] = timestamp >> 8;
  102. uint8_t chan = 0;
  103. while (chan < CHANNELS) {
  104. value = analogRead(chan++);
  105. WriteBuffer[WriteBufferFilled++] = value;
  106. WriteBuffer[WriteBufferFilled++] = value >> 8;
  107. }
  108. //WriteBufferFilled = newWriteBufferFilled;
  109. #ifdef LOCKS
  110. WriteBufferLock_pushValue = 0;
  111. #endif
  112. //Serial.println(WriteBufferFilled);
  113. }
  114. /* ========= */
  115. void stateWarning() {
  116. #ifdef HAVE_LEDS
  117. digitalWrite(LED_GREEN, LOW);
  118. delay(250);
  119. digitalWrite(LED_GREEN, HIGH);
  120. delay(250);
  121. digitalWrite(LED_GREEN, LOW);
  122. delay(250);
  123. digitalWrite(LED_GREEN, HIGH);
  124. #endif
  125. delay(250);
  126. return;
  127. }
  128. void setup()
  129. {
  130. Serial.begin(115200);
  131. #ifdef WAIT_FOR_SERIAL
  132. while (!Serial) {
  133. ; // wait for serial port to connect. Needed for Leonardo only
  134. }
  135. #endif
  136. Serial.println("Welcome to VoltloggerA0000!\n");
  137. Serial.println("Starting initialization...");
  138. #ifdef HAVE_LEDS
  139. pinMode(LED_GREEN, OUTPUT);
  140. digitalWrite(LED_GREEN, HIGH);
  141. pinMode(LED_RED, OUTPUT);
  142. digitalWrite(LED_RED, HIGH);
  143. #endif
  144. #if FASTADC
  145. sbi(ADCSRA, ADPS2);
  146. cbi(ADCSRA, ADPS1);
  147. cbi(ADCSRA, ADPS0);
  148. #endif
  149. SPI.setClockDivider(SPI_CLOCK_DIV2);
  150. #if STORETO == ETHERNET
  151. pinMode(SDCARD_CS, OUTPUT);
  152. digitalWrite(SDCARD_CS, HIGH); // disable SD card if one in the slot
  153. #endif
  154. #if STORETO == SDCARD
  155. pinMode(W5200_CS, OUTPUT);
  156. digitalWrite(W5200_CS, HIGH); // disable W5200
  157. #endif
  158. pinMode(SS, OUTPUT);
  159. pinMode(nRST, OUTPUT);
  160. pinMode(nPWDN, OUTPUT);
  161. pinMode(nINT, INPUT);
  162. digitalWrite(nPWDN, LOW); // enable power
  163. digitalWrite(nRST, LOW); // reset W5200
  164. delay(10);
  165. digitalWrite(nRST, HIGH);
  166. delay(200); // wait W5200 work
  167. #if STORETO == ETHERNET
  168. Serial.println("Trying to get an IP-address...");
  169. while(!Ethernet.begin(mac)) {
  170. Serial.println("Retring DHCP...");
  171. stateWarning();
  172. }
  173. Serial.print("Local address: ");
  174. Serial.print(Ethernet.localIP());
  175. Serial.print(":");
  176. Serial.println(port_local);
  177. ip_remote = Ethernet.localIP();
  178. ip_remote[3] = 3;
  179. Serial.print("Remote address: ");
  180. Serial.print(ip_remote);
  181. Serial.print(":");
  182. Serial.println(port_remote);
  183. udp.begin(port_local);
  184. #endif
  185. #if STORETO == SDCARD
  186. Serial.println("Initializing SD card...");
  187. while (!sdCard.begin(SDCARD_CS, SPI_FULL_SPEED)) {
  188. Serial.println("Error: Initialization of the SD card failed or it doesn't present! Retrying...");
  189. stateWarning();
  190. }
  191. sdCardSizeBlocks = sdCard.cardSize();
  192. memset(WriteBuffer, 0, SD_BLOCKSIZE);
  193. memcpy(WriteBuffer, SD_HEADERS, sizeof(SD_HEADERS));
  194. WriteBuffer[13] = CHANNELS;
  195. sdCard.writeBlock(0, WriteBuffer);
  196. sdWriteBlockAddress = 1;
  197. Serial.print("The SD card is initialized. Availiable block-count (512 bytes): ");
  198. Serial.println(sdCardSizeBlocks);
  199. #endif
  200. WriteBufferFilled = 0;
  201. Timer1.initialize(STORAGE_LATENCY * (1 + CHANNELS));
  202. Timer1.attachInterrupt(pushValue);
  203. #ifdef HAVE_LEDS
  204. digitalWrite(LED_RED, LOW);
  205. //digitalWrite(LED_GREEN, LOW);
  206. #endif
  207. Serial.println("Initialization complete.");
  208. }
  209. /* ========= */
  210. //uint16_t count = 0;
  211. void loop()
  212. {
  213. volatile uint16_t oldWriteBufferFilled;
  214. #if STORETO == ETHERNET
  215. udp.beginPacket(ip_remote, port_remote);
  216. oldWriteBufferFilled = WriteBufferFilled;
  217. udp.write(WriteBuffer, WriteBufferFilled);
  218. int newWriteBufferFilled = WriteBufferFilled;
  219. WriteBufferFilled = 0;
  220. if (oldWriteBufferFilled != newWriteBufferFilled) {
  221. udp.write(&WriteBuffer[oldWriteBufferFilled], newWriteBufferFilled - oldWriteBufferFilled);
  222. }
  223. udp.endPacket();
  224. #endif
  225. #if STORETO == SDCARD
  226. /*
  227. count++;
  228. if (count >> 8 != 0) {
  229. Serial.println(count);
  230. count = 0;
  231. }*/
  232. //Serial.println("Waiting for data...");
  233. if (WriteBufferFilled < SD_BLOCKSIZE) {
  234. //pushValue();
  235. return;
  236. }
  237. //Serial.println("Writting the data...");
  238. oldWriteBufferFilled = WriteBufferFilled;
  239. sdCard.writeBlock(sdWriteBlockAddress++, WriteBuffer);
  240. #ifdef LOCKS
  241. WriteBufferLock_loop = 1;
  242. while(WriteBufferLock_pushValue);
  243. #endif
  244. volatile uint16_t leftLen = WriteBufferFilled - oldWriteBufferFilled;
  245. WriteBufferFilled = leftLen;
  246. if (leftLen > 0) {
  247. #ifdef DEBUG
  248. if (leftLen == 512) {
  249. Serial.println("Overflow.");
  250. }
  251. #endif
  252. memcpy(WriteBuffer, &WriteBuffer[SD_BLOCKSIZE], leftLen);
  253. }
  254. #ifdef DEBUG
  255. else {
  256. Serial.println("No data queued");
  257. }
  258. #endif
  259. #ifdef LOCKS
  260. WriteBufferLock_loop = 0;
  261. #endif
  262. while (sdWriteBlockAddress >= sdCardSizeBlocks) {
  263. Serial.println("SD card is full...");
  264. #ifdef HAVE_LEDS
  265. digitalWrite(LED_RED, LOW);
  266. digitalWrite(LED_GREEN, HIGH);
  267. delay(500);
  268. digitalWrite(LED_RED, LOW);
  269. digitalWrite(LED_GREEN, HIGH);
  270. #endif
  271. delay(500);
  272. }
  273. #endif
  274. }
  275. /*** Interrupt routine ADC ready *** /
  276. * ISR(ADC_vect) {
  277. * int aval = ADCL; // store lower byte ADC
  278. * aval += ADCH << 8; // store higher bytes ADC
  279. * if (sendStatus == 0) {
  280. * if (startDelay < 10000) { // do nothing the first x samples
  281. * startDelay++;
  282. * }
  283. * else {
  284. * valueBin[aval] += 1; // increase value bin
  285. * if (valueBin[aval] == 255) { // stop if a bin is full
  286. * sendStatus = 1;
  287. * }
  288. * }
  289. * }
  290. * }
  291. */