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)))/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,"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,"Shaving");
        u8x8.draw1x2String(8,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,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,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();
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)