Anzeigefehler bei 1,3" OLED 128*64 mit Treiber SH1106

Hallo zusammen,

ich habe ein Problem mit der Anzeige auf meinem OLED mit SH1106-Treiber, denn es zeigt Pixelfehler an den Ziffern.

Am Display liegt es nicht, ein anderes Display mit SH1106-Treiber zeigt eine völlig identische Darstellung, es muss also am Code liegen.

Hat jemand vielleicht eine Idee wie ich das beheben kann?

Vielen Dank und Grüße
Dan

/*  Manual Mill Controller v1.0
    written by Iron-Dan
    Creates stepper pulses to set speeds in mm/min and rpm and included rapid traverse mode.
    Implemented with the usage of the libraries which are included below.
*/

/*********************************************************************
  This is an example for our Monochrome OLEDs based on SSD1306 drivers

  Pick one up today in the adafruit shop!
  ------> http://www.adafruit.com/category/63_98

  This example is for a 128x64 size myOLED using I2C to communicate
  3 pins are required to interface (2 I2C and one reset)

  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada  for Adafruit Industries.
  BSD license, check license.txt for more information
  All text above, and the splash screen must be included in any redistribution
*********************************************************************/

/*********************************************************************
  I change the adafruit SSD1306 to SH1106
  SH1106 driver don't provide several functions such as scroll commands.
*********************************************************************/

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH1106.h>

#define OLED_RESET -1
Adafruit_SH1106 myOLED(OLED_RESET);

#include <Tone.h>

// Variables

const byte minusButtonA = 8;                        // Minus Button for speed value on A-Axis at Arduino Pin 10.
const byte plusButtonA = 7;                         // Plus Button for speed value on A-Axis at Arduino Pin 9.
const byte rapidButtonA = 2;                        // Button for rapid traverse mode on A-Axis at Arduino Pin 2.
const byte rapidLEDA = 11;                          // LED for indication of rapid traverse mode on A-Axis at Arduino Pin 11.
byte stateRapidModeA = LOW;                         // State of rapid traverse mode on A-Axis.
const unsigned long maxSpeedA = 200;                // Max. speed in rpm.
unsigned long currentSpeedA = 0;                    // Current speed in rpm.
unsigned long oldSpeedA = 0;                        // Old speed in rpm.

const byte minusButtonXYZ = 10;                     // Minus Button for speed value on XYZ-Axis at Arduino Pin 8.
const byte plusButtonXYZ = 9;                       // Plus Button for speed value on XYZ-Axis at Arduino Pin 7.
const byte rapidButtonXYZ = 3;                      // Button for rapid traverse mode on XYZ-Axis at Arduino Pin 3.
const byte rapidLEDXYZ = 12;                        // LED for indication of rapid traverse mode on XYZ-Axis at Arduino Pin 12.
byte stateRapidModeXYZ = LOW;                       // State of rapid traverse mode on XYZ-Axis.
const unsigned long maxSpeedXYZ = 20000;            // Max. speed in mm/min.
unsigned long currentSpeedXYZ = 0;                  // Current speed in mm/min.
unsigned long oldSpeedXYZ = 0;                      // Old speed in mm/min.

// Timer variables

unsigned long previousMillisRapidButtonA = 0;       // Time value in ms when rapidButtonA was pressed last time.
unsigned long currentMillisRapidButtonA;            // New time value in ms when rapidButtonA was pressed.
unsigned long previousMillisMinusButtonA = 0;       // Store time in ms as MinusButtonA was clicked first time.
unsigned long currentMillisMinusButtonA = 0;        // Store time value as long as MinusButtonA is held.
unsigned long previousMillisPlusButtonA = 0;        // Store time in ms as PlusButtonA was clicked first time.
unsigned long currentMillisPlusButtonA = 0;         // Store time value as long as PlusButtonA is held.

unsigned long previousMillisRapidButtonXYZ = 0;     // Time value in ms when rapidButtonXYZ was pressed last time.
unsigned long currentMillisRapidButtonXYZ;          // New time value in ms when rapidButtonXYZ was pressed.
unsigned long previousMillisMinusButtonXYZ = 0;     // Store time in ms as MinusButtonXYZ was clicked first time.
unsigned long currentMillisMinusButtonXYZ = 0;      // Store time value as long as MinusButtonXYZ is held.
unsigned long previousMillisPlusButtonXYZ = 0;      // Store time in ms as PlusButtonXYZ was clicked first time.
unsigned long currentMillisPlusButtonXYZ = 0;       // Store time value as long as PlusButtonXYZ is held.

// Stepper variables

unsigned int microStepsA = 16;
unsigned int motorStepsA = 200;
unsigned int turnsPerRoundA = 90;
unsigned int microStepsXYZ = 16;
unsigned int motorStepsXYZ = 200;
unsigned int mmPerRoundXYZ = 5;
unsigned int frequencyA = 0;
unsigned int frequencyXYZ = 0;

Tone pulseA;                                        // Create Tone object pulseA.
Tone pulseXYZ;                                      // Create Tone object pulseXYZ.

// Setup

void setup() {
  pinMode(minusButtonA, INPUT_PULLUP);
  pinMode(plusButtonA, INPUT_PULLUP);
  pinMode(rapidButtonA, INPUT_PULLUP);
  pinMode(minusButtonXYZ, INPUT_PULLUP);
  pinMode(plusButtonXYZ, INPUT_PULLUP);
  pinMode(rapidButtonXYZ, INPUT_PULLUP);
  pinMode(rapidLEDA, OUTPUT);
  pinMode(rapidLEDXYZ, OUTPUT);

  pulseA.begin(5);                                  // Init stepper pulses for A-Axis at Arduino Pin 5.
  pulseXYZ.begin(6);                                // Init stepper pulses for XYZ-Axis at Arduino Pin 6.

  bootScreen();                                     // Show Boot Screen

}

void loop() {

  readRapidButtonA();
  readRapidButtonXYZ();
  readMinusButtonA();
  readPlusButtonA();
  readMinusButtonXYZ();
  readPlusButtonXYZ();
  updateDisplay();
}

void bootScreen()
{
  myOLED.begin();                                   // Init the OLED.
  myOLED.clearDisplay();                            // Clear display buffer.
  myOLED.setTextSize(1);
  myOLED.setTextColor(WHITE);
  myOLED.setCursor(0, 0);
  myOLED.print("MANUAL");
  myOLED.setCursor(0, 10);
  myOLED.print("MILL");
  myOLED.setCursor(0, 20);
  myOLED.print("CONTROLLER");
  myOLED.setCursor(0, 30);
  myOLED.print("v1.0");
  myOLED.setCursor(0, 40);
  myOLED.print("BY IRON-DAN");
  myOLED.display();
  delay(3000);
  myOLED.clearDisplay();                            // Clear display buffer.
  myOLED.setTextSize(2);
}

void updateDisplay()
{
  int xPosSpeedA;
  int xPosSpeedXYZ;

  if ((currentSpeedA / 10) >= 0 && (currentSpeedA / 10) <= 9)
  {
    xPosSpeedA = 46 + 36;
  }
  else if ((currentSpeedA / 10) >= 10 && (currentSpeedA / 10) <= 99)
  {
    xPosSpeedA = 46 + 24;
  }
  else if ((currentSpeedA / 10) >= 100 && (currentSpeedA / 10) <= 999)
  {
    xPosSpeedA = 46 + 12;
  }
  else if ((currentSpeedA / 10) >= 1000)
  {
    xPosSpeedA = 46;
  }

  if ((currentSpeedXYZ / 10) >= 0 && (currentSpeedXYZ / 10) <= 9)
  {
    xPosSpeedXYZ = 46 + 36;
  }
  else if ((currentSpeedXYZ / 10) >= 10 && (currentSpeedXYZ / 10) <= 99)
  {
    xPosSpeedXYZ = 46 + 24;
  }
  else if ((currentSpeedXYZ / 10) >= 100 && (currentSpeedXYZ / 10) <= 999)
  {
    xPosSpeedXYZ = 46 + 12;
  }
  else if ((currentSpeedXYZ / 10) >= 1000)
  {
    xPosSpeedXYZ = 46;
  }

  myOLED.clearDisplay();                            // Clear display buffer.
  myOLED.drawRect(0, 0, 128, 20, WHITE);
  myOLED.drawLine(39, 0, 39, 20, WHITE);
  myOLED.fillRect(96, 15, 2, 2, WHITE);
  myOLED.drawRect(0, 30, 128, 20, WHITE);
  myOLED.drawLine(39, 30, 39, 50, WHITE);
  myOLED.fillRect(96, 45, 2, 2, WHITE);
  myOLED.setCursor(3, 3);
  myOLED.print("XYZ");
  myOLED.setCursor(xPosSpeedXYZ, 3);
  myOLED.print(currentSpeedXYZ / 10);
  myOLED.setCursor(103, 3);
  myOLED.print(currentSpeedXYZ % 10);
  myOLED.setCursor(3, 33);
  myOLED.print("A");
  myOLED.setCursor(xPosSpeedA, 33);
  myOLED.print(currentSpeedA / 10);
  myOLED.setCursor(103, 33);
  myOLED.print(currentSpeedA % 10);
  myOLED.display();
  delay(50);

}

void readRapidButtonA()
{
  if (!digitalRead(rapidButtonA))
  {
    currentMillisRapidButtonA = millis();
    if (currentMillisRapidButtonA - previousMillisRapidButtonA > 200)             // Push button debouncing.
    {
      stateRapidModeA = !stateRapidModeA;           // Toggle stateRapidModeA when rapidButtonA was pressed.
      if (stateRapidModeA)
      {
        digitalWrite(rapidLEDA, HIGH);
        oldSpeedA = currentSpeedA;                  // Store previous speed for A-Axis.
        currentSpeedA = maxSpeedA;                  // Set max speed for A-Axis.
        setSpeedA();
      }
      else
      {
        digitalWrite(rapidLEDA, LOW);
        currentSpeedA = oldSpeedA;                  // Restore speed value before rapid traverse mode was entered.
        setSpeedA();
      }
    }
    previousMillisRapidButtonA = currentMillisRapidButtonA;
  }
}

void readRapidButtonXYZ()
{
  if (!digitalRead(rapidButtonXYZ))
  {
    currentMillisRapidButtonXYZ = millis();
    if (currentMillisRapidButtonXYZ - previousMillisRapidButtonXYZ > 200)         // Push button debouncing.
    {
      stateRapidModeXYZ = !stateRapidModeXYZ;       // Toggle stateRapidModeXYZ when rapidButtonXYZ was pressed.
      if (stateRapidModeXYZ)
      {
        digitalWrite(rapidLEDXYZ, HIGH);
        oldSpeedXYZ = currentSpeedXYZ;              // Store previous speed for XYZ-Axis.
        currentSpeedXYZ = maxSpeedXYZ;              // Set max speed for XYZ-Axis.
        setSpeedXYZ();
      }
      else
      {
        digitalWrite(rapidLEDXYZ, LOW);
        currentSpeedXYZ = oldSpeedXYZ;              // Restore speed value before rapid traverse mode was entered.
        setSpeedXYZ();
      }
    }
    previousMillisRapidButtonXYZ = currentMillisRapidButtonXYZ;
  }
}

void readMinusButtonA()
{
  if (!digitalRead(minusButtonA))
  {
    previousMillisMinusButtonA = millis();          // Store first time value when MinusButtonA was clicked.

    while (!digitalRead(minusButtonA))
    {
      currentMillisMinusButtonA = millis();         // Update time value as long as MinusButtonA is held.
      if (currentMillisMinusButtonA - previousMillisMinusButtonA > 50 && currentMillisMinusButtonA - previousMillisMinusButtonA <= 1000)
      {
        if (currentSpeedA >= 1)
        {
          currentSpeedA -= 1;
        }
        updateDisplay();
        setSpeedA();
      }
      else if (currentMillisMinusButtonA - previousMillisMinusButtonA > 1000 && currentMillisMinusButtonA - previousMillisMinusButtonA <= 5000)
      {
        if (currentSpeedA >= 5)
        {
          currentSpeedA -= 5;
        }
        updateDisplay();
        setSpeedA();
      }
      else if (currentMillisMinusButtonA - previousMillisMinusButtonA > 5000)
      {        
        if (currentSpeedA >= 10)
        {
          currentSpeedA -= 10;
        }
        updateDisplay();
        setSpeedA();
      }
    }
  }
}

void readPlusButtonA()
{
  if (!digitalRead(plusButtonA))
  {
    previousMillisPlusButtonA = millis();           // Store first time value when PlusButtonA was clicked.

    while (!digitalRead(plusButtonA))
    {
      currentMillisPlusButtonA = millis();          // Update time value as long as PlusButtonA is held.
      if (currentMillisPlusButtonA - previousMillisPlusButtonA > 50 && currentMillisPlusButtonA - previousMillisPlusButtonA <= 1000)
      {        
        if (currentSpeedA <= (maxSpeedA - 1))
        {
          currentSpeedA += 1;
        }
        updateDisplay();
        setSpeedA();
      }
      else if (currentMillisPlusButtonA - previousMillisPlusButtonA > 1000 && currentMillisPlusButtonA - previousMillisPlusButtonA <= 5000)
      {        
        if (currentSpeedA <= (maxSpeedA - 5))
        {
          currentSpeedA += 5;
        }
        updateDisplay();
        setSpeedA();
      }
      else if (currentMillisPlusButtonA - previousMillisPlusButtonA > 5000)
      {        
        if (currentSpeedA <= (maxSpeedA - 10))
        {
          currentSpeedA += 10;
        }
        updateDisplay();
        setSpeedA();
      }
    }
  }
}
void readMinusButtonXYZ()
{
  if (!digitalRead(minusButtonXYZ))
  {
    previousMillisMinusButtonXYZ = millis();        // Store first time value when MinusButtonXYZ was clicked.

    while (!digitalRead(minusButtonXYZ))
    {
      currentMillisMinusButtonXYZ = millis();       // Update time value as long as MinusButtonXYZ is held.
      if (currentMillisMinusButtonXYZ - previousMillisMinusButtonXYZ > 50 && currentMillisMinusButtonXYZ - previousMillisMinusButtonXYZ <= 1000)
      {        
        if (currentSpeedXYZ >= 1)
        {
          currentSpeedXYZ -= 1;
        }
        updateDisplay();
        setSpeedXYZ();
      }
      else if (currentMillisMinusButtonXYZ - previousMillisMinusButtonXYZ > 1000 && currentMillisMinusButtonXYZ - previousMillisMinusButtonXYZ <= 5000)
      {        
        if (currentSpeedXYZ >= 5)
        {
          currentSpeedXYZ -= 5;
        }
        updateDisplay();
        setSpeedXYZ();
      }
      else if (currentMillisMinusButtonXYZ - previousMillisMinusButtonXYZ > 5000 && currentMillisMinusButtonXYZ - previousMillisMinusButtonXYZ <= 10000)
      {        
        if (currentSpeedXYZ >= 10)
        {
          currentSpeedXYZ -= 10;
        }
        updateDisplay();
        setSpeedXYZ();
      }
      else if (currentMillisMinusButtonXYZ - previousMillisMinusButtonXYZ > 10000)
      {        
        if (currentSpeedXYZ >= 100)
        {
          currentSpeedXYZ -= 100;
        }
        updateDisplay();
        setSpeedXYZ();
      }
    }
  }
}

void readPlusButtonXYZ()
{
  if (!digitalRead(plusButtonXYZ))
  {
    previousMillisPlusButtonXYZ = millis();         // Store first time value when PlusButtonXYZ was clicked.

    while (!digitalRead(plusButtonXYZ))
    {
      currentMillisPlusButtonXYZ = millis();        // Update time value as long as PlusButtonXYZ is held.
      if (currentMillisPlusButtonXYZ - previousMillisPlusButtonXYZ > 50 && currentMillisPlusButtonXYZ - previousMillisPlusButtonXYZ <= 1000)
      {        
        if (currentSpeedXYZ <= (maxSpeedXYZ - 1))
        {
          currentSpeedXYZ += 1;
        }
        updateDisplay();
        setSpeedXYZ();
      }
      else if (currentMillisPlusButtonXYZ - previousMillisPlusButtonXYZ > 1000 && currentMillisPlusButtonXYZ - previousMillisPlusButtonXYZ <= 5000)
      {        
        if (currentSpeedXYZ <= (maxSpeedXYZ - 5))
        {
          currentSpeedXYZ += 5;
        }
        updateDisplay();
        setSpeedXYZ();
      }
      else if (currentMillisPlusButtonXYZ - previousMillisPlusButtonXYZ > 5000 && currentMillisPlusButtonXYZ - previousMillisPlusButtonXYZ <= 10000)
      {        
        if (currentSpeedXYZ <= (maxSpeedXYZ - 10))
        {
          currentSpeedXYZ += 10;
        }
        updateDisplay();
        setSpeedXYZ();
      }
      else if (currentMillisPlusButtonXYZ - previousMillisPlusButtonXYZ > 10000)
      {        
        if (currentSpeedXYZ <= (maxSpeedXYZ - 100))
        {
          currentSpeedXYZ += 100;
        }
        updateDisplay();
        setSpeedXYZ();
      }
    }
  }
}

void setSpeedA()
{
  if (currentSpeedA >= 1)
  {
    frequencyA = ((currentSpeedA / 10) * microStepsA * motorStepsA * turnsPerRoundA) / 60;
    pulseA.play(frequencyA);
  }
  else
  {
    pulseA.stop();
  }
}

void setSpeedXYZ()
{
  if (currentSpeedXYZ >= 1)
  {
    frequencyXYZ = ((currentSpeedXYZ / 10) * microStepsXYZ * motorStepsXYZ) / (60 * mmPerRoundXYZ);
    pulseXYZ.play(frequencyXYZ);
  }
  else
  {
    pulseXYZ.stop();
  }
}

Bei mir sieht das so aus, wenn ich Tone kommentiere:

grafik

Die Displayanzeige und Tone vertragen sich irgendwie nicht. Wie man das abstellen kann, weiß ich aber leider nicht.

Hallo agmue,

Danke für den Hinweis!
Das ist natürlich doof, denn auf Tone basiert mein gesamtes Programm. :frowning: