Oled Lib

GuMo

Ich bastel grade mit Case switch und brauche einen Rat.
Ich habe zwei Taster zum switchen die ich mittels der Bounce2.h Lib entprelle … das funzt super und flüssig über den Seriellen Monitor.

Baue ich nun das Oled und die Lib´s dazu ein, werden die switches nur beim längerem halten erkannt.

Weiß jemand warum oder hat einen Hinweis.

LG Lisa

Ohne

#include <Bounce2.h>

int turn_R = 11;
int turn_L = 12;
int Wert = 0 ;


Bounce debouncer1 = Bounce();
Bounce debouncer2 = Bounce();


void setup() {
  
  pinMode(12, INPUT_PULLUP);
  pinMode(11, INPUT_PULLUP);
  
  
  
  debouncer1.attach(turn_R);
  debouncer1.interval(5);
  debouncer2.attach(turn_L);
  debouncer2.interval(5);
  
  Serial.begin(9600);
}

void loop() {
   debouncer1.update();
   debouncer2.update();  
     

   
   if ( debouncer1.fell() ) { Wert++;} 
   if ( debouncer2.fell() ) { Wert--;}
   
     
   


switch (Wert) {
    case 0:   
      Serial.println("Null");
      break;
      
    case 1:    
      Serial.println("Eins");
      break;
      
    case 2:    
      Serial.println("Zwei");
      break;
      
    case 3:    
      Serial.println("Drei");
      break;
  } 


if (Wert == 4 ) {Wert = 0; }
if (Wert== -1 ) {Wert = 3; }
  
}

Und mit

#include <Bounce2.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

 
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);


int turn_R = 11;
int turn_L = 12;
int Wert = 0 ;


Bounce debouncer1 = Bounce();
Bounce debouncer2 = Bounce();


void setup() {
   display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
   display.setTextColor(WHITE);
   display.clearDisplay();
  
  pinMode(12, INPUT_PULLUP);
  pinMode(11, INPUT_PULLUP);
 
  
  debouncer1.attach(turn_R);
  debouncer1.interval(5);
  debouncer2.attach(turn_L);
  debouncer2.interval(5);
  
  
}

void loop() {
   display.clearDisplay();
  
   debouncer1.update();
   debouncer2.update();  
   

   
   if ( debouncer1.fell() ) { Wert++;} 
   if ( debouncer2.fell() ) { Wert--;}
   
     
   


switch (Wert) {
    case 0:   
      display.setTextSize(1);  
      display.setCursor(33, 30); 
      display.print("Null");
      break;
    
    case 1:    
      display.setTextSize(1);  
      display.setCursor(33, 30); 
      display.print("Eins");
      break;
   
    case 2:    
      display.setTextSize(1);  
      display.setCursor(33, 30); 
      display.print("Zwei");
      break;
      
    case 3:    
      display.setTextSize(1);  
      display.setCursor(33, 30); 
      display.print("Drei");
      break;
  } 

display.display();

if (Wert == 4 ) {Wert = 0; }
if (Wert== -1 ) {Wert = 3; }
  
}

Geht es ohne clearDisplay() schneller?

Hallo,

ich würde auch sagen es liegt am display.clearDisplay() im loop und daran das immer mit jedem Umlauf das Display aktualisiert wird. Du solltest das nur dann tun wenn eine Flanke der Taster erkannt wird oder sich der Inhalt von Wert geändert hat.

Du kannst clearDisplay() auch so mit millis() verbandeln, dass es nur z. B. alle paar Sekunden für eine kurze Zeit regelmäßig aufgerufen wird. Ich lasse das Display meines aktuellen Gebastels mit folgendem Codeschnipsel aktualisieren:

if(sw1.check()==true || (millis()/5000)%5==0)
  {
    displ.update();
  }
  else
  {
    displ.clearBuffer();
  }

So wird entweder andauernd aktualisiert (sw1 eingeschaltet) oder nur alle paar Sekunden für kurze Zeit.

Gruß

Gregor

Hallo,

ich hab jetzt hier in den letzten Tagen eine Abfrage in der Form:

if (millis()/5000)%5==0){

tu was

}

mehrfach gesehen. Es sieht einfach aus und macht die zusätzliche Verwendung einer Hilfsvariablen augenscheinlich nicht erforderlich. Ich denke aber das das nicht richtig klappt, da so nur maximal 1ms Umlaufzeit möglich ist. Wenn die Umaufzeit des loop etwas länger ist, kann es sein das die Abfrage %5 nicht immer 0 als Ergebnliss liefert. So zusagen Zeitpunkt verpasst. :slight_smile:

Es geht eigendlich nur mit der bekannten standard Abfrage auf :

if( millis()-altzeit >=5000){

altzeit=millis();
tu was

}

wenn hier die Abfrage auf

if( millis()-altzeit ==5000)

gemacht würde passiert das gleiche.

man verzeihe mir das ich die Codeschnipsel nicht in codetags gesetzt habe.

Heinz

Es sieht einfach aus und macht die zusätzliche Verwendung einer Hilfsvariablen augenscheinlich nicht erforderlich.

Wie bemerkt macht es Probleme, wenn die exakte ms nicht erwischt wird. Auch ist in der Regel nicht erwünscht, dass es in der gefundenen ms beliebig oft drankommt. Die Verwendung einer Variable nach dem BlinkWithoutDelay - Prinzip ist der bessere Weg.
Auch sind die / und % Operatoren aufwendiger als sie aussehen.

Hi

Aber Durchlaufzeiten von <1ms sollten trotzdem anzustreben sein - klar: delay()-Verbot und den ganzen anderen blockierenden Kram nur verwenden, wenn man weiß, was man Da tut.

Der µC rennt mit 16MHz - der macht 16 Takte jede µs (10E-6), also 16000 Takte je ms (10E-3) oder eben, Überraschung, 16.000.000 Takte pro Sekunde. (ein paar mehr oder weniger, je nach Laune des Quarz)
Mit 16000 Takten (ein Großteil der Befehle benötigt nur einen Takt) sollte man Es also doch schon wieder nach loop() schaffen - dann ist auch diese ms vorbei und millis() wird spätestens jetzt einen neuen Wert ausgeben.

MfG

Hallo,

@postmaster mag sein mir fehhlt da so das Gefühl,

Ich stelle mit gerade vor z.B 1000 Zeichen einer HTML Datei von einer SD Karte einzulesen um sie an den Webserver zu geben. Ich denke da kommt mehr als 1 ms bei raus.

Gruß Heinz

Rentner:
Ich stelle mit gerade vor z.B 1000 Zeichen einer HTML Datei von einer SD Karte einzulesen ...

Stelle Dir dazu im Verhältnis den Speicher für Variablen des UNO vor, dann merkst Du das unglückliche Konzept. Besser sind kleine Häppchen, die dann auch wieder einen schnelleren Durchlauf von loop ermöglichen.

Bei Arduino Due, Teensy und ESP32 sieht das anders aus, aber die takten auch etwas schneller.

Guten Morgen...
Sorry für meine lange Abwesenheit..viel zu tun.
Danke für eure Hinweise..
Ich konnte das Prob jetzt einkreisen bzw. ausfindig machen.

display.clearDisplay(); ist es allerdings nicht.

Ich habe nach und nach die Befehle eingefügt und im Monitor den Sketch überwacht.

Es wird erst "ZÄH" wenn ich

display.display();

hinzufüge, also erst wenn tatsächlich auch was geschrieben werden soll.

Dabei ist auch die Position unerheblich. Ob im Case oder ausserhalb, oder in einer eigenen Funktion.
Sobald display.display(); im Loop steht wird es zäh.

Iwelche Ideen ?

LG Lisa

HouseLisa:
Sorry für meine lange Abwesenheit..viel zu tun.

TGIF :slight_smile:

Was für ein Display/Controller benutzt Du?

Gruß

Gregor

Hallo,

das hatten wir doch schon geschrieben . Werte nur dann in das Display schreiben wenn sich was geändert hat oder bei Flanke der Taster. Dazu gehört dann auch

display.display();

denn damit werden die Werte sicher auf das Display übertagen. warum sollte das denn auch bei jedem Umlauf gemacht werden. ?

Heinz

Ja :-[ hast ja recht

ich habe es jetzt so gemacht…sicherlich nicht die eleganteste Lösung, aber sie funzt…Danke für die Denk anstöße.

#include <Bounce2.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

int turn_R = 11;
int turn_L = 12;
int Wert = 0 ;
int Update = 0 ;


Bounce debouncer1 = Bounce();
Bounce debouncer2 = Bounce();


void setup() {
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.setTextColor(WHITE);
  display.setTextSize(2); 
  display.clearDisplay();

  
  pinMode(12, INPUT_PULLUP);
  pinMode(11, INPUT_PULLUP);
  
  
  
  debouncer1.attach(turn_R);
  debouncer1.interval(5);
  debouncer2.attach(turn_L);
  debouncer2.interval(5);
  
  Serial.begin(9600);
}

void loop() {
   debouncer1.update();
   debouncer2.update();  
     

   
   if ( debouncer1.fell() ) { Wert++;} 
   if ( debouncer2.fell() ) { Wert--;}
   
     
   


switch (Wert) {
    case 0:  
      display.clearDisplay(); 
      display.setCursor(33, 30); // RL HR
      display.print("null");
      if (Update != 1  ) {Update = 2;};
      break;
      
    case 1:    
      display.clearDisplay(); 
      display.setCursor(33, 30); // RL HR
      display.print("eins");
      if (Update != 3 ) {Update = 4;};
      break;
      
    case 2:  
       
      display.clearDisplay(); 
      display.setCursor(33, 30); // RL HR
      display.print("zwei");
       if (Update != 1 ) {Update = 2;};
      break;
      
    case 3:    
      display.clearDisplay(); 
      display.setCursor(33, 30); // RL HR
      display.print("drei");
      if (Update != 3 ) {Update = 4;};
      break;
  } 

if (Update == 2) {display.display(); Update = 1 ;}
if (Update == 4) {display.display(); Update = 3 ;}



if (Wert == 4 ) {Wert = 0; }
if (Wert== -1 ) {Wert = 3; }
  
}

HouseLisa:
... sie funzt ...

... wenn auch potthässlich :slight_smile:

Gruß

Gregor

Potthässlich :grinning:

Jaha!

 if ( debouncer1.rose() ) { display.display();}
   if ( debouncer2.rose() ) { display.display();}

So isses natürlich noch einfacher...
Danke nochmal!

Für das von Dir verwendete Display gibt es verschiedene Programmbibliotheken, so auch von Oli Kraus. Geschwindigkeitsvergleiche habe ich noch keine gemacht, aber er hat spezielle Fonts beispielsweise nur für Text, die Speicher sparen. Im Wiki ist das beschrieben. Das Problem ist allerdings die Qual der optimalen Wahl. Oli ist auch gelegentlich in diesem Forum aktiv.