Difficoltà nello scrivere su SD

ok...ho dato per scontato che "legge da seriale" fosse globalmente riconosciuto come "scrivi un qualche cosa sul monitor seriale e premi invio"....

@zuruck_val : tu hai scritto un qualche cosa da monitor seriale e premuto invio?

In realtà non ho capito bene che comando scriva ma sul monitor escono fuori i valori accompagnati da relative intestazioni.

Includo foto:

Non avevo capito :upside_down_face:!
Se scrivo io da tastiera sul monitor seriale vengono salvati su SD, ho appena provato.

Io però devo salvare quelli che vengono stampati da Arduino per capirci.

Appunto, leggi ma non scrivi. Prova a scrivere qualcosa nella riga "Message(Enter...etc.." e poi premi invio, e vedi se viene scritto nella SD.
Non è che inviando i dati al monitor seriale questi te li rimanda indietro!
Quindi, in soldoni, perchè non scrivi direttamente i dati delle letture lasciando perdere la seriale?

Ciao, Ale.

Ciao, grazie mille,
se scrivo io sul monitor vengono salvati.

Il problema è che non riesco a capire da che comando arrivino questi dati, se vai al primo commento puoi vedere cosa avevo fatto.

Grazie veramente

Questo dovrebbe essere (perlomeno in parte) il codice che stampa sulla seriale, basta che fai la stessa cosa anche per la SD (accertandoti che il file sia aperto,etc).

Ciao, Ale.

in che modo posso fare la stessa cosa per SD (scusa veramente se rompo ma non riesco a farlo funzionare)

ecco il codice:

//dichiarazione librerie
#include "Seeed_HM330X.h"
#include <SD.h>
#include <SPI.h>

//oggetto file
File dataFile;

//chip per SD
const int chipSelect = 4;


#ifdef  ARDUINO_SAMD_VARIANT_COMPLIANCE
#define SERIAL_OUTPUT SerialUSB
#else
#define SERIAL_OUTPUT Serial
#endif

HM330X sensor;
u8 buf[30];


const char *str[]={"sensor num: ","PM1.0 concentration(CF=1,Standard particulate matter,unit:ug/m3): ",
                   "PM2.5 concentration(CF=1,Standard particulate matter,unit:ug/m3): ",
                   "PM10 concentration(CF=1,Standard particulate matter,unit:ug/m3): ",
                   "PM1.0 concentration(Atmospheric environment,unit:ug/m3): ",
                   "PM2.5 concentration(Atmospheric environment,unit:ug/m3): ",
                   "PM10 concentration(Atmospheric environment,unit:ug/m3): ",
};

HM330XErrorCode print_result(const char* str,u16 value)
{
    dataFile = SD.open("dati.txt", FILE_WRITE);

    if(NULL==str)
        return ERROR_PARAM;
    dataFile.print(str);
    dataFile.println(value);
    dataFile.close();

    return NO_ERROR;
}


/*parse buf with 29 u8-data*/
HM330XErrorCode parse_result(u8 *data)
{
    u16 value=0;
    if(NULL==data)
        return ERROR_PARAM;
    for(int i=1;i<8;i++)
    {
        value = (u16)data[i*2]<<8|data[i*2+1];
        print_result(str[i-1],value);

    }

    return NO_ERROR;
}

HM330XErrorCode parse_result_value(u8 *data)
{
    if(NULL==data)
        return ERROR_PARAM;
    for(int i=0;i<28;i++)
    {
        SERIAL_OUTPUT.print(data[i],HEX);
        SERIAL_OUTPUT.print("  ");
        if((0==(i)%5)||(0==i))
        {
            SERIAL_OUTPUT.println(" ");
        }
    }
    u8 sum=0;
    for(int i=0;i<28;i++)
    {
        sum+=data[i];
    }
    if(sum!=data[28])
    {
        SERIAL_OUTPUT.println("wrong checkSum!!!!");
    }
    SERIAL_OUTPUT.println(" ");
    SERIAL_OUTPUT.println(" ");
    return NO_ERROR;
}


