**Dear all, **
I provide a code for the acquisition of current and voltage data at a frequency of 6.25 kHz (adjustable). The code is the one that corresponds to the description given in this link.
#include <SPI.h>
#include <SD.h>
#include <Arduino.h>
#include <RTCZero.h>
#include <Bounce2.h>
// Include the Bounce2 library found here :
// GitHub - thomasfredericks/Bounce2: Debouncing library for Arduino and Wiring
#include "avdweb_SAMDtimer.h"
// SAMD21 Timer library for the SAM15x15 and Arduino Zero
// SAMD21 Timer
// SAMD21 Timer library for the Arduino Zero - Libraries - Arduino Forum
#include "Albert.h"
// Fast ADC library
// Faster analogRead
Sd2Card card;
#define TRANSMISSIONSPEED 115200
#define BUTTON1_PIN 4
#define BUTTON2_PIN 5
#define AnalogPinU A1 // Analog Channel for voltage acquisition
#define AnalogPinI A2 // Analog Channel for current acquisition
#define BUFFSIZE 510 // 512/3=170.6666 or 510/3 = 170 --> 3 bytes
#define Te 200 // Aquisition period in µs //Fe= 2000 Hz
#define InformationBlockNumber 1
//------------------------------------------------------------------------------
void ISR_acquisition(struct tc_module *const module_inst); // This is just a prototype
//------------------------------------------------------------------------------
boolean start_acq, SD_init, SD_transfer, success, MyDebug = true;
byte dataUI, dateByte1, dateByte2, dateByte3, dateByte4, NumberOfAcquisitions;
uint8_t Data[2][510], DataSD[510], InformationBlock[512];
int i, dataU0_int, dataI0_int, dataU1_int, dataI1_int, LineIndex, SD_LineIndex, ColIndex;
int ColBlock1 = 1;
long NumberOfBlocks, blockNumberR, FirstBlockNumberW, blockNumberW, LastblockNumber, blockIndicatif;
String CurrentDate, CurrentTime;
char date[8];
Bounce debouncer1 = Bounce(); // Instantiate two Bounce objects
Bounce debouncer2 = Bounce();
RTCZero rtc;
SAMDtimer timer = SAMDtimer(3, ISR_acquisition, Te, 0); // ISR ISR_timer4, 1Hz (0.5s on, 0.5s off), timer is disabled
//------------------------------------------------------------------------------
void Dateformat(char const *date, char *buff) {
int month, day, year;
static const char month_names[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
sscanf(date, "%s %d %d", buff, &day, &year);
month = (strstr(month_names, buff) - month_names) / 3 + 1;
sprintf(buff, "%02d%02d%d", day, month, year);
}
//------------------------------------------------------------------------------
void setCompileTimeDate() {
String timeString = TIME; // get the time from the compiler:
byte timeArray[3]; // byte array for the elements of the time
int t = 0; // array counter
while (timeString.length() > 0) { // iterate over the string, reading the first number then removing it from the string, until the string is gone:
byte nextNumber = timeString.toInt(); // read beginning of string, convert to integer:
timeArray[t] = nextNumber; // save number in the array:
timeString.remove(0, 3); // remove the first three chars of the array:
t++;
}
Dateformat(DATE, date);
byte dateArray[3]; // array for the elements of the time
String Empty = "";
dateArray[0] = (String(Empty + date[0] + date[1])).toInt();
dateArray[1] = (String(Empty + date[2] + date[3])).toInt();
dateArray[2] = (String(Empty + date[6] + date[7])).toInt();
rtc.setTime(timeArray[0], timeArray[1], timeArray[2]);
rtc.setDate(dateArray[0], dateArray[1], dateArray[2]);
}
//------------------------------------------------------------------------------
void ISR_acquisition(struct tc_module *const module_inst) {
int dataU = analogReadFast(AnalogPinU); dataU = 257;
int dataI = analogReadFast(AnalogPinI); dataI = 514;
if (ColIndex % 5 == 0) {
dataUI = dataU & 0B11;
dataUI = (dataUI << 2) | (dataI & 0B11);
Data[LineIndex][ColIndex] = dataU >> 2; ColIndex = ColIndex + 1;
Data[LineIndex][ColIndex] = dataI >> 2; ColIndex = ColIndex + 1;
} else if (ColIndex % 5 == 2) {
dataUI = (dataUI << 2) | (dataU & 0B11);
dataUI = (dataUI << 2) | (dataI & 0B11);
Data[LineIndex][ColIndex] = dataU >> 2; ColIndex = ColIndex + 1;
Data[LineIndex][ColIndex] = dataI >> 2; ColIndex = ColIndex + 1;
Data[LineIndex][ColIndex] = dataUI; ColIndex = ColIndex + 1;
}
if (ColIndex == BUFFSIZE) {
SD_LineIndex = LineIndex; LineIndex = 1 - LineIndex;
ColIndex = 0;
if (SD_transfer) {
Serial.println(F("interruptions stopped."));
timer.enableInterrupt(0); // disable ISR_acquisition
} else
SD_transfer = true;
}
}
//------------------------------------------------------------------------------
void CodeDate() {
int Day = rtc.getDay(); int Month = rtc.getMonth(); int Year = rtc.getYear();
int Hours = rtc.getHours(); int Minutes = rtc.getMinutes(); int Seconds = rtc.getSeconds();
dateByte1 = (Year << 2) | ((Month & 0b1100) >> 2);
dateByte2 = ((Month & 0b11) << 6) | ((Day & 0b11111) << 1) | ((Hours & 0b10000) >> 4);
dateByte3 = ((Hours & 0b1111) << 4) | ((Minutes & 0b111100) >> 2);
dateByte4 = ((Minutes & 0b11) << 6) | (Seconds & 0b111111);
}
//------------------------------------------------------------------------------
void DecodeDL(int index) { /* Decode Date and Lastblock address */
long LastBlock;
index = (index - 1) * 8 + 1;
int Year = InformationBlock[index ] >> 2;
int Month = ((InformationBlock[index ] & 0B00000011) << 2) | ((InformationBlock[index + 1] & 0B11000000) >> 6);
int Day = ((InformationBlock[index + 1] & 0B00111110) >> 1);
int Hours = ((InformationBlock[index + 1] & 0B00000001) << 4) | ((InformationBlock[index + 2] & 0B11110000) >> 4);
int Minutes = ((InformationBlock[index + 2] & 0B00001111) << 2) | ((InformationBlock[index + 3] & 0B11000000) >> 6);
int Seconds = InformationBlock[index + 3] & 0B00111111;
LastBlock = InformationBlock[index + 4];
LastBlock = LastBlock << 8 | InformationBlock[index + 5];
LastBlock = LastBlock << 8 | InformationBlock[index + 6];
LastBlock = LastBlock << 8 | InformationBlock[index + 7];
Serial.print("Date: "); Serial.print(Day); Serial.print("/"); Serial.print(Month); Serial.print("/"); Serial.print(Year); Serial.print(" ");
Serial.print("Time: "); Serial.print(Hours); Serial.print(":"); Serial.print(Minutes); Serial.print(":"); Serial.print(Seconds); Serial.print(" ");
Serial.print("Last Block: "); Serial.print(LastBlock); Serial.println(" ");
}
//------------------------------------------------------------------------------
void setup() {
if (MyDebug) {
Serial.begin(TRANSMISSIONSPEED);
delay(10000);
Serial.println(F("Application started"));
pinMode(SDCARD_SS_PIN, OUTPUT); Serial.print("SDCARD_SS_PIN="); Serial.println(SDCARD_SS_PIN);
}
card.init(SPI_HALF_SPEED, SDCARD_SS_PIN);
NumberOfBlocks = card.cardSize(); Serial.print("Total number of blocks="); Serial.println(NumberOfBlocks);
pinMode(BUTTON1_PIN, INPUT_PULLUP);
digitalWrite(BUTTON1_PIN, HIGH);
debouncer1.attach(BUTTON1_PIN);
debouncer1.interval(5);
pinMode(BUTTON2_PIN, INPUT_PULLUP);
digitalWrite(BUTTON2_PIN, HIGH);
debouncer2.attach(BUTTON2_PIN);
debouncer2.interval(5);
Serial.println(F("Setup buttons"));
rtc.begin();
setCompileTimeDate();
Serial.println("RTC initialized");
start_acq = false;
if (!card.readBlock(InformationBlockNumber, InformationBlock)) { //try to read block
Serial.println("Unable to read a block");
}
NumberOfAcquisitions = InformationBlock[0];
if (NumberOfAcquisitions == 0) {
FirstBlockNumberW = 2;
}
else {
int index = (NumberOfAcquisitions - 1) * 8 + 5;
FirstBlockNumberW = InformationBlock[index + 4];
FirstBlockNumberW = FirstBlockNumberW << 8 | InformationBlock[index + 5];
FirstBlockNumberW = FirstBlockNumberW << 8 | InformationBlock[index + 6];
FirstBlockNumberW = FirstBlockNumberW << 8 | InformationBlock[index + 7];
FirstBlockNumberW = FirstBlockNumberW + 1;
}
Serial.print("First block number available = "); Serial.print(FirstBlockNumberW);
blockNumberW = FirstBlockNumberW;
Serial.println("System ready press button 1 to start the acquisition");
}
//------------------------------------------------------------------------------
void loop() {
if (start_acq && SD_transfer) {
uint8_t (&temp)[BUFFSIZE] = Data[SD_LineIndex];
success = card.writeBlock(blockNumberW, temp);
if (!success) {
Serial.println("unable to write a block");
}
//Serial.print("blockNumber= 0x"); Serial.print(blockNumber, HEX); Serial.print(" "); printBlock(DataIU[SD_LineIndex]);
blockNumberW = blockNumberW + 1;
SD_transfer = false ;
} else if (start_acq && SD_init) {
SD_init = false ;
SD_transfer = true ;
} else if (debouncer1.update() && debouncer1.fell()) {
start_acq = !start_acq;
if (start_acq) {
Serial.println("button 1 pressed, starting acquisition ");
NumberOfAcquisitions++;
CodeDate();
timer.enableInterrupt(1); // enable ISR_acquisition
LineIndex = 0;
ColIndex = 0;
SD_transfer = false;
} else {
LastblockNumber = blockNumberW - 1;
InformationBlock[0] = NumberOfAcquisitions;
InformationBlock[ColBlock1] = dateByte1; ColBlock1 = ColBlock1 + 1;
InformationBlock[ColBlock1] = dateByte2; ColBlock1 = ColBlock1 + 1;
InformationBlock[ColBlock1] = dateByte3; ColBlock1 = ColBlock1 + 1;
InformationBlock[ColBlock1] = dateByte4; ColBlock1 = ColBlock1 + 1;
InformationBlock[ColBlock1] = (LastblockNumber >> 24) & 0xFF; ColBlock1 = ColBlock1 + 1;
InformationBlock[ColBlock1] = (LastblockNumber >> 16) & 0xFF; ColBlock1 = ColBlock1 + 1;
InformationBlock[ColBlock1] = (LastblockNumber >> 8) & 0xFF; ColBlock1 = ColBlock1 + 1;
InformationBlock[ColBlock1] = LastblockNumber & 0xFF; ColBlock1 = ColBlock1 + 1;
if (!card.writeBlock(blockIndicatif, InformationBlock)) {
Serial.println("unable to write a block");
}
timer.enableInterrupt(0); // disable ISR_acquisition
Serial.println("button 1 pressed, stopping acquisition ");
//Serial.print("LastblockNumber= "); Serial.println(LastblockNumber);
}
} else if ( debouncer2.update() && debouncer2.fell()) {
Serial.println(" ");
Serial.println("Début affichage");
if (!card.readBlock(InformationBlockNumber, InformationBlock)) { //try to read block
Serial.println("unable to read a block");
}
else {
Serial.print("blockNumber= "); Serial.print(InformationBlockNumber); Serial.print(": ");
Serial.print("Push button counter: "); Serial.println(InformationBlock[0]);
for (i = 1; i <= InformationBlock[0]; i++) {
DecodeDL(i);
}
//acquisitionLog(InformationBlock[0], InformationBlock);
Serial.println();
}
/for (ColIndex = 0; ColIndex < 512;ColIndex++){
Serial.print(InformationBlock[ColIndex]);
Serial.print("(");Serial.print(ColIndex);Serial.print(") "); }
Serial.println();/
for (blockNumberR = InformationBlockNumber; blockNumberR <= LastblockNumber; blockNumberR++) {
if (!card.readBlock(blockNumberR, DataSD)) { //try to read block
Serial.println("unable to read a block");
} else {
Serial.print("blockNumber= "); Serial.print(blockNumberR); Serial.print(": ");
for (ColIndex = 0; ColIndex < BUFFSIZE; ) {
byte dataU0 = DataSD[ColIndex]; ColIndex = ColIndex + 1;
byte dataI0 = DataSD[ColIndex]; ColIndex = ColIndex + 1;
byte dataU1 = DataSD[ColIndex]; ColIndex = ColIndex + 1;
byte dataI1 = DataSD[ColIndex]; ColIndex = ColIndex + 1;
byte dataIU = DataSD[ColIndex]; ColIndex = ColIndex + 1;
dataU0_int = (dataU0 << 2) | ((dataIU & 0B11000000) >> 6) ;
dataI0_int = ((dataI0 << 2 ) | ((dataIU & 0B00110000) >> 4));
dataU1_int = (dataU1 << 2) | ((dataIU & 0B00001100) >> 2) ;
dataI1_int = ((dataI1 << 2 ) | ((dataIU & 0B00000011)));
Serial.print(dataU0_int); Serial.print(" ; "); Serial.print(dataI0_int); Serial.print(" ");
Serial.print(dataU1_int); Serial.print(" ; "); Serial.print(dataI1_int); Serial.print(" ");
Serial.print(" ");
}
Serial.println();
}
}
//InformationBlockNumber = LastblockNumber + 1;
Serial.println("Fin affichage");
}
}