วัตถุประสงค์
1) ความเข้าใจและฝึกทักษะในการเขียนโค้ดคำสั่งการทำงานของ
arduino มากยิ่งขึ้น
2) ความเข้าใจกลไกการแปลงข้อมูลจาก infix
เป็น postfix และสามารถนำมาประยุกต์ใช้งานได้
3) การใช้นำความรู้ด้านอัลกอริทึมในการเก็บข้อมูลแบบ
stack มาประยุกต์
วัสดุ
อุปกรณ์และเครื่องมือ (Materials and Equipment)
1) คอมพิวเตอร์
PC
หรือ Notebook ที่มีโปรแกรม Arduino
2) บอร์ด
Arduino
UNO R3
3) สาย USB ใช้เชื่อมต่อระหว่าง Arduino กับ Notebook
Block diagram
หลักการทำงาน
จะรับข้อมูลชนิด char ผ่านทาง Arduino serial แล้วมาเก็บเป็น String ซึ่งข้อมูลที่รับมานั้นจะคือนิพจน์ที่เป็น infix เมื่อได้รับนิพจน์ที่เป็น infix มาเรียบร้อยแล้วก็จะเป็นกลไกการแปลงนิพจน์จาก infix เป็น postfix ที่ต้องนำ stack มาใช้ในการเก็บ Operator ตามลำดับการดำเนินการทางคอมพิวเตอร์ ดังนี้ |
Operator
|
Operator Precedence & Association
|
|
Precedence
|
Associativity
|
|
^
|
3
|
Right
|
%
|
2
|
Left
|
/
|
2
|
Left
|
*
|
2
|
Left
|
-
|
1
|
Left
|
+
|
1
|
Left
|
1. 1 ตารางเปรียบเทียบการดำเนินการของ Operator
Algorithm ในการแปลง infix เป็น postfix ได้ศึกษาแนวทางการดำเนินการมาจาก http://www.engineersgarage.com/contribution/expert/calculator-using-postfix-notification
โดยศึกษาจาก
Flowchart มีดังนี้
1. อ่านค่าอินพุตที่ได้รับถ้าเป็น number ให้นำไปเก็บเป็น String (output)
เมื่อนำค่าที่รับมาแปลงเป็น postfix เรียบร้อย แล้ว เราก็จะนำ postfix ที่ได้ไปคำนวณค่าทางคณิตศาสตร์ โดยเราจะใช้ Stack ในการเก็บค่าของตัวเลข (Number) ที่ได้จากการวน loop ตาม index ของ postfix ที่ได้รับมา แต่ถ้าวนไปแล้วไปเจอ Operator ก็จะทำการ Pop Number ที่อยู่ใน Stack ออกมาจำนวนสองค่า เพื่อนำมาดำเนินการตาม Operator ที่พบ เมื่อคำนวณเสร็จแล้วก็จะเก็บค่าคำตอบนั้นลงไปใน Stack เพื่อนำไปคำนวณต่อไป เมื่อคำนวณเสร็จเรียบร้อยแล้วก็จะส่งคำตอบออกจากฟังก์ชัน และนำไปแสดงผลที่หน้าจอ
Code for calculator
1. อ่านค่าอินพุตที่ได้รับถ้าเป็น number ให้นำไปเก็บเป็น String (output)
2. อ่านค่าอินพุตถ้าเป็น operand ให้ทำดังนี้
2.1 นำ operand เก็บลงใน Stack ถ้า Stack Empty (ว่าง)
2.2 ถ้า Stack ไม่ว่างให้เปรียบเทียบค่า Precedence ของ operator ที่อินพุตกับ operator ใน Stack โดยเทียบค่าในตาราง
3. อ่านค่าอินพุตถ้าเป็นเครื่องหมายวงเล็บเปิด ‘(’ ก็ให้ทำการ pop Stack
4. อ่านค่าอินพุตถ้าเป็นเครื่องหมายวงเล็บปิด ‘)’ ก็ให้ทำการ pop Stack ออกไปเก็บที่ String
(output) จนกว่าจะเจอเครื่องหมายวงเล็บเปิดใหม่แล้วทิ้งเครื่องหมายวงเล็บปิดไป
5.
ถ้าอ่านค่าอินพุตหมดแล้วให้ตรวจใน Stack ว่าว่างหรือไม่ถ้าไม่ว่างให้ pop Stack
ออกไปเก็บไว้ที่ String (output) จน Stack ว่างมีดังนี้
1. อ่านค่าอินพุตที่ได้รับถ้าเป็น number ให้นำไปเก็บเป็น
String (output)
2. อ่านค่าอินพุตถ้าเป็น operand ให้ทำดังนี้
2.1 นำ operand เก็บลงใน Stack ถ้า Stack Empty (ว่าง)
2.2 ถ้า Stack ไม่ว่างให้เปรียบเทียบค่า Precedence ของ operator ที่อินพุตกับ operator ใน Stack โดยเทียบค่าในตาราง
3. อ่านค่าอินพุตถ้าเป็นเครื่องหมายวงเล็บเปิด ‘(’ ก็ให้ทำการ pop Stack
4. อ่านค่าอินพุตถ้าเป็นเครื่องหมายวงเล็บปิด ‘)’ ก็ให้ทำการ pop Stack ออกไปเก็บที่ String
(output) จนกว่าจะเจอเครื่องหมายวงเล็บเปิดใหม่แล้วทิ้งเครื่องหมายวงเล็บปิดไป
5.
ถ้าอ่านค่าอินพุตหมดแล้วให้ตรวจใน Stack ว่าว่างหรือไม่ถ้าไม่ว่างให้ pop Stack
ออกไปเก็บไว้ที่ String (output) จน Stack ว่าง
Step การแปลง
Infix เป็น Postfix
|
|||
Token
|
Action
|
Output String
|
opStack
|
1
|
Add
to string(output)
|
1
|
|
5
|
Add
to string(output)
|
15
|
|
-
|
Push
to Stack
|
15
|
-
|
(
|
Push
to Stack
|
15
|
- (
|
(
|
Push
to Stack
|
15
|
- ( (
|
1
|
Add
to string(output)
|
15 1
|
- ( (
|
0
|
Add
to string(output)
|
15 10
|
- ( (
|
-
|
Push
to Stack
|
15 10
|
- (
( -
|
5
|
Add
to string(output)
|
15 10 5
|
- (
( -
|
)
|
Pop
Stack to string(output)
|
15 10
5 -
|
- ( (
|
Pop
Stack
|
15 10
5 -
|
- (
|
|
-
|
Push
to Stack
|
15 10
5 -
|
- ( -
|
3
|
Add
to string(output)
|
15 10
5 - 3
|
- ( -
|
)
|
Pop
Stack to string(output)
|
15 10
5 - 3 -
|
- (
|
Pop
Stack
|
15 10
5 - 3 -
|
-
|
|
=
|
Pop
Stack to string(output)
|
15 10
5 - 3
- -
|
เมื่อนำค่าที่รับมาแปลงเป็น postfix เรียบร้อย แล้ว เราก็จะนำ postfix ที่ได้ไปคำนวณค่าทางคณิตศาสตร์ โดยเราจะใช้ Stack ในการเก็บค่าของตัวเลข (Number) ที่ได้จากการวน loop ตาม index ของ postfix ที่ได้รับมา แต่ถ้าวนไปแล้วไปเจอ Operator ก็จะทำการ Pop Number ที่อยู่ใน Stack ออกมาจำนวนสองค่า เพื่อนำมาดำเนินการตาม Operator ที่พบ เมื่อคำนวณเสร็จแล้วก็จะเก็บค่าคำตอบนั้นลงไปใน Stack เพื่อนำไปคำนวณต่อไป เมื่อคำนวณเสร็จเรียบร้อยแล้วก็จะส่งคำตอบออกจากฟังก์ชัน และนำไปแสดงผลที่หน้าจอ
จากPostfix 15
10 5 -
3 - -
Step การคำนวณ
Postfix
|
|||
Token
|
Action
|
String
|
Stack
|
1
|
Add
to string(number)
|
1
|
|
5
|
Add
to string(number)
|
15
|
|
Push
string(number) to Stack
|
15
|
15
|
|
Clear
string
|
15
|
||
1
|
Add
to string(number)
|
1
|
15
|
0
|
Add
to string(number)
|
10
|
15
|
Push
string(number) to Stack
|
10
|
15
10
|
|
Clear
string
|
15
10
|
||
5
|
Add
to string(number)
|
5
|
15
10
|
Push
string(number) to Stack
|
5
|
15
10 5
|
|
Clear
string
|
15
10 5
|
||
-
|
Pop
two times form stack and calculate (10-5)
|
15
|
|
Push
answer to stack
|
15
5
|
||
3
|
Add
to string(number)
|
3
|
15
5
|
Push
string(number) to Stack
|
3
|
15
5 3
|
|
Clear
string
|
15
5 3
|
||
-
|
Pop
two times form stack and calculate
(5-3)
|
15
|
|
Push
answer to stack
|
15
2
|
||
-
|
Pop
two times form stack and calculate
(15-2)
|
||
Push
answer to stack
|
13
|
||
Return
pop stack (=13)
|
Code for calculator
สาธิตการทำงาน
ส่งข้อความที่เป็นนิพจน์
(10-3/2+5)*2= ผ่านทาง Arduino serial monitor (รูปซ้าย) ส่งไปคำนวณและนำกลับมาแสดงคำตอบ (รูปขวา)
ส่งข้อความที่เป็นนิพจน์
((100+1)*50)/100= ผ่านทาง Arduino serial monitor (รูปซ้าย) ส่งไปคำนวณและนำกลับมาแสดงคำตอบ (รูปขวา) โดยยังสามารถมองเห็นผลลัพธ์ที่ได้จากการส่งข้อความไปก่อนหน้านี้ด้วย
ส่งข้อความที่เป็นนิพจน์ 15-((10-5)-3)= ผ่านทาง Arduino serial monitor (รูปซ้าย)
ส่งไปคำนวณและนำกลับมาแสดงคำตอบ (รูปขวา) โดยยังสามารถมองเห็นผลลัพธ์ที่ได้จากการส่งข้อความไปก่อนหน้านี้ด้วย
ส่งข้อความที่เป็นนิพจน์ (10^2+2^10)%(100^2)= ผ่านทาง Arduino serial monitor
(รูปซ้าย) ส่งไปคำนวณและนำกลับมาแสดงคำตอบ
(รูปขวา) โดยยังสามารถมองเห็นผลลัพธ์ที่ได้จากการส่งข้อความไปก่อนหน้านี้ด้วย
ส่งข้อความที่เป็นนิพจน์ 2^3-5*2^2-3*2+10= ผ่านทาง Arduino serial monitor
(รูปซ้าย) ส่งไปคำนวณและนำกลับมาแสดงคำตอบ
(รูปขวา) โดยยังสามารถมองเห็นผลลัพธ์ที่ได้จากการส่งข้อความไปก่อนหน้านี้ด้วย