/*30s*/
void setup()
{

  SERIAL_OUTPUT.begin(115200);

  // Inizializza il modulo SD-------------------------------------
  if (!SD.begin(4))
  {
    Serial.println("Errore inizializzazione SD");
    return;
  }
  Serial.println("SD inizializzata correttamente");
  //---------------------------------------------------------------

  delay(100);

  SERIAL_OUTPUT.println("Serial start");
  if(sensor.init())
  {
      SERIAL_OUTPUT.println("HM330X init failed!!!");
      while(1);
  }

}



void loop()
{

  if(sensor.read_sensor_value(buf,29))
  {
    SERIAL_OUTPUT.println("HM330X read result failed!!!");
  }

  parse_result_value(buf);
  parse_result(buf);

  SERIAL_OUTPUT.println(" ");
  SERIAL_OUTPUT.println(" ");
  SERIAL_OUTPUT.println(" ");
  
  delay(5000);
}


  


grazie, nick

Che dire, mi dispiace...

Ciao, Ale.

ribadisco quanto anticipato...un passo alla volta...chiarito che riesci a scrivere in SD (crei il file, lo apri, lo aggiorni, e lo chiudi)...passiamo a decidere cosa ci vuoi/devi mettere.
Sembra tu voglia avere nel file, ogni 5 secondi, una serie di righe che riportino "descrizione" e "valore" tipo:

sensor num:  0
PM1.0 concentration(CF=1,Standard particulate matter,unit:ug/m3): 50
PM2.5 concentration(CF=1,Standard particulate matter,unit:ug/m3): 13
...

giusto?

se è così prova questo e quando sul monitor leggi "fatto!" dimmi cosa trovi scritto sul file nella SD.

#include <SD.h>
#include <SPI.h>
#include "Seeed_HM330X.h"

File dataFile;
const int chipSelect = 4;

const char *str[] = {"sensor num: ", "PM1.0 concentration(CF=1,Standard particulate matter,unit:ug/m3): ",
                     "PM2.5 concentration(CF=1,Standard particulate matter,unit:ug/m3): ",
                     "PM10 concentration(CF=1,Standard particulate matter,unit:ug/m3): ",
                     "PM1.0 concentration(Atmospheric environment,unit:ug/m3): ",
                     "PM2.5 concentration(Atmospheric environment,unit:ug/m3): ",
                     "PM10 concentration(Atmospheric environment,unit:ug/m3): ",
                    };

HM330XErrorCode print_result(const char* str, u16 value)
{
  dataFile = SD.open("dati.txt", FILE_WRITE);

  if (NULL == str)
    return ERROR_PARAM;
  dataFile.print(str);
  dataFile.println(value);
  dataFile.close();

  return NO_ERROR;
}

uint16_t value16[7] = {100, 200, 300, 400, 500, 600, 700};

void setup() {
  Serial.begin(115200);

  if (!SD.begin(4))
  {
    Serial.println("Errore inizializzazione SD");
    return;
  }
  Serial.println("SD inizializzata correttamente");

  for (uint8_t i = 0; i < 7; i++) {
    if (print_result(str[i], value16[i])) {
      Serial.println("fatto!");
    }
    else {
      Serial.print("errore alla riga: ");
      Serial.println(i);
    }
  }
}

void loop() {
  // put your main code here, to run repeatedly:

}

Allora, innanzi tutto ti ringrazio moltissimo per starmi seguendo con attenzione.

IL tuo codice funziona! mitico (anche se nel seriale dice "errore a riga ..." nell'effettivo scrive su SD) .

Rimangono però due problemi fondamentali:

  1. scrive solo 2 volte (potrei metterlo nel loop con un delay così da gestirmi il tempo)

  2. i valori che escono sono i valori del vettore value16[7] quindi escono tipo cosi:

sensor num:  100 //QUA ESCE IL CENTO
PM1.0 concentration(CF=1,Standard particulate matter,unit:ug/m3): 200
PM2.5 concentration(CF=1,Standard particulate matter,unit:ug/m3): 300
...

Sei veramente un grande, devo finire il codice per la scuola e mi sta facendo impazzire, apprezzo veramente moltissimo il tuo aiuto grazie. :star_struck:

in effetti nel for ho scritto "i<7" anzichè "i<6"...errore di distrazione.

in che senso scrive solo 2 volte?

questo lo sapevo...l'ho scritto io :wink:
la domanda che ti faccio...hai capito quale è la funzione che scrive nel file SD e cosa scrive (e come)?
partendo dalla funzione che scrive nella SD, diciamo a ritroso, riesci a risalire a dove viene richiamata e da dove si ricavano i valori che gli vengono passati?
fatto questo devi verificare che i valori letti dal sensore siano coerenti...ma questo lo puoi fare tu...io non ho ne sensore ne datasheet.

Nella funzione HM330XErrorCode print_result è presente il comando dataFile.print (che mi scrive su dataFile che corrisponde all'SD (da quel che ho capito) )

la stringa che stampa l'ha dichiarata sopra, invece value, che immagino siano i valori presi dal sensore, non ho capito dove li prenda dichiari ecc.

Ho modificato il codice così da farlo scrivere più di una volta:

#include <SD.h>
#include <SPI.h>
#include "Seeed_HM330X.h"

File dataFile;
const int chipSelect = 4;

const char *str[] = {"sensor num: ", "PM1.0 concentration(CF=1,Standard particulate matter,unit:ug/m3): ",
                     "PM2.5 concentration(CF=1,Standard particulate matter,unit:ug/m3): ",
                     "PM10 concentration(CF=1,Standard particulate matter,unit:ug/m3): ",
                     "PM1.0 concentration(Atmospheric environment,unit:ug/m3): ",
                     "PM2.5 concentration(Atmospheric environment,unit:ug/m3): ",
                     "PM10 concentration(Atmospheric environment,unit:ug/m3): ",
                    };

HM330XErrorCode print_result(const char* str, u16 value)
{
  dataFile = SD.open("dati.txt", FILE_WRITE);

  if (NULL == str)
    return ERROR_PARAM;
  dataFile.print(str);
  dataFile.println(value);
  dataFile.close();

  return NO_ERROR;
}

uint16_t value16[7] = {100, 200, 300, 400, 500, 600, 700};

void setup() {
  Serial.begin(115200);

  if (!SD.begin(4))
  {
    Serial.println("Errore inizializzazione SD");
    return;
  }
  Serial.println("SD inizializzata correttamente");

 
}

void loop() {

 for (uint8_t i = 0; i < 7; i++) {
    if (print_result(str[i], value16[i])) {
      Serial.println("fatto!");
    }
    else
    {
      // Serial.print("errore alla riga: ");
      //Serial.println(i);
    }
  }

  delay(5000);

}

Rimane però il problema di capire come prendere i valori del sensore e non quelli fittizzi.

(inoltre ho commentato il comando di errore perchè me lo dava in ogni riga ma in realtà scrive su SD senza problemi, stampa solo su monitor l'avviso)
Provo a mettere i<6 ma dovrebbe cambiare solo sull'ultima riga.

Grazie mille, nick

usando il tuo codice originale cosa ti stampa sul monitor seriale?

Provo?

se non commento da errore ma poco importa, a me basta che scriva i valori reali su SD

Fate molta attenzione con quella definizione di tipo "u16" ...

... e cosa del tutto arbitraria e fuori standard ... sono tipi definiti in un modulo del "core" Arduino per AVR (non so se presente anche in altri core) e, per l'esattezza, nel file USBAPI.h

typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;

Il giorno che cambiate magari "board" o cambiate ambiente ... magari il compilatore che andate ad usare vi da errore ... tenetelo presente :roll_eyes:

Guglielmo

intendevo il TUO codice originale...quello del tuo primo post...cosa stampa sul monitor seriale?...e dato che ci siamo...il sensore è fisicamente collegato ad arduino?

poi vale quanto detto da Guglielmo per la definizione dei tipi...meglio se sostituisci la "u8" con "uint8_t" la "u16" con "uint16_t" e la "u32" con "uint32_t"

Stampa I valori presi dal sensore (che é collegato ad Arduino uno da un groove shield) con le relative etichette.

Ma il tuo codice andava benissimo, dovevo solo riuscire a mettere i valori del sensore e non quelli "fittizi" del tuo codice che giustamente non avendo il sensore non poteva ricevere.

Grazie ancora veramente :star_struck: