olikraus / u8g2

U8glib library for monochrome displays, version 2
Other
5k stars 1.04k forks source link

Text fade in fade out #1103

Closed Beppi4U closed 4 years ago

Beppi4U commented 4 years ago

PLEASE KILL POST OR DELETE IF I'M OFF TOPIC WITH THIS! Hi! My name is Andreas. I'm new to GITHUB and also to u8g2. For a present project(simple desktop clock) i have to change from adafruit's library(0,96oled) to u8g2. Because the bigger oled has a different display driver1106. After a some spaghetticoding the original sketch works fine for me. I wanted some sort of intro of the clock after reboot. There for i wanted the text to fade in out to look like bit different than just print it on screen. I tried to write a function for that and i want you to have a look on it and maybe give me a hint/suggestions if there is a better way to do it. (i'm sure there is, because i am a poor/lausiger programmer, but i really try!) code for fadeinout and clock is attached. Greetings

Andreas
(Tetsted on Arduino UNO/NANO with 1.3Oled I2C connection)

FADEINOUT.txt ......mhhhm, seems that only one file is uploaded, what have i done wrong??

Beppi4U commented 4 years ago

Sorry for that , but my machine wont allow me to send the .txt file. I dont know why!

#include <Wire.h>
#include <Arduino.h>
#include <U8x8lib.h>

#ifdef U8x8_HAVE_HW_I2C

#endif

U8X8_SH1106_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);  // DEFINITION DES DISPLAYS UND DER SCHNITTSTELLE

#define button1    3                       // Button B1 is connected to Arduino pin 9 CHANGE BUTTON 
#define button2    2                       // Button B2 is connected to Arduino pin 8 SET BUTTON 

// ARDUINO NANO CLONE ODER - ARDUINO UNO CLONE
// 1.3'' OLED DISPLAY I2C MONOCHROME
// DER DRITTE BUTTON (RESET BUTTON) IST DIREKT AUSGEFÜHRT RST TO GND 

void setup(void) {
  pinMode(button1, INPUT_PULLUP);
  pinMode(button2, INPUT_PULLUP);
  delay(1000);

  u8x8.begin(); 
  u8x8.clear();

  // VORSCHAU
  u8x8.setFont(u8x8_font_inr21_2x4_r);
  u8x8.drawString(0,2,"AVL i60"); 
  delay(5000);
  u8x8.clear();
  u8x8.setFont(u8x8_font_pcsenior_r); //  (u8x8_font_5x7_f)
  u8x8.drawString(0,1," ZUR ERINNERUNG");
  u8x8.drawString(0,2,"   AN DEINE ");
  u8x8.drawString(0,3," KOLLEGEN BEI");
  u8x8.drawString(0,4,"  DER PS/ETF3 ");
  u8x8.drawString(0,5,"  MESSTECHNIK! ");
  u8x8.drawString(0,6," DATUMXXXXXX");
  delay(7000);
  u8x8.clear();
  u8x8.setFont(u8x8_font_pcsenior_r); //  (u8x8_font_5x7_f)
  u8x8.drawString(0,2,"  NAMEN  ");
  u8x8.drawString(0,3," SIND SCHALL ");
  u8x8.drawString(0,4,"    UND RAUCH");
  u8x8.drawString(0,5,"  GIO UND ANDI ");
  delay(7000);
  u8x8.clear();
  u8x8.drawString(0,0," WIR VERMISSEN");
  u8x8.drawString(0,1,"     DICH !");
  u8x8.drawString(0,3," BEGINNE DEN TAG");
  u8x8.drawString(0,4,"MIT EINEM LACHEN");
  u8x8.drawString(0,5,"  UND DER TAG");
  u8x8.drawString(0,6," LACHT MIT DIR!");
  delay(8000);
  u8x8.clear();

}

char Time[]     = "  :  :  ";
char Calendar[] = "  /  /20  ";
char temperature[] = " 00.00";
char temperature_msb;
byte i, second, minute, hour, day, date, month, year, temperature_lsb;

void display_day(){
  switch(day){
    u8x8.setFont(u8x8_font_pcsenior_r);
    case 1:  u8x8.drawString(0, 0, " SO "); break;
    case 2:  u8x8.drawString(0, 0, " MO "); break;
    case 3:  u8x8.drawString(0, 0, " DI "); break;
    case 4:  u8x8.drawString(0, 0, " MI "); break;
    case 5:  u8x8.drawString(0, 0, " DO "); break;
    case 6:  u8x8.drawString(0, 0, " FR "); break;
    default: u8x8.drawString(0, 0, " SA ");
  }
}

void DS3231_display(){
  // Convert BCD to decimal
  second = (second >> 4) * 10 + (second & 0x0F);
  minute = (minute >> 4) * 10 + (minute & 0x0F);
  hour   = (hour >> 4)   * 10 + (hour & 0x0F);
  date   = (date >> 4)   * 10 + (date & 0x0F);
  month  = (month >> 4)  * 10 + (month & 0x0F);
  year   = (year >> 4)   * 10 + (year & 0x0F);
  // End conversion

  Time[7]     = second % 10 + 48;
  Time[6]     = second / 10 + 48;
  Time[4]     = minute % 10 + 48;
  Time[3]     = minute / 10 + 48;
  Time[1]     = hour   % 10 + 48;
  Time[0]     = hour   / 10 + 48;
  Calendar[9] = year   % 10 + 48;
  Calendar[8] = year   / 10 + 48;
  Calendar[4] = month  % 10 + 48;
  Calendar[3] = month  / 10 + 48;
  Calendar[1] = date   % 10 + 48;
  Calendar[0] = date   / 10 + 48;
  if(temperature_msb < 0){
    temperature_msb = abs(temperature_msb);
    temperature[0] = '-';
  }
  else
    temperature[0] = ' ';
  temperature_lsb >>= 6;
  temperature[2] = temperature_msb % 10  + 48;
  temperature[1] = temperature_msb / 10  + 48;
  if(temperature_lsb == 0 || temperature_lsb == 2){
    temperature[5] = '0';
    if(temperature_lsb == 0) temperature[4] = '0';
    else                     temperature[4] = '5';
  }
  if(temperature_lsb == 1 || temperature_lsb == 3){
    temperature[5] = '5';
    if(temperature_lsb == 1) temperature[4] = '2';
    else                     temperature[4] = '7';
 } 
  u8x8.setFont(u8x8_font_pcsenior_r);
  u8x8.drawString(5,0, Calendar);   // Display the date (format: dd/mm/yyyy)
  u8x8.setFont(u8x8_font_profont29_2x3_r);
  u8x8.drawString(0, 2, Time);                         // Display the time
  u8x8.setFont(u8x8_font_pcsenior_r);
  u8x8.drawString(1, 6," TEMP"); 
  u8x8.drawString(6, 6, temperature);  // Display the temperature
  u8x8.drawString(13, 6,"C");
}

void blink_parameter(){
  byte j = 0;
  while(j < 10 && digitalRead(button1) && digitalRead(button2)){
    j++;
    delay(25);
  }
}

byte edit(byte x_pos, byte y_pos, byte parameter){
  char text[3];
  sprintf(text,"%02u", parameter);
  while(!digitalRead(button1));                      // Wait until button B1 released
  while(true){
    while(!digitalRead(button2)){                    // If button B2 is pressed
      parameter++;
      if(i == 0 && parameter > 31)                   // If date > 31 ==> date = 1
        parameter = 1;
      if(i == 1 && parameter > 12)                   // If month > 12 ==> month = 1
        parameter = 1;
      if(i == 2 && parameter > 99)                   // If year > 99 ==> year = 0
        parameter = 0;
      if(i == 3 && parameter > 23)                   // If hours > 23 ==> hours = 0
        parameter = 0;
      if(i == 4 && parameter > 59)                   // If minutes > 59 ==> minutes = 0
        parameter = 0;
      sprintf(text,"%02u", parameter);
      draw_text(x_pos, y_pos, text, 1);
      delay(200);                                    // Wait 200ms
    }
    draw_text(x_pos, y_pos, "   ", 1);
    blink_parameter();
    draw_text(x_pos, y_pos, text, 1);
    blink_parameter();
    if(!digitalRead(button1)){                       // If button B1 is pressed
      i++;                                           // Increament 'i' for the next parameter
      return parameter;                              // Return parameter value and exit
    }
  }
}

void draw_text(byte x_pos, byte y_pos, char *text, byte text_size) {
  u8x8.setCursor(x_pos, y_pos);
  u8x8.setFont(u8x8_font_5x7_f);       //  u8x8.setTextSize(text_size);
  u8x8.print(text);
  u8x8.display();
}

void loop() {

  if(!digitalRead(button1)){                         // If button B1 is pressed
    i = 0;
    while(!digitalRead(button1));                    // Wait for button B1 release
    while(true){
      while(!digitalRead(button2)){                  // While button B2 pressed
        day++;                                       // Increment day
        if(day > 7) day = 1;
        display_day();                               // Call display_day function
        delay(200);                                  // Wait 200 ms
      }
      u8x8.setFont(u8x8_font_5x7_f);
      u8x8.drawString(0, 0, "   ");
      blink_parameter();                             // Call blink_parameter function
      display_day();                                 // Call display_day function
      blink_parameter();                             // Call blink_parameter function
      if(!digitalRead(button1))                      // If button B1 is pressed
        break;
    }
    //set position of text when editing on button press
    date   = edit(6, 0, date);                      // Edit date
    month  = edit(9, 0, month);                    // Edit month
    year   = edit(13,0, year);                    // Edit year
    hour   = edit(0, 2, hour);                     // Edit hours
    minute = edit(4, 2, minute);                   // Edit minutes

    // Convert decimal to BCD
    minute = ((minute / 10) << 4) + (minute % 10);
    hour = ((hour / 10)  << 4) + (hour % 10);
    date = ((date / 10) <<  4) + (date % 10);
    month = ((month / 10)  << 4) + (month % 10);
    year = ((year / 10)  << 4) + (year % 10);
    // End conversion

    // Write data to DS3231 RTC
    Wire.beginTransmission(0x68);               // Start I2C protocol with DS3231 address
    Wire.write(0);                              // Send register address
    Wire.write(0);                              // Reset sesonds and start oscillator
    Wire.write(minute);                         // Write minute
    Wire.write(hour);                           // Write hour
    Wire.write(day);                            // Write day
    Wire.write(date);                           // Write date
    Wire.write(month);                          // Write month
    Wire.write(year);                           // Write year
    Wire.endTransmission();                     // Stop transmission and release the I2C bus
    delay(200);                                 // Wait 200ms
  }

  Wire.beginTransmission(0x68);                 // Start I2C protocol with DS3231 address
  Wire.write(0);                                // Send register address
  Wire.endTransmission(false);                  // I2C restart
  Wire.requestFrom(0x68, 7);                    // Request 7 bytes from DS3231 and release I2C bus at end of reading
  second = Wire.read();                         // Read seconds from register 0
  minute = Wire.read();                         // Read minuts from register 1
  hour   = Wire.read();                         // Read hour from register 2
  day    = Wire.read();                         // Read day from register 3
  date   = Wire.read();                         // Read date from register 4
  month  = Wire.read();                         // Read month from register 5
  year   = Wire.read();                         // Read year from register 6
  Wire.beginTransmission(0x68);                 // Start I2C protocol with DS3231 address
  Wire.write(0x11);                             // Send register address
  Wire.endTransmission(false);                  // I2C restart
  Wire.requestFrom(0x68, 2);                    // Request 2 bytes from DS3231 and release I2C bus at end of reading
  temperature_msb = Wire.read();                // Read temperature MSB
  temperature_lsb = Wire.read();                // Read temperature LSB

  display_day();
  DS3231_display();                             // Diaplay time & calendar

  delay(50);                                    // Wait 50ms 
}
olikraus commented 4 years ago

nettes projekt...

I first did the proper c code formating.

There is problem with this code

for (int stufe=0; stufe<255; stufe=stufe+4) {
  u8x8.setFont(u8x8_font_pcsenior_r);
  u8x8.setCursor(xpos, ypos);
  u8x8.print(text);
  u8x8.setContrast(stufe);
  Serial.print(text);
  Serial.println(stufe);
  stufe=stufe+3;

Or I should better say, the assumtion, that setContrast() allows you to change the display brightness from full black to very bright is wrong. The behavior of setContrast() depends very much on the target display. U8g2 just uses the generic display command 0x81 which will behave differently for target displays. In case of OLEDs the visible difference between setContrast(0) and setContrast(255) is minimal.

I suggest to look here: https://github.com/olikraus/u8g2/issues/98

You should at least include the "setSSD1306VcomDeselect" function into your code. setSSD1306VcomDeselect() should be compatible with the sh1106

Beppi4U commented 4 years ago

….Danke!!! Soll ein Abschiedsgeschenk für unsere Kollegin werden!

Thanks for the fast response! To make it clear "Clock" Code is just adapted by me! I simply replaced the Adafruit library with your library. I tried out the "fadeinout" and the effect is, as you said, poor but recognizable! Maybe i send a Little Video when the work the of AVLi60 is done. Will try to include your Code into the Sketch but as i told you i am a lousy to no programmer. If i cant get it running in next days i will cut it out and leave it as it is! Effect would be cool but is not needed for this present. Thank you for helping me out!

Beppi4U commented 4 years ago

I60_FINAL.zip

.......now this is the final Version of the i60 clock! Dont knew how to post videos here so i put it in zip......delete if not wanted! Fading effect is not ot bad!

olikraus commented 4 years ago

sehr cool :-)

Which solution did you finally use for the fading? "setSSD1306VcomDeselect"?

Beppi4U commented 4 years ago

No, just played with the contrast. I have another set of same hardware so i will try that out. Where do i have to put in the 'vcomdeselect' state?

olikraus commented 4 years ago

Meine Frage war eher: wie hast du das Fading im Video umgesetzt?

Beppi4U commented 4 years ago

Ich habe genauer gesagt die "setcontrast" Methode in einer Schleife unschön Missbraucht! ;-)

include

include

include

ifdef U8x8_HAVE_HW_I2C

endif

U8X8_SH1106_128X64_NONAME_HW_I2C u8x8(/ reset=/ U8X8_PIN_NONE); // DEFINITION DES DISPLAYS UND DER SCHNITTSTELLE

void setup() {

// put your setup code here, to run once: Serial.begin(9600); u8x8.begin(); u8x8.clearDisplay(); } void loop() { u8x8.clearDisplay(); fadeinout(1, 1, " Hallo Andi", 255); delay(1000); fadeinout(1, 2, "That's a test!", 255); delay(1000); fadeinout(1, 3, "Alles klar?!?", 150); delay(1000); fadeinout(1, 4, "BALLALALLLALALX", 150); delay(1000); fadeinout(1, 5, "LABERRHABARBERO", 50); delay(1000); fadeinout(1, 6, ";-)1234567678RR", 50);

// put your main code here, to run repeatedly: }

void fadeinout(int xpos, int ypos,String text, int stufe) { stufe = 0; // JE KLEINER DAS IN(DE)KREMENT STUFE+-(X) DESTO WEICHER DER VERLAUF ABER LANGSAMER - +2 hoch und -3 bei runter FAND ICH BEI DEM OLED AM BESTEN for (int stufe=0; stufe<255; stufe=stufe+2) { u8x8.setFont(u8x8_font_pcsenior_r); u8x8.setCursor(xpos, ypos); u8x8.print(text); u8x8.setContrast(stufe); } for (int stufe=255; stufe>0; stufe=stufe-3) { u8x8.setFont(u8x8_font_pcsenior_r); u8x8.setCursor(xpos, ypos); u8x8.print(text); u8x8.setContrast(stufe); } }

olikraus commented 4 years ago

Ah, cool. Sieht gut aus.