OLED I2C 128x64 - Aiuto

Ciao,
scrivo in questo post tutti i problemi riscontrati con questo componente OLED SSD1306.

Per prima cosa, con quale modulo posso comandarlo? In rete ho trovato U8glib.

Ho montato sulla breadboard il mini display seguendo questo schema:

GND->GND

VCC -> 3,3v

SCL -> A4

SDA ->A5

Provando a compilare lo script di test (trovato in rete), ho un messaggio di errore:

// --------------------------------------
// i2c_scanner
//
// Version 1
//    This program (or code that looks like it)
//    can be found in many places.
//    For example on the Arduino.cc forum.
//    The original author is not know.
// Version 2, Juni 2012, Using Arduino 1.0.1
//     Adapted to be as simple as possible by Arduino.cc user Krodal
// Version 3, Feb 26  2013
//    V3 by louarnold
// Version 4, March 3, 2013, Using Arduino 1.0.3
//    by Arduino.cc user Krodal.
//    Changes by louarnold removed.
//    Scanning addresses changed from 0...127 to 1...119,
//    according to the i2c scanner by Nick Gammon
//    http://www.gammon.com.au/forum/?id=10896
// Version 5, March 28, 2013
//    As version 4, but address scans now to 127.
//    A sensor seems to use address 120.
// Version 6, November 27, 2015.
//    Added waiting for the Leonardo serial communication.
// 
//
// This sketch tests the standard 7-bit addresses
// Devices with higher bit address might not be seen properly.
//
 
#include <Wire.h>
 
 
void setup()
{
  Wire.begin();
 
  Serial.begin(9600);
  while (!Serial);             // Leonardo: wait for serial monitor
  Serial.println("\nI2C Scanner");
}
 
 
void loop()
{
  byte error, address;
  int nDevices;
 
  Serial.println("Scanning...");
 
  nDevices = 0;
  for(address = 1; address < 127; address++ ) 
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
 
    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");
 
      nDevices++;
    }
    else if (error==4) 
    {
      Serial.print("Unknown error at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
 
  delay(5000);           // wait 5 seconds for next scan
}

Allego l'errore al post.

Successivamente, ho caricato il classico esempio "Hello world" usando il modulo U8glib e tutto è ok.

Il problema è che questo modulo utilizza il seguente metodo:

u8g.drawStr( 0, 10, "Hello World!");

drawStr(int, int, String). int e int sono X e Y per la posizione del testo e String è la stringa da visualizzare.

Io non so come far leggere a questo metodo 2 valori float calcolati dal sensore DHT22.

Grazie

I2C_Scan_error.txt (10.8 KB)

NON puoi fare copia/incolla nell'IDE di una pagina HTML perché, anche se tu non li vedi, ti porti dietro tutta una serie di caratteri di formattazione che invece il compilatore vede e NON capisce !!!

Devi copiare e incollare passando attraverso un editor di testo semplice, come il notepad, così da eliminare i caratteri di formattazione.

Guglielmo

Ciao Guglielmo,
è quello che ho fatto.

Ma continuo ad avere errori in fase di compilazione del codice.

... mi sembra strano, sicuro di aver usato un editor di SOLO testo ? ? ?

Comunque, se usi il tasto [Select] sopra il codice che hai messo nel post iniziale, poi fai copia/incolla direttamente nell'IDE ... ho idea che tutto di sitemerà :wink:

Guglielmo

Niente...

copiato il codice in Notepadd++ , Notepad e Wordpad.

Non ci sono caratteri sporchi.

Ricopio il tutto sull'IDE e la verifica non passa....

Ma hai fatto quanto ho scritto sopra la post #3 ? ? ? :o

Perché l'ho provato e non da alcun problema !

Guglielmo

si! ho cliccato su Select e copiato nell'IDE. :o

.... guarda, quello allegato è stato ottenuto esattamente selezionando dal tuo primo post e copiandolo nell'IDE.

Guglielmo

i2cscanner.zip (1.14 KB)

Ci sono riuscito. Ho fatto un lavoraccio di cancellazione su ogni riga. Spostando tutto a sinistra. In pratica anche copiando su notepad non vedevo i caratteri sporchi.

Adesso il test funziona.

Finalmente riesco a far comparire i valori sul display.

Allego il codice, in caso qualcun'altro volesse provare:

#include "U8glib.h"
#include "DHT.h"
#include <Wire.h>
#include <SPI.h>

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_DEV_0); // I2C / TWI
DHT dht(2,DHT22); //Definisco il pin al quale è collegato il sensore e il tipo

int h;
int t;
String thisH = "";
String thisT = "";

