kusho
kusho

Reputation: 1

SSD1306 128x64 OLED. Only seems to work with less than 64 lines Height. ( 48 to be specific)

So a couple of weeks ago i started to build and code my own lasertag. Everything worked fine until i started to work on it again 2 days ago. The problem is if i use the lasertag code the ssd1306 allocation fails. But if i dont change anything on my wiring or exchange the screen and use a test script the OLED works completely fine. Ive came this far that the oled works with the lasertag code only if i use the screen resolution 128x48. if i want to use the full 64 lines of height it just stops to work. i will post both codes i used to test.

Lasertag code:

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <RF24.h>
#include <IRremote.h>
#include <nRF24L01.h>
#include <SPI.h>
#include <Wire.h>
#define SCREEN_WIDTH 128    //Länge des OLED
#define SCREEN_HEIGHT 64    //Höhe des OLED
#define OLED_RESET -1

int irSender = 3;
int laser = 5;
int taster = 2;
int tasterstat;
//int changenameBUTTON = 6;
int idle = 50;`your text`

type here


int Munition = 30;
int Player1_Kills = 0;
int Kills = 0;
int boxcount = 1;
int i;
int h = 2;
int h1;
int serial_input = 1;
String Spielername;



const byte address [6] = "00002";
const byte slave [6] = "00001";

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
RF24 radio (7, 8); //CE,  CSN



void setup()
{

  Serial.begin(9600);
  
  pinMode(laser, OUTPUT);
  pinMode(taster, INPUT);
  

// DISPLAY

  

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3D)) 
  { 
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }

  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.display();
  delay(500);

  display.clearDisplay();

// RADIO 
  radio.begin();
  radio.openReadingPipe(0, address);
  radio.setPALevel(RF24_PA_MIN);
  radio.startListening();
  
 IrSender.begin(irSender);

  h1 = 60;
Serial.println("Setup done");
display.display();
}


void loop()
{
  display.clearDisplay(); 
  
  display.print("Kills: ");
  display.setCursor(40, 0);
  display.print(Kills);

  display.setCursor(0, 20);
  display.print("Ammo:");
  display.setCursor(40, 20);
  display.print(Munition);
  display.setCursor(45, 50);
  display.print("Kusho");
  
 display.display();


   tasterstat = digitalRead(taster); //liest den Tasterstatus ein (Schuss?)

   Serial.println(tasterstat);

  
  
  if (tasterstat == LOW && Munition != 0)     // Wenn man den Taster drückt (taster = abzug)
  {
    Munition --;
    h ++;
    h1 = h1- 2;
    digitalWrite(laser, HIGH);
    
    IrSender.sendNEC(1608, 20);

    delay(idle);
    digitalWrite(laser, LOW);

    
    radio.read(&Player1_Kills, sizeof Player1_Kills);
    Serial.println(Player1_Kills);


    if (Player1_Kills > Kills)
    {
      Kills = Player1_Kills;
      Serial.println(Player1_Kills);
    }

    delay(200);

   
  
  }



  // Wenn Muntion Leer ist und man Nachladen muss (LCD Display Anzeige und Munition zurücksetzen)
  else if (Munition <= 0)

  {
    
    int w = 100;
    int w1 = 0;
    boxcount = 1;
    int boxtime = 0;

    display.clearDisplay();  //löscht jede Ausgabe auf dem Display sodasss nichts angezeigt wird


    if (boxcount == 1 && boxcount != 0)
    {

      while (boxtime < 750 && w1 != 100)
      {

        display.setTextSize(2);
        display.setCursor (10, 10);
        display.print("Reloading");
        display.drawRect(15, 45, w, 10, WHITE);
        display.fillRect (15, 45, w1, 10,WHITE);

        display.display();
        w1 = w1 + 4;                    //vergrößert den Wert der Box um 4 pro schleifen durchlauf sodass eine Nachladezeit von 1,5 Sec erreicht werden kann.
        boxtime ++;                    
        

        if ( boxtime == 749)
        {
          boxcount = 0;
          Munition = 30;              // setzt Munition auf 30 == Muntion ist nachgeladen und Anzeige ist wieder auf Standard (Munition Kills Accuracy etc)
         
        }
      }
      Munition = 30;
      h1 = 60;
      h = 2;
      


    }

  



  }
}


TEST CODE:

/*Einfache Laufschrift,von rechts nach links, für ein 0.96 Zoll OLED Display 
 * mit einem Arduino Mega 2560 und Tasterabfrage 
 * Als erstes einmal kurz die Pins des Dsplay erklärt:
 * Das Display hat 4 Pins GND,VCC,SCK,SDA
 * GND + VCC dienen der Spannungsversorgung des Display
 * SCK(bzw.SCL) + SDA sind die beiden Pins für den I2C Bus der für die Datenübertragung genutzt wird
 * Die Verdahtung zwischen Board und Display ist recht einfach
 * GND vom Display mit GND vom Board verbinden 
 * VCC vom Display mit +5V vom Board verbinden
 * SCK vom Display mit SCL(Pin21) vom Board verbinden das ist der oberste Pin auf der Seite des USB-Port 
 * SDA vom Display mit SDA(Pin20) vom Board verbinden das ist der erste Pin neben SCL
 * Pin 20+21 gilt  soweit mir bekannt ist nur für das Mega2560 Board.Die anderen "Mini-Boards" verwenden andere
 * Pins.Bitte vorher prüfen.
 * 
 */
#include <Wire.h> // Für die Aktivierung des I2C Bus
#include <Adafruit_GFX.h> // Diese und die nächste Zeile laden der notwendige Bibliotheken für das Display
#include <Adafruit_SSD1306.h>
#define Display_Breite 128 //  Display Gesambreite, in Pixel
#define Display_Hoehe 64 //  Display Gesamthöhe, in Pixel
Adafruit_SSD1306 display(Display_Breite, Display_Hoehe, &Wire);//hier wird das Display mit den nötigen Parametern verbunden
/*previousMillis(),currentMillis() und hilfsmerker sind an BlinkWithoutDelay angelehnt bzw. entnommen 
 * Hiermit wird bei gedrücktem Taster ein  "blinken" erzeugt 
 * das den Schriftzug nach links wandern lässt indem bei jedem Durchlauf die X-Positin(xpos) 
 * neu  berechnet wird wenn der hilfsmerker==LOW ist
 */
unsigned long previousMillis = 0; 
int hilfsmerker=HIGH;
int xpos=138;  //Legt die Startposition x des Schriftzuges fest hier etwas ausserhalb des Displays
int ypos=10;   //Legt die Höhe y des Schriftzuges fest in Abhängigkeit mit der Schriftgröße
int groesse=3;
int zaehler=0;
const int Taster = 2; // Ordnet die Variable "Taster" dem Pin 2 zu 
void setup() {
   Serial.begin(115200);
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Prueft, ob das Display korrekt am I2C-Bus angeschlossen ist
    Serial.println(F("SSD1306 allocation failed"));// Fehlerausgabe, wenn nicht
    for(;;);                                       // Endlosschleife
  }
 pinMode (Taster,INPUT);  //Legt die Variable Taster mit Pin 2 als Eingang fest  
}
void loop() { 
unsigned long currentMillis = millis();
if (digitalRead(Taster)==HIGH){   ////hier wird der Taster ausgelesen  (Taster muss festgehalten werden)
if (currentMillis - previousMillis >=15) {
        previousMillis = currentMillis;  
      if (hilfsmerker == LOW) {        
      xpos=xpos-2;      ///verringert bei jedem Durchlauf die x-Position um zwei Pixel
      hilfsmerker = HIGH;
    } else {
      hilfsmerker = LOW;
    }  
   if (xpos<=-340){  ////setzt die x-Position auf den Startpunkt zurück wenn der Schriftzug ganz verschwunden ist
    xpos=138;
   }
    display.clearDisplay(); // löscht vor jedem Schreiben das Display da ansonsten alles nur überschrieben würde und man nichts mehr lesen könnte
  display.setTextSize(3); // legt die Schriftgöße fest 
  display.setTextColor(WHITE);//schaltet so zu sagen  die Farbe der Schrift ein
  display.setCursor(xpos,ypos); ///hier werden dem Cursor bzw. dem Text die x und y Position zugewiesn
  display.println("Syntax Error in 10");  ////LANG LEBE DER "C64" !!!!!!
   display.display();//////??????
     }
}else{////ab hier etwas Text damit das Display nicht dunkel bleibt wenn der Taster losgelassen wurde
      display.clearDisplay(); 
  display.setTextSize(2); // legt die neu Schriftgöße fest 
  display.setTextColor(WHITE);
  display.setCursor(0,10); ///dieses Mal festgelegte Werte für x und y
  display.println("Tach auch");  
   display.display();  
xpos=138; ///setzt die x-Position auf ihren Startwertzurück
     }
}


the test code is just a random one i found on the internet.

this is the console output after uploadin the lasertag code:

Sketch uses 18036 bytes (55%) of program storage space. Maximum is 32256 bytes. Global variables use 912 bytes (44%) of dynamic memory, leaving 1136 bytes for local variables. Maximum is 2048 bytes. "C:\Users\Joach\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/bin/avrdude" "-CC:\Users\Joach\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf" -v -V -patmega328p -carduino "-PCOM6" -b115200 -D "-Uflash:w:C:\Users\Joach\AppData\Local\Temp\arduino\sketches\958344E6CCC3000F9601D7670CCC5F27/lasertag_Player1.ino.hex:i"

avrdude: Version 6.3-20190619 Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/ Copyright (c) 2007-2014 Joerg Wunsch

     System wide configuration file is "C:\Users\Joach\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf"

     Using Port                    : COM6
     Using Programmer              : arduino
     Overriding Baud Rate          : 115200
     AVR Part                      : ATmega328P
     Chip Erase delay              : 9000 us
     PAGEL                         : PD7
     BS2                           : PC2
     RESET disposition             : dedicated
     RETRY pulse                   : SCK
     serial program mode           : yes
     parallel program mode         : yes
     Timeout                       : 200
     StabDelay                     : 100
     CmdexeDelay                   : 25
     SyncLoops                     : 32
     ByteDelay                     : 0
     PollIndex                     : 3
     PollValue                     : 0x53
     Memory Detail                 :

                              Block Poll               Page                       Polled
       Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
       ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
       eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
       flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
       lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
       hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
       efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
       lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
       calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
       signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

     Programmer Type : Arduino
     Description     : Arduino
     Hardware Version: 3
     Firmware Version: 4.4
     Vtarget         : 0.3 V
     Varef           : 0.3 V
     Oscillator      : 28.800 kHz
     SCK period      : 3.3 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e950f (probably m328p) avrdude: reading input file "C:\Users\Joach\AppData\Local\Temp\arduino\sketches\958344E6CCC3000F9601D7670CCC5F27/lasertag_Player1.ino.hex" avrdude: writing flash (18036 bytes):

Writing | ################################################## | 100% 2.89s

avrdude: 18036 bytes of flash written

avrdude done. Thank you.

checked wiring. Thats correct.

Upvotes: 0

Views: 994

Answers (1)

BitBank
BitBank

Reputation: 8725

You're probably running out of RAM. Initializing the Adafruit_GFX library for the SSD1306 will gobble up 1024 bytes of RAM. It requires a backing buffer for the display and that leaves you with too little RAM to reliably run the rest of the Arduino code. If you only need to draw text and fixed graphics (aka sprites) on the display, you can use a different display library (like my OneBitDisplay) that doesn't require you to allocate a backing buffer.

Upvotes: 0

Related Questions