Reputation: 1
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
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