SainSmart SPI_1.3_OLED

OP #4895673
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
Gast
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 .
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
OP
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--;
    }
      }
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
Gast
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 ?
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
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.
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
}
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.
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
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.
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
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.
OP
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.
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 ;)
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
OP
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ß
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?
(Firma: privat)
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
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

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.