24. Wio Terminal EP.11, อนาล็อกมิเตอร์ วัดความสว่างของแสง


Wio Terminal EP.11,  อนาล็อกมิเตอร์ วัดความสว่างของแสง 

วิธีการเขียนโค้ด เพื่อวัดค่าความสว่างของแสง ครั้งนี้ นำเสนอ อนาล็อกมิเตอร์ วัดความสว่างของแสง โดยใช้ Arduino ในการเขียนโค้ดคำสั่ง สร้างเป็นเครื่องวัดความสว่างของแสง แบบอนาล็อก คือ มีเข็มชี้บนหน้าปัด และมีสเกล 0 - 100 โดยแบ่งเป็น 5 ช่วง ช่วงละ 20%

 คำอธิบาย
    การเขียนโค้ดครั้งนี้ มีการแยกเขียนเป็นส่วน ๆ เพื่อให้ง่ายต่อการศึกษาและแก้ไข โดยแบ่งเป็นฟังก์ชั่นต่าง ๆ ดังนี้ 
    1. ฟังก์ชั่น drawArc(int x, int y, int start_angle, int end_angle, int rx, int ry, int w, unsigned int color1)
สำหรับสร้างส่วนโค้งที่ตำแหน่งใด ๆ
    2. ฟังก์ชั่น 
drawBar(int bx, int by) สำหรับสร้างส่วนโค้งที่เป็นแถบสีบนหน้าปัดมิเตอร์ โดยเรียกใช้ ฟังก์ชั่น drawArc 
    3. ฟังก์ชั่น 
drawScale(int d1, int d2) สำหรับสร้างเส้นแบ่งสเกล และ ตัวเลขบนแถบสีของหน้าปัดมิเตอร์
    4. ฟังก์ชั่น 
drawNeedle(int rx, int ry, int v) สำหรับสร้างเข็มของมิเตอร์ เพื่อให้ชี้ไปยังค่าที่ได้มาจากเซ็นเซอร์
    5. การเขียนโค้ดเพื่อหาค่าพิกัดต่าง ๆ จำเป็นต้องใช้ ฟังก์ชั่นตรีโกณมิติ ในการคำนวณหาพิกัด (x,y) ของตำแหน่งต่าง ๆ เช่น ตำแหน่งปลายของเข็มชี้ และที่ต้องไม่ลืมคือ ระบบมุมที่ใช้ ต้องเป็น เรเดียน ดังนั้นเพื่อให้เข้าใจได้ง่าย จึงต้องมีการแปลงค่ามุม จาก องศา ไปเป็น เรเดียน ในการคำนวณ

ขั้นตอนการทำงาน
    1. วาดหน้าปัดของมิเตอร์
    2. สเกลลงบนหน้าปัดมิเตอร์
    3. วนรอบอ่านค่าความสว่างของแสง จำนวน 10 ครั้ง
    4. นำค่าแสงที่ได้ มาหาค่าเฉลี่ย
    5. แปลงค่า ให้เหมาะสมในการแสดงผล *
    6. นำค่าที่ได้จากข้อ 5 ไปคำนวณและแสดงเป็นเข็มเคลื่อนที่ตามปริมาณแสงที่วัดได้ 


เขียนโค้ด ใช้ทดสอบ


/*
   plakemphet.blogspot.com
   27/09/2021
   analog panel meter 5 sections for 0-20-40-60-80-100
*/
#include <TFT_eSPI.h>

TFT_eSPI tft = TFT_eSPI();
#define D2R 0.0174532925
#define panel_color TFT_LIGHTGREY
#define mic analogRead(WIO_MIC)
#define light analogRead(WIO_LIGHT)

int last;
int raw;
String panel;

int drawArc(int x, int y, int start_angle, int end_angle, int rx, int ry, int w, unsigned int color1)
{
  byte inc = 6;
  int seg_count = int((end_angle - start_angle) / inc);
  for (int i = start_angle; i < start_angle + inc * seg_count; i += inc)
  {
    int x0 = cos((i - 90) * D2R) * (rx - w) + x;
    int y0 = sin((i - 90) * D2R) * (ry - w) + y;
    int x1 = cos((i - 90) * D2R) * rx + x;
    int y1 = sin((i - 90) * D2R) * ry + y;
    int x2 = cos((i + inc - 90) * D2R) * (rx - w) + x;
    int y2 = sin((i + inc - 90) * D2R) * (ry - w) + y;
    int x3 = cos((i + inc - 90) * D2R) * rx + x;
    int y3 = sin((i + inc - 90) * D2R) * ry + y;
    tft.fillTriangle(x0, y0, x1, y1, x2, y2, color1);
    tft.fillTriangle(x1, y1, x2, y2, x3, y3, color1);
  }
}

void drawBar(int bx, int by)
{
  drawArc(bx, by, -60, -36, 140 , 100, 8, TFT_WHITE);
  drawArc(bx, by, -36, -12, 140 , 100, 8, TFT_ORANGE);
  drawArc(bx, by, -12, 12, 140 , 100, 8, TFT_YELLOW);
  drawArc(bx, by, 12, 36, 140 , 100, 8, TFT_GREEN);
  drawArc(bx, by, 36, 60, 140 , 100, 8, TFT_RED);
}

void drawScale(int d1, int d2)
{
  for (int i = -60; i < 61; i += 6)
  {
    int x0 = cos((i - 90) * D2R) * (d1 - 30) + d1;
    int y0 = sin((i - 90) * D2R) * (d2 - 30) + d2;
    int x1 = cos((i - 90) * D2R) * (d1 - 15) + d1;
    int y1 = sin((i - 90) * D2R) * (d2 - 15) + d2;
    int nx0 = cos((i - 90) * D2R) * (d1 - 10) + d1;
    int ny0 = sin((i - 90) * D2R) * (d2 - 10) + d2;
    if (i == -60)
    {
      tft.drawLine(x0, y0, x1, y1, TFT_BLACK);
      tft.drawString("0", nx0 - 5, ny0 - 10, 2);
    }
    if (i == -36)
    {
      tft.drawLine(x0, y0, x1, y1, TFT_BLACK);
      tft.drawString("20", nx0 - 5, ny0 - 10, 2);
    }
    if (i == -12)
    {
      tft.drawLine(x0, y0, x1, y1, TFT_BLACK);
      tft.drawString("40", nx0 - 5, ny0 - 10, 2);
    }
    if (i == 12)
    {
      tft.drawLine(x0, y0, x1, y1, TFT_BLACK);
      tft.drawString("60", nx0 - 5, ny0 - 10, 2);
    }
    if (i == 36)
    {
      tft.drawLine(x0, y0, x1, y1, TFT_BLACK);
      tft.drawString("80", nx0 - 5, ny0 - 10, 2);
    }
    if (i == 60)
    {
      tft.drawLine(x0, y0, x1, y1, TFT_BLACK);
      tft.drawString("100", nx0, ny0 - 10, 2);
    }
  }
}

void drawNeedle(int rx, int ry, int v)
{
  if (v != last)
  {
    int x3 = 0.85 * cos((last - 90) * D2R) * rx + 160;
    int y3 = 0.85 * sin((last - 90) * D2R) * ry + 115;
    tft.drawLine(158, 140, x3 - 1, y3, panel_color);
    tft.drawLine(159, 140, x3, y3, panel_color);
    tft.drawLine(160, 140, x3 + 1, y3, panel_color);
    tft.drawLine(0, 140, 319, 140, TFT_BLACK);
    // Erase Old Value
    tft.setTextSize(2);
    tft.setTextColor(panel_color);
    int vv = map(last, -60, 60, 0, 100);
    tft.drawString(" " + String(vv) + "  " , 5, 120);
    tft.setTextSize(1);
    tft.setTextColor(TFT_BLACK);
  }
  int x3 = 0.85 * cos((v - 90) * D2R) * rx + 160;
  int y3 = 0.85 * sin((v - 90) * D2R) * ry + 115;
  tft.drawLine(158, 140, x3 - 1, y3, TFT_BLUE);
  tft.drawLine(159, 140, x3, y3, TFT_BLUE);
  tft.drawLine(160, 140, x3 + 1, y3, TFT_BLUE);
  last = v;
  tft.drawCentreString(panel, 160, 145, 4);
  tft.drawString("plakemphet.blogspot.com", 175, 130);
  // Draw Value
  tft.setTextColor(TFT_BLACK);
  tft.setTextSize(2);
  int dv = map(v, -60, 60, 0, 100);
  tft.drawString(" " + String(dv) + "  " , 5, 120);
  tft.setTextSize(1);
  tft.setTextColor(TFT_BLACK);
}

void setup(void)
{
  tft.init();
  tft.setRotation(3);
  tft.fillScreen(TFT_BLACK);
  tft.fillRect(0, 0, 320, 170, TFT_LIGHTGREY);
  tft.setTextColor(TFT_BLACK);
  drawBar(160, 120);
  drawScale(160, 120);
}

void loop()
{
  // For Light meter //
  panel = "LIGHT";  // Panel Label
  
 for (int k=0;k < 10; k++)
     raw = raw + light;  // for WIO_LIGHT
 raw = raw / 10;
  
  // Map and display needle
  raw = map(raw, 0, 1024, -60, 60);
  drawNeedle(150, 100, raw);
  delay(50);
}

  
ข้อสังเกตุ !! ค่าตัวเลขที่แสดงบนหน้าปัด ไม่ได้มีหน่วย ใด ๆ ทางฟิสิกส์ ผู้เขียนเพียงสร้างให้ดูเป็นแนวทางในการนำไปประยุกต์ใช้เท่านั้น 


 ผลที่ได้จากการทำงาน

   
รูปที่ 1 ผลจากการทำงานของคำสั่ง

## ภาพที่อยู่ในบล็อกนี้ อาจมีบางภาพหายไป เนื่องจากปัญหาของ blogspot.com ซึ่งเป็นการอย่างแพร่หลาย ##


โพสต์ยอดนิยมจากบล็อกนี้

14. Wio Terminal EP.01 , เริ่มตันกับ Wio Terminal ด้วย circuitPython

28. Wio Terminal GPS