[TH] Arduino: STM32F103CBT6 ADC&LDR.

จากที่ได้อ่านบทความการใช้ ADC ของบอร์ด STM32L432 และบทความเกี่ยวกับ STM32F103x ในการเชื่อมต่อกับ ST7735S เลยถึงคราวนำ STM32F103CBT6 หรือบอร์ด Blue-Pill/Black-Pill มาเขียนโปรแกรมใช้งาน ADC เพื่อแสดงผลบนจอ TFT กันบ้าง โดยตัวอย่างผลลัพธ์ของบทความนี้เป็นดังภาพที่ 1 อันเป็นการอ่านค่าจากขา PA0 ที่ได้เชื่อมต่อกับขาสัญญาณแอนาล็อกจากบอร์ด LDR ในภาพที่ 2 เพื่อแสดงผลบนจอแสดงผลแบบ TFT

ภาพที่ 1 ตัวอย่างการทำงานของโปรแกรมในบททความ

อุปกรณ์ทดลอง

  1. บอร์ด STM32F103CBT6 เช่น Blue-Pill, Black-Pill หรือ ET-STM32F103 
  2. โมดูล LDR ดังภาพที่ 2
  3. โมดูลจอ TFT ที่ใช้ตัวควบคุมเป็นชิพ ST7735s โดยในบทความนี้เป็นแบบ REDTAB ส่วนการใช้ BLUETAB สามารถอ่านได้จากบทความ
  4. ตัวแปลง USB/RS232 เพื่อใช้เป็นส่วนของโปรแกรมชิพ หรือใช้ ST-Link แทนได้
  5. ซอฟต์แวร์
    1. Arduino IDE
    2. stm23duino
    3. ไลบรารี TFT_eSPI
ภาพที่ 2 โมดูล LDR

การเชื่อมต่อ

การต่อ STM32F103CBT6 กับ TFT-LCD ST7735s เป็นดังที่ได้กล่าวในบทความ ST7735s ส่วนการเชื่อมต่อกับโมดูล LDR เป็นดังนี้

  • ขา – ของ LDR ต่อเข้ากับ GND ของ STM32F103CBT6
  • ขา + ของ LDR ต่อเข้ากับขา 3V3 ของ STM32F103CBT6
  • ขา S ของ LDR ต่อเข้ากับขา PA0 ของ STM32F103CBT6

ตัวอย่างโปรแกรม

ตัวอย่างโปรแกรมประกอบไปด้วยตัวอย่างการอ่านค่าจาก LDR ผ่านทางพอร์ต PA0 แล้วแสดงผลเป็นข้อความ กับการวาดเป็นกราฟเส้นตรง มีโค้ดการทำงานดังนี้

แสดงค่าเป็นข้อความ

ตัวอย่างนี้เป็นการแสดงผลค่าที่อ่านจาก LDR ด้วยการแสดงข้อความซึ่งจะแสดงเป็นตัวอักษรขนาดเล็กเป็นเวลา 3 วินาที หลังจากนั้นแสดงเป็นตัวอักษรขนาดใหญ่กว่าเป็นเวลา 3 วินาทีดังภาพที่ 3 และ 4 หลังจากนั้นวนรอบการทำงานไปเรื่อย ๆ

// micGraph.ino
// JarutEx
#include <TFT_eSPI.h> // Graphics and font library for ST7735 driver chip
#include <SPI.h>
TFT_eSPI tft = TFT_eSPI();  // Invoke library, pins defined in User_Setup.h

#define textColor TFT_WHITE
#define textBgColor 0x3861
#define pinMic PA0
#define ADC_BITS 12

String msg;
uint16_t dValue;

void setup() {
  analogReadResolution(ADC_BITS);
  tft.init();
  tft.setRotation(1);
  tft.writecommand(ST7735_MADCTL);
  tft.writedata(TFT_MAD_MV | TFT_MAD_COLOR_ORDER );
  tft.fillScreen(textBgColor);
}

void loop() {
  dValue = analogRead( pinMic );
  msg = "ADC value=";
  msg += dValue;
  
  tft.fillScreen( textBgColor );
  tft.setTextColor( textColor );
  tft.drawString( msg, 8 , 40,  1  ); // Font No.1
  delay(3000);
  tft.fillScreen( textBgColor );
  tft.setTextColor( textColor );
  tft.drawString( msg, 8 , 40,  2  ); // Font No.2
  delay(3000);
}
ภาพที่ 3 ตัวอย่างการแสดงผลด้วยตัวอักษรขนาด 1
ภาพที่ 4 ตัวอย่างการแสดงผลด้วยตัวอักษรขนาด 2

แสดงเป็นกราฟเส้น

ตัวอย่างนี้เป็นการเปลี่ยนการแสดงผลจากตัวอักษรเป็นกราฟเส้นตรง โดยข้อมูลแสดงอยู่บริเวณตำแหน่ง (76,0)-(84,79) โดยทำการแปลงค่า dValue ที่อ่านจาก PA0 ให้เป็นค่าในช่วง 0 ถึง 79 เพื่อนำมาใช้เป็นค่าในแกน Y โดยเก็บในตัวแปรชื่อ yValue ดังตัวอย่างในภาพที่ 1 โค้ดโปรแกรมเป็นดังนี้

// micGraph.ino
// JarutEx
#include <TFT_eSPI.h> // Graphics and font library for ST7735 driver chip
#include <SPI.h>
TFT_eSPI tft = TFT_eSPI();  // Invoke library, pins defined in User_Setup.h

#define textColor TFT_WHITE
#define textBgColor 0x3861
#define pinMic PA0
#define ADC_BITS 12

uint16_t dValue;
uint16_t yValue = 0;

void setup() {
  Serial.begin(115200);
  analogReadResolution(ADC_BITS);
  tft.init();
  tft.setRotation(1);
  tft.writecommand(ST7735_MADCTL);
  tft.writedata(TFT_MAD_MV | TFT_MAD_COLOR_ORDER );
  drawScr();
  Serial.println("Started");
}

void drawScr() {
  tft.fillScreen(textBgColor);
  tft.drawLine(0, 40, 75, 40, textColor);
  tft.drawLine(85, 40, 159, 40, textColor);
}

void loop() {
  // อ่านค่า
  dValue = analogRead( pinMic );

  // ลบเส้นเดิม
  tft.drawLine(75, 40, 80, yValue, textBgColor);
  tft.drawLine(80, yValue, 85, 40, textBgColor);

  // แปลง 0..4095 เป็น 0..79
  yValue = (uint16_t)(((float)dValue / 4095.0) * 79.0);

  // วาดเส้นใหม่
  tft.drawLine(75, 40, 80, yValue, textColor);
  tft.drawLine(80, yValue, 85, 40, textColor);

}

สรุป

จากบทความนี้จะพบว่า ADC ที่มีความละเอียด 12 บิตของ STM32F103 นั้นไวมากพอต่อการนำเข้าข้อมูลเพื่อแสดงผลบนจอ TFT ซึ่งผู้อ่านจะพบว่ากราฟนั้นอัพเดตจนมองแทบไม่ทัน (เนื่องจากไม่ได้สนใจเรื่องอัตราการแสดงผล) และจะพบว่าผู้เขียนได้สั่งวาดกราฟอับตำแหน่งเดิมแทนการลบหน้าจอทั้งหน้าจอเพื่อประหยัดเวลาในการทำงานของไมโครคอนโทรลเลอร์และการสั่งงาน TFT นอกจากนี้ ผู้เขียนสามารถนำโค้ดไปปรับปรุงโดยการนำเข้าข้อมูลเก็บไว้ในแถวลำดับก่อนนำมาแสดงผลเพื่อให้ดูเป็นกราฟแบบต่อเนืองที่สวยงามขึ้น หรือเพิ่มเติมเรื่องการปรับอัตราการนำเข้าให้เพมาะสม เป็นต้น สุดท้าย ขอให้สนุกกับการเขียนโปรแกรมครับ

(C) 2020-2022, โดย อ.ดนัย เจษฎาฐิติกุล/อ.จารุต บุศราทิจ
ปรับปรุงเมื่อ 2021-12-24, 2022-02-01