123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356 |
- #include <SPI.h>
- #include <TimerOne.h>
- #include <digitalWriteFast.h>
- #define FASTADC 1
- #define CHANNELS 3 /* possible values: 1, 3, 7 */
- #define ETHERNET 1
- #define SDCARD 2
- #define STORETO ETHERNET
- //#define STORETO SDCARD
- #define HAVE_LEDS
- //#define LOCKS
- #define DEBUG
- #if STORETO == ETHERNET
- #include <EthernetV2_0.h>
- //#define UDP_BUFSIZE UDP_TX_PACKET_MAX_SIZE
- #define UDP_BUFSIZE 768
- #define STORAGE_LATENCY 25
- #define BUFSIZE UDP_BUFSIZE
- #endif
- #if STORETO == SDCARD
- #include <SdFat.h>
- #include <SdFatUtil.h>
- Sd2Card sdCard;
- #define SD_BLOCKSIZE 512
- #define SD_BUFSIZE (SD_BLOCKSIZE + 512)
- #define SD_HEADERS "\000voltlogger\000\001\000\000\000VoltloggerA0000\0000"
- #define STORAGE_LATENCY 25
- #define BUFSIZE SD_BUFSIZE
- uint32_t sdWriteBlockAddress;
- uint32_t sdCardSizeBlocks;
- #endif
- #ifdef LOCKS
- volatile uint8_t WriteBufferLock_loop = 0;
- volatile uint8_t WriteBufferLock_pushValue = 0;
- #endif
- #if STORETO != ETHERNET
- # if STORETO != SDCARD
- # error STORETO is not defined
- # endif
- #endif
- #if STORETO == ETHERNET
- byte mac[] = {
- 0xfe, 0x00, 0x00, 0x00, 0x01, 0x00
- };
- unsigned int port_local = 30319;
- IPAddress ip_remote;
- unsigned int port_remote = 30319;
- EthernetClient eth;
- EthernetUDP udp;
- #endif
- #if STORETO == SDCARD
- File sddumpfile;
- #endif
- // defines for setting and clearing register bits
- #ifndef cbi
- #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
- #endif
- #ifndef sbi
- #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
- #endif
- #define W5200_CS 10
- #define SDCARD_CS 4
- #define LED_GREEN 2
- #define LED_RED 5
- #define SS 10
- #define nRST 8
- #define nPWDN 9
- #define nINT 3
- /*
- extern volatile unsigned long timer0_overflow_count;
- unsigned long ticks()
- {
- return timer0_overflow_count;
- }
- */
- /*
- void resetFunc() {
- delay(1000000);
- }
- */
- void (*resetFunc)(void) = 0;
- unsigned char WriteBuffer[BUFSIZE];
- volatile uint16_t WriteBufferFilled;
- void pushValue()
- {
- if (WriteBufferFilled >= BUFSIZE - (1+CHANNELS)*2) {
- return;
- }
- #ifdef LOCKS
- WriteBufferLock_pushValue = 1;
- if (WriteBufferLock_loop) {
- WriteBufferLock_pushValue = 0;
- return;
- }
- #endif
- //volatile uint16_t newWriteBufferFilled = WriteBufferFilled;
- uint16_t value;
- uint16_t timestamp;
- timestamp = micros();
- WriteBuffer[WriteBufferFilled++] = timestamp;
- WriteBuffer[WriteBufferFilled++] = timestamp >> 8;
-
- uint8_t chan = 0;
- while (chan < CHANNELS) {
- value = analogRead(chan++);
- WriteBuffer[WriteBufferFilled++] = value;
- WriteBuffer[WriteBufferFilled++] = value >> 8;
- }
- //WriteBufferFilled = newWriteBufferFilled;
- #ifdef LOCKS
- WriteBufferLock_pushValue = 0;
- #endif
- //Serial.println(WriteBufferFilled);
- }
- /* ========= */
- void stateWarning() {
- #ifdef HAVE_LEDS
- digitalWrite(LED_GREEN, LOW);
- delay(250);
- digitalWrite(LED_GREEN, HIGH);
- delay(250);
- digitalWrite(LED_GREEN, LOW);
- delay(250);
- digitalWrite(LED_GREEN, HIGH);
- #endif
- delay(250);
- return;
- }
- void setup()
- {
- Serial.begin(115200);
- #ifdef WAIT_FOR_SERIAL
- while (!Serial) {
- ; // wait for serial port to connect. Needed for Leonardo only
- }
- #endif
- Serial.println("Welcome to VoltloggerA0000!\n");
- Serial.println("Starting initialization...");
- #ifdef HAVE_LEDS
- pinMode(LED_GREEN, OUTPUT);
- digitalWrite(LED_GREEN, HIGH);
- pinMode(LED_RED, OUTPUT);
- digitalWrite(LED_RED, HIGH);
- #endif
- #if FASTADC
- sbi(ADCSRA, ADPS2);
- cbi(ADCSRA, ADPS1);
- cbi(ADCSRA, ADPS0);
- #endif
- SPI.setClockDivider(SPI_CLOCK_DIV2);
- #if STORETO == ETHERNET
-
- pinMode(SDCARD_CS, OUTPUT);
- digitalWrite(SDCARD_CS, HIGH); // disable SD card if one in the slot
- #endif
- #if STORETO == SDCARD
- pinMode(W5200_CS, OUTPUT);
- digitalWrite(W5200_CS, HIGH); // disable W5200
- #endif
- pinMode(SS, OUTPUT);
- pinMode(nRST, OUTPUT);
- pinMode(nPWDN, OUTPUT);
- pinMode(nINT, INPUT);
- digitalWrite(nPWDN, LOW); // enable power
- digitalWrite(nRST, LOW); // reset W5200
- delay(10);
- digitalWrite(nRST, HIGH);
- delay(200); // wait W5200 work
- #if STORETO == ETHERNET
- Serial.println("Trying to get an IP-address...");
- while(!Ethernet.begin(mac)) {
- Serial.println("Retring DHCP...");
- stateWarning();
- }
- Serial.print("Local address: ");
- Serial.print(Ethernet.localIP());
- Serial.print(":");
- Serial.println(port_local);
- ip_remote = Ethernet.localIP();
- ip_remote[3] = 3;
- Serial.print("Remote address: ");
- Serial.print(ip_remote);
- Serial.print(":");
- Serial.println(port_remote);
- udp.begin(port_local);
- #endif
- #if STORETO == SDCARD
- Serial.println("Initializing SD card...");
-
- while (!sdCard.begin(SDCARD_CS, SPI_FULL_SPEED)) {
- Serial.println("Error: Initialization of the SD card failed or it doesn't present! Retrying...");
- stateWarning();
- }
- sdCardSizeBlocks = sdCard.cardSize();
- memset(WriteBuffer, 0, SD_BLOCKSIZE);
- memcpy(WriteBuffer, SD_HEADERS, sizeof(SD_HEADERS));
- WriteBuffer[13] = CHANNELS;
- sdCard.writeBlock(0, WriteBuffer);
- sdWriteBlockAddress = 1;
- Serial.print("The SD card is initialized. Availiable block-count (512 bytes): ");
- Serial.println(sdCardSizeBlocks);
- #endif
- WriteBufferFilled = 0;
- Timer1.initialize(STORAGE_LATENCY * (1 + CHANNELS));
- Timer1.attachInterrupt(pushValue);
- #ifdef HAVE_LEDS
- digitalWrite(LED_RED, LOW);
- //digitalWrite(LED_GREEN, LOW);
- #endif
- Serial.println("Initialization complete.");
-
- }
- /* ========= */
- //uint16_t count = 0;
- void loop()
- {
-
- volatile uint16_t oldWriteBufferFilled;
- #if STORETO == ETHERNET
- udp.beginPacket(ip_remote, port_remote);
- oldWriteBufferFilled = WriteBufferFilled;
- udp.write(WriteBuffer, WriteBufferFilled);
- int newWriteBufferFilled = WriteBufferFilled;
- WriteBufferFilled = 0;
- if (oldWriteBufferFilled != newWriteBufferFilled) {
- udp.write(&WriteBuffer[oldWriteBufferFilled], newWriteBufferFilled - oldWriteBufferFilled);
- }
- udp.endPacket();
- #endif
- #if STORETO == SDCARD
- /*
- count++;
- if (count >> 8 != 0) {
- Serial.println(count);
- count = 0;
- }*/
- //Serial.println("Waiting for data...");
- if (WriteBufferFilled < SD_BLOCKSIZE) {
- //pushValue();
- return;
- }
- //Serial.println("Writting the data...");
- oldWriteBufferFilled = WriteBufferFilled;
- sdCard.writeBlock(sdWriteBlockAddress++, WriteBuffer);
- #ifdef LOCKS
- WriteBufferLock_loop = 1;
- while(WriteBufferLock_pushValue);
- #endif
- volatile uint16_t leftLen = WriteBufferFilled - oldWriteBufferFilled;
-
- WriteBufferFilled = leftLen;
- if (leftLen > 0) {
- #ifdef DEBUG
- if (leftLen == 512) {
- Serial.println("Overflow.");
- }
- #endif
- memcpy(WriteBuffer, &WriteBuffer[SD_BLOCKSIZE], leftLen);
- }
- #ifdef DEBUG
- else {
- Serial.println("No data queued");
- }
- #endif
- #ifdef LOCKS
- WriteBufferLock_loop = 0;
- #endif
- while (sdWriteBlockAddress >= sdCardSizeBlocks) {
- Serial.println("SD card is full...");
- #ifdef HAVE_LEDS
- digitalWrite(LED_RED, LOW);
- digitalWrite(LED_GREEN, HIGH);
- delay(500);
- digitalWrite(LED_RED, LOW);
- digitalWrite(LED_GREEN, HIGH);
- #endif
- delay(500);
- }
- #endif
- }
- /*** Interrupt routine ADC ready *** /
- * ISR(ADC_vect) {
- * int aval = ADCL; // store lower byte ADC
- * aval += ADCH << 8; // store higher bytes ADC
- * if (sendStatus == 0) {
- * if (startDelay < 10000) { // do nothing the first x samples
- * startDelay++;
- * }
- * else {
- * valueBin[aval] += 1; // increase value bin
- * if (valueBin[aval] == 255) { // stop if a bin is full
- * sendStatus = 1;
- * }
- * }
- * }
- * }
- */
|