Forum: Mikrocontroller und Digitale Elektronik u8glib ohne delay


von Herr Bert (Gast)


Lesenswert?

Hallo,

gibt es eine Möglichkeit,

die I2C 0.96" Oled Displays ohne Delay anzusteuern?

So gehts leider nicht
[c]
  while(1)
  {
    static uint8_t i;
    char str[10];
    itoa(i, str, 10);

    if(u8g_NextPage(&u8g))
    {
      u8g_SetFont(&u8g, u8g_font_9x18B);
      u8g_DrawStr(&u8g, 63-u8g_GetStrWidth(&u8g, "ATmega1284P")/2, 10, 
"ATmega1284P");

      u8g_SetFont(&u8g, u8g_font_6x10);
      u8g_DrawStr(&u8g, 0, 26, str);
      u8g_DrawStr(&u8g, 0, 38, "I123456789ABCDEFGHIJKLM");
      u8g_DrawStr(&u8g, 0, 50, "g123456789ABCDEFGHIJKLM");
      u8g_DrawStr(&u8g, 0, 62, "Ig23456789ABCDEFGHIJKLM");
    }
    if(++i >= 10) {i = 0;u8g_FirstPage(&u8g);}
    _delay_ms(100);
    PORTB ^= 1<<PORTB2;
  }
[/code]

von Herr Bert (Gast)


Lesenswert?

1
  while(1)
2
  {
3
    static uint8_t i;
4
    char str[10];
5
    itoa(i, str, 10);
6
    
7
    if(u8g_NextPage(&u8g))
8
    {
9
      u8g_SetFont(&u8g, u8g_font_9x18B);
10
      u8g_DrawStr(&u8g, 63-u8g_GetStrWidth(&u8g, "ATmega1284P")/2, 10, "ATmega1284P");
11
12
      u8g_SetFont(&u8g, u8g_font_6x10);
13
      u8g_DrawStr(&u8g, 0, 26, str);
14
      u8g_DrawStr(&u8g, 0, 38, "I123456789ABCDEFGHIJKLM");
15
      u8g_DrawStr(&u8g, 0, 50, "g123456789ABCDEFGHIJKLM");
16
      u8g_DrawStr(&u8g, 0, 62, "Ig23456789ABCDEFGHIJKLM");
17
    }
18
    if(++i >= 10) {i = 0;u8g_FirstPage(&u8g);}
19
    _delay_ms(100);
20
    PORTB ^= 1<<PORTB2;
21
  }

von Dirk K. (dekoepi)


Lesenswert?

Hm, ich mache das so mit einem Arduino-Progrämmchen ;)
1
   if (!sent) {
2
      // I2C OLED -> 8 pages of 8 px height
3
      u8g.firstPage();
4
      u8g.setFont(u8g_font_helvR08);  // small font
5
      u8g.drawStr( 20, 8, "Smell-o-matik v0.1\n");
6
      u8g.nextPage();
7
      
8
      u8g.setFont(u8g_font_helvB14);  // Big font
9
      
10
      sprintf(text, "R(s): %u",sensor_val);
11
      u8g.drawStr( 0, 28, text);  
12
      u8g.nextPage();
13
      u8g.drawStr( 0, 28, text);  
14
      u8g.nextPage();
15
      u8g.drawStr( 0, 28, text);  
16
      u8g.nextPage();
17
      
18
      sprintf(text, "R(h): %u",temperature);
19
      u8g.drawStr( 0, 48, text);  
20
      u8g.nextPage();
21
      u8g.drawStr( 0, 48, text);  
22
      u8g.nextPage();
23
      u8g.drawStr( 0, 48, text);  
24
      u8g.nextPage();
25
26
      u8g.setFont(u8g_font_helvR08);  // small font
27
      sprintf(text, "%u mV",voltage);
28
      u8g.drawStr( 0, 64, text);  
29
      sprintf(text, "PWM %u%% ", pulsewidth);
30
      u8g.drawStr( 76, 64, text);  
31
      u8g.nextPage();
32
33
      sent = true;
34
    }

Keinde delays. Läuft direkt am ATmega328 mit 16MHz (Arduino Pro Micro).

: Bearbeitet durch User
von Sebastian (Gast)


Lesenswert?

Man könnte ja das _delay_ms durch ein Timer-basiertes delay ersetzen, 
oder durch eine ausgezählte Schleife, wenn die Displays zu langsam sind. 
Falls nur Optimierung das Ziel ist, kann man die 100 ms vielleicht nach 
geeigneten Vorversuchen kürzen, wenn einem nicht Exemplarstreuung oder 
Temperaturabhängigkeit einen Strich durch die Rechnung machen.

von Herr Bert (Gast)


Lesenswert?

Das "_delay_ms(x)" spielt hier keine Rolle. Kann auch einen Timer 
verwenden, hilft hier nicht weiter. Das Problem ist, dass die Libary 
selber für den Sendevorgang delays verwendet.

von Nils S. (krumeltee) (Gast)


Lesenswert?

Herr Bert schrieb:
> Das Problem ist, dass die Libary
> selber für den Sendevorgang delays verwendet.

Ich weiss nicht, was dein Display genau kann, aber viele Displays lassen 
sich über ein Flag oder eine Leitung abfragen, ob sie fertig und bereit 
für neue Daten/Kommandos sind.
Eine Interrupt-Leitung des Displays existiert vielleicht auch?

von Herr Bert (Gast)


Angehängte Dateien:

Lesenswert?

Hallo, leider kein Flag über eine zusätzliche Leitung

von Rudolph (Gast)


Angehängte Dateien:

Lesenswert?

Leider ist immer noch nicht klar, um was für ein Display es überhaupt 
geht.
Auch die u8glib unterstützt eine Menge.
Und das Problem wurde auch nicht wirklich hinreichend beschrieben.

Ein Display mit I2C Schnittstelle und u8glib Unterstütung wäre eines mit 
einem SSD1306 Controller.
Und in der Timing-Tabelle aus dem Datenblatt erkenne ich jetzt erstmal 
keinen Grund für Delays.
Die ganz unten erwähnten t_idle mit 1,3µs sind ja die Wartezeit zwischen 
zwei Übertragungen und nicht etwa zwischen den einzelnen Bytes einer 
Übertragung.

Die Lib wird ja hoffentlich nicht jedes Zeichen einzeln übertragen, aber 
auch dann sind 1,3µs nicht wirklich viel.

Aber, ein Problem könnte das I2C sein, gerade die I2C Einheit in den 
AVRs ist ja eher stumpf und somit schwer Software-lastig.
Pro Byte das auf den I2C gelegt werden dauert das ja schon mindestens 
20µs.

Da ziehe ich SPI einfach vor, mit nur zwei Pins mehr für den Anschluss 
an sich und einem Pin pro Baustein mehr wird man den ganzen 
Address-Overhead los und kann die Daten auch noch erheblich fixer los 
werden.

Der SSD1306 Controller läuft am SPI bis 10MHz.

Tja, bei sowas hilft eigentlich nur die Library zu zerpflücken und an 
die Anforderungen anzupassen oder gleich selber entsprechenden Code zu 
schreiben.

von nico (Gast)


Lesenswert?

Dear Bert,
Look what the author of ug8lib said on Arduino forum:
"Hi


There is no clear screan as such, instead you can say, that FirstPage 
will clear the screen.

To implement the switching between your sensors, you should implement 
two or more "draw" precodures. Let me call these procedures draw1() and 
draw2().
Now you need a new master draw procedure, let me call this "draw()". 
draw1() and draw2() are called from draw(), but this depends on a 
globale "state" variable, like this:

Code: [Select]

void draw(void)
{
  if ( state == 0 )
   draw1();
  else
   draw2();
}


Now you need to call draw() within the picture loop (like in your code). 
Additionally you must change "state" from 0 to 1 and back to 0 every 10 
seconds. I think this often refered as "blink without delay()" problem.

Another option is to implement the picture loop twice The first picture 
loop calls draw1(), then add a 10 sec delay, then implement second 
picture loop with draw2() and add a delay again."
Hope it halps you.
Best regards

von George (Gast)


Lesenswert?

Das ist ein alter Beitrag. Die u8glib wird auch nicht mehr weiter 
entwickelt. Es gibt bereits eine u8glib2. TROTZDEM gibt es gute Gruende 
auf diese Frage noch einmal zu antworten.

Die u8glib ist nach meiner Erfahrung ziemlich klein. Fuer ein OLED 
128x64 mit SSD1306 (iC2) VIEL KLEINER als die Adafruit SSD1306 und auch 
kleiner als die u8glib2.

Ich benoetige sie auf einem Arduino nano. Da ist sie bei mir fast ca. 
30% kleiner, was vorwiegend die dynamischen Variablen betrifft. Das 
heist am Ende, mit einer Adafruit SSD1306 library bin ich bei 106% 
Speicherauslastung und das ganze System funktioniert nicht. Mit u8glib 
bin ich gerade bei so ca. 65%.

ALLERDINGS hat der Autor dieser Frage ganz Recht. Das delay im "picture 
loop" stoert GANZ GEWALTIG, weil es natuerlich alle anderen Prozesse 
ganz stoppt. Mein Arduino nano kommuniziert ueber das Internet mit 
Blynk. Dort lese ich temp. Sensore aus und schalte auch die Ausgaenge 
des Nano. Mit einem "delay" funktionert das ganze nicht richtig.

Den "picture loop" habe ich natuerlich aus dem "loop" entfernt und 
anstelle des "delay" lasse ich zaehlen. Bei jeweils ca. 5 
"Wiederholungen" von "draw1" und "draw2".....schaltet das display 
ungefaehr im Rhythmus von 1,5 sek. zwischen den beiden Seiten draw1 und 
draw2 hin und her. Das beeinflusst den gesamten Ablauf am wenigsten. Bei 
Interesse poste ich den ganzen code. Jetzt hier nur der entsprechende 
Teil zur Frage :

....und wer das besser kann und weiss.....bitte hier beschreiben !! :-)
1
void sendSensor1() {
2
  for (int i = 0; i < 5; i++) {   //XXXXXXXXXXXXXXXXXXX
3
  u8g.firstPage();
4
  do { draw1(); } 
5
  while( u8g.nextPage() );    };    
6
  
7
  sensors.requestTemperatures();  
8
  temperature1 = sensors.getTempC(tempSensor1);   // temp in F. getTempF 
9
  dtostrf(temperature1, 1, 2, temperatureString1);
10
  Blynk.virtualWrite(V1, temperature1); // Send to Blynk virtual V1 "pin"
11
}
12
13
void sendSensor2() {  
14
  for (int i = 0; i < 5; i++) {    //XXXXXXXXXXXXXXXXXX
15
  u8g.firstPage();
16
  do { draw2(); } 
17
  while( u8g.nextPage() );    }; 
18
                             
19
  sensors.requestTemperatures();                  
20
  temperature2 = sensors.getTempC(tempSensor2);   // temp in F. getTempF
21
  dtostrf(temperature2, 1, 2, temperatureString2);  // Format            
22
  Blynk.virtualWrite(V2, temperature2); // Send to Blynk virtual V2 "pin"
23
}

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.