Ciao a tutti,
Sto usando un Arduino R4 wifi ed un modulo SD per salvare dei dati su una sd card, in particolare vorrei raggiungere 20KB/s.
Nel codice salvo un array di 510 float ( quindi 2040 byte) ogni 102 millisecondi sulla SD, la trascrizione dei dati impiega circa 28millisecondi, durante la trascrizione Arduino rimane bloccato. Non c'è un modo per evitare di bloccare Arduino così da consentire il continuo della memorizzazione dei dati nel vettore?
Sto usando un modulo con comunicazione SPI, la SD card è una SanDisk 32GB classe 10.
Di seguito il codice:
Main
/*
SD card datalogger
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 10
*/
#include "SDController.h"
bool f=false;
SDController sd;
unsigned long time;
unsigned long previousMillis = 0;
void setup() {
Serial.begin(112500);
sd.iniz();
delay(100);
}
void loop() {
unsigned long currentMillis = millis();
//aggiungi dati al buffer
if (currentMillis - previousMillis >= 1) {
previousMillis = currentMillis;
sd.addToBuffer(millis());
sd.addToBuffer(analogRead(A3));
sd.addToBuffer(analogRead(A2));
sd.addToBuffer(analogRead(A1));
sd.addToBuffer(analogRead(A0));
}
//salva dati su SD
sd.saveData();
//Stampa nella seriale tutti i dati presenti sulla SD
if(Serial.available() && f==false){
f=true;
Serial.println("dati sulla sd");
long t = millis();
Serial.println(millis());
sd.dataFile.close();
sd.fromBinToSerial();
}
}
Codice per gestire SD ed il buffer:
#ifndef SDCONTROLLER_H
#define SDCONTROLLER_H
#include <SPI.h>
#include <SD.h>
class SDController{
private:
const static int MAX_SIZE = 510;
//Gestisce il buffer
class Lista{
private:
float vett[MAX_SIZE];
int nelem = 0;
public:
void add(const float item) {
vett[nelem] = item;
nelem++;
}
void remove() {
nelem--;
}
bool isEmpty(){return nelem == 0 ? true : false;}
bool isFull(){return nelem == MAX_SIZE ? true : false;}
int getNumElem(){ return nelem;}
float* getVett(){return vett;}
void svuota(){
nelem = 0;
}
};
Lista buffer;
//numero blocchi da 510 elementi salvati
int numerBlocchi = 0;
const int chipSelect = 10;
public:
File dataFile;
//inizializza SD e crea il file
void iniz(){
if(!SD.begin(SPI_QUARTER_SPEED,chipSelect))Serial.println("errore apertura");
SPI.beginTransaction(SPISettings(48000000, MSBFIRST, SPI_MODE0));
SD.remove("data.bin");
SD.remove("dataCsv.csv");
dataFile = SD.open("data.bin", FILE_WRITE);
}
//Aggiunge un elemento al buffer
bool addToBuffer(const float v){
if(!buffer.isFull())buffer.add(v);
else return false;
return true;
}
//Rimuove un elemento dal buffer
bool removeFromBuffer(){
if(!buffer.isEmpty())buffer.remove();
else return false;
return true;
}
//salva i dati
bool saveData(){
if(buffer.isFull()){
byte *byteArray = reinterpret_cast<byte*>(buffer.getVett());
dataFile.write(byteArray, sizeof(byte) * MAX_SIZE*4);
buffer.svuota();
numerBlocchi++;
}
}
//Stampa i dati della sd sul monitor seriale
void fromBinToSerial(){
File binaryFile = SD.open("data.bin", FILE_READ);
byte value[4];
int indexWhile = 0;
while (indexWhile != MAX_SIZE*numerBlocchi) {
for(int i=0;i<4;i++)
value[i] = binaryFile.read();
Serial.print(*reinterpret_cast<float*>(value));
Serial.print(" ");
if(indexWhile%5==0)Serial.println("");
indexWhile++;
}
binaryFile.close();
}
};
#endif