void draw(void) {
  //grafica a video 
  u8g.setFont(u8g_font_unifont);
  //u8g.setFont(u8g_font_osb21);
  u8g.drawStr( 0, 10, "Umidità:"); 
  thisH = String(h) + "%";
  const char* newH = (const char*) thisH.c_str(); //converto in stringa l'intero 
  u8g.drawStr( 80, 10, newH);
  u8g.drawStr( 0, 32, "Temp:");
  thisT = String(t) + "*C";
  const char* newT = (const char*) thisT.c_str();
  u8g.drawStr( 40, 32, newT);
}

void setup(void) {
  // flip screen, if required
  // u8g.setRot180();

  // set SPI backup if required
  //u8g.setHardwareBackup(u8g_backup_avr_spi);

  // assign default color value
  if ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
    u8g.setColorIndex(255); // white

  }
  else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
    u8g.setColorIndex(3); // max intensity

  }
  else if ( u8g.getMode() == U8G_MODE_BW ) {
    u8g.setColorIndex(1); // pixel on

  }
  else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
    u8g.setHiColorByRGB(255, 255, 255);

  }
}

void loop(void) {
  h = dht.readHumidity();
  t = dht.readTemperature(); 
  // picture loop
  u8g.firstPage();
  do {
    draw();
  } while ( u8g.nextPage() );

  // rebuild the picture after some delay
  delay(2000);
}

Senza scomodare le String (pessima idea), credo che u8glib implementi Print, per cui dovrebbe bastare:

u8g.print(h);
u8g.println('%');

Come fai sulla seriale, insomma.

SukkoPera:
Senza scomodare le String (pessima idea), credo che u8glib implementi Print, per cui dovrebbe bastare:

u8g.print(h);
u8g.println('%');

Come fai sulla seriale, insomma.

Ciao, e come fai a passargli il posizionamento X e Y sullo schermo?

Con setPrintPos(), vedi userreference · olikraus/u8glib Wiki · GitHub.

Per gli oled 128x64 consiglio caldamente questa libreria, decisamente migliore, sia come velocità di refresh del display che come occupazione flash/ram, della u8glib e di quella fatta da Adafruit.
Rammento che gli oled 128x64 richiedono un buffer ram da 1k, pertanto sul 328P è un attimo finire la ram e trovarsi con il codice che va in crash.

Grazie astrobeed per la dritta. Ora guardo questa libreria da te indicata.

In risposta a sukkopera:

Mi ritrovo questo messaggio di errore

"
Arduino: 1.8.5 (Windows 10), Board: "Arduino/Genuino Uno"

C:\Users\pgraziano84\Documents\Arduino\esempi\U8glib_PRINT\U8glib_PRINT.ino: In function 'void draw()':

U8glib_PRINT:26: error: 'class U8GLIB_SSD1306_128X64' has no member named 'SetPrintPos'

u8g.SetPrintPos(0, 10);

^

U8glib_PRINT:27: error: invalid use of 'Print::Print'

u8g.Print(h);

^

exit status 1
'class U8GLIB_SSD1306_128X64' has no member named 'SetPrintPos'

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
"

setPrintPos() e print() iniziano con la minuscola.

U8glib è più lenta nel refresh proprio perché usa un buffer ridotto, almeno di default.

Chiedo venia, errore mio....

u8g.setPrintPos (con la s minuscolo) e u8g.print (con p minuscolo).

Ho provato ora e funziona.

Grazie per la dritta.

Ora finalmente posso stampare un valore float

Ecco il nuovo codice:

#include "U8glib.h"
#include "DHT.h"
#include <Wire.h>
#include <SPI.h>

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_DEV_0); // I2C / TWI
DHT dht(2,DHT22); //Definisco il pin al quale è collegato il sensore e il tipo

float h;
float t;

void draw(void) {
  u8g.setFont(u8g_font_unifont);
  u8g.setPrintPos(0, 10);
  u8g.print("H:");
  u8g.setPrintPos(30, 10);
  u8g.print(h);
  u8g.setPrintPos(80, 10);
  u8g.print("%");
  u8g.setPrintPos(0,40);
  u8g.print("T:");
  u8g.setPrintPos(30, 40);
  u8g.print(t);
  u8g.setPrintPos(80, 40);
  u8g.print("*C");
}

void setup(void) {

  // assign default color value
  if ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
    u8g.setColorIndex(255); // white

  }
  else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
    u8g.setColorIndex(3); // max intensity

  }
  else if ( u8g.getMode() == U8G_MODE_BW ) {
    u8g.setColorIndex(1); // pixel on

  }
  else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
    u8g.setHiColorByRGB(255, 255, 255);

  }
}

void loop(void) {
  h = dht.readHumidity();
  t = dht.readTemperature(); 
  // picture loop
  u8g.firstPage();
  do {
    draw();
  } while ( u8g.nextPage() );

  // rebuild the picture after some delay
  delay(2000);
}

Due cose:

  1. Se stampi "di seguito", non è necessario riposizionare ogni volta il cursore.
  2. Se guardi le mappe dei font sul wiki linkato sopra, puoi trovare il codice del vero simbolo dei gradi.

Ottimo! Grazie