SSD1306 OLED Display

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    Aufgrund technischer Veränderungen ist der Mailverkehr innerhalb des Forums (Private Nachrichten) nur noch eingeschränkt möglich. Die Einschränkung ist notwendig, um zusätzliche Betriebskosten für das Forum zu vermeiden. Näheres zu den Hintergründen im Thread "Aktuelles zum Forum".Wir bitten um Verständnis.

    Hinweis kann nach Kenntnisnahme deaktiviert werden!

    • 17b schrieb:

      Die Baudrate hab ich überall auf gleichen Wert geändert und 1000x überprüft.
      Ist die nicht unabhängig vom Takt? Hab ich da was falsch verstanden?
      Sieh Dir mal das Tool von Zitronenfalter an, da kannst Du erkennen und berechnen wie die Baudrate sein muß und welche Fehler die Übertragung bringt.
      Wem ich nicht ausdrücklich widerspreche, der darf das bis auf Widerruf als "Gefällt mir" verstehen.
    • Hab ich gemacht.
      Bei 9600 Baud habe ich mit einem crystal Wert von 1843200 eine Fehlerrate lt. Tool von 0%. Chip ist ein 168, benutzte Pins für RX und TX sind PD0 und PD1.
      Im Terminal Emulator sind 9600N81 eingestellt, dennoch kommt Müll raus.

      Mein Testcode:

      Quellcode

      1. $regfile = "m168def.dat" ' benutzter Mikrocontroller
      2. $crystal = 1843200 ' Taktfrequenz
      3. $hwstack = 40 ' Hardware Stack
      4. $swstack = 40 ' SW Stack
      5. $framesize = 60 ' Frame
      6. $baud = 9600
      7. Do
      8. print
      9. print"Test Test Test"
      10. waitms 500
      11. loop
      Alles anzeigen
    • Du sollst natürlich für $crystal nicht irgendeinen Wert einstellen sondern den mit dem Dein Controller läuft, also entweder die Frequenz des angeschlossenen Quarzes oder dem Takt des intern aktivierten Oszillators einschl. seines Vorteilers.

      Vielleicht solltes Du dich erstmal mit den Grundlagen von Mikrocontrollern (AVR) und der Programmiersprache BASCOM vertraut machen. Ich denke da herrscht bei Dir noch überhaupt keine Klarheit. In deinen posts lese ich immer "... habe ich kopiert...", aber kopieren kann meinen z.Bsp. einen Speiseplan aber Programme sollte man schon verstehen wollen.
      Wem ich nicht ausdrücklich widerspreche, der darf das bis auf Widerruf als "Gefällt mir" verstehen.
    • Ich würde lügen wenn ich sagen würde, das ich das selbst hinbekommen hab. Alles nur zusammenkopiert...
      Hier ist mein Programm soweit wie ich jetzt bin:
      An 3 18B20 Sensoren wird die Temperatur abgefragt und angezeigt. Zusätzlich wird eine Spannung abgefragt und passend dazu eine 2812 in verschiedenen Farben und Blinkmustern angesteuert. Der Auswerteteil ist noch nicht fertig.
      Das Ganze wird in eins meiner Modell U-Boote eingebaut um Spannungen und Temperaturen zu überwachen. Was noch fehlt wäre eine Funkübertragung, aber da muss ich noch Code zum abkupfern finden, haha.

      Hast du ein anderes Display zum Vergleich? Hab Freitag eins mit 1.30" bekommen, das scheint kaputt zu sein und geht wieder zurück. Vielleicht hat deins ja auch ne Macke wenn nur jede zweite Zeile funktioniert

      Quellcode

      1. $Regfile = "m168def.dat"
      2. $Crystal = 8000000
      3. $hwstack = 40
      4. $swstack = 16
      5. $framesize = 32
      6. '******************* rainbow lib einstellungen ************************
      7. $Lib "Rainbow.lib"
      8. $external WS2812b
      9. Declare Sub Select_Rainbow(byval Channel As Byte)
      10. Declare Sub SetColor(byval LedNr As Word , Color() as Byte)
      11. Declare Sub Send()
      12. const Rainbow0_Len = 1'just 1 Led
      13. Const Rainbow0_Port = PORTb
      14. Const Rainbow0_Pin = PB0
      15. '******************* ad wandler ************************
      16. Config Adc = Single , Prescaler = Auto , Reference = Avcc
      17. Start Adc
      18. declare sub spannung_lesen
      19. '******************* i2c bus ************************
      20. Config Scl = Portc.5 'Konfigurieren von I2C
      21. Config Sda = Portc.4
      22. Config Twi = 400000 ' i2c speed
      23. '******************* oled ************************
      24. Declare Sub Oled_init
      25. I2cinit
      26. $lib "i2c_twi.lbx" ' we do not use software emulated I2C but the TWI
      27. $lib "glcdSSD1306-I2C.lib" ' override the default lib with this special one
      28. #if _build < 20784
      29. Dim ___lcdrow As Byte , ___lcdcol As Byte ' dim these for older compiler versions
      30. #endif
      31. Config Graphlcd = Custom , Cols = 128 , Rows = 32 , Lcdname = "SH1106"
      32. 'Config Graphlcd = Custom , Cols = 128 , Rows = 32 , Lcdname = "SSD1306"
      33. Cls
      34. Setfont font8x8TT
      35. call oled_init
      36. '******************* 1wire ************************
      37. Declare Sub Temp_messen_start
      38. Declare Sub Temp_lesen_start
      39. Config Single = Scientific , Digits = 1
      40. Dim Sc(9) As Byte
      41. Dim Temperatur(3) As Single
      42. '******************* lipoblitzer variablen ************************
      43. Dim Channel As Byte
      44. Dim Voltage As word
      45. Dim I As Byte
      46. Dim Color(3) as Byte
      47. Dim warten as word
      48. Dim blitz as word
      49. Dim ta as integer
      50. Dim hu as integer
      51. Dim ze as integer
      52. Dim ei as integer
      53. R alias Color(_base) : G alias Color(_base+1) : B alias Color(_base+2)
      54. warten = 100
      55. blitz = 30
      56. Call Select_Rainbow(0)'select Rainbow
      57. '******************* main ************************
      58. 'Showpic 0 , 0 , wallp
      59. 'wait 5
      60. 'cls
      61. Lcdat 1 , 1 , "- 22er Sensoren -"
      62. Do
      63. Call Temp_messen_start
      64. Call Temp_lesen_start
      65. call spannung_lesen
      66. Lcdat 2 , 1 , "Temp. Motor= ";Temperatur(1);"'C"
      67. Lcdat 3 , 1 , "Temp. Regler= ";Temperatur(2);"'C"
      68. Lcdat 4 , 1 , "Temp. frei= ";Temperatur(3);"'C"
      69. print Temperatur(1);Temperatur(2);Temperatur(3)
      70. Loop
      71. End
      72. '******************* spannung lesen ************************
      73. sub spannung_lesen
      74. Channel = 3 'read potentiometer
      75. voltage = Getadc(channel) '10 bit
      76. 'ausgabe ws2812
      77. select case voltage
      78. case 800 to 1024: gosub eins
      79. case 600 to 799: gosub zwei
      80. case 400 to 599: gosub drei
      81. case 200 to 399: gosub vier
      82. case 0 to 199: gosub fuenf
      83. end select
      84. 'konvertierung in einzelwerte
      85. ei = voltage mod 10
      86. voltage = voltage /10
      87. ze = voltage mod 10
      88. voltage = voltage /10
      89. hu = voltage mod 10
      90. voltage = voltage /10
      91. ta = voltage mod 10
      92. Lcdat 6 , 1 , "Akku=";ta;hu;ze;ei;"V"
      93. end sub
      94. '******************* temperatur messen und lesen ************************
      95. Sub Temp_messen_start
      96. Config 1wire = PortD.2
      97. 1wreset
      98. 1wwrite &HCC ' Überspringe Rombefehl Seriennummer weglassen
      99. 1wwrite &H44 ' Messen
      100. Config 1wire = PortD.3
      101. 1wreset
      102. 1wwrite &HCC ' Überspringe Rombefehl Seriennummer weglassen
      103. 1wwrite &H44 ' Messen
      104. Config 1wire = PortD.4
      105. 1wreset
      106. 1wwrite &HCC ' Überspringe Rombefehl Seriennummer weglassen
      107. 1wwrite &H44 ' Messen
      108. End Sub
      109. Sub Temp_lesen_start
      110. Waitms 800
      111. Local Dummy As Integer
      112. Config 1wire = PortD.2
      113. 1wreset
      114. 1wwrite &HCC
      115. 1wwrite &HBE ' Start Daten lesen
      116. Sc(1) = 1wread(9) ' Gelesene Daten ins Array
      117. Dummy = Makeint(sc(1) , Sc(2))
      118. Temperatur(1) = Dummy * 0.0625
      119. Config 1wire = PortD.3
      120. 1wreset
      121. 1wwrite &HCC
      122. 1wwrite &HBE ' Start Daten lesen
      123. Sc(1) = 1wread(9) ' Gelesene Daten ins Array
      124. Dummy = Makeint(sc(1) , Sc(2))
      125. Temperatur(2) = Dummy * 0.0625
      126. Config 1wire = PortD.4
      127. 1wreset
      128. 1wwrite &HCC
      129. 1wwrite &HBE ' Start Daten lesen
      130. Sc(1) = 1wread(9) ' Gelesene Daten ins Array
      131. Dummy = Makeint(sc(1) , Sc(2))
      132. Temperatur(3) = Dummy * 0.0625
      133. End Sub
      134. '******************* Unterprogramme lipoblitz ************************
      135. eins:
      136. R = 255 :g= 255: b=255 'weiss
      137. Call SetColor(0 , color())
      138. Call Send()
      139. waitms blitz
      140. R = 0 :g= 0: b=0
      141. Call SetColor(0 , color())
      142. Call Send()
      143. return
      144. zwei:
      145. For I = 1 To 2
      146. g = 255 'gruen
      147. Call SetColor(0 , color())
      148. Call Send()
      149. waitms blitz
      150. g = 0
      151. Call SetColor(0 , color())
      152. Call Send()
      153. Waitms warten
      154. Next I
      155. return
      156. drei:
      157. For I = 1 To 3
      158. R = 255 :g=255 'gelb
      159. Call SetColor(0 , color())
      160. Call Send()
      161. waitms blitz
      162. R = 0 :g=0
      163. Call SetColor(0 , color())
      164. Call Send()
      165. Waitms warten
      166. Next I
      167. return
      168. vier:
      169. For I = 1 To 4
      170. R = 255 :g=110 'orange
      171. Call SetColor(0 , color())
      172. Call Send()
      173. waitms blitz
      174. R = 0 :g=0
      175. Call SetColor(0 , color())
      176. Call Send()
      177. Waitms warten
      178. Next I
      179. return
      180. fuenf:
      181. For I = 1 To 5
      182. R = 255
      183. Call SetColor(0 , color())
      184. Call Send()
      185. waitms blitz
      186. R = 0
      187. Call SetColor(0 , color())
      188. Call Send()
      189. Waitms warten
      190. Next I
      191. return
      192. 'OLED initialisation ***********************************************************
      193. Sub Oled_init
      194. I2cstart
      195. I2cwbyte &H78
      196. I2cwbyte &HAE 'DISPLAYOFF
      197. I2cwbyte &HD5 'SETDISPLAYCLOCKDIV
      198. I2cwbyte &H80 'ratio 0x80
      199. I2cwbyte &H00 'SETMULTIPLEX
      200. I2cwbyte &H3F ' 1f 128x32
      201. I2cwbyte &HD3 'SETDISPLAYOFFSET
      202. I2cwbyte &H00
      203. I2cwbyte &H40 'SETSTARTLINE
      204. I2cwbyte &H8D 'CHARGEPUMP
      205. I2cwbyte &H14 'vccstate 14
      206. I2cwbyte &H20 'MEMORYMODE
      207. I2cwbyte &H00 '
      208. I2cwbyte &HA1 'A0 upside down SEGREMAP
      209. I2cwbyte &HC8 'COMSCANDEC
      210. I2cwbyte &HDA 'SETCOMPINS
      211. I2cwbyte &H12 ' 02 128x32 12
      212. I2cwbyte &H81 'SETCONTRAST
      213. I2cwbyte &HD9 'SETPRECHARGE
      214. I2cwbyte &HF1 'vccstate f1
      215. I2cwbyte &HDB 'SETVCOMDETECT
      216. I2cwbyte &H40
      217. I2cwbyte &HA4 'DISPLAYALLON_RESUME
      218. I2cwbyte &HA6 'NORMALDISPLAY
      219. I2cwbyte &HAF
      220. I2cstop
      221. End Sub
      222. $include "font8x8TT.font"
      223. 'wallp:
      224. ' $bgf "22er.bgf" ' include the picture data
      Alles anzeigen
    • 17b schrieb:

      Vielleicht hat deins ja auch ne Macke wenn nur jede zweite Zeile funktioniert
      Oder zu billig gekauft X( - neulich hatte ein 16 bit Adc nur 11 nutzbare <X
      Diese Routine hatte ich auch versucht. Es reagiert richtig auf alle Befehle vermutlich haben die tatsächlich ein 32x128 Display angebaut. Die neuen sind bestellt. Das vorhandene wird nun im Zoom Mode betrieben (heller bzw weniger Strom) Bei ihm reicht das einschalten alleine nach dem Reset:

      Quellcode

      1. I2cstart
      2. I2cwbyte $78 'Adresse
      3. I2cwbyte $80 'Befehl folgt
      4. 'I2cwbyte $8d 'Ladepumpe
      5. 'I2cwbyte $80
      6. 'I2cwbyte $14 'Ein
      7. 'I2cwbyte $80
      8. I2cwbyte $af 'Display on
      9. #if _sim = 0
      10. I2cstop
      11. #endif
      Alles anzeigen
      selbst die Ladepumpe schaltet es defaultmäßig ein (Im gegensatz zum Datenblatt)
      PS Durch die fehlenden I2cwbyte $80 werden bei Deiner Routine nicht alle Befehle ausgeführt. Aber das im Normalfall nicht auf. Erst wenn einige Parameter geändert werden sollen. Aber die lassen sich alle auch alleine Ändern ohne das gesamte Init.
      PPS In den Code ist das Init unnötig da die lib schon eins integriert. Es schaltet jedoch den Kontrast auf vollgas (FF) - Bei Deinem fehlt der Wert so das evt D9 gesetzt wird. Und sie hat vermutlich einen Tippfehler:
      D8 ist kein bekannter Befehl (DB ist SETVCOMDETECT lt Datenblatt)

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Pluto25 ()

    • 17b schrieb:

      Gibt es Befehle um Zeichen zu invertieren oder Zeilen zu scrollen.
      Vergißt bitte Beitrag 71

      Quellcode

      1. I2cstart
      2. I2cwbyte $78 'Adresse
      3. I2cwbyte 128 'Vor jedem Befehl nötig
      4. I2cwbyte $26 'Scroll Horizontal Rechts ($27 links)
      5. I2cwbyte 128 : I2cwbyte 0 'Startpage (0-6)
      6. I2cwbyte 128 : I2cwbyte 0 'Speed (0-7)
      7. I2cwbyte 128 : I2cwbyte 7 'Endpage (>Start-7)
      8. I2cstop
      Der Scroll Befehl beim SH1106 hat nur 3 Parameter nicht 6 wie im Datenblatt des 1306.Dafür steht in dem Datenblatt was ich vom 1106 habe nichts über Scroll nur (sinngemäß) "Nutze keine andern Befehle sie können Fehlfunktionen auslösen"
      Die Pages sind 8 Zeilen große Bereiche beginnend Oben. Somit kann auch nur ein Teil des Displays gescrollt werden.
      Eingeleitet wird das Scrollen dann mit $2F und abgeschaltet mit $2E(i2cwrite Adresse,$80,$2E/F)
      Während des Scrollens können die Parameter geändert werden, er übernimmt es sofort.
      Beim 1106 funktioniert das diagonal Scroll (noch?) nicht. Das gesamte Display kann jedoch vertikal "zu Fuß" gescrollt werden. Der Befehl $D3 gefolgt von Offset/Startzeile (0-63) bestimmt welcher Adressbereich oben beginnt.
      Würde nun (gleichmäßig) D3,0..D3,1.....D3,63..D3,0 zu Display gesendet scrollt es nach unten. Das gleiche(?) wird erreicht indem direkt die Startzeile geändert wird mit $40,41,42,...$7f,$40
      PS Der 1306 "humpelte" auch beim Scrollen vielleicht funktionierts bei ihm auch so.
    • Heute ist Nachschub gekommen. Funktionierte mit meinem Programm aus Beitrag 89 aber auch nicht. Auch die beiden I2C Adressen aus meinem Link aus Beitrag 98 brachten nix. Da ich mit dem Terminal auf Kriegsfuss stehe und nie sinnvolle Ausgaben bekomme, konnte ich die I2C Adressen mit dem I2C Suchprogramm nicht testen und für einen Aufbau mit nem LCD Display war ich zu faul.
      Was aber sofort funktionierte ist das Demoprogramm aus Beitrag 5 von RoBue.
      Das Ganze funktioniert mit diesen Displays. Für den Fall, dass der Link irgendwann nicht mehr geht, es sind die 4poligen 1.3" Displays mit der Bezeichnung "1,3 Zoll Arduino OLED 128x64 Display SH1106 I2C IIC TWI weiß Raspberry Pi".
    • 17b schrieb:

      und für einen Aufbau mit nem LCD Display war ich zu faul.
      irgendeinen nicht genutzten Pin auf High /Low wenn erfogreich würde auch reichen. Die Adresse dann ins Eeprom. Zum testen nutze ich meißt eine Uart Verbindung zum PC dann kann der Avr "sein Leid klagen"
      Lcds benötigen viel Zeit und sind daher oft nicht günstig um Zeitkritische Dinge zu verfolgen. Dann kann man ihnen auch nichts mitteilen. Durch die Modifikationen an dem Init hatte ich das Glück das meine neuen mit der 1306 Lib sofort was zeigten. Auch scheint es so zu sein das sie ohne Init nur mit dem Befehl "Einschalten" loslegen.
      Sollten wir das Terminal zum laufen bringen? Welcher Clock hat der Chip und weiche Baudrate ist gewünscht?