วันเสาร์ที่ 9 พฤศจิกายน พ.ศ. 2562

ESP32:Coding:Basic

โค้ดสำหรับผู้เริ่มหัดใช้งาน

  สำหรับผู้เริ่มต้นใช้ ESP32 ต้องสามารถอัปโหลดโปรแกรมขึ้นบอร์ดให้ได้ก่อน แล้วลองใช้โค้ดตัวอย่างที่มีใน Arduino IDE สำรวจ บอร์ดของเราก่อนว่ามี ปุ่มหรือไฟ LED ให้ใช้งานหรือไม่  ดูจากคู่มือบอร์ดที่เราใช้ ตัวอย่างในหน้านี้อาจจะมีการดัดแปลงเล็กน้อยเพื่อให้สะดวกต่อการใช้งาน  แนะนำให้เลือกโค้ดที่ ใช้ ปุ่มBOOT, LED ,Wifi ,Blue, tooth , sensor ที่มากับบอร์ด จะได้ไม่ต้องต่ออุปกรณ์เพิ่ม พอคุ้นเคยแล้วถึงเริ่มต่ออุปกรณ์แล้วเขียนโค้ดเพื่อใช้งาน
ตัวอย่างที่อยู่ใน Arduino IDE


จากภาพ Build in Example จะเป็นตัวอย่างที่ใช้กับ Arduino  บางตัวอย่างใช้กับ ESP32 ได้ บางตัวอย่างก็ใช้ไม่ได้ เช่นที่ใช้ฟังก์ชั่น analogWrite() ซึ่ง ESP32 ไม่รองรรับ ส่วนตัวอย่างที่ใช้ได้กับ ESP32 จะอยู่จะอยู่ด้านล่างๆ ที่เขียนว่า Example for [ชื่อบอร์ด ESP32]
สำหรับวิธีการใช้ฟังชั่นต่างๆและไวยากรภาษา C สามารถดูได้จากเมนู Help/Reference ใน Arduino IDE ได้เลย

Examples/01.Basics/Blink

ตัวอย่างไฟกระพริบทุกๆหนึ่งวินาที ถ้าบอร์ดมี LED ในตัวหรือ แล้วเลือกบอร์ดบน Arduino IDE ได้ถูกรุ่น จะมีการประกาศค่า LED_BUILTIN ไว้เรียบร้อยแล้ว ว่าเป็นขาไหน (บางรุ่นก็ไม่ประกาศก็จะคอมไฟล์ไม่ผ่าน) ผมขอแก้นิดหน่อยเพื่อให้คอมไฟล์กับบอร์ดไหนก็ได้ แต่ต้องแก้ค่า led_pin ให้ตรงกับขาที่เป็น LED

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
int led_pin = 13; //ใส่เลขขา LED หรือใช้ LED_BUILTIN ก็ได้
void setup() {
  pinMode(led_pin, OUTPUT); //กำหนดให้ led_pin เป็น OUTPUT(ส่งค่าออก)
}
void loop() {
  digitalWrite(led_pin, HIGH);   // เปิดไฟ (HIGH มีค่าเป็น 1)
  delay(1000);                   // รอ 1000 มิลลิวินาที(1วินาที)
  digitalWrite(led_pin, LOW);    // ปิดไฟ (LOW มีค่าเป็น 0)
  delay(1000);                   // รอ 1000 มิลลิวินาที(1วินาที)
}

pinMode(pin_number, INPUT);  กำหนด ขา(pin_number)ให้เป็นขาสำหรับรับค่า INPUT (กำหนดได้ 3 ค่า INPUT, OUTPUT, INPUT_PULLUP)
digitalWrite(pin_number, 0_or_1);  คำสั่งนี้จะเขียน 0(LOW) หรือ 1(HIGH) ไปที่ขาที่กำหนดใน pin_number
delay(1000) จะเป็นการหยุดรอ เป็นจำนวนมิลลิวินาที ดังนั้น 1000มิลลิวินาทีก็คือหนึ่งวินาที
ลองเปลี่ยนค่า delay แล้วดูการเปลี่ยนแปลงของการกระพริบ สำหรับผู้ที่ต่อไฟ LED เพิ่มเอง ควรใช้ตัวต้านทานซัก 330 - 1K โอมห์ ร่วมด้วย ระวัง LED ต่อกลับข้างไฟจะไม่ติด
 ต่อหลอด LED กับ ESP32

Examples/02.Digital/Button

กดปุ่มเพื่อปิดหรือเปิดไฟ บอร์ดหลายรุ่นมีปุ่ม Boot ซึ่งต่อกับขา 0 เรานำมาใช้ได้ (ปุ่ม EN หรือ Reset ไม่สามารถอ่านค่าด้วยโค้ดได้)คล้ายตัวอย่างที่แล้วเพิ่มการอ่านปุ่มเข้ามา ใช้ปุ่มเพื่อปิดเปิด LED มีการแก้โค้ดเดิมนิดหน่อยให้กระชับขึ้น


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
const int buttonPin = 0;// เลขขาที่ต่อปุ่ม ปุ่ม BOOT อยู่ที่ขา 0
const int ledPin =  4;  // ใส่เลขขา LED หรือใช้ LED_BUILTIN ก็ได้
int buttonState = 0;    // ตัวแปรเก็บสถานะ LOW/HIGH ของปุ่ม
void setup() {
  pinMode(ledPin, OUTPUT);   //กำหนดให้ ledPin เป็น OUTPUT(ส่งค่าออก)
  pinMode(buttonPin, INPUT); //กำหนดให้ buttonPin เป็น INPUT(รับค่าเข้า)
}
void loop() {
  buttonState = digitalRead(buttonPin);
  digitalWrite(ledPin, buttonState);
}

digitalRead(pin_number); ฟังก์ชั่นนี้จะอ่านค่าสถานะ(0 หรือ 1 )จากขา
โปรแกรมอ่านสถานะของปุ่มด้วย digitalRead ไปเก็บในตัวแปร buttonState แล้วนำค่าใน buttonState ส่งออกไปด้วย digitalWrite สู่หลอด LED
ปุ่ม BOOT จะให้ค่าเป็น LOW ก่อนกดปุ่มแล้วจะให้ HIGH เมื่อกดปุ่ม


คำถาม : ถ้าจะให้ปุ่มทำงานตรงกันข้ามกับที่เป็นอยู่ตอนนี้จะต้องแก้โค้ดอย่างไร

ถ้าบอร์ดไม่มีปุ่ม BOOT หรืออยากต่อปุ่มเอง จำเป็นต้องใช้วงจร Pull Up เพื่อให้ขาอยู่สถานะที่ถูกต้อง ใน ESP32 มีวงจร Pull up อยู่ในตัวสามารถเรียกใช้ได้เลย ให้ต่อสวิตซ์ด้านหนึ่งกับ GND อีกด้านต่อกับขาใดขาหนึ่งที่อ่านค่าดิจิตอลได้ นำโค้ด ก่อนหน้ามาแก้ตรง
pinMode(buttonPin, INPUT); 
ให้เป็น
pinMode(buttonPin, INPUT_PULLUP); 



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
const int buttonPin = 6;// เลขขาที่ต่อปุ่มที่ขา 6
const int ledPin =  22;  // ใส่เลขขา LED ที่ขา 22
int buttonState = 0;    // ตัวแปรเก็บสถานะ LOW/HIGH ของปุ่ม
void setup() {
  pinMode(ledPin, OUTPUT);   //กำหนดให้ ledPin เป็น OUTPUT(ส่งค่าออก)
  pinMode(buttonPin, INPUT_PULLUP); //กำหนดให้ buttonPin เป็น INPUT(รับค่าเข้า)
}
void loop() {
  buttonState = digitalRead(buttonPin);
  digitalWrite(ledPin, buttonState);
}

ปุ่มต่อขา16 หลอด LED ต่อขา 22 ใช้ตัวต้านทาน 1Kโอมห์

Examples/01.Basics/DigitalReadSerial

   เวลาบอร์ดต่อก้บคอมพิวเตอร์จะติดต่อสื่อสารกันผ่านพอร์ตซีเรียล เป็นการสื่อสารแบบอนุกรม ส่งข้อมูลเรียงๆกันไปเป็นจังหวะ(baud rate)ที่รู้กันระหว่างสองฝั่ง จะไม่อธิบายรายละเอียดในที่นี้  ขอให้รู้เพียงว่าเป็นการสื่อสารประเภทหนึ่งก็พอ  ขณะอัปโหลดโปรแกรมจะใช้เพื่อส่งโปรแกรมที่คอมไพล์เสร็จแล้วไปใส่ไว้ในบอร์ด หลังจากนั้นพอร์ตซีเรียลก็จะนำไปใช้งานอื่นได้ ตัวอย่างนี้จะใช้เพื่อส่งข้อความจากบอร์ดไปคอมพิวเตอร์ มีประโยชน์มากคือใช้ดีบักโปรแกรม เพราะบอร์ดส่วนใหญ่จะไม่มีจอแสดงผล ส่งข้อมูลกลับมาที่จอคอมพิวเตอร์จะได้รู้ว่าโปรแกรมทำงานไปถึงไหนแล้ว ตัวแปรมีค่าอะไร ในเมนู Tools/Serial Monitor จะมีโปรแกรมสำหรับรับและส่งค่าไปที่พอร์ตซีเรียล ถ้าข้อมูลที่ส่งมาเป็นตัวเลขเรานำมาแสดงเป็นกราฟได้ด้วย  Tools/Serial Plotter 


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
int pushButton = 0; 
void setup() {
  Serial.begin(9600); //ความเร็วหรือจังหวะการรับส่งข้อมูล
  pinMode(pushButton, INPUT);
}
void loop() {
  int buttonState = digitalRead(pushButton);
  Serial.println(buttonState);//ส่งค่า 0 หรือ 1 ไปที่พอร์ตซีเรียล
  delay(10); 
}
ตัวอย่างโค้ดจะอ่านค่าจากปุ่ม BOOT แล้วส่งค่าไปที่พอร์ตซีเรียล ถ้าเปิด Serial Monitor จะเห็นค่า 0 กับ 1 ทีละบรรทัด
Serial.begin(9600); ฟังก์ชั่นนี้จะกำหนดจังหวะการรับส่ง่ข้อมูล ใน Serial Monitor ก็ต้องเซ็ตเป็นค่าเดียวกันถึงจะรับส่งข้อมูลได้
Serial.println(buttonState); ส่งค่า buttonState ไปออกพอร์ตซีเรียล และปิดท้ายด้วยขึ้นบรรทัดใหม่(ส่งอักขระ Enter) ถ้าใช้ Serial.print() จะไม่มีเครื่องหมายขึ้นบรรทัดใหม่ปิดท้าย

DigitalReadSerial แสดงใน Serial Plotter

Examples/ESP32/Touch/TouchRead

ESP32 มีปุ่มสัมผัส ไม่ต้องต่ออะไรเพิ่มแค่ใช้นิ้วมือแตะก็พอ ใช้การตรวจสอบประจุไฟฟ้าที่ขา จะมีบางขาที่ทำปุ่มสัมผัสได้  ยกตัวอย่าง(ภาพล่าง)ผังการวางขาของบอร์ดรุ่นหนึ่ง เราจะเห็น Touch5 อยู่ขา 12 จะสำหรับบอร์ดนี้ T5 จะแทนค่า 12 (มี T0-T9)




โค้ดของโปรแกรมตัวอย่างจะคล้ายกับ DigitalReadSerial ที่ผ่านมาแต่ค่าที่อ่านได้จะไม่ใช่ 0/1 จะเป็นค่าที่ไม่ค่อยนิ่งเท่าไหร่ขึ้นกับความชื้นและวิธีการสัมผัส ทดสอบโดยใช้นิ้วแตะที่ขา T5 เราสามารถใช้เลข 12 แทนก็ได้


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
void setup()
{
  Serial.begin(115200); //จังหวะการส่งข้อมูล
  delay(1000); // give me time to bring up serial monitor
  Serial.println("ESP32 Touch Test");
}
void loop()
{
  Serial.println(touchRead(T5));// อ่านค่าจากขา T5 แล้วส่งออกพอร์ตซีเรียล
  delay(1000);
}
ในกราฟด้านล่างเมื่อแตะขา 12 ค่าจะตกลงมา
TouchRead แสดงค่าใน Serial Plotter


เพิ่มเติม

Examples/ESP32/Fading/LEDSoftwareFade

การปรับความสว่างของหลอด LED สามารถใช้การต่อตัวต้านทานแบบปรับค่าได้อนุกรมกัน โวลต์ตกคร่อมหลอดไฟก็จะอยู่ระหว่าง 0-3.3โวลต์(อนาล็อก)  แต่ ESP32 ไม่สามารถส่งค่าออกเป็นอนาล็อกได้  เลยส่งเป็นสัญญาณ เปิดปิดถี่ๆสลับกัน ถ้าไฟสว่างก็ให้ช่วงการเปิดนานกว่าปิด ถ้าหรี่ไฟก็ให้มีช่วงที่ปิดนานขึ้น การทำแบบนี้เรียก PWM  ขา GPIOs 34 ถึง 39 ใช้ PWM ไม่ได้ อ่านเพิ่มเติมได้จากลิงค์ด้านล่าง
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
const int ledPin=2; // ใส่เลขขา LED หรือใช้ LED_BUILTIN ก็ได้
const int freq = 5000;     // ความถี่
const int ledChannel = 0;  // ช่องของ PWM ,มี 16 channel
const int resolution = 8; // ความละเอียด 8บิต
void setup(){
  ledcSetup(ledChannel, freq, resolution); //ช่อง,ความถี่,ความละเอียด
  ledcAttachPin(ledPin, ledChannel);// เชื่อม channel เข้ากับขา GPIO
}
void loop(){
  // increase the LED brightness
  for(int dutyCycle = 0; dutyCycle <= 255; dutyCycle++){   
    ledcWrite(ledChannel, dutyCycle);// ส่งเออกป็น PWM ที่ channel ที่กำหนด
    delay(15);
  }
}

เพิ่มเติม

Examples/ESP32/HallSensor

ในตัวชิป ESP32 จะมีเซนเซอร์วัดสนามแม่เหล็ก เราสามารถเรียกดูค่าได้จากฟังก์ชั่น hallRead()  ให้นำแม่เล็กแรงสูงมาจ่อที่ชิป แล้วดูค่าผ่าน Serial Plotter

1
2
3
4
5
6
7
8
//อ่านค่าจาก Hall Sensor ไปแสดงที่ Serial
//ใช้แม่เหล็กแรงสูงเพื่อทดสอบ
void setup() {
  Serial.begin(9600);
}
void loop() { 
  Serial.println(hallRead());
}

Examples/Wifi/WifiScan

   ค้นหา Wifi Access Point ที่อยู่ใกล้เคียงแล้วแสดงชื่อพร้อมความแรงสัญญาณ ตัวอย่างนี้จะใช้ Library เพิ่มเติมโดยตรงบรรทัดแรกจะเห็น
#include "ไฟล์ header ของ Library"
สามารถศึกษาการใช้ไลบารี่เพิ่มเติมได้ที่นี้


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include "WiFi.h" //ใช้ Library เกี่ยวกับ Wifi
void setup()
{
    Serial.begin(115200);
    WiFi.mode(WIFI_STA); //ใช้โหมด Station
    WiFi.disconnect(); //ตัดการเชื่อมต่อกัย Access point (ถ้าต่ออยู่)
    delay(100);
    Serial.println("Setup done");
}
void loop()
{
    Serial.println("scan start");
    int n = WiFi.scanNetworks(); //ค้นหา Access Point ที่อยู่รอบๆ,n จำนวนที่พบ
    Serial.println("scan done");
    if (n == 0) {
        Serial.println("no networks found");
    } else {
        Serial.print(n);
        Serial.println(" networks found");
        for (int i = 0; i < n; ++i) {
            // Print SSID and RSSI for each network found
            Serial.print(i + 1);
            Serial.print(": ");
            Serial.print(WiFi.SSID(i)); //Service Set Identifier(ชื่อ Access Point)
            Serial.print(" (");
            Serial.print(WiFi.RSSI(i)); //Received signal strength(ความแรงสัญญาณ)
            Serial.print(")");
            Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN)?" ":"*");
            delay(10);
        }
    }
    Serial.println("");
    delay(5000); //รอซักครู่ก่อนค้นหารอบต่อไป
}

WifiScan: ชื่อ Accesspoint แสดงใน Serial Monitor

Examples/Wifi/WifiAccessPoint

    ตัวอย่างนี้ยาวหน่อย เป็นการสั่งปิดเปิดไฟผ่านเวป ESP32 จะกระจายสัญญาณ Wifi (Access Point) สามารถใช้มือถือหรือคอมพิวเตอร์เชื่อมต่อได้แต่ออกอินเตอร์เน็ตไม่ได้ เปิดเวปบราวเซอร์แล้วไปที่ IP Address ของ ESP32 ก็จะเห็นหน้าเวป มีลิงค์ให้เลือกปิดเปิดหลอด LED ที่อยู่บนบอร์ด
การสื่อสารด้วยเวป(โปรโตคอล HTTP) จะประกอบไปด้วย request กับ response
Request: คอมพิวเตอร์ร้องขอไปที่เซิร์ฟเวอร์
Response: เวปเซิร์ฟเวอร์ตอบกลับมา
เช่นมือถือ(client)ร้องขอหน้าเวป https://www.google.com
เวปเซิร์ฟเวอร์ของ google ตอบกลับโดยส่งหน้าเวปกลับมาแสดงที่มือถือ ลองดูวีดีโอของโค้ดที่เราจะลองอัปโหลด


โค้ดก็อปไปใช้ได้เลย

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <WiFi.h>
#include <WiFiClient.h>
#include <WiFiAP.h>
//#define LED_BUILTIN 2   //ถ้าบอร์ดมีการกำหนดค่านี้แล้วให้คอมเมนต์บรรทัดนี้ออกหรือกำหนดเลขขาให้ถูกถ้าไม่มี
const char *ssid = "yourAP"; //ชื่อ Access point ที่เราสร้างขึ้น
const char *password = "yourPassword"; //รหัสผ่านของ Access point
WiFiServer server(80);
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(115200);
  Serial.println();
  Serial.println("Configuring access point...");
  WiFi.softAP(ssid, password); // ถ้าไม่ต้องการให้มีการใส่รหัสผ่านให้เอา password ออก
  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(myIP);
  server.begin();
  Serial.println("Server started");
}

