Arduino Nano 驱动OLED测试入门(三)(SSD1306仪表盘设计)

本来介绍如何在Nano上面,通过SSD1306设计一个仪表盘

SSD1306基本设置请参照下面的链接

Arduino Nano 驱动OLED测试入门(一)(软IIC以及硬IIC链接SSD1306屏)

SSD1306库函数参数讲解参照下面的链接

Arduino Nano 驱动OLED测试入门(二) U8glib 库函数及参数讲解

本文通过一个可调电位器,设计一个电压仪表盘。
屏的连线方式请参照入门(一),电位器三端,一端接地,一端接5V,另一端接Nano的模拟输入端A1 引脚。

在这里插入图片描述
程序中定义了三个变量,p代表AD采集的值,p的范围从0到1023,w和m分别是通过map函数重映射的值,map是一个arduino的库函数,定义为:
map(value, fromLow, fromHigh, toLow, toHigh)

value的取值范围是fromLow to fromHigh,该函数的作用是把value从一个范围变换到另一个范围。
w可以理解为百分率,p为1023的时候,w为100;
m可以理解为仪表盘指的偏转角度,初始位置为180度。

源代码参照国外例子,但源代码中关于指针角度的换算很让人费解,我重新改动了一下,更易于理解。
注释掉的部分为原代码,希望了解原作者思路的同学可以自己选择注释看一下。

p = analog read (potmeterPin); 
w = map (p, 0, 1023, 0, 100);
//m = map (p, 0, 1023, 0, 90);
m = map (p, 0, 1023, 180, 0);

程序中用到一个库函数map();
函数的作用是把

下面直接上代码,主要注意两个地方,一是确保你的Arduino IDE里已经添加了 U8glib的库文件,二是设置显示屏参数:
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);

/*
 Analog gauge v1.03
 - Shows half circle gauge with scale labels
 - Shows digital value, 00 - 100 aligned
 - Shows gauge label
 21/12/2015 - Rudi Imbrechts
 23/06/2020 - MGM
 http://arduinows.blogspot.com

*/
#include "U8glib.h"

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);  

//U8GLIB_SH1106_128X64 u8g(13, 11, 10, 9, 12); // SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, Res = 12
                                                // For OLED display with SH1106 driver. If you use another display, 
                                                // then please check the u8glib documentation and website at
                                                // https://github.com/olikraus/u8glib

int xmax=128;                                   // max length x-axis
int ymax=62;                                    // max length y-axis
int xcenter=xmax/2;                             // center of x-axis
int ycenter=ymax/2+10;                          // center of y-axis
int arc=ymax/2;                              
int angle=0;                                    
char* label[] = {
    
    "LOAD","COOLANT","INTAKE", "VOLT"};    // some custom gauge labels
int labelXpos[] = {
    
    53, 45, 49, 53};                     // predefined x-position of a gauge label
#define potmeterPin A1                                  // simulate analogue value with potentiometer
int p, w, m;
u8g_uint_t xx=0;

// ------------------------------------------------- void gauge() ------------------------------------------
void gauge(uint8_t angle) {
    
    

  // draw border of the gauge
  u8g.drawCircle(xcenter,ycenter,arc+6, U8G_DRAW_UPPER_RIGHT);
  u8g.drawCircle(xcenter,ycenter,arc+4, U8G_DRAW_UPPER_RIGHT);
  u8g.drawCircle(xcenter,ycenter,arc+6, U8G_DRAW_UPPER_LEFT);
  u8g.drawCircle(xcenter,ycenter,arc+4, U8G_DRAW_UPPER_LEFT);

  // draw the needle
  //float x1=sin(2*angle*2*3.14/360);              // needle position
  //float y1=cos(2*angle*2*3.14/360);  			//needle position
  float x1=cos(angle*2*3.14/360);    // changed by MGM            
  float y1=sin(angle*2*3.14/360); 
  u8g.drawLine(xcenter, ycenter, xcenter+arc*x1, ycenter-arc*y1);
  u8g.drawDisc(xcenter, ycenter, 5, U8G_DRAW_UPPER_LEFT);
  u8g.drawDisc(xcenter, ycenter, 5, U8G_DRAW_UPPER_RIGHT);
  u8g.setFont(u8g_font_chikita);
  
  // show scale labels
  u8g.drawStr( 20, 42, "0");                    
  u8g.drawStr( 25, 18, "25");
  u8g.drawStr( 60, 14, "50");
  u8g.drawStr( 95, 18, "75");
  u8g.drawStr( 105, 42, "100");
  
  // show gauge label
  u8g.setPrintPos(labelXpos[1],32);             
  u8g.print(label[1]);
  
  // show digital value and align its position
  u8g.setFont(u8g_font_osb18);              
  u8g.setPrintPos(54,60);
  if (w<10){
    
                                        // leading 0 when value less than 10
    u8g.print("0");
  }
  if (w>99) {
    
                                       // position at 100%
    u8g.setPrintPos(47,60);
  }
  u8g.print(w);
}

// ------------------------------------------------- void setup() ------------------------------------------
void setup(void) {
    
    
  pinMode(potmeterPin, INPUT);
  u8g.setFont(u8g_font_chikita);
  u8g.setColorIndex(1);                         // Instructs the display to draw with a pixel on. 

  // assign default color value
  if ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
    
    
    u8g.setColorIndex(255);                     // white
  }
  else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
    
    
    u8g.setColorIndex(3);                       // max intensity
  }
  else if ( u8g.getMode() == U8G_MODE_BW ) {
    
    
    u8g.setColorIndex(1);                       // pixel on
  }
//  else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
    
    
//    u8g.setHiColorByRGB(255,255,255);
//  }
}

// ------------------------------------------------- void loop() ------------------------------------------

void loop(void) {
    
    

  
  p = analogRead(potmeterPin);                  // get value from potmeter
  w = map(p,0,1023,0,100);                      // map it between 0 and 100
 // m = map(p,0,1023,0,90);                       // map needle movement
 m = map(p,0,1023,180,0);  
  // show needle and dial
  xx = m;                                      // 135 = zero position, 180 = just before middle, 0 = middle, 45 = max
  if (xx<45){
    
                                       // positie correctie
    xx=xx+135;
  }
  else {
    
    
    xx=xx-45;
  }
  
  // picture loop
  {
    
    
    u8g.firstPage();  
    do {
    
                  
    //  gauge(xx); 
       gauge(m);  // changed by MGM
    } 
    while( u8g.nextPage() ); 
  }
}

猜你喜欢

转载自blog.csdn.net/malcolm_110/article/details/106919205