首页 > 解决方案 > SSD1306 显示屏闪烁

问题描述

我目前正在做一个项目,我想同时显示“设置”、角度和符号(向上箭头、向下箭头和复选标记)(角度的值会改变,当值是在某个阈值内,符号会发生变化)。我们已经设法获得“设置和角度”显示,但符号在不同时间闪烁。在我的加速度计/void accel() 代码中构建的延迟的同时,文本也会闪烁。闪烁是否完全来自加速度计/void accel() 函数的延迟,是否有解决方法。我们在 'void loop()' 中注释掉了 'void accel()' 函数来测试这个假设,它确实有助于让字符几乎以“稳定”的方式显示。然而,这是“进步”,

我们还怀疑 .clearDisplay 函数导致了闪烁。不幸的是,通过避免清除屏幕功能,闪烁仍然存在,并且由于它没有清除屏幕,因此角度编号和符号之间存在先前像素的“残余”。然后,我们尝试设置字体并显示设置,无论是“剃须”、“切片”等,每种情况一次,因为唯一需要更改的是角度编号和符号。嗯......这通过显示不正确使问题变得更糟。奇怪的是,屏幕不会随着“Sharp Pebble”闪烁,然后延迟 2.5 秒,但它确实会在 'void oled()' 函数中的所有显示函数闪烁。我们还尝试在最后一个 . 每个 if() 语句中的 draw1x2string() 但这没有帮助。如果有帮助,我还可以提供该问题的视频。

非常感谢!!源代码片段如下。

具有似乎与闪烁一起播放的延迟的加速度计功能:

void accel()
{ 
  myIMU.standby( false );
  int16_t dataHighres = 0;
  //if( myIMU.readRegisterInt16( &dataHighres, KXTJ3_OUT_X_L ) != 0 )
  //Serial.print(" Acceleration X RAW = ");
  //Serial.println(dataHighres);
  //if( myIMU.readRegisterInt16( &dataHighres, KXTJ3_OUT_Z_L ) != 0 )
  //Serial.print(" Acceleration Z RAW = ");
  //Serial.println(dataHighres);
  // Read accelerometer data in mg as Float, sprintf "%f" isn't working, which is why the *1000  is ultized 
  AcX = myIMU.axisAccel( X );
  AcY = myIMU.axisAccel( Y );
  AcZ = myIMU.axisAccel( Z );
  //Raw Data to degrees
  x_angle = atan(AcX/sqrt((pow (AcZ,2)+pow(AcY,2))))*57.2958;
  y_angle = atan(AcY/sqrt((pow (AcZ,2)+pow(AcX,2))))*57.2958;
  z_angle = atan(sqrt((pow (AcX,2)+pow(AcY,2)))/AcZ)*57.2958;

  sprintf(bufferxa,"xAngle:%d",round(x_angle));
  sprintf(bufferya,"yAngle:%d",round(y_angle));
  sprintf(bufferza,"zAngle:%d",round(z_angle));
  //Read accelerometer data in mg as Float, sprintf "%f" isn't working
  //Float Converstion 
  AcX_adj = (myIMU.axisAccel( X ))*1000;
  r_AcX_adj = round(AcX_adj);
  sprintf(bufferx,"Accelx:%d",r_AcX_adj);
  AcY_adj = (myIMU.axisAccel( Y ))*1000;
  r_AcY_adj = round(AcY_adj);
  sprintf(buffery,"Accely:%d",r_AcY_adj);
  AcZ_adj = (myIMU.axisAccel( Z ))*1000;
  r_AcZ_adj = round(AcZ_adj);
  sprintf(bufferz,"Accelz:%d",r_AcZ_adj);
  myIMU.standby( true );
  delay(333);
}

出于可读性目的,初始显示函数和“void oled()”函数的一小段代码:

void logo()
{
  u8x8.setFont(u8x8_font_8x13B_1x2_r);
  u8x8.draw1x2String(2,0,"Sharp Pebble");
  delay(2500);
}
void oled()
{
  switch(button_number)
  {
    case 0:
     u8x8.clearDisplay();
      if(z_angle_adj < 11)
      {
        //Set Cursor for up or down arrow and Check mark 
        u8x8.setCursor(12,1);
        u8x8.setFont(u8x8_font_open_iconic_arrow_4x4);
        u8x8.print(arrow_up);  
        //Set Font for mode and angle 
        u8x8.setFont(u8x8_font_8x13B_1x2_r);
        u8x8.draw1x2String(0,0,"Shaving");
        u8x8.draw1x2String(8,0,bufferzadj);   
      }
      if(z_angle_adj > 15)
      {
        //Set Cursor for up or down arrow and Check mark 
        u8x8.setCursor(12,1);
        u8x8.setFont(u8x8_font_open_iconic_arrow_4x4);
        u8x8.print(arrow_down); 
        //Set Font for mode and angle
        u8x8.setFont(u8x8_font_8x13B_1x2_r);
        u8x8.draw1x2String(0,0,"Shaving");
        u8x8.draw1x2String(8,0,bufferzadj);
      }
      if((z_angle_adj >= 11)&&(z_angle_adj <= 15))
      {
        //Set Cursor for up or down arrow and Check mark 
        u8x8.setCursor(12,1);
        u8x8.setFont(u8x8_font_open_iconic_check_4x4);
        u8x8.print(check); 
        //Set Font for mode and angle
        u8x8.setFont(u8x8_font_8x13B_1x2_r);
        u8x8.draw1x2String(0,0,"Shaving");
        u8x8.draw1x2String(8,0,bufferzadj); 
      }
    break;  

调用“void accel()”函数的循环函数。

void loop() 
{
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= 1000)
  {
    timer++;
    previousMillis = millis();
  }
  sprintf(bufferB,"%d",button_number);
  accel();
  zangle_adj();
  oled();
}

标签: c++displayflickerlcd

解决方案


推荐阅读