Arduino 1.3" OLED gleichzeitige Bewegung

Hallo,

ich bin noch relativ neu im Arduino-Thema und habe mir ein 1.3" OLED Display (SH1106) gekauft und einen Arduino Nano. Nun möchte ich, dass sich Kreis 1 (von oben nach unten) und Kreis 2 (von links nach rechts) bewegt. Das funktioniert auch grundsätzlich, jedoch nicht gleichzeitig, so wie ich es mir wünschen würde. Kann mir jemand einen Tipp geben, wie ich sowas umsetzen kann?

Großes Ziel ist es, später eine Art Radar zu erstellen, bei dem sich Zahlenwerte ändern und einzelne Pixel bewegen.

Ich hoffe das mir jemand helfen kann oder zumindest einen Hinweis gibt, mit welchen Methoden ich so etwas umsetzen kann. Vielen Dank!

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

#define OLED_RESET 4
Adafruit_SH1106 display(OLED_RESET);

void circle1 (){
   
    for (int i=0; i <= 64; i++){

    display.clearDisplay();
    display.fillCircle(50, i, 5, WHITE);
    display.display(); }
}

void circle2 (){
    
    for (int i=0; i <= 128; i++){

    display.clearDisplay();
    display.fillCircle(i, 25, 5, WHITE);
    display.display(); }
}

void setup()   {                

  display.begin(SH1106_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3D (for the 128x64)
}

void loop() {

    circle1();
    circle2();
}

Ersetze mal die beiden Funktionen.
Vollkommen ungetestet und nur aus dem Bauch raus.

void circle1 () {
  static int i = 0;
  display.clearDisplay();
  display.fillCircle(50, i, 5, WHITE);
  display.display();
  i++;
  if (i > 64) i = 0;
}

void circle2 () {
  static int i = 0;
  display.clearDisplay();
  display.fillCircle(i, 25, 5, WHITE);
  display.display();
i++;
if (i > 128) i = 0;
}

Musst sehen, ob Dir das zu schnell durchläuft.
Wenn dem so ist einfach im loop zu testzwecken ein delay einbasteln. Nur zu Testzwecken!

Kranken nicht momentan beide Varianten daran, dass die jeweiligen circle()-Funktionen durch das clearDisplay() die Arbeit des Anderen zunichte machen?
Dann wäre doch vielleicht eine Logik der folgenden Art vielleicht zu überlegen (Pseudo-Code):

for (...) // bis 128
{
  display.clearDisplay();
  circle1();  // aktuellen Schritt malen oder aussetzen
              // alternativ circle1() - Aufrufe hier schon mit if(...) kapseln
  circle2();  // aktuellen Schritt malen
  display.display();
}

Da momentan circle1 ja nur halb so viele Schritte macht wie circle2 muss er halt jeden zweiten Schritt aussetzen - wenn die synchron laufen sollen. Wenn das Verhältnis nicht ganzzahlig ist, wird es etwas komplizierter.

Ja machen sie. :frowning: Aber ich schrub ja - nur ausm Bauch raus.
Es reicht m.E., wenn im circle2() das clearDisplay entfernt wird.

Ja - aber dann auch in circle1() das display.display(). Es wird dann etwas schwieriger, wenn weitere Objekte dazukommen.
Eigentlich würde ich gerne - so wie in Deinen circles - auch gar keine Schleife mehr sehen wollen. loop() gibt den Takt (clear und display) vor und jedes Objekt zeichnet sich im aktuellen Zustand selbst.

1 Like

Jepp...

Ich fasse mal zusammen:

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

#define OLED_RESET -1
Adafruit_SH1106 display(OLED_RESET);

void circle1 () {
  static int i = 0;
  display.fillCircle(50, i, 5, WHITE);
  if ( i <= 64 ) {
    i++;
  } else {
    i = 0;
  }
}

void circle2 () {
  static int i = 0;
  display.fillCircle(i, 25, 5, WHITE);
  if ( i < 128 ) {
    i++;
  } else {
    i = 0;
  }
}

void setup()   {
  display.begin(SH1106_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3D (for the 128x64)
}

void loop() {
  display.clearDisplay();
  circle1();
  circle2();
  display.display();
}

Zusammen mit einem UNO ist die Bewegung so langsam, daß eine Verzögerung nicht notwendig ist. Limitierend ist wohl der I2C-Bus des SH1106, denn auch mit einem ESP32 geht es nicht schneller:

// getestet mit ESP32
#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>

U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

void setup(void) {
  Wire.setClock(1700000); // ESP32: set I2C frequency to 1.7mhz
  u8g2.begin();
  u8g2.enableUTF8Print(); // enable UTF8 support for the Arduino print()
}

void loop(void) {
  u8g2.clearBuffer();
  circle1();
  circle2();
  u8g2.setFont(u8g2_font_crox2h_tr);
  u8g2.drawStr(40, 10, "Radar");
  u8g2.sendBuffer();
}

void circle1 () {
  static int i = 0;
  u8g2.drawDisc(50, i, 5);
  if ( i <= 64 ) {
    i++;
  } else {
    i = 0;
  }
}

void circle2 () {
  static int i = 0;
  u8g2.drawDisc(i, 25, 5);
  if ( i < 128 ) {
    i++;
  } else {
    i = 0;
  }
}

Für ein Radarbild dürfte es etwas lahm wirken, fürchte ich.

2 Likes

Na geht doch mit Dir :slight_smile:

Klar doch :rofl:

Hallo. Vielen Dank für die Mühe und Tipps. Die zusammengefasste Variante von agmue erfüllt das was ich nicht hinbekommen habe, obwohl es eigentlich recht einfach ist, wie ich jetzt festgestellt habe. Ich versuche jetzt alleine weiterzukommen. Dankeschön an alle!

Danke für die Rückmeldung, viel Erfolg!