Buonasera,
volevo chiedervi se è possibile salvare dei dati di sensori su una sd (usando questo modulo)... il dubbio che mi viene è che i dati li leggo anche su un display lcd che utilizza spi perciò come posso fare per collegare anche il modulo?
Grazie!
Quale display LCD è ?
è di questo tipo
Quello e' un normale LCD, non SPI.
Basta che non lo colleghi ai pin 13, 12, 11 ( più un'altro pin per il CS ) e funziona tutto
Io l'lcd l'ho settato così:
LiquidCrystal lcd(12, 11, 5, 4, 3, 6);
quindi basta che cambio il 12,l'11 e quale altro?
...poi invece per il modulo sd posso usare quelli per SPI?
è normale che mi crei dei file strani all'interno? che non modifica nemmeno....
il codice che sto provando è questo:
#include <SPI.h>
#include <SD.h>
const int chipSelect = 10;
int dataString=0;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("Initializing SD card...");
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// don't do anything more:
return;
}
Serial.println("card initialized.");
}
void loop() {
// make a string for assembling the data to log:
dataString++;
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File dataFile = SD.open("datalog.txt", FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
dataFile.println(dataString);
dataFile.close();
// print to the serial port too:
Serial.println(dataString);
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening datalog.txt");
}
}
Come mi è stato fatto notare dal sig. Guglielmo (dato che me ne ero completamente dimenticato) riposto il mio problema:
come avete potuto leggere quando provo a vedere se mi scrive correttamente i dati sulla sd mi escono questi strani file e il file datalogger.txt (su cui scrivo) non riesco ad aprirlo e tanto meno a leggerlo...
il codice che utilizzo è questo:
/*
SD card datalogger
This example shows how to log data from three analog sensors
to an SD card using the SD library.
The circuit:
* analog sensors on analog ins 0, 1, and 2
* SD card attached to SPI bus as follows:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 4 (for MKRZero SD: SDCARD_SS_PIN)
created 24 Nov 2010
modified 9 Apr 2012
by Tom Igoe
This example code is in the public domain.
*/
#include <SD.h>
#include <SPI.h>
const int chipSelect = 4;
int dataString = 0;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("Initializing SD card...");
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// don't do anything more:
return;
}
Serial.println("card initialized.");
}
void loop() {
// make a string for assembling the data to log:
dataString++;
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File dataFile = SD.open("datalog.txt", FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
dataFile.println(dataString);
dataFile.close();
// print to the serial port too:
Serial.println(dataString);
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening datalog.txt");
}
}
...sapete dirmi il motivo?
Grazie
Il codice che ho trovato sul sito di arduino non va! Non riesce ad aprire il file quando in realtà è presente... cosa posso fare a parte distruggere tutto?????????????
Qualche buona anima riesce a capire il perchè di tutto questo?
Grazie
... mah ... se NON hai il LCD collegato ed hai SOLO il modulo con la SD, il problema può essere solo nel modulo o nella SD ... il codice è corretto.
E senza andare in giro a trovare codici su "siti", usa quelli che trovi tra gli esempi dell'IDE !
Guglielmo
gpb01:
... mah ... se NON hai il LCD collegato ed hai SOLO il modulo con la SD, il problema può essere solo nel modulo o nella SD ... il codice è corretto.E senza andare in giro a trovare codici su "siti", usa quelli che trovi tra gli esempi dell'IDE !
Esatto! Io sto usando proprio quello ora.... se carico l'esempio che mi fornisce le caratteristiche della schedina sd funziona.. ma quando si tratta di aprire il file mi da rogne soprattutto perchè una volta che disinserisco la schedina per veder dentro il file... il file non si apre più!
Ho due domande:
- la schedina è da 8gb...è troppo? non la regge?
- potrebbe essere che il codice mi crea altri file che mi impediscono di aprire il mio?
ho comprato anch'io il lettore da quel negozio... e a me funziona senza problemi.
uso però schede più piccole... dovresti chiedere al negozio che tipo di schede supporta.
poi, giusto per scrupolo, hai provato a vedere se la stessa sd infilata nel pc ti fa creare, salvare e poi leggere un file di testo?
La libreria non credo concepisca che la SD possa essere estratta. Prima di farlo dovrai in qualche modo "chiudere" la scheda e al reinserimento dovrai in qualche modo reinizializzarla.
Allora aggiorno la situazione:
Ho trovato un codice che mi inizializza il file in modo corretto e mi prepara la sd ma ora ho un'altro problema: in pratica sulla seriale con il debug vedo che i dati teoricamente me li salva ma quando estraggo la sd e la metto nel pc, il file è vuoto... sapete dirmi il motivo? Ah altra cosa: dopo posterò in codice in cui lo integro e su quello non funziona mentre su quello del link si.... secondo me è un problema di conversione string - char[] ... sapete dirmi/consigliarmi come tradurre un char[] in string e viceversa in modo semplice e chiaro?
Grazie mille a tutti!!
-
ti è stato già detto che NON puoi estrarre la SD con il programma in esecuzione ... il loop() gira in continuazione e quindi è molto facile che tu togli la SD con il file aperto con .. conseguente danneggiamento/mancato aggiornamento della directory.
Se vuoi estrarre la SD, una volta chiusa, devi entrare in un ciclo che blocca il loop() così da poter estrarre correttamente la SD. -
Nel reference trovi le funzioni di conversione e funzionano tutte correttamente, quindi NON cercare malfunzionamenti nelle funzioni ... perché NON ce ne sono.
Guglielmo
gpb01:
- ti è stato già detto che NON puoi estrarre la SD con il programma in esecuzione ... il loop() gira in continuazione e quindi è molto facile che tu togli la SD con il file aperto con .. conseguente danneggiamento/mancato aggiornamento della directory.
Se vuoi estrarre la SD, una volta chiusa, devi entrare in un ciclo che blocca il loop() così da poter estrarre correttamente la SD.
...secondo me è proprio questo il problema... comunque il codice è integrato qua:
#include <BMP180.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>
#include <Wire.h>
#include <SD.h>
#include <SPI.h>
#include <SoftwareSerial.h>
#define CALIBRATION 5200 //da calibrare per riferimento pressione al livello del mare
//#define Altitude 42.713 //Altitude San Pietro in Cerro (Piacenza, Emilia-Romagna, Italy)
//#define Altitude 60.843 //Altitude Piacenza (Piacenza, Emilia-Romagna, Italy)
#define ONE_WIRE_BUS 2
#define LDR_Pin A0
#define MQ5_Pin A1
#define FC4_Pin A2
BMP180 bmp_p_sensor;
float seaLevelPressure = 102370; // cambia in continuazione la pressione al livello del mare, perciò impossibile definire un dato fisso
float pressionelivellodelmarehPa; // variabile per la pressione al livello del mare in hPa
float pressionelivellodelmare; // variabile per la pressione in Pa
float temp;
float presAssoluta;
float presRelativa;
float altitudine;
int valLuce;
int percLuce;
int valGas;
int percGas;
int valSuono;
int percSuono;
byte alterna = 0;
unsigned long Tempo = 0;
const long intervalloTemperatura = 5000;
const long intervalloLuminosita = 5000;
const long intervalloGas = 5000;
const long intervalloSuono = 5000;
const long intervalloBMP = 5000;
const long intervallo = 5000;
int CS_PIN = 10;
String data;
File file;
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
LiquidCrystal lcd(9, 8, 5, 4, 3, 6);
void MostraLuminosita()
{
lcd.clear();
lcd.setCursor(0, 0);
valLuce = analogRead(LDR_Pin);
percLuce = map(valLuce, 0, 1023, 0.0, 100.0);
lcd.print(F("Luminosita': "));
lcd.setCursor(0, 1);
lcd.print(F(" "));
lcd.setCursor(0, 1);
lcd.print(percLuce);
lcd.print(F("%"));
}
void MostraTemperatura()
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Temperatura: ");
lcd.setCursor(0, 1);
lcd.print(sensors.getTempCByIndex(0));
lcd.print(" ");
lcd.print ((char)223);
lcd.print('C');
temp = sensors.getTempCByIndex(0);
}
void MostraSuono()
{
lcd.clear();
lcd.setCursor(0, 0);
valSuono = analogRead(FC4_Pin);
Serial.print(valSuono);
Serial.println();
percSuono = map(valSuono, 0, 1023, 0.0, 100.0);
lcd.print(F("Rumore: "));
lcd.setCursor(0, 1);
lcd.print(F(" "));
lcd.setCursor(0, 1);
lcd.print(percSuono);
lcd.print(F("%"));
}
void MostraPresenzaGas()
{
lcd.clear();
lcd.setCursor(0, 0);
valGas = analogRead(MQ5_Pin);
percGas = map(valGas, 0, 1023, 0.0, 100.0);
lcd.print(F("Presenza Gas: "));
lcd.setCursor(0, 1);
lcd.print(F(" "));
lcd.setCursor(0, 1);
lcd.print(percGas);
lcd.print(F("%"));
}
void MostraPressioneAssoluta()
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Pr.Assoluta: "));// calcolata nel vuoto
lcd.setCursor(0, 1);
lcd.print(F(" "));
lcd.setCursor(0, 1);
lcd.print(bmp_p_sensor.GetPressure());
lcd.print(F(" Pa"));
presAssoluta = bmp_p_sensor.GetPressure();
}
void MostraPressioneRelativa()
{
pressionelivellodelmare = bmp_p_sensor.GetPressure() + CALIBRATION; //in Pa
pressionelivellodelmarehPa = pressionelivellodelmare / 100; //in hPa
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Pr.Relativa: "));//calcolata grazie ad un'altra pressione
lcd.setCursor(0, 1);
lcd.print(F(" "));
lcd.setCursor(0, 1);
lcd.print(pressionelivellodelmarehPa);
lcd.print(F(" hPa"));
}
void MostraAltitudine()
{
altitudine = bmp_p_sensor.GetAltitude(seaLevelPressure);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Altitudine: "));
lcd.setCursor(0, 1);
lcd.print(F(" "));
lcd.setCursor(0, 1);
lcd.print(altitudine);
lcd.print(F(" m"));
}
void setup()
{
Serial.begin(9600);
sensors.begin();
Wire.begin();
bmp_p_sensor = BMP180();
if (bmp_p_sensor.EnsureConnected())
{
bmp_p_sensor.SoftReset();
bmp_p_sensor.Initialize();
}
lcd.begin(16, 2);
pinMode(LDR_Pin, INPUT);
pinMode(MQ5_Pin, INPUT);
pinMode(FC4_Pin, INPUT);
lcd.setCursor(1, 0);
lcd.print("ARDUROVER 1.2");
delay(3000);
initializeSD();
createFile("datalog.txt");
openFile("datalog.txt");
Tempo = millis();
}
void loop() {
sensors.requestTemperatures();
switch (alterna) {
case 0:
if (millis() - Tempo <= intervalloTemperatura)
{
MostraTemperatura();
}
else {
Tempo = millis();
alterna = 1;
}
break;
case 1:
if (millis() - Tempo <= intervalloLuminosita)
{
MostraLuminosita();
}
else {
Tempo = millis();
alterna = 2;
}
break;
case 2:
if (millis() - Tempo <= intervalloGas)
{
MostraPresenzaGas();
}
else {
Tempo = millis();
alterna = 3;
}
break;
case 3:
if (millis() - Tempo <= intervalloBMP)
{
MostraPressioneAssoluta();
}
else {
Tempo = millis();
alterna = 4;
}
break;
case 4:
if (millis() - Tempo <= intervalloBMP)
{
MostraPressioneRelativa();
}
else {
Tempo = millis();
alterna = 5;
}
break;
case 5:
if (millis() - Tempo <= intervalloBMP)
{
MostraAltitudine();
}
else {
Tempo = millis();
alterna = 6;
}
break;
case 6:
if (millis() - Tempo <= intervalloSuono)
{
MostraSuono();
}
else {
Tempo = millis();
alterna = 7;
}
break;
case 7:
if (millis() - Tempo <= intervallo)
{
data='{'+ String(percLuce)+';'+String(temp)+';'+String(percSuono)+';'+String(percGas)+';'+String(presAssoluta)+';'+String(pressionelivellodelmarehPa)+';'+String(altitudine)+';'+String(millis())+'}';
char t[100];
data.toCharArray(t,100);
writeToFile(t);
}
else {
Tempo = millis();
alterna = 0;
}
break;
}
}
void initializeSD()
{
Serial.println("Initializing SD card...");
pinMode(CS_PIN, OUTPUT);
if (SD.begin())
{
Serial.println("SD card is ready to use.");
} else
{
Serial.println("SD card initialization failed");
return;
}
}
int createFile(char filename[])
{
file = SD.open(filename, FILE_WRITE);
if (file)
{
Serial.println("File created successfully.");
return 1;
} else
{
Serial.println("Error while creating file.");
return 0;
}
}
int writeToFile(char text[])
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(F("Saving Data..."));
if (file)
{
file.println(text);
Serial.println("Writing to file: ");
Serial.println(text);
return 1;
} else
{
Serial.println("Couldn't write to file");
return 0;
}
}
void closeFile()
{
if (file)
{
file.close();
Serial.println("File closed");
}
}
int openFile(char filename[])
{
file = SD.open(filename);
if (file)
{
Serial.println("File opened with success!");
return 1;
} else
{
Serial.println("Error opening file...");
return 0;
}
}
String readLine()
{
String received = "";
char ch;
while (file.available())
{
ch = file.read();
if (ch == '\n')
{
return String(received);
}
else
{
received += ch;
}
}
return "";
}
...secondo voi al "turno" del salvataggio dei dati se apro e poi chiudo il file ogni volta può funzionare?
gpb01:
Se vuoi estrarre la SD, una volta chiusa, devi entrare in un ciclo che blocca il loop() così da poter estrarre correttamente la SD.
come blocco il loop() ?
entri in un loop senza fine e lo hai bello che bloccato ...
for( ; ; ) ;
... e da qui NON esci più fermando completamente il loop().
Guglielmo
gpb01:
entri in un loop senza fine e lo hai bello che bloccato ...for( ; ; ) ;
... e da qui NON esci più fermando completamente il loop().
ok ma il problema è questo: come lo posso integrare nel codice che ho fatto? dato che i file li devo salvare e poi quando voglio vedere i dati la devo estrarre... il problema è che con questo codice:
#include <SD.h>
#include <SPI.h>
int CS_PIN = 10;
File file;
void setup()
{
Serial.begin(9600);
initializeSD();
createFile("test.txt");
writeToFile("This is sample text!");
closeFile();
openFile("prefs.txt");
Serial.println(readLine());
Serial.println(readLine());
closeFile();
}
void loop()
{
}
void initializeSD()
{
Serial.println("Initializing SD card...");
pinMode(CS_PIN, OUTPUT);
if (SD.begin())
{
Serial.println("SD card is ready to use.");
} else
{
Serial.println("SD card initialization failed");
return;
}
}
int createFile(char filename[])
{
file = SD.open(filename, FILE_WRITE);
if (file)
{
Serial.println("File created successfully.");
return 1;
} else
{
Serial.println("Error while creating file.");
return 0;
}
}
int writeToFile(char text[])
{
if (file)
{
file.println(text);
Serial.println("Writing to file: ");
Serial.println(text);
return 1;
} else
{
Serial.println("Couldn't write to file");
return 0;
}
}
void closeFile()
{
if (file)
{
file.close();
Serial.println("File closed");
}
}
int openFile(char filename[])
{
file = SD.open(filename);
if (file)
{
Serial.println("File opened with success!");
return 1;
} else
{
Serial.println("Error opening file...");
return 0;
}
}
String readLine()
{
String received = "";
char ch;
while (file.available())
{
ch = file.read();
if (ch == '\n')
{
return String(received);
}
else
{
received += ch;
}
}
return "";
}
...senza bloccare il loop, mi salvava i dati....
docsavage:
Una volta chiusa, spegneFa prima è non ci sono questioni di fili volanti che vanno a toccare
Ocio che purtroppo parlo per esperienza
non capisco cosa intendi...
... quando decidi che vuoi estrarre la SD :
- chiudi il file
- avvisi su monitor seriale che tutto è a posto
- entri nel for che ti ho messo e blocchi tutto
- chi deve estrarre sa che può SPEGNERE Arduino ed estrarre la SD
Guglielmo