#include <SSD1306Ascii.h>
#include <SSD1306AsciiAvrI2c.h>
#include <SPI.h>
#include <SD.h>
// 0X3C+SA0 - 0x3C or 0x3D
#define I2C_ADDRESS 0x3C
SSD1306AsciiAvrI2c oled;
float profon;
float temper;
float vbatt;
char strDati[38];
unsigned int lettura = 0;
bool mode = 0;
bool vb = 0;
char nomeFile[15];
File Dati;
File root;
char gbuff[9]; // generic buffer
uint32_t timer;
void screen0() {
oled.clear();
oled.setFont(fixed_bold10x15);
oled.setCursor(0, 0);
oled.print(F("Lett"));
//oled.print(lettura);
oled.setCursor(0, 2);
oled.print(F("Temp"));
//oled.print(temper, 1);
//oled.setCursor(0, 2);
//oled.print(F("C"));
oled.setCursor(0, 4);
oled.print(F("Prof"));
//oled.print(profon, 1);
//oled.print(F("m"));
oled.setCursor(0, 6);
oled.print(F("BATT"));
}
bool ifSdAbsent() {
bool absent = false;
if (!SD.begin(10)) {
absent = true; //se non sente la SD cambia modo di funzionamento
oled.setFont(fixed_bold10x15);
oled.clear();
oled.setCursor(0, 0);
oled.print(F(" NESSUNA SD"));
oled.setCursor(0, 2);
oled.print(F(" SOLO LETT"));
oled.setCursor(0, 4);
oled.print(F(" DIRETTA"));
delay(2000);
}
return absent;
}
void showTemperature() {
// usa gbuff[9] globale
sprintf(gbuff, "%3d.%uC", (int)temper, (uint8_t)(temper * 10) % 10);
oled.setCursor(55, 2);
oled.print(gbuff);
}
void showLettura() {
// usa gbuff[9] globale
sprintf(gbuff, "%5u", lettura);
oled.setCursor(65, 0);
oled.print(gbuff);
}
void showProfondita() {
// usa gbuff[9] globale
sprintf(gbuff, "%3d.%um", (int)profon, (uint8_t)(profon * 10) % 10);
oled.setCursor(55, 4);
oled.print(gbuff);
}
void showVbatt() {
// usa gbuff[9] globale
if (vbatt >=3.3) {
sprintf(gbuff, "% 1d.%1uV", (int)vbatt, (uint8_t)(vbatt * 10) % 10);
} else {
sprintf(gbuff, "%s", "BASSA");
}
oled.setCursor(68, 6);
oled.print(gbuff);
}
void errore(byte e) {
Serial.print("errore: ");
Serial.println(e);
while(1);
}
void openFile() {
/*for (byte idx = 1; idx < 100; idx++) { //controllo i files esistenti
sprintf(nomeFile, "Dati%04i.txt", idx);
if ( !SD.exists(nomeFile) ) break;
}
Serial.println(nomeFile);
Dati = SD.open(nomeFile, FILE_WRITE); //apro il nuovo file con l'ultimo nome creato
if (!Dati) { //controllo se il file e' stato creato correttamente, se no
errore(1); // chiamo gestione errori passandogli il numero dell'errore
}
Dati.close();*/
Dati = SD.open("wokwi.txt", FILE_WRITE); //apro il nuovo file con l'ultimo nome creato
if (!Dati) { //controllo se il file e' stato creato correttamente, se no
errore(1); // chiamo gestione errori passandogli il numero dell'errore
}
}
void scrivisd() {
if (Dati) {
Serial.println(strDati);
Dati.println(strDati);
Dati.flush();
/*digitalWrite(ledp, HIGH); // breve lampeggio ogni scrittura eseguita
delay(30);
digitalWrite(ledp, LOW);*/
}
else {
errore(2);
}
}
void leggisens() {
temper = (950 / 6.6) - (analogRead(A0) / 6.6);
profon = analogRead(A1) / 8.5;
vbatt = analogRead(A7) / 243.0;
//65535
showLettura();
showTemperature();
showProfondita();
showVbatt();
}
void printDirectory(File dir, int numTabs) {
while (true) {
File entry = dir.openNextFile();
if (! entry) {
// no more files
break;
}
for (uint8_t i = 0; i < numTabs; i++) {
Serial.print('\t');
}
Serial.print(entry.name());
if (entry.isDirectory()) {
Serial.println("/");
printDirectory(entry, numTabs + 1);
} else {
// files have sizes, directories do not
Serial.print("\t\t");
Serial.println(entry.size(), DEC);
}
entry.close();
}
}
void setup()
{
pinMode(4, INPUT_PULLUP);
Serial.begin(115200);
oled.begin(&Adafruit128x64, I2C_ADDRESS);
mode = ifSdAbsent();
root = SD.open("/");
printDirectory(root, 0);
Serial.println("");
Serial.println(mode);
screen0();
openFile();
}
bool headerFileIsWrite = false;
void loop() {
if (millis() - timer >= 500) {
lettura++;
timer = millis();
if (!headerFileIsWrite) {
char fileHeader[] = "Lettura,Temperarura,Profondit\n";
Serial.print(fileHeader);
headerFileIsWrite = true;
}
sprintf(strDati, "%u,%d.%u,%d.%u", lettura, (int)temper, (uint8_t)(temper * 10) % 10, (int)profon, (uint8_t)(profon * 10) % 10);
//sprintf(strDati, "L %u, T %d.%d C, P %d.%d m", lettura, (int)temper, (int)(temper * 10) % 10, (int)profon, (int)(profon * 10) % 10);
//Serial.print(strDati);
scrivisd();
}
// chiamata senza ritardi solo per mostrare l'aggiornamento rapido
leggisens();
if (!digitalRead(4)) {
Dati.close();
while(1);
}
}
#if(0)
#include <Wire.h>
#include <SPI.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
#include <SD.h>
#include <MS5837.h>
#define I2C_ADDRESS 0x3C
#define ledp 3
float profon = 103.45;
float temper = 24.56;
float vbatt;
char strDati[38];
unsigned int lettura = 0;
bool modo = 0;
bool vb = 0;
char nomeFile[15];
MS5837 sensor;
File Dati;
SSD1306AsciiWire oled;
void errore(byte ernm) {
oled.setFont(fixed_bold10x15);
oled.clear();
oled.setCursor(0, 0);
if (ernm == 1) {
oled.print(F(" ERRORE"));
oled.setCursor(0, 2);
oled.print(F("CREAZIONE"));
oled.setCursor(0, 4);
oled.print(F("FILE DATI"));
}
else if (ernm == 2) {
oled.print(F(" ERRORE"));
oled.setCursor(0, 2);
oled.print(F("SCRITTURA"));
oled.setCursor(0, 4);
oled.print(F(" SULLA SD"));
}
else if (ernm == 3) {
oled.print(F(" ERRORE"));
oled.setCursor(0, 2);
oled.print(F(" SENSORE"));
}
else if (ernm == 4) {
oled.print(F(" BATTERIA"));
oled.setCursor(0, 2);
oled.print(F(" TROPPO"));
oled.setCursor(0, 4);
oled.print(F(" SCARICA!"));
}
while (1) {
digitalWrite(ledp, HIGH);
delay(250);
digitalWrite(ledp, LOW);
delay(250);
}
}
void leggibatt() {
vb = 0;
int valore = analogRead(14); //scarto una lettura
valore = 0;
delay(5);
for (byte y = 0; y < 4; y++) { // 4 letture
valore += analogRead(14);
delay(5);
}
valore /= 4; //media di 4 letture
if (valore <= 665) vb = 1; // 665 = 3.0V
vbatt = (float) ((valore * 1.1) / 1024.0) * 4.2; // per AREF impostato su internal 1.1V
// x4.2 perche' con il partitore da 150k e 47k, sul pin ci sono 1.00V con 4.2V di batteria
}
void leggisens() {
for (byte x = 0; x < 4; x++) {
sensor.read();
temper += sensor.temperature();
profon += sensor.depth();
delay(40);
}
temper /= 4;
profon /= 4;
sprintf(strDati, "L %u, T %d.%d C, P %d.%d m", lettura, (int)temper, (int)(temper * 10) % 10, (int)profon, (int)(profon * 10) % 10);
}
void dispdati() { // scrive i dati sul display
oled.setFont(fixed_bold10x15);
oled.clear();
oled.setCursor(0, 0);
oled.print(F("Lett "));
oled.print(lettura);
oled.setCursor(0, 2);
oled.print(F("Temp "));
oled.print(temper, 1);
oled.print(F("C"));
oled.setCursor(0, 4);
oled.print(F("Prof "));
oled.print(profon, 1);
oled.print(F("m"));
//oled.setFont(font5x7);
oled.setCursor(0, 6);
if (vb == 1) {
oled.print(F("BATT BASSA"));
}
else {
oled.print(F("Batt "));
oled.print(vbatt, 1);
oled.print(F("V"));
}
}
void scrivisd() {
if (Dati) {
Dati.println(strDati);
Dati.flush();
digitalWrite(ledp, HIGH); // breve lampeggio ogni scrittura eseguita
delay(30);
digitalWrite(ledp, LOW);
}
else {
errore(2);
}
}
void setup() {
Wire.begin();
Wire.setClock(400000L);
oled.begin(&Adafruit128x64, I2C_ADDRESS);
pinMode(ledp, OUTPUT); //non uso la seriale
digitalWrite(ledp, LOW);
analogReference(INTERNAL); //settato su 1.1V
pinMode(14, INPUT); //adc7
//controllo se la batteria e' troppo bassa, se si blocco in errore
int valore = analogRead(14); //scarto una lettura
valore = 0;
delay(5);
for (byte y = 0; y < 4; y++) { // 4 letture
valore += analogRead(14);
delay(5);
}
valore /= 4; //media di 4 letture
if (valore <= 710) errore (4); //710 = 3.2V, autonomia troppo scarsa
if (!SD.begin(4)) {
modo = 1; //se non sente la SD cambia modo di funzionamento
oled.setFont(fixed_bold10x15);
oled.clear();
oled.setCursor(0, 0);
oled.print(F(" NESSUNA SD"));
oled.setCursor(0, 2);
oled.print(F(" SOLO LETT"));
oled.setCursor(0, 4);
oled.print(F(" DIRETTA"));
delay(2000);
}
else modo = 0;
if (modo == 0) {
for (byte idx = 1; idx < 100; idx++) { //controllo i files esistenti
sprintf(nomeFile, "Dati%04i.csv", idx);
if ( !SD.exists(nomeFile) ) break;
}
Dati = SD.open(nomeFile, FILE_WRITE); //apro il nuovo file con l'ultimo nome creato
if (!Dati) { //controllo se il file e' stato creato correttamente, se no
errore(1); // chiamo gestione errori passandogli il numero dell'errore
}
}
//sensor.init();
//if (!sensor.init()) { //sensore ko, blocca e lampeggia
// errore(3); // blocco commentato in attesa del sensore, da ripristinare per funzionamento regolare
// delay(2000);
//}
oled.setFont(fixed_bold10x15);
oled.clear();
oled.setCursor(0, 2);
oled.print(F(" INIZIO"));
oled.setCursor(0, 4);
oled.print(F(" SCRITTURE"));
delay(2000);
}
void loop() {
lettura++;
leggibatt();
//leggisens(); // commentato in attesa del sensore, da ripristinare per funzionamento regolare
dispdati();
if (modo == 0) { // SD presente, chiama scrittura
scrivisd();
delay(400);
}
else { // SD non presente, modo lettura diretta
for (byte z = 0; z < 3; z++) {
digitalWrite(ledp, HIGH); // 3 lampeggi ogni lettura per ricordare
delay(30); // che non c'e' scrittura sulla SD
digitalWrite(ledp, LOW);
delay(100);
}
delay(1500);
}
}
#endif