void loop() {
  WiFiClient client = server.available();   // รอ client ติดต่อมา
  if (client) {                             // มีอุปกรณ์(client)ต่อเชื่อมเข้ามา
    Serial.println("New Client.");          
    String currentLine = "";                // สร้าง String เพื่อเก็บข้อมูลจาก client
    while (client.connected()) {            // ลูปวนรอขณะที่มีการเชื่อมต่อจาก client
      if (client.available()) {             // ถ้ามีข้อมูลที่ยังสามารถอ่านได้จาก client
        char c = client.read();             // อ่านมาหนึ่งไบต์เก้บไว้ในตัวแปร c (อ่านทีละตัวอักษร)
        Serial.write(c);                    
        if (c == '\n') {                    // ถ้าขึ้นบรรทัดใหม่(อักขระ new line)
          // ถ้าพบการขึ้นบรรรทัดใหม่ ที่ต้นบรรทัด(currentLine เป็น 0 )
          // อีกความหมายหนึ่งก็คือเจอขึ้นบรรทัดใหม่สองรอบ จะเป็นการจบ  HTTP request ดังนั้นส่ง response ได้
          if (currentLine.length() == 0) {
            // ต้องส่งสามบรรทัดก่อนส่งข้อมูล 1.ส่วนหัว, 2.ชนิดข้อมูล, 3.ตบท้ายด้วยบรรทัดว่างๆ
            client.println("HTTP/1.1 200 OK"); // ส่วนหัวของ HTTP จะต้องส่งโค้ดบอกสถานะ
            client.println("Content-type:text/html"); //เพื่อให้ client รู้ว่าข้อมูลที่ส่งกลับเป็น HTML
            client.println();//บรรทัดว่าง
            // ส่งข้อมูลเป็นหน้าเวปกลับไป
            client.print("Click <a href=\"/H\">here</a> to turn ON the LED.<br>");
            client.print("Click <a href=\"/L\">here</a> to turn OFF the LED.<br>");
            client.println();// ปิดจบด้วยบรรทัดว่าง
            break; //ออกจากลูป while
          } else {    
            currentLine = ""; //จบหนึ่งบรรทัดทำให้ว่างเตรียมบรรทัดใหม่
          }
        } else if (c != '\r') { // ถ้าคุณได้อักขระใดๆที่ไม่ใช่ carriage return
          currentLine += c;     // เอาตัวอักษรนั้นไปต่อในบรรทัด( carriage return จะทิ้งไป)
        }

        // ถ้าได้ "GET /H" หรือ "GET /L" ในท้ายบรรทัด// ถ้าได้ "GET /H" หรือ "GET /L" ในท้ายบรรทัด
        if (currentLine.endsWith("GET /H")) {
          digitalWrite(LED_BUILTIN, HIGH);   // เปิดไฟ
        }
        if (currentLine.endsWith("GET /L")) {
          digitalWrite(LED_BUILTIN, LOW);    // ปิดไฟ
        }
      }
    }//จบ while
    client.stop(); //จบการเชื่อมต่อกับ client
    Serial.println("Client Disconnected.");
  }
}

โค้ดนี้จำเป็นต้องมีความรู้เรื่องเวปและ HTML มาบ้าง ส่วนโค้ดที่เป็นแสดงหน้าเวปจะเป็นสองบรรทัดล่างนี้
Click here to turn ON the LED
Click here to turn OFF the LED

แต่เวลาเขียนเป็นโค้ดภาษา C ถ้าตัวหนังสือจะแสดงเครื่องหมายคำพูดต้องใช้เครื่องหมาย \ ไว้หน้าเสมอเพื่อจะได้ไม่กลายเป็นหมายคำพูดของต้นและท้ายประโยค
เวลาเปิดไฟคลิ้กที่ลิงค์ก็จะไปที่ http://192.168.4.1/H ถ้าปิดไฟจะเป็นลิงค์ http://192.168.4.1/L




ไม่มีความคิดเห็น:

แสดงความคิดเห็น

Module:Control:IFR 520

MOSFET Module  สวิตซ์ปิดเปิดไฟเหมือน Relay แต่เป็น Solid state (ไม่มีส่วนที่เคลื่อนไหว) มันทำงานที่ความถี่สูงได้เหมาะกับเอาไปใช้งาน PWM ...