IOT > Internet of Thing ESP32 | ESP8266 : การเขียนโปรแกรมใช้งานขาพอร์ตในโหมด Digital Output

การเขียนโปรแกรมใช้งานขาพอร์ตในโหมด Digital Output

การชื่อเรียกขาพอร์ตของ NodeMCU และ Wemos D1 mini  ใช้อักษร D นำหน้า ส่วนชิพ ESP8266 (ซึ่งอยู่บนบอร์ด NodeMCU,WeMos) ใช้อักษรนำหน้าว่า GPIO เมื่อนำมาใช้งานสามารถใช้ได้ทั้งสองแบบโดยหากใช้เรียกขาที่เป็น GPIO จะใส่เพียงตัวเลข แต่ถ้าใช้ดังตัวที่สกีนบนบอร์ดจะใช้ D นำหน้า เมื่อเทียบกันแล้วจะได้ดังรูป


โดย NodeMCU ,WeMos D1 mini จะเรียกชื่อเป็น D0,D1,... ส่วน ESP8266 จะเรียกว่า GPIO ดังนั้นเวลาเขียนโปรแกรมจะต้องเรียกชื่อให้ตรงกับชื่อขาที่ต้องการใช้งาน โดยหากใส่ตัวเลขอย่างเดียวจะเป็นการเรียกใช้ขา GPIO แต่ถ้าหากใส่ D นำหน้าจะเป็นการเรียกใช้งานแบบ NodeMCU (ตัวโปรแกรมจะจัดการเอง)

หมายเหตุ 
NodeMCU V2 จะมี LED อยู่ 2 ตัวคือบนชิพ ESP8266 (D4) และบนบอร์ด (D0)
NodeMCU V3 จะมี LED อยู่ 1 ตัวคือบนชิพ ESP8266 (D4) ซึ่งไม่มีบนบอร์ดเหมือน V2
WeMosD1 mini จะมี LED อยู่ 1 ตัวคือบนชิพ ESP8266 (D4) ซึ่งไม่มีบนบอร์ดเหมือน V2 เช่นเดียวกับ V3

การใช้งานทั่วไปสามารถเลือกเป็นบอร์ดตัวใดก็ได้ โดยมีสิ่งที่แตกต่างคือ
-เลือกบอร์ดเป็น NodeMCU 1.0 ความเร็วอัพโหลดจะเป็น 115200 และ LED_BUILTIN จะเป็น D0
-เลือกบอร์ดเป็น WeMos D1 R2&mini ความเร็วอัพโหลดจะเป็น 921600 และ LED_BUILTIN จะเป็น D4

ดังนั้น หากเลือกอร์ดเป็น NodeMCU 1.0 แต่บอร์ดจริงใช้ NodeMCU V3 หรือ WeMos D1 เมื่อมีการใช้งาน LED_BUILTIN จะไม่มีผลอะไรแสดงยกเว้นมาการต่อ LED เพิ่มภายนอกเข้าที่ขา D0


ค่าที่ถูกกำหนดเมื่อเลือกบอร์ดเป็น NodeMCU 1.0
ข้อมูลจากไฟล์กำหนดขา pins_arduino.h
อยู่ในโฟลเดอร์ C:\Users\...(comName)...\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.1\variants\nodemcu

โค๊ด: [Select]
static const uint8_t SDA = 4;
static const uint8_t SCL = 5;

static const uint8_t LED_BUILTIN = 16;
static const uint8_t BUILTIN_LED = 16;

static const uint8_t D0   = 16;
static const uint8_t D1   = 5;
static const uint8_t D2   = 4;
static const uint8_t D3   = 0;
static const uint8_t D4   = 2;
static const uint8_t D5   = 14;
static const uint8_t D6   = 12;
static const uint8_t D7   = 13;
static const uint8_t D8   = 15;
static const uint8_t D9   = 3;
static const uint8_t D10  = 1;
ข้อมูลจากเวป https://nodemcu.readthedocs.io/en/master/en/modules/gpio/
โค๊ด: [Select]
IO index ESP8266 pin
0 [*]  GPIO16 
1  GPIO5 
2  GPIO4 
3  GPIO0 
4  GPIO2 
5  GPIO14 
6  GPIO12  
7  GPIO13
8  GPIO15
9  GPIO3
10  GPIO1
11  GPIO9
12  GPIO10
[*] D0(GPIO16) can only be used as gpio read/write. No support for open drain/interrupt/pwm/i2c/ow.
จะเห็นว่า D11, D12 ไม่ได้มีการกำหนดค่าไว้ในไฟล์กำหนดขา ดังนั้นเมื่อใช้งานให้เรียกเลขขาแทน (D11->9, D12->10) และ D11 บางบอร์ดอาจใช้งานไม่ได้ทั้งนี้ขึ้นอยู่เกิดจาก OS ของแต่ละบอร์ด

ค่าที่ถูกกำหนดเมื่อเลือกบอร์ดเป็น WeMos D1 R2&mini
ข้อมูลจากไฟล์กำหนดขา pins_arduino.h
อยู่ในโฟลเดอร์ C:\Users\...(comName)...\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.1\variants\d1_mini

โค๊ด: [Select]
#define PIN_WIRE_SDA (4)
#define PIN_WIRE_SCL (5)

static const uint8_t SDA = PIN_WIRE_SDA;
static const uint8_t SCL = PIN_WIRE_SCL;

#define LED_BUILTIN 2

static const uint8_t D0   = 16;
static const uint8_t D1   = 5;
static const uint8_t D2   = 4;
static const uint8_t D3   = 0;
static const uint8_t D4   = 2;
static const uint8_t D5   = 14;
static const uint8_t D6   = 12;
static const uint8_t D7   = 13;
static const uint8_t D8   = 15;
static const uint8_t RX   = 3;
static const uint8_t TX   = 1;
ข้อมูลจากเวป https://wiki.wemos.cc/products:d1:d1_mini
โค๊ด: [Select]
WeMos Pin ESP-8266 Pin Function
TX  TXD  TXD
RX  RXD  RXD
A0  A0  Analog input, max 3.3V input
D0  GPIO16  IO
D1  GPIO5  IO, SCL
D2  GPIO4  IO, SDA
D3  GPIO0  IO, 10k Pull-up
D4  GPIO2  IO, 10k Pull-up, BUILTIN_LED
D5  GPIO14  IO, SCK
D6  GPIO12  IO, MISO
D7  GPIO13  IO, MOSI
D8  GPIO15  IO, 10k Pull-down, SS
G  GND  Ground
5V  -  5V
3V3  3.3V  3.3V
RST  RST  Reset
All of the IO pins have interrupt/pwm/I2C/one-wire support except D0.

ฟังก์ชั่นที่ใช้งาน
-pinMode() http://arduino.cc/en/Reference/PinMode
-digitalWrite() http://arduino.cc/en/Reference/DigitalWrite
-delay() http://arduino.cc/en/reference/delay
*ฟังก์ชั่นที่ใช้งานมีลักษณะเดียวกันกับ arduino
http://www.esp8266.com/wiki/doku.php?id=esp8266_gpio_pin_allocations 


โจทย์การทดลอง
-เชื่อมต่อ LED 4 digit เข้ากับพอร์ตดิจิตอลตามวงจร
-เขียนโปรแกรมไฟวิ่งที่มีรูปแบบและเป็นระเบียบ (ไม่ใช่การติดดับแบบสุ่ม)
-โปรแกรมรายละเอียดพิเศษรายกลุ่ม (แจ้งให้ทราบเมื่อถึงชั่วโมงเรียน)


วงจรที่ใช้ทดลอง
กรณีใช้บอร์ดรุ่น NodeMCU

กรณีใช้บอร์ดรุ่น WeMos D1 mini

ข้อแนะนำในการเลือกใช้บอร์ดทดลองเมื่อใช้กับโปรโต้บอร์ด
บอร์ดทดลองที่มีขายในท้องตลาดจะมี 3 รุ่นหลัก ๆ คือ
1. NodeMCU V3 บอร์ดใหญ่(ชิพ USB รูปสี่เหลี่ยมผืนผ้ายาว)
2. NodeMCU V2 บอร์ดเล็ก(ชิพ USB รูปสี่จตุรัส)
3. WeMos D1 mini
เมื่อใช้งานโปรโต้บอร์ดไม่แนะนำให้ใช้  NodeMCU V3 เนื่องจากเมื่อเสียบลงบอร์ดจะไม่เหลือรูใช้งานดังรูป
รูปเรียงจาก NodeMCU V3---NodeMCU V2--- WeMos D1


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

โค๊ด: [Select]
#define LED1 D1
#define LED2 D2
#define LED3 D3
#define LED4 D4
void setup() 
{
  pinMode(LED1,OUTPUT);
  pinMode(LED2,OUTPUT);
  pinMode(LED3,OUTPUT);
  pinMode(LED4,OUTPUT);
}
void loop() 
{
  digitalWrite(LED1,HIGH);digitalWrite(LED2,LOW);digitalWrite(LED3,LOW);digitalWrite(LED4,LOW);delay(200);
 digitalWrite(LED1,LOW);digitalWrite(LED2,HIGH);digitalWrite(LED3,LOW);digitalWrite(LED4,LOW);delay(200);
 digitalWrite(LED1,LOW);digitalWrite(LED2,LOW);digitalWrite(LED3,HIGH);digitalWrite(LED4,LOW);delay(200);
 digitalWrite(LED1,LOW);digitalWrite(LED2,LOW);digitalWrite(LED3,LOW);digitalWrite(LED4,HIGH);delay(200);
}

ตัวอย่างโปรแกรมที่ 2 (ฟังก์ชั่นย่อยขับ LED)
โค๊ด: [Select]
#define LED1 D1
#define LED2 D2
#define LED3 D3
#define LED4 D4
void send2port(char data);
char pattern[]={0b0000,
                0b0001,
                0b0011,
                0b0111,
                0b1111,
                0b1110,
                0b1100,
                0b1000};
void setup() 
{
  pinMode(LED1,OUTPUT);
  pinMode(LED2,OUTPUT);
  pinMode(LED3,OUTPUT);
  pinMode(LED4,OUTPUT);
}
void loop() 
{
  char i=0;
  for(i=0;i<=7;i++)
  {
      send2port(pattern[i]);
      delay(250);
  }
}
void send2port(char data)
{
    if (data & 1 ){digitalWrite(LED1,HIGH);} else {digitalWrite(LED1,LOW);}
    if (data & 2 ){digitalWrite(LED2,HIGH);} else {digitalWrite(LED2,LOW);}
    if (data & 4 ){digitalWrite(LED3,HIGH);} else {digitalWrite(LED3,LOW);}
    if (data & 8 ){digitalWrite(LED4,HIGH);} else {digitalWrite(LED4,LOW);}  
}
ตัวอย่างโปรแกรมที่ 3 (ฟังก์ชั่นย่อยขับ LED ใช้ if แบบย่อ)
โค๊ด: [Select]
#define LED1 D1
#define LED2 D2
#define LED3 D3
#define LED4 D4
void send2port(char data);
char pattern[]={0b0000,
                0b0001,
                0b0011,
                0b0111,
                0b1111,
                0b1110,
                0b1100,
                0b1000};
void setup() 
{
  Serial.begin(115200);
  pinMode(LED1,OUTPUT);
  pinMode(LED2,OUTPUT);
  pinMode(LED3,OUTPUT);
  pinMode(LED4,OUTPUT);
}
void loop() 
{
  char i=0;
  for(i=0;i<=7;i++)
  {
      send2port(pattern[i]);
      Serial.println(pattern[i],DEC);
      delay(250);
  }
}
void send2port(char data)
{
  digitalWrite(LED1,(data & 1 )? HIGH:LOW);
  digitalWrite(LED2,(data & 2 )? HIGH:LOW);
  digitalWrite(LED3,(data & 4 )? HIGH:LOW);
  digitalWrite(LED4,(data & 8 )? HIGH:LOW);
}

ความคิดเห็น