ไมโครคอนโทลรเลอร์ขั้นพื้นฐาน �และอินเตอร์เน็ตของสรรพพสิ่ง (IoT)
มหาวิทยาลัยเทคโนโลยีพระจอมเกล้าพระนครเหนือ
ประวัติวิทยาการ
การพัฒนาสู่อุตสาหกรรม 4.0 สามารถแบ่งการพัฒนาเป็น 5 ระดับ ในการปรับเปลี่ยนกระบวนการผลิตทางอุตสาหกรรมให้เป็นกระบวนการอัตโนมัติ สำหรับการบูรณาการระบบควบคุมอุตสาหกรรมซึ่งสามารถนำมาใช้ได้กับการพัฒนาไปสู่ระบบอุตสาหกรรม 4.0 โดยแบ่งระดับการพัฒนาเป็น 5 ระดับ ดังแสดงในรูป
1. ไมโครคอนโทรลเลอร์คืออะไร
ไมโคร คอนโทรลเลอร์ มีกี่ประเภทอะไรบ้าง?
ไมโคร คอนโทรลเลอร์ มีด้วยกันหลายประเภทแบ่งตามสถาปัตยกรรม
2. Arduino คืออะไร
โครงสร้างขาของ Node MCU 8266
http://arduino.esp8266.com/stable/package_esp8266com_index.json
1 ติด 2 ดับ
Delay 1 sec
1 ดับ 2 ติด
Delay 1 sec
1. โครงสร้างของบอร์ด Arduino UnoR3
คำสั่งพื้นฐานของภาษาซี
1.การเริ่มต้นโปรแกรม
โครงสร้างพื้นฐานของการเขียนโปรแกรมภาษา Arduino ค่อนข้างง่ายและทำงานในเวลาอย่างน้อยสองส่วน คือส่วนเริ่มต้นและส่วนที่วนไม่รู้จบ
void setup()
{
//เริ่มต้นการตั้งค่า
}
void loop()
{
//วนลูปไม่รู้จบ
}
2. ชนิดของตัวแปร
การเปรียบเทียบ Comparison Operators
ยกตัวอย่าง if (a==b) ไม่ใช่ if (a=b)
== (equal to)
!= (not equal to)
< (less than)
> (greater than)
<= (less than or equal to)
>= (greater than or equal to)
Boolean Operator
&& (and)
|| (or)
! (not)
If (switch1 && swithc2) {on led};
If (switch1 || swithc2) {on led};
Compound Operators
Compound Operators
ยกตัวอย่าง
x = 2;
x += 4; // x now contains 6
x -= 3; // x now contains 3
x *= 10; // x now contains 30
x /= 2; // x now contains 15
x %= 5; // x now contains 0
3. คำสั่งพื้นฐานของภาษาซี if else
If…else…
if (เงื่อนไข A)
{
// ถ้าเงื่อนไข A เป็นจริงทำงานในลูปนี้
// เช่น 1==1
}
else
{
// action B
}
คำสั่ง for
int data;
int i;
Data = 0;
for(int i=0; i < 4; i++)
{
data++;
}
// สุดท้าย data = 4
คำสั่ง switch
switch (var) {
case 1:� //do something when var equals 1� break;� case 2:� //do something when var equals 2� break;� default: � // if nothing else matches, do the default � // default is optional� break;� }
คำสั่ง while
while(expression)
{
// statement(s)
}
var = 0;�while(var < 200)
{� // do something repetitive 200 times� var++;�}
คำสั่ง break
{� x = 0;� break;� } � x++;�}
การส่งค่าเอาท์พุต(Digital Output)
ลง Library
ESP8266 Scheduler
ตัวอย่าง ทดลองเปิด-ปิดหลอดไฟบนบอร์ดที่ขา 2 หรือ D4 เพื่อเปิด-ปิดหลอดไฟ
|
void setup() { pinMode(2,OUTPUT); // ตั้งค่าขา 2 ให้เป็น Output Serial.begin(9600); // กำหนดการสื่อสารให้เป็น 9600 b/s } void loop() { digitalWrite(2,1); // สั่งให้ขา 2 มีไฟออก 3.3 v delay(1000); // หน่วงเวลา 1 วินาที digitalWrite(2,0); // สั่งให้ขา 2 ส่งกราวด์ delay(1000); // หน่วงเวลา 1 วินาที } |
ควบคุมการเปิด ปิดหลอดไฟ
กด sw(0) – LED 2 (ติด)
ปล่อย sw(1) – LED 2 (ดับ)
ควบคุมการเปิด ปิดหลอดไฟ
void setup()
{
pinMode(13, OUTPUT);
}
void loop()
{
digitalWrite(13, HIGH); // ส่งสัญญาณ 5 โวล์ต ออกมาจากขา 13
delay(1000); // รอ 1 วินาที
digitalWrite(13, LOW); // ส่งสัญญาณ 0 ออกมาจากขา 13
delay(1000); // รอ 1 วินาที
}
แบบฝึกหัด
Sw1 –gpio 0 | Sw2-gpio 14 | Led1 -5 | Led2-2 |
0 (กด) | 0 | 0 (ดับ) | 0 |
0 | 1 | 0 | 1 |
1 (ไม่กด) | 0 | 1(ติด) | 0 |
1(ไม่กด) | 1(ไม่กด) | 1(ติด) | 1(ติด) |
การรับค่าอินพุต (Digital Input)
การต่ออินพุตให้ไมโครคอนโทรลเลอร์
การรับสวิตช์
const int buttonPin = 2; // the number of the pushbutton pin
const int ledPin = 13; // the number of the LED pin
int button = 0;
void setup() {
pinMode(13, OUTPUT); // เริ่มต้นกำหนดให้ ขา 13 เป็นเอาท์พุท
pinMode(12, INPUT); // เริ่มต้นกำหนดให้ ขา 12 เป็นอินพุท}
void loop() {
button = digitalRead(12);
// อ่านค่าสวิตช์จาก ขา 12 มาเก็บไว้ในตัวแปร button
if (button == HIGH) // ถ้ากดปุ่มมีแรงดัน 5 โวลต์เข้าไมโครคอนโทรเลอร์
{
digitalWrite(13, HIGH);
// ส่งสัญญาณ 5 โวล์ต ออกมาจากขา 13
}
else {
// ถ้าไม่มีการกดปุ่มมีแรงดัน 0 โวลต์เข้าไมโครคอนโทรเลอร์
digitalWrite(13, LOW);
}
}
int button;
void setup()
{
Serial.begin(9600);
pinMode(2,OUTPUT);
pinMode(5,OUTPUT);
pinMode(0,INPUT_PULLUP);
}
void loop()
{
button = digitalRead(0);
Serial.print("button = "); Serial.println(button);
if(button==1) // ไม่ได้กด sw
{
Serial.println("if loop");
digitalWrite(2,1); // หลอดไฟดับ
}
else //กดsw
{
Serial.println("else loop");
digitalWrite(2,0); // หลอดไฟติด
}
แบบฝึกหัด
การรับค่าสัญญาแอนะล็อก
(Analog Signal)
รายการเซนเซอร์ที่มีในชุด 37-in-1 ชุดรวม Sensor สำหรับ Arduino Sensor Kit for Arduino
1 x Joystick
1 x Relay
1 x Big sound
1 x Small sound
1 x Tracking
1 x Avoidance
1 x Flame
1 x Linear hall
1 x Mental touch
1 x Digital temperature
1 x Active buzzer
1 x Passive buzzer
1 x RGB LED
1 x SMD RGB
1 x Two-color
1 x Mini two-color
1 x Magnetic spring
1 x Mini reed switch
1 x Heartbeat
1 x 7 color flash
1 x 7 color flash
1 x Button
1 x Shock
1 x Rotary encoders
1 x Light cup
1 x Hydrargyrum-switch
1 x Tilt-switch
1 x Photo-resistor
1 x Temp and humidity
1 x Analog hall
1 x Hall magnetic
1 x 18B20 temp
1 x Analog temp
1 x IR mission
1 x IR receiver
1 x Tap module
1 x Light blocking
การรับค่าแอนะล็อก (Analog input)
สัญญาณอะแนล็อกและค่าดิจิทัล
ค่าดิจิตอล
อะแนล๊อก
512
0
5V
2.5V
analogRead(ขาที่ต่อ)
ขา analog ที่รับได้จะมีทั้งหมด 6 ขาคือ A0-A5
int sensorValue;
float x;
void setup()
{
Serial.begin(9600);
}
void loop()
{
sensorValue = analogRead(A0);
// กำหนดอ่านค่าแรงดันทางขา A0
x = sensorvalue;
Serial.print(x); // ส่งค่าที่แปลงได้เข้าสู่คอมพิวเตอร์
Delay(1000);
}
LM35 temperature analog sensor
float tempC;
int reading;
int tempPin = A0;
void setup()
{
analogReference(INTERNAL);
Serial.begin(9600);
}
void loop()
{
reading = analogRead(tempPin);
tempC = reading / 9.31;
Serial.println(tempC);
delay(1000);
}
การใช้คำสั่ง map
Newvalue =map(sensorValue,0,10,100,200);
โปรแกรมจะเป็นการเปลี่ยนค่าอัตราส่วนจากค่าเดิมที่อยู่ระหว่าง 0-10 เป็นค่าใหม่ที่อยู่ระหว่าง 100-200 โดยมีอัตราส่วนที่คงที่ต่อกัน ถ้าคำสั่งรับค่า sensorValue เป็น 5 คำสั่ง map จะทำงานและส่งค่าอัตราส่วนที่เปลี่ยนใหม่คือ 500 ไปสู่ตัวแปร Newvalue
Analog input
Analog input
int sensorValue;
void setup()
{
Serial.begin(9600);
}
void loop()
{
sensorValue = analogRead(A0); // กำหนดอ่านค่าแรงดันทางขา A0
Serial.print(sensorValue); // ส่งค่าที่แปลงได้เข้าสู่คอมพิวเตอร์
Delay(1000);
}
LCD Display
Pulse Width Modulation (PWM)
ตัวอย่าง ปรับความสว่างของหลอดไฟที่ต่อกับขา 9 |
int ledPin = 9; // LED connected to digital pin 9 int analogPin = 3; // potentiometer connected to analog pin 3 int val = 0; // variable to store the read value void setup() { pinMode(ledPin, OUTPUT); // sets the pin as output } void loop() { analogWrite(ledPin, 127); } |
เซ็นเซอร์อัลตาร์โซนิคส์
Ultrasonic Sensor
เซ็นเซอร์อัลตาร์โซนิคส์ HC-SR04
หลักการทำงานเป็นดังนี้
เซ็นเซอร์ | ขา Arduino |
Trig | D0 / 16 |
Echo | D3 / 0 |
Vcc | 5V |
Gnd | Gnd |
#define echoPin 2 // กำหนดขา Echo
#define trigPin 0 // กำหนดขาTrigger
#define LEDPin 13 // กำหนดขา LED บนบอร์ด
int maximumRange = 200; // กำหนดย่านวัดไกลที่สุด
int minimumRange = 0; // กำหนดย่านวัดใกล้ที่สุด
long duration, distance; // ระยะเวลาที่ใช้ในการคำนวณระยะทาง
void setup() {
Serial.begin (9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(LEDPin, OUTPUT);
}
void loop() {
digitalWrite(trigPin, LOW); // สั่งงานให้ขา trig เป็น LOW
delayMicroseconds(2);
digitalWrite(trigPin, HIGH); // สั่งงานให้ขา trig เป็น HIGH และรอเป็นเวลา 10us โมดูลจะเริ่มทำงาน
delayMicroseconds(10);
digitalWrite(trigPin, LOW); // สั่งงานให้ขา trig เป็น LOW
duration = pulseIn(echoPin, HIGH); // รอจนกระทั่งขา echo มีสัญญาณ high กลับมา
// คำนวณเวลาในหน่วย ซม
เซ็นเซอร์ | ขา Arduino |
Trig | 8 |
Echo | 9 |
Vcc | 5V |
Gnd | Gnd |
void loop() {
digitalWrite(trigPin, LOW); // สั่งงานให้ขา trig เป็น LOW
delayMicroseconds(2);
digitalWrite(trigPin, HIGH); // สั่งงานให้ขา trig เป็น HIGH และรอเป็นเวลา 10us โมดูลจะเริ่มทำงาน
delayMicroseconds(10);
digitalWrite(trigPin, LOW); // สั่งงานให้ขา trig เป็น LOW
duration = pulseIn(echoPin, HIGH); // รอจนกระทั่งขา echo มีสัญญาณ high กลับมา
// คำนวณเวลาในหน่วย ซม
distance = duration/58;
// ถ้าระยะทางเกินกว่าค่าสูงสุด หรือต่ำสุดที่กำหนดไว้ให้ ส่งค่า -1 และไฟ 13 ติด
if (distance >= maximumRange || distance <= minimumRange){
Serial.println("-1"); digitalWrite(LEDPin, HIGH);
}
else { // ส่งค่าระยะทางออกทาง UART และไฟ 13 ดับ
Serial.println(distance); digitalWrite(LEDPin, LOW);
} //หน่วงเวลา 50ms ก่อนการอ่านครั้งต่อไป.
delay(50);
}
LCD Display
หลักการทำงาน
ขาที่ | สัญลักษณ์ | ความหมาย |
1 | VSS | GND |
2 | VDD | ไฟเลี้ยง 5V |
3 | VE | ใช้ในการปรับความเข้มของตัวอักษร จากรูปเช่นตัว h สามารถปรับความเข้ม ให้เข้มมากหรือจางจากกการปรับแรงดันที่เข้าทางขา VE ถ้าไม่ต้องการปรับความเข้มของตัวหนังสือสามารถต่อตัวต้านทานคงที่ระหว่างขา 3 กับขา 1 ได้ประมาณ 1kΩ |
4 | RS | โดยปกติการส่งข้อมูลให้ LCD จะมีข้อมูลสองประเภทในการส่งคือข้อมูลคำสั่ง (command) และตัวอักษร (data) โดยที่ช่องที่ส่งเข้ามาจะส่งมาที่ช่องเดียวกันคือ Data0-Data7 ขา RS จะเป็นขาที่กำหนดว่าข้อมูลที่เข้ามาจะเป็น command หรือ data ถ้า RS = 0 ข้อมูลที่เข้ามาเป็น command RS=1 ข้อมูลที่เข้ามาเป็น data |
5 | Read/write | นอกจากที่ LCD เป็นอุปกรณ์ในการแสดงผลแล้วยังสามารถที่จะอ่านข้อมูลจากตัวเองด้วยเช่นกัน คือ ถ้าให้ ขา 5 เป็น GND (write) จะสามารถใช้ไมโครคอนโทรลเลอร์ในการเขียนข้อมูลมาสูง LCD แต่ถ้าให้ขา 5 เป็น VDD LCD จะอยู่ในโหมด Read ไมโครคอนโทรลเลอร์จะสามารถอ่านข้อมูลจาก LCD ได้ |
6 | Enable | ยอมให้ LCD ทำงานหรือไม่ ถ้า VDD จะยอมให้ LCD ทำงานได้ปกติ |
7-14 | D0-D7 | ข้อมูล และ command ขนาด 8 บิต |
15 | +ve | Black Light เป็นไฟที่แสดงฉากหลังของ LCD ปัจจุบันมีหลายสีไม่ว่าจะเป็น เหลือง แดง เขียว ฟ้า ต้องต่อตัวต้านทานด้วยเสมอ ประมาณ 330 Ω |
16 | GND | GND |
LCD | Arduino |
GND | GND |
Vcc | Vcc |
RS | 12 |
R/W | GND |
Enable | 11 |
D4 | 5 |
D5 | 4 |
D6 | 3 |
D7 | 2 |
R/W | GND |
ทำการต่อวงจรดังต่อไปนี้ เพื่อเชิ่อมต่อระหว่าง LCD กับ arduino
นอกเหนือจากนั้นให้ทำการต่อความต้านทาน 200 โอห์ม ที่ขา 3 เพื่อปรับความสว่าง หน้าจอ LCD
#include <LiquidCrystal.h> //ทำการเพิ่มไลบารี่ LCD เข้ามาในโปรแกรม
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //กำหนดขาที่ใช้กับ Arduino ดังให้เรียงกันดังนี้RS,Enable,D4,D5,D6,D7
void setup() {� // คำสั่ง begin กำหนดการใช้งาน LCD 16 ตัว 2 บรรทัด
lcd.begin(16, 2);� // สั่งงานให้ตัวหนังสือ hello, world ออกที่ LCD
lcd.print("hello, world!");
}�void loop() {
lcd.setCursor(0, 1); // เลื่อนตำแหน่ง cursor ไปที่แถว 1 ตำแหน่ง 0
lcd.print("Thailand"); // ตัวอักษรคำว่า Thailand จะขึ้นที่ แถว 1 ตำแหน่ง 0
}�}
Data = 578�Voltage = 3.1 V
https://maxpromer.github.io/LCD-Character-Creator/
--------------------------
Data = ….
Data = 1024
Data = ….
Data = 1578
https://blynk.io/
Servo Motor
ส้ม สัญญาณ
แดง +5
น้ำตาล GND
หลักการทำงาน
การใช้ MILLIS การกำหนดระยะเวลา
void loop()
{// here is where you'd put code that needs to be running all the time...
บรรทัดถัดไปตรวจสอบเพื่อดูว่าช่วงเวลาที่ต้องการได้ผ่าน:
if (millis() - previousMillis > interval)
{// save the last time you blinked the LED
//หากช่วงเวลาได้ผ่านค่า MILLIS ปัจจุบันจะถูกบันทึกไว้ในตัวแปร
previousMillis:
previousMillis = millis();
// if the LED is off turn it on and vice versa: if (ledState == LOW)
ledState = HIGH; else
ledState = LOW; // set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}}
#include <Servo.h>
Servo myservo; // สร้างตัแปรในการควบคุม servo motor
int pos = 0; // กำหนดค่าเริ่ม
void setup()
{
myservo.attach(9); // ต่อ servo
}
void loop()
{
myservo.write(90); // หมุนมอเตอร์มาที่ตำแหน่ง 90 องศา
delay(1000); // หน่วงเวลา 1 วินาที
myservo.write(0); // หมุนมอเตอร์มาที่ตำแหน่ง 0 องศา
delay(1000); // หน่วงเวลา 1 วินาที
}
}
การสร้างกระดิ่งเป็นจังหวะ
ตัวอย่าง ระบบเปิด-ปิดประตูอัตโนมัติ
เซ็นเซอร์ตัวจับอุณหภูมิ�และความชื้น
วัดอุณหภูมิ และความชื้น (DHT11)
คุณสมบัติของเซ็นเซอร์
-DHT series digital temperature and humidity sensor�- Full scale calibration, single-wire digital output;�- Humidity measuring range: 20% ~ 90% RH (0- 50°C temperature compensation);�- Temperature measuring range: 0 ~ +50 °C;�- Humidity measurement accuracy: ± 5.0% RH�- Temperature measurement accuracy: ± 2.0 °C�- Response time: <5s;�- Low power consumption
void loop() {
delay(2000);
float h = dht.readHumidity();
// Read temperature as Celsius
float t = dht.readTemperature();
// Read temperature as Fahrenheit
float f = dht.readTemperature(true);
}
Serial.print("Humidity: ");
Serial.print(h);
Serial.print("Temperature: ");
Serial.print(t);
}
attachInterrupt
* ขา GPIO ทุกขาสามารถใช้คำสั่ง Interrupt ได้ ยกเว้นขา GPIO16�
attachInterrupt(digitalPinToInterrupt(pin), ISR, mode);
Delay(5000);
interrupt: | the number of the interrupt (int) |
ISR: | คือฟังก์ชั่นย่อยที่โปรแกรมจะเรียกใช้งานเมื่อเกิดการขัดจังหวะ โดยจะไม่มีการคืนค่าใดๆกลับไปสู่โปรหลักใดๆ หรือสามารถเรียกได้ว่า interrupt service routine. |
mode: | ความหมายของการเกิดอินเตอร์รัพdefines when the interrupt should be triggered. Four constants are predefined as valid values: LOW เกิดการขัดจังหวะเมื่อสัญญาณเป็นศูนย์ CHANGE เกิดการขัดจังหวะเมื่อที่มีการเปลี่ยนแปลงสัญญาณ RISING เกิดการขัดจังหวะเมื่อสัญญาณเกิดขอบขาขึ้น FALLING เกิดการขัดจังหวะเมื่อสัญญาณเกิดขอบขาลง HIGH เกิดการขัดจังหวะเมื่อสัญญาณเป็นไฮ |
#define ledPin 2
#define interruptPin 5
volatile byte state = LOW;
int button;
void setup()
{
pinMode(ledPin, OUTPUT);
//pinMode(3, OUTPUT);
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), blink, RISING);
}
void loop()
{
Serial.println("Main Loop");
delay(1000);
}
�void blink() {
//button = digitalRead(5);
//if (button==HIGH)
//{
digitalWrite(2,0);
delay(1000);
//}
//else
//{
digitalWrite(2,1);
delay(1000);
}
��
การควบคุมมอเตอร์กระแสตรง
หลักการควบคุมมอเตอร์กระแสตรง
การทำงานของ H-Bridge เพื่อควบคุมความเร็วมอเตอร์
การปรับความกว้างของ พลัสซ์ (duty cycle)
มอเตอร์จะหยุดหมุนเมื่อ duty cycle = 0%
มอเตอร์หมุนช้าเมื่อมีแรงดันจ่ายมาที่ duty cycle = 25%
ความเร็วสูงสุดที่ duty cycle = 100%
ชุดขับเคลื่อนมอเตอร์ไอซี LM298
ตัวอย่าง การปรับทิศทางการหมุนมอเตอร์ |
int IN1=8; int IN2=9; int ENA=3; void setup() { pinMode(IN1,OUTPUT); pinMode(IN2,OUTPUT); } void loop() { analogWrite(ENA, 200);// motor speed digitalWrite(IN1,LOW);// rotate forward digitalWrite(IN2,HIGH); delay(2000); digitalWrite(IN1,HIGH);// rotate reverse digitalWrite(IN2,LOW); delay(2000); } |