Visualizzazione dati da BME280 a Disolay numerico

Buongiorno, sto (inutilmente!!) cercando di trasferire il valore di pressione da un sensore BME280 ad un visore a 4 display TM1637.

Ho provato a trasferire in un array il valore di pressione moltiplicato per 1000 e trasferirlo ai singoli display in binario e esadecimale (codificando i singoli numeri in una tabella) con encodeDigit senza alcun risultato positivo.

Provato il seguente programma (che funziona digitando il numero) ottenento (col valore in variabile) solo 4 zeri.

#include <Arduino.h>
#include <TM1637Display.h>

#include <Wire.h>
#include <BMx280I2C.h>

#define I2C_ADDRESS 0x76

// Module connection pins (Digital Pins)
#define CLK 3
#define DIO 4
float pres;
int prex;

BMx280I2C bmx280(I2C_ADDRESS);

// The amount of time (in milliseconds) between tests
#define TEST_DELAY   1000

TM1637Display display(CLK, DIO);


void setup()
{
  uint8_t data[] = { 0xff, 0xff, 0xff, 0xff };
  uint8_t blank[] = { 0x00, 0x00, 0x00, 0x00 };
  display.setBrightness(0x0f);
  // All segments on
  display.setSegments(data);
  delay(TEST_DELAY);
  display.clear();
  Wire.begin();

  bmx280.begin();
  bmx280.resetToDefaults();
  bmx280.writeOversamplingPressure(BMx280MI::OSRS_P_x16);
}

void loop()
{
  bmx280.measure();
    do {
      delay(100);
    } while (!bmx280.hasValue());
  
  pres = bmx280.getPressure();
  prex = int(pres * 1000);
  display.showNumberDec(prex, true);
  delay(TEST_DELAY);
  display.showNumberDec(301, true); // Expect: 0301

}

Purtroppo non ho altre idee, qualcuno può indirizzarmi sulla giusta strada o indicarmi dove sbaglio?

Grazie
Enrico

PS: i valori ottenuti dal sensore, se inviati a seriale appaioni e sono corretti.

Scusa, fammi capire meglio cosa vuoi ottenere... Intanto magari postando l'output seriale e dicendo quindi cosa vedi sul display (perché "senza alcun risultato positivo" non dà informazioni).

Tu "pres" l'hai definita "int", quindi dato che la getPressure() restituisce un float, prendi solo il valore intero ma se poi lo moltiplichi per 1000 di fatto potrai avere solo valori interi di pressione 0, 1000, 2000, eccetera fino a 32000 (dato che un "int" può avere un valore massimo di 32767).
Tu hai un display a 4 cifre, per cui fammi un esempio: dato un certo valore di getPressure() quale risultato vuoi ottenere sul display? In base a questo posso darti una risposta.

magari postando l'output seriale

Purtroppo utilizzo un at85, per cui non posso verificare direttamente la seriale; comunque ho un secondo sensore collegato ad un nano che mi dà 952 (il float -0,952- moltiplicato per 1000 e traformato in int -prex-).

Sul display dovrebbe comparire 952, come sulla seriale. I collegamenti sono OK, scambiando i sensori il risultato NON cambia.

Saluti
Enrico

Ma lo 0301 che metti dopo il delay lo vedi?

Si, infatti l'ho messo per controllo-.

Se ottieni 0000 forse la colpa è nel cast "int()" che fai, che forza la moltiplicazione tra interi (e su Attiny qualcosa deve esserci di diverso).
Ho finito le idee, intanto prova a fare così:

  prex = bmx280.getPressure() * 1000.0;
  display.showNumberDec(prex, true);

Non funziona, sui display non compare alcuna cifra.

Forse ci arrivo utilizzando il comando setSegments; ma penso ci vorranno alcuni giorni e molta pazienza, a risultato ottenuto posterò il programma.

Saluti e grazie
Enrico

Scusa ma avevo capito che compariva 0000, invece non mostra nulla, come se fosse spento?

Certo che se sul Nano funziona (confermi?), deve essere qualcosa legato all'Attiny o meglio alla libreria, ma non capisco cosa possa essere.
Io farei qualche altra prova per cercare di capire.
Ad esempio, prova a caricare l'esempio della libreria ("TM1637Test.ino") e vedi se funziona tutto come previsto nei commenti (hai visto mai che qualcosa della libreria non funziona correttamente su Attiny).

Io però su Wokwi ho cercato di simulare la cosa (rimuovendo la parte del sensore di pressione perché non c'è nell'emulatore), ed a me funziona:

Prova a copiare e caricare sul tuo Attiny quel codice e vedi se funziona. Se funziona ma rimettendo la libreria del sensore di pressione torna a non funzionare, il problema potrebbe essere quello.
Fammi sapere.

Esatto! anche il valore 301 non compare più, come il programma si fosse bloccato.

Su Nano funziona, confermo.

La stessa cosa succede usando le librerie x 280 di Adafruit (addirittura non mi lascia compilare il programma) e Grove.

Penso proprio si tratti di un problema di incompatibilità delle librerie!

Saluti
Enrico

PS: bello il programmino wokwi, non lo conoscevo; pochi però i sensori ed accessori presenti.

Provato altre soluzioni, cambiando anche la libreria del 280 ma proprio non va. L'ultimo programma utilizzato è questo:

/*
   OK, compare ilnumero sul display
   con 280 NO ************
*/

//#include <Wire.h>
//#include "Seeed_BME280.h"
#include <Arduino.h>
#include <TM1637Display.h>

// Module connection pins (Digital Pins)
#define CLK 3
#define DIO 4

TM1637Display display(CLK, DIO);

//#define I2C_ADDRESS 0x76

double d_prex, d_temp, d_humd;
int prex, temp, humd;

//BME280 bme280;

void setup()
{
  uint8_t data[] = { 0xff, 0xff, 0xff, 0xff };
  uint8_t blank[] = { 0x00, 0x00, 0x00, 0x00 };
  display.setBrightness(0x0f);

//  Wire.begin();
//  bme280.init();
//  bmx280.resetToDefaults();
//  bmx280.writeOversamplingPressure(BMx280MI::OSRS_P_x16);
//  bmx280.writeOversamplingTemperature(BMx280MI::OSRS_T_x16);
//  bmx280.writeOversamplingHumidity(BMx280MI::OSRS_H_x16);
}

byte NUM [] = {
  B00111111,  // 0
  B00000110,  // 1
  B01011011,  // 2
  B01001111,  // 3
  B01100110,  // 4
  B01101101,  // 5
  B01111101,  // 6
  B00000111,  // 7
  B01111111,  // 8
  B01101111,  // 9
};

void loop()
{
//  bmx280.measure();
//  do
//  {
//    delay(100);
//  } while (!bmx280.hasValue());

//  d_prex = round(bme280.getPressure() / 100);  //ottengo i valori in hPa
//  d_temp = bme280.getTemperature();
//  d_humd = bme280.getHumidity();

  prex = 1024;
//  prex = d_prex;

  int prex_u = prex % 10;
  int prex_d = (prex / 10) % 10;
  int prex_c = (prex / 100) % 10;
  int prex_m = (prex / 1000) % 10;

  int v0 = NUM[prex_u];
  int v1 = NUM[prex_d];
  int v2 = NUM[prex_d];
  int v3 = NUM[prex_u];

//  uint8_t data[] = { v0, v1, v2, v3 };
//  display.setSegments(data, 4, 0);
   display.showNumberDec(prex,false);

  delay (2000);
}

Per far comparire qualcosa ho dovuto eliminare le riche che si riferiscono al 280.
Partendo dal fondo solo dopo aver eliminato le righe 280 nel loop sono comparsi dei valori (errati); ad eliminazione completa i dati sono corretti anche con setSegments se dati in esadecimale.
Mi è venuto il dubbio che possa dipendere anche dallo AT85, settimana prossima provo con un MiniPro o un Nano.

Saluti
Enrico

Perché ti stai facendo del male da solo?

Tu hai un programma al post1
Che compila e comanda correttamente i display

Ha solo un errore di calcolo, anzi nemmeno, solo di conversione int float

E invece di mettere a posto una riga hai cominciato una danza infernale, tra librerie e cambi di schede e poi non s iu perché ho smesso di seguirti, troppo casino

Ti conviene fermarti e ripartire del post 1
Metti a posto il casting e hai finito

Se invece vuoi proseguire in quel ginepraio che ti sei costruito da te non hai da fare altro che cambiare di nuovo MCU e display e librerie...

Ah
Ricorda di cambiare ogni tanto anche la toolchain, altrimenti rischi di trovare "involontariamente" la soluzione in pochi mesi

1 Like

... infatti, è bastato utilizzarenun Nano al posto dello AT85 ed il programma funziona benissimo.

Probabilmente si trattava solo di insufficente capacità d'elaborazione dello Attiny.

/*
   OK, compare ilnumero sul display
   Modificato per arduino nano
   con 280 Funziona
*/

#include <Wire.h>
#include "Seeed_BME280.h"
#include <Arduino.h>
#include <TM1637Display.h>

// Module connection pins (Digital Pins)
#define CLK 3
#define DIO 2

TM1637Display display(CLK, DIO);


double d_prex, d_temp, d_humd;
int prex, temp, humd;

BME280 bme280;

void setup()
{
  Serial.begin(9600);
  display.setBrightness(0x0f);

  if (!bme280.init()) {
    Serial.println("Device error!");
  }
}

void loop()
{
  Serial.println(d_prex = (bme280.getPressure() / 100));

  //  d_prex = round(bme280.getPressure() );  //ottengo i valori in hPa
  //  d_temp = bme280.getTemperature();
  //  d_humd = bme280.getHumidity();

  Serial.println(d_prex);

  prex = d_prex;
  Serial.println(prex);

  display.showNumberDec(prex, false);

  delay (2000);
}

Saluti
Enrico

PS: x C1P8, non ho capito, il programma indicato, utilizzando AT85, NON visualizzava la pressione (scopo dello stesso), ma solo l'intero (301) inserito SOLO per controllo.

È evidente che non hai capito
Non hai capito il problema, la soluzione è nemmeno come casualmente lo hai messo a posto

Come dicevo prima: " soluzione involontaria"

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.