2020年6月22日 星期一

OLED顯示器各式繪圖功能顯示實習

四.10-3  OLED顯示器各式繪圖功能顯示實習

在第一個Adafruit原廠的範例程式中每一個示範的動作看起來都滿複雜的但是我們常常只會用到一些簡單的繪圖功能而已因此在這個小節中會就一些比較常用且基本的繪圖功能來作示範


功能與動作說明

本範例會將前面Adafruit的”ssd1306_128X64_i2c”這個範例程式中跟繪圖(不是貼圖)有關的部分拿出來做比較詳細的說明這些動作包括


  1. 繪出多重的水平與垂直點(pixel)

  2. 繪出多條的水平與垂直的直線(line)

  3. 繪出單一的矩形(rectangle)外框

  4. 繪出單一的的填滿矩形(filled  rectangle)

  5. 繪出單一的圓形(circle)外框

  6. 繪出單一的填滿圓形(filled  circles )

  7. 繪出單一的圓角矩形(rounded  rectangle)外框

  8. 繪出單一的填滿圓角矩形(filled  rounded  rectangle)

  9. 繪出單一的三角形(triangles)外框

  10. 繪出單一的填滿三角形(filled  triangles)


電路圖

本次實習所使用之電路與前面幾個相同學者可依自己的方便自行選用


程式列表與說明



 

#include <Wire.h>

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>

 

#define SCREEN_WIDTH 128 // OLED display width, in pixels

#define SCREEN_HEIGHT 64 // OLED display height, in pixels

 

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

 

void setup()   

{                

  Serial.begin(115200);

  Serial.println();

  // initialize with the I2C addr 0x3C

if(display.begin(SSD1306_SWITCHCAPVCC, 0x3C))  // Address 0x3D for 128x64

  Serial.println("SSD1036 OLED allocation Successed!");

else  {

    Serial.println("SSD1306 allocation failed");

    for(;;);

  }

  delay(2000);

 

  while(1) 

  { // while()無窮迴圈開始:

    // 繪製點

    display.clearDisplay();

    display.setTextSize(1);

    display.setTextColor(WHITE);

    display.setCursor(0,0);

    display.println("Draw Pixels:");

    for(int i=10;i<SCREEN_HEIGHT;i+=10)

      for(int j=0;j<SCREEN_WIDTH;j+=10)

        display.drawPixel(j, i, WHITE);

    display.display();

    delay(3000);

 

    // 繪製線條:水平線及垂直線

    display.clearDisplay();

    display.setTextSize(1);

    display.setTextColor(WHITE);

    display.setCursor(0,0);

    display.println("Draw Lines:");

    for(int i=10;i<SCREEN_HEIGHT;i+=10)   // 繪製水平線

      display.drawLine(0, i, SCREEN_WIDTH-1,i, WHITE);

    for(int i=0;i<SCREEN_WIDTH;i+=10)     // 繪製垂直線

      display.drawLine(i, 10, i, SCREEN_HEIGHT-1, WHITE);

    display.display();

    delay(3000);

 

    // 繪製矩形

    display.clearDisplay();

    display.setTextSize(1);

    display.setTextColor(WHITE);

    display.setCursor(0,0);

    display.println("Rectangle");

    display.drawRect(0, 15, 60, 40, WHITE);

    display.display();

    delay(3000);

  

    // 繪製與填滿矩形

    display.clearDisplay();

    display.setTextSize(1);

    display.setTextColor(WHITE);

    display.setCursor(0,0);

    display.println("Filled Rectangle");

    display.fillRect(0, 15, 60, 40, WHITE);

    display.display();

    delay(3000);

  

    // 繪製圓角矩形

    display.clearDisplay();

    display.setTextSize(1);

    display.setTextColor(WHITE);

    display.setCursor(0,0);

    display.println("Round Rectangle");

    display.drawRoundRect(0, 15, 60, 40, 8, WHITE);

    display.display();

    delay(3000);

 

    // 繪製填滿圓角矩形

    display.clearDisplay();

    display.setTextSize(1);

    display.setTextColor(WHITE);

    display.setCursor(0,0);

    display.println("Filled Round Rectangl");

    display.fillRoundRect(0, 15, 60, 40, 8, WHITE);

    display.display();

    delay(3000);

    display.clearDisplay();

 

    // 繪製圓形

    display.setTextSize(1);

    display.setTextColor(WHITE);

    display.setCursor(0,0);

    display.println("Circle");

    display.drawCircle(20, 35, 20, WHITE);

    display.display();

    delay(3000);

 

    // 繪製填滿圓形

    display.clearDisplay();

    display.setTextSize(1);

    display.setTextColor(WHITE);

    display.setCursor(0,0);

    display.println("Filled Circle");

    display.fillCircle(20, 35, 20, WHITE);

    display.display();

    delay(3000);

 

    // 繪製三角形

    display.clearDisplay();

    display.setTextSize(1);

    display.setTextColor(WHITE);

    display.setCursor(0,0);

    display.println("Triangle");

    display.drawTriangle(30, 15, 0, 60, 60, 60, WHITE);

    display.display();

    delay(3000);

  

    // 繪製填滿三角形

    display.clearDisplay();

    display.setTextSize(1);

    display.setTextColor(WHITE);

    display.setCursor(0,0);

    display.println("Filled Triangle");

    display.fillTriangle(30, 15, 0, 60, 60, 60, WHITE);

    display.display();

    delay(3000);

  } // while()迴圈結束

  

}

 

void loop() {} // 主程式為空迴圈

 



程式名稱ESP_OLED2_Draw.ino

本範例程式的前面1~21行和前面的範例相同都是在作變數定義與初始化的動作真正繪圖的部分是23~129行這個由while(1){ …}語法所構成的無窮迴圈在這個迴圈中會重複做著本小節功能表列的10個繪圖動作接著我們就對這功能表列的程式碼一一加以說明:

繪出多重的水平與垂直點(pixel)

在Adafruit的函式庫中繪製單一點的指令為


        display.drawPixel(x, y, COLOR);


括弧中的前兩個參數就是這個點在螢幕上的顯示座標其中x是螢幕的寬度範圍為0~127而y則是螢幕的高度範圍為0~63第三個參數則是這個點的顏色只有兩種可選擇即”WHITE”和”BLACK”

下面這段程式是本範例程式中的25~35行會先在螢幕上方顯示” Draw Pixels:”這樣的提示訊息然後使用了兩層的for()迴圈在其他的位置顯13 X 6個像素的點陣列顯示時間為3秒鐘


    // 繪製點

    display.clearDisplay();

    display.setTextSize(1);

    display.setTextColor(WHITE);

    display.setCursor(0,0);

    display.println("Draw Pixels:");

    for(int i=10;i<SCREEN_HEIGHT;i+=10)

      for(int j=0;j<SCREEN_WIDTH;j+=10)

        display.drawPixel(j, i, WHITE);

    display.display();

    delay(3000);


繪出多條的水平與垂直的直線(line)

在Adafruit的函式庫中繪製單一線條的指令為


      display.drawLine(x1, y1, x2, y2, COLOR);


其中的x1,y1是線條的起點而x2,y2則為終點應該很容易了解才是下列程式碼是範例程式中示範繪製線條的部分(37~48行)同樣先在螢幕上方顯示” Draw Lines:”的提示訊息然後使用了兩次的for()迴圈第一個for()迴圈會在螢幕上畫出6條的水平線條而第二個for()迴圈則會在螢幕上畫出13條的垂直線條顯示時間一樣是3秒鐘


    // 繪製線條:水平線及垂直線

    display.clearDisplay();

    display.setTextSize(1);

    display.setTextColor(WHITE);

    display.setCursor(0,0);

    display.println("Draw Lines:");

    for(int i=10;i<SCREEN_HEIGHT;i+=10)   // 繪製水平線

      display.drawLine(0, i, SCREEN_WIDTH-1,i, WHITE);

    for(int i=0;i<SCREEN_WIDTH;i+=10)     // 繪製垂直線

      display.drawLine(i, 10, i, SCREEN_HEIGHT-1, WHITE);

    display.display();

    delay(3000);


繪出單一的矩形(rectangle)外框與單一的填滿矩形(filled rectangle)

下面兩個指令分別是用來繪製矩形(只有外框)及填滿型矩形圖案的指令括弧中的參數x1,y1代表矩形的左上角座標widthhigh則為矩形的水平寬度及垂高度值


   display.drawRect(x1, y1, width, height, COLOR);        // 矩形(rectangle)

   display.fillRect(x1, y1, width,height,COLOR); //填滿矩形(filled rectangle)


下面【圖4、26-1】右上方的程式是本範例程式50~58行內容,用來執行繪製矩形之用左上方的畫面是執行後的結果,兩相比對應該很容易了解程式的動作;而右下方的程式則是本範例程式示範填滿型矩形圖案的部分(60~68行)左下方的畫面是執行的結果這兩個動作都會持續顯示3秒鐘


圖426-1 I2C介面OLED顯示器繪製矩形與填滿矩形


繪出單一的圓角矩形(rounded rectangle)外框與單一的填滿圓角矩形(filled rounded rectangle)

在Adafruit的函式庫中除了可以畫出一般直角的矩形之外還可以畫出圓角的矩形出來當然也可以將它填滿其指令如下

 

    display.drawRoundRect(x1, y1, width, height, COLOR); // 圓角矩形

    display.fillRoundRect(x1, y1, width, height, COLOR); // 填滿圓角矩形

同樣的括弧中的參數x1,y1代表矩形的左上角座標widthhigh為矩形的水平寬度及垂高度值

至於下面【圖4、26-2】右上方的程式是本範例程式中用來執行繪製圓角矩形的部分(70~78行),左上方的畫面為其執行的結果;而右下方的程式則是本範例程式執行填滿型圓角矩形圖案的程式(80~88行)左下方的畫面是執行的結果,同樣的這兩個動作會持續顯示3秒鐘


圖426-2 OLED顯示器繪製圓角矩形與填滿圓角矩形


繪出單一的圓形(circle)外框與單一的填滿圓形(filled circles )

而畫圓型及填滿圓型的部分則是由下面兩個指令負責括弧中的參數x,y是該圓形的圓心座標而r則為圓形的半徑值


    display.drawCircle(x, y, r, COLOR); // 圓形(circles)

    display.fillCircle (x, y, r, COLOR); // 填滿圓形(filled circles)


下面【圖4、26-3】右上方的程式是本範例程式畫圓型的部分(90~98行),左上方的畫面是執行後的結果;右下方的程式則是本範例程式中負責填滿型圓形圖案的部分(100~108行)左下方的畫面是繪製的結果這兩個動作一樣持續顯示3秒鐘

圖426-3 OLED顯示器繪製圓形與填滿圓形



繪出單一的三角形(triangles)外框與單一的填滿三角形(filled  triangles)

最後來介紹函式庫中畫三角形及填滿三角形的部分其指令如下


    display.drawTriangle (x1, y1, x2, y2, x3, y3, COLOR); // 三角形

    display. fillTriangle (x1, y1, x2, y2, x3, y3, COLOR); // 填滿三角形


上面指令中括弧中的參數”x1,y1”、”x2,y2”、”x3,y3”分別是三角形的三個角的座標值應該一眼就可以看懂這兩個指令使用的方法才是至於下面【圖4、26-4】右上方的程式是本範例程式中用來繪製三角形的部分(110~118行),左上方的畫面是執行的結果;而右下方的程式則是本範例程式執行填滿型三角形圖案的程式(120~128行)左下方的畫面是執行的結果,這兩個動作同樣會持續顯示3秒鐘




圖426-4 OLED顯示器繪製三角形與填滿三角形


行文至此關於Adafruit的OLED顯示器函式庫各式繪圖功能已經介紹的差不多了下面的影片是這個範例程式實際執行的結果讀者們請自習觀看比對一下。



https://youtu.be/wnNDWBm6Rjo


沒有留言:

張貼留言