Forum: Mikrocontroller und Digitale Elektronik SainSmart SPI_1.3_OLED


von Juppo N. (juppo)


Lesenswert?

Hallo
Versuche das OLED Display anzusteuern.
Prozessor Atmega 168

Leider funzt. da noch garnichts.
Laut Hersteller ist ein SH1106 Controller auf der Platine.

Hat jemand ein Projekt für AVR Studio mit dem Display ?

google kenne ich .
programmieren kann ich auch ein wenig.
Wenn jemand was passendes hat..
LG

von jupp (Gast)


Lesenswert?

Moin

Ich haben nun das Display angesteuert und es tut sich auch was.
Da gab es Probleme mit der SPI ansteuerung .



Nun mal eine Frage an die Experten.

Ist die SS1306 controller ansteuerung gleich der SH1106 ?

Hat jemand doch noch eine projekt für atmega ?

die u8glib Lib ist bischen übertrieben für das Display.

schon mal den besten .

von Waldemar M. (waldim90)


Lesenswert?

Hi,
wie wäre es denn mit einem Link zum Artikel?

Ich benutze auch OLED Displays mit einem SSD1306 Controller und verwende 
die u8glib. Übertrieben ist diese Bibliothek allemal NICHT. Sie kann 
lediglich einfache Funktionen, die für mich aber ausreichen.
Ich weiß nicht wie du dir eine Bibliothek mit noch weniger Funktionen 
vorstellst?
Was ist dir denn an der u8glib zu viel?

Such mal nach u8g2, dort gibt es eine neue Version die auch einen 
abgespeckten Modus ohne RAM Verbrauch unterstützt und lediglich Text 
erzeugen kann.

MfG Waldemar

von Juppo N. (juppo)


Lesenswert?

Hallo

Mit der u8glib habe ich probleme beim erstellen eines projektes unt
avr studio 4.

Komme aber schon weiter.
der 168er prozessor hatte probleme mit dem speicher so das er jedesmal 
restet wenn ich auf das display was schrieb.
habe nun einen 644er  mit dem ich das display ansteuern kann.

Ein byte senden geht.  " ssd1306_write_byte(x,y,wert)"


aber beim senden eines frame buffer von 128x8 byte erscheint nur was in 
der ersten zeile.

Muss da noch bei jeder zeile die adresse verändert werden ?



}
void
ssd1306_write_byte (const uint8_t x, const uint8_t page, const uint8_t 
byte)
{
  ssd1306_write_instruction (SSD1306_SET_PAGE_START_ADDR | page);
  ssd1306_write_instruction (SSD1306_SET_COL_LO_NIBBLE | (x & 0xF));
  ssd1306_write_instruction (SSD1306_SET_COL_HI_NIBBLE | (x >> 4));
  ssd1306_write_data(byte);
}

void
ssd1306_clear_screen (void)
{
  ssd1306_reset_cursor ();

  for (uint16_t byte = 0; byte < SSD1306_PIXEL_BYTES; byte++)
//  for (uint16_t byte = 0; byte < 8448; byte++)
    {
      ssd1306_write_data (0x00);
    }
}

/*  Transfer display buffer to LCD */
void
ssd1306_display_fb (void)
{
  ssd1306_reset_cursor ();

  for (uint8_t page = 0; page < SSD1306_PIXEL_PAGES; page++)
//  for (uint8_t page = 0; page < 3; page++)
    {
      for (uint8_t column = 0; column < SSD1306_X_PIXELS; column++)
//      for (uint8_t column = 0; column < 132; column++)
  {
    ssd1306_write_data (0x0f);

//    ssd1306_write_data (ssd1306_frame_buffer_g[page][column]);
  }
    }
}

void test_send()
{
uint16_t i;
    ssd1306_reset_cursor ();
  for(i=0;i<(128*8);i++)  ssd1306_write_data (0x0f);
}


void
ssd1306_clear_fb (void)
{
  memset(ssd1306_frame_buffer_g, 0, SSD1306_PIXEL_BYTES);
}

void
ssd1306_set_pixel_fb (const uint8_t x, const uint8_t y, const 
pixel_state_t pixel_state)
{
  switch (pixel_state)
    {
    case PIXEL_STATE_ON:
      ssd1306_frame_buffer_g[y / SSD1306_PIXEL_PAGES][x] |= (1 << y % 
SSD1306_PIXEL_PAGES);
      break;
    case PIXEL_STATE_OFF:
      ssd1306_frame_buffer_g[y / SSD1306_PIXEL_PAGES][x] &= ~(1 << y % 
SSD1306_PIXEL_PAGES);
      break;
    default:
      break;
    }
}

/* Writes a run length encoded image to the display buffer */
void
ssd1306_write_image_fb (const uint8_t * image)
{
  uint8_t image_byte = 0, next_image_byte, write_byte_count = 0;

  for (uint8_t page = 0; page < SSD1306_PIXEL_PAGES; page++)
    {
      for (uint8_t column = 0; column < SSD1306_X_PIXELS; column++)
  {
    if (!write_byte_count)
      {
        image_byte = pgm_read_byte_near (image++);
        next_image_byte = pgm_read_byte_near (image++);
        if (image_byte == next_image_byte)
    {
      write_byte_count = pgm_read_byte_near (image++);
    }
        else
    {
      write_byte_count = 1;
      image--;
    }
      }

von Waldemar M. (waldim90)


Lesenswert?

Hi,
wie wäre es denn wenn du deinen Sourcecode als Dateien anhängst? So ist 
das hier ein Graus!

Und dann bitte alle Dateien die für dein Projekt notwendig sind: also 
main.c, header Dateien und die Lib

Dann kann man dir vielleicht besser helfen!

MfG Waldemar

von Jupo (Gast)


Lesenswert?

Eigentlich ist das nur ein Probem mit dem Verständnisses des Speicher 
vom Display.
Wenn ich ein Reset Cursor mache und dann 128x 8 Byte in dem Display 
Speicher schreibe wird nur in der ersten Page was angezeigt.
 Nach dem Original sourcen wird auch nur ein Speicher abgelegt ( FB) und 
dann zum Display gesendet.

Wie schreibe ich in die nächste Page .Also 1-7 ?
Oder gibt es ein Register für autoincrement ?

von Juppo N. (juppo)


Angehängte Dateien:

Lesenswert?

Moin
Anbei mein Test Projekt für das OLED Display

Wie schon beschrieben wird immer nur die erste Page beschrieben.

von Joachim B. (jar)


Lesenswert?

jupp schrieb:
> Ist die SS1306 controller ansteuerung gleich der SH1106 ?

Die Ramgrenzen sind verschieden, falsche Wahl gibt flimmernde Ränder 
rechts.

Bis jetzt habe ich nur Erfolg mit umgerüstet auf I2C mit SPI keinen 
Erfolg, die beiden letzten 0.96 laufen nicht, ein 1.3 läuft, ein 1.3 ist 
defekt.

von Waldemar M. (waldim90)


Lesenswert?

Juppo N. schrieb:
> Moin
> Anbei mein Test Projekt für das OLED Display
>
> Wie schon beschrieben wird immer nur die erste Page beschrieben.

mach doch bitte einen Screenshot davon und hänge ihn an. Wir können dir 
hier erst helfen, (ich zumindest), wenn ich das Problem vollends 
verstehen und nachvollziehen kann!
Wenn du schreibst, es wird nur die erste Page beschrieben, weiß trotzdem 
niemand, wie das Endergebnis auf dem Display aussieht...

MfG Waldemar

von Juppo N. (juppo)


Angehängte Dateien:

Lesenswert?

Anbei das Foto.

Problemm :
resete cursor ,geht
dann 128 x 64 pixel schreiben geht nicht.

was passiert wenn ich das pixel 129 schreibe ?
muss dann der cursor auf page 1 gesetzt werden ?
da ist mein problem .

von M. K. (sylaina)


Lesenswert?

jupp schrieb:
> Ist die SS1306 controller ansteuerung gleich der SH1106 ?
>
> Hat jemand doch noch eine projekt für atmega ?

Für I2C hab ich eine Lösung: 
Beitrag "SSD1306/1309 Library zum Darstellen von Text auf OLED Displays"

Siehe dort meinen letzten Eintrag, da ist die Lib mit angehangen.

Stellst du auf I2C um kannst du die Lib direkt benutzten, willst du SPI 
weiterhin verwenden musst du alle i2c-Funktionen entsprechend anpassen.
Wirklich schwer ist das nicht.

Juppo N. schrieb:
> was passiert wenn ich das pixel 129 schreibe ?
> muss dann der cursor auf page 1 gesetzt werden ?

Wenn du in die Nächste Zeile willst musst du den Cursor auf die nächste 
Page und X wieder auf 2 setzen.

Der RAM-Inhalt ist wie folgt:

es gibt 132 Columns von denen die Column 2 bis 128 der Displayanzeige 
entspricht. Die Column 0 & 1 ist links außerhalb des Displays, die 
Column 131 & 132 ist rechts außerhalb des Displays. Läuft der Cursor aus 
dem Bereich heraus wird er automatisch wieder auf Column 0 gesetzt, die 
Page wird (im Gegensatz zum SSD1306) nicht geändert.

Die Pages werden alle auf dem Display da gestellt, hier gibt es keine 
außerhalb des Anzeigenbereichs des Displays.

von Juppo N. (juppo)


Angehängte Dateien:

Lesenswert?

Moin

Wie schon beschrieben wird immer nur die erste Page beschrieben.

Das liegt wohl daran das ich die sourcen vom SSD1306 verwende.
Habe aber den SH1106,
Wie du geschrieben hast wird die page seite nicht automatisch bei dem 
sh1106 controller erhöht.

Besten dank.

: Bearbeitet durch User
von Katatafisch (Gast)


Lesenswert?

Hi,
alternativ kannst du mal diese Bib aus dem Forum ausprobieren:
Beitrag "Re: SSD1306 Library zum Darstellen von Text auf OLED Displays"

Die beherrscht Text und Grafik auf OLEDs mit SSD1306 und SH1106 
Controller.

Habe die selbst noch nicht genutzt, da das Display noch unterwegs ist. 
:-)

von Joachim B. (jar)


Lesenswert?

Juppo N. schrieb:
> Wie schon beschrieben wird immer nur die erste Page beschrieben.

vielleicht hilft dir das?

mit der U8GLIB auf Arduino sollte aber auch passend umzubauen sein für 
pur AVR

im loop (natürlich nur alle 250ms)
1
  if ( u8g.getMode() == U8G_MODE_BW ) 
2
  { u8g.setColorIndex(1);         // pixel on
3
  }
4
  u8g.firstPage();  
5
  do 
6
  { draw(_txt);
7
  } while( u8g.nextPage() );


1
#include "U8glib.h"
2
//U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE);  // I2C / TWI 
3
//U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_FAST);  // Dev 0, Fast I2C / TWI
4
U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NO_ACK);  // Display which does not send ACK
5
6
char _txt[15]={0};
7
char start[]="Tach auch";
8
9
void draw(char *txt) 
10
{
11
  // graphic commands to redraw the complete screen should be placed here  
12
  
13
  u8g.setFont(u8g_font_unifont);
14
  //u8g.setFont(u8g_font_5x7);
15
  //u8g.setFont(u8g_font_osb21); // viel Platz im Sketch
16
17
/*
18
  uint8_t font_high = 0.9 * u8g.getFontLineSpacing();
19
  u8g.drawStr( 0, 1 * font_high, txt);
20
  u8g.drawStr( 0, 3 * font_high, lefts(r_date_str, 14));
21
  u8g.drawStr( 0, 4 * font_high, lefts(r_time_str, 14));
22
  u8g.drawStr( 0, 5 * font_high, "123456789012345678901234567890");
23
*/
24
  u8g.drawStr( 0, 11, txt);
25
  u8g.drawStr( 0, 33, lefts(r_date_str, 14));
26
  u8g.drawStr( 0, 44, lefts(r_time_str, 14));
27
  u8g.drawStr( 0, 55, "Line 5");
28
  u8g.setFont(u8g_font_5x7);
29
  u8g.drawStr( 0, 64, "1234567890123456789012345");
30
}

von Juppo N. (juppo)


Lesenswert?

Hallo

Mal ne frage zu adruino.
sind die lib's kompatible zu avr c ?

mir scheint die U8GLIB lib doch sehr groß und umfangreich.

von M. K. (sylaina)


Lesenswert?

Juppo N. schrieb:
> Mal ne frage zu adruino.
> sind die lib's kompatible zu avr c ?

Nein, die müssen umgeschrieben werden da die Arduino Libraries in C++ 
geschrieben sind. C kann damit nichts anfangen.

Der Umfang der bekannten Libraries (Adafruit, u8g) war meine Intention 
mir für den SSD1306 für I2C selbst eine (bzw. zwei) Library zu 
schreiben. Auf Nachfrage hier im Forum habe ich dann noch die 
SH1106-Kompatibilität hergestellt.
Meine Lib nur für Text-Darstellung benötigt keinen statischen RAM und 
"nur" ca. 1500 kByte Flash, die Lib für Grafik benötigt ca. 1900 kByte 
Flash und 1027 byte statischen RAM. Als Gegenvergleich: Ich mein die u8g 
braucht etwas über 4 kByte Flash, die von Adafruit hab ich was mit 10 
kByte im Kopf und beide brauchen etwas über 1kByte statischen RAM.

: Bearbeitet durch User
von Joachim B. (jar)


Lesenswert?

also alle meine C zu Ino umbenennen klappte

Der andere Weg sollte auch funktionieren, nur kann ich kein cpp

Aber im cpp File auch c-code oder preprozessor statements einfügen 
klappt

Es wäre auszuprobieren

Notfalls geht man nicht über die IDE vom Arduino und lässt setup und 
loop weg, dann ist die fast wie AVR nur muss man dann die Make wohl 
passend machen oder gleich den gcc aufrufen, aber da schwimme ich 
gerade, brauchte ich ja nie

von M. K. (sylaina)


Lesenswert?

Joachim B. schrieb:
> also alle meine C zu Ino umbenennen klappte
>
> Der andere Weg sollte auch funktionieren, nur kann ich kein cpp

C zu C++ zu konvertieren geht daher, da C eine Teilmenge von C++ 
darstellt. Der andere Weg geht aber nicht da C++ schlicht keine 
Teilmenge von C ist. Woher soll z.B. C wissen was ein Konstruktor ist? 
Schon die Symantik würde der C-Compiler anmeckern.
Also der C++-Quellcode müsste dann schon sehr speziell sein, nur C-Code 
enthalten aber nichts aus dem C++ Pool, und das ist eben sehr 
unwahrscheinlich.

von Juppo N. (juppo)


Lesenswert?

Ein Problem habe ich noch

Da gibt es doch Unterschiede mit den Adressen bei dem SSD1306 und SH1106

Bekommen auf der ersten page und byte 0 nicht angezeigt.
irgendwo muss doch um 2 bit gschoben werden ?
aber wo?

von M. K. (sylaina)


Lesenswert?

Juppo N. schrieb:
> Bekommen auf der ersten page und byte 0 nicht angezeigt.
> irgendwo muss doch um 2 bit gschoben werden ?
> aber wo?

Das habe ich vorhin doch hier beschrieben: 
Beitrag "Re: SainSmart SPI_1.3_OLED"

;-)

von Joachim B. (jar)


Lesenswert?

M. K. schrieb:
> C zu C++ zu konvertieren geht daher, da C eine Teilmenge von C++
> darstellt. Der andere Weg geht aber nicht da C++ schlicht keine
> Teilmenge von C ist.

übersiehst du dabei nicht das Arduino und A-Studio 4 auf GCC aufsetzen?

Damit sollte die Verwendbarkeit von cpp möglich sein.

Juppo N. schrieb:
> Hat jemand ein Projekt für AVR Studio

OK welches Studio wird nicht benannt, ich nutze 4.18 mit gcc

von M. K. (sylaina)


Lesenswert?

Joachim B. schrieb:
> übersiehst du dabei nicht das Arduino und A-Studio 4 auf GCC aufsetzen?
>
> Damit sollte die Verwendbarkeit von cpp möglich sein.

Aber nicht in C, das war ja die Frage. Probiere es einfach mal aus. 
Schreibe dir eine Standard-C++-Klasse und versuche sie in C zu benutzen. 
Der C-Compiler wird hier meckern weil er u.a. mit den 
Constructor/Destructor nichts anzufangen weis.

von Juppo N. (juppo)


Lesenswert?

Ich benutze AVR Studio 4

Beim Schreiben muss der x wert +2 genommen werden.
Dann passt es.
Hab nun einen buffer angelegt der das ganze Display beschreibt.
in diesen buffer kann ich dann hinein schreiben.
Funktioniert.

Asccii Zeichensatz mit 8 pixel höhe und 5 pixel breite geht auch.
Weiter gehts dann mit große Zeichen und funktionen für rahmen und usw.

Besten Dank an alle.

von M. K. (sylaina)


Lesenswert?

Juppo N. schrieb:
> Ich benutze AVR Studio 4

Warum eigentlich diese alte Gurke? Etabliertes System?

Juppo N. schrieb:
> Beim Schreiben muss der x wert +2 genommen werden.

Ja, das habe ich oben geschrieben. ;)
Grund ist, dass links und rechts vom sichtbaren Bereichs des Display 
jeweils zwei Spalten sind, die man nicht sieht. Wahrscheinlich um das 
Scrolling Smoother aussehen zu lassen.

Juppo N. schrieb:
> Weiter gehts dann mit große Zeichen und funktionen für rahmen und usw.

Wie geschrieben, schau dir mal meine Lib ruhig an wie ich es löste. Das 
hilft dir sicher auch ;)

Viel Spass mit dem Display ;)

: Bearbeitet durch User
von Waldemar M. (waldim90)


Lesenswert?

Juppo N. schrieb:
> Asccii Zeichensatz mit 8 pixel höhe und 5 pixel breite geht auch.
> Weiter gehts dann mit große Zeichen und funktionen für rahmen und usw.

ich gebe hier nochmal den Hinweis, dass die u8glib (bzw. mittlerweile 
u8g2) das alles kann. Und die Lib kann auch nicht besonders viel mehr, 
bzw. sie ist nicht überladen und auch nicht übertrieben!

Dafür ist die Lib gut strukturiert, hat sehr viele Fonts in allen 
erdenklichen Größen und funktioniert einfach gut!

Überleg dir nochmal ob du alles selber programmieren willst, obwohl es 
das schon fertig gibt!?

Wenn du mit der u8glib / u8g2 nicht auf Anhieb klar kommst, kann ich dir 
nur sagen: Es lohnt sich, dort eine halbe Stunde zu investieren und die 
Lib kennenzulernen.

Damit kannst du nämlich auch sehr sehr viele andere Displays ansteuern, 
und brauchst, wenn du mal das Display wechselst, keine neue Lib zu 
"erlernen"...

Ist nur so ein Hinweis...

MfG Waldemar

von Juppo N. (juppo)


Lesenswert?

Moin
Nochmal wegen der u8glib

Ich habe einen Speicherbereich der das Display immer beschreibet.
Nun ist mir bei der Lib noch unklar wo die übergabe der von der u8glib 
zum speicherberich des Display übergeben wird.

Gruß

von M. K. (sylaina)


Lesenswert?

Ist quasi ewig her, dass ich die mir anschaute aber ich mein das hieß 
was mit u8g_sendBuffer oder so ähnlich. Vielleicht irre ich mich aber 
auch...müsste aber eigentlich aus dem Quelltext doch hervor gehen, oder 
nicht?

von U8g2 (Gast)


Lesenswert?

Ok, der Beitrag ist schon etwas älter, aber ich hab' gerade eine 
Schritt-für-Schritt Anleitung erstellt, in der erklärt wird, wie man 
U8g2 mit dem Atmel Studio 7 verwendet:

https://github.com/olikraus/u8g2/wiki/u8g2as7

Grüße,
Oliver

von Reinhard O. (Firma: privat) (flug52)


Lesenswert?

Hallo,
ich brüte gerade über der Umsetzung mit der u8h2 Lib ein I2C Display 
anzusteuern. Ein SSD1306 soll mit HW TWI des Atmega 328P angesteuert 
werden.
Ich finde aber nichts für das Setup in der Form: 
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2 für ein HW I2C.
Beinhaltet die Bibliothek schon die HW I2C Ansteuerung?
Gruß
Reinhard

von Joachim B. (jar)


Lesenswert?

Reinhard O. schrieb:
> u8h2

?

ich habe gerade noch mal geschaut
//U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);  // I2C 
/ TWI
//U8GLIB_SSD1306_128X64 
u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_NO_ACK|U8G_I2C_OPT_FAST);  // Fast I2C 
/ TWI
//U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NO_ACK);  // Display which does 
not send AC

alles da, ist aber eine ältere Version

von Reinhard O. (Firma: privat) (flug52)


Lesenswert?

Benutze ich ich eigentlich die richtige Bibliothek? 
https://github.com/olikraus/u8g2/archive/master.zip
Mit der Arduino IDE funktioniert der Aufbau, möchte aber das Atmel- 
Studio7 benutzen!

von M. K. (sylaina)


Lesenswert?

Reinhard O. schrieb:
> Mit der Arduino IDE funktioniert der Aufbau, möchte aber das Atmel-
> Studio7 benutzen!

Dann liegt es an der Software. Ich mein Arduino hat C++, hast du das 
berücksichtigt? Benutzt du im Studio auch C++ oder vewendest du C?

von Reinhard O. (Firma: privat) (flug52)


Lesenswert?

Ich benutze im Studio C. Ich habe das so verstanden, daß die Bibliothek 
C versteht!
hier heruntergeladen: https://github.com/olikraus/u8g2
und den Ordner: "CSRC" in mein Projektverzeichnis kopiert. Nicht den 
CPPSRC!

: Bearbeitet durch User
von Reinhard O. (Firma: privat) (flug52)


Lesenswert?

Ich finde kein Beispiel, wie ich das i2C anspreche. Muß ich das über i2C 
Routinen machen (i2c_init usw.) oder übernimmt das die u8g2 Bibliothek? 
Wenn ja, wie geht das?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.