← กลับ Simulator

คู่มือใช้งาน RazorSIM

เริ่มต้นจำลองหุ่นยนต์ด้วย Blocks หรือ C++ พร้อมคำสั่ง เซ็นเซอร์ และตัวอย่างใช้งาน

สารบัญ

เริ่มต้นใช้งาน

RazorSIM มีพื้นที่เขียนโปรแกรมทางซ้ายและหน้าจอจำลองทางขวา เลือกสนามกับหุ่นยนต์จากแถบด้านบน แล้วกด RUN เพื่อทดสอบโปรแกรม

1. เลือกโหมดกด Blocks Mode เพื่อใช้บล็อก หรือสลับเป็น C++ Code Mode
2. เลือก Robot / MAPกำหนดแบบหุ่นยนต์และสนามที่ต้องการทดสอบ
3. สร้างโปรแกรมวางบล็อกใน setup หรือ loop หรือพิมพ์ C++
4. RUN และ Resetกด RUN เพื่อเริ่ม หยุดด้วยปุ่มเดิม และ Reset เพื่อกลับจุดเริ่ม
คีย์ลัด: กด Ctrl+Enter เพื่อ RUN ได้จาก Block Editor และดูข้อความจาก Serial.print ที่แท็บ Console ด้านล่าง

Block Editor

โหมด Blocks เหมาะสำหรับเริ่มต้น ลากบล็อกจากรายการด้านซ้ายมาต่อกันในพื้นที่ทำงาน บล็อกคำสั่งจะต่อเป็นแนวตั้ง ส่วนบล็อกค่าและเงื่อนไขต้องเสียบในช่องที่มีรูปทรงตรงกัน ระบบจะแปลงเป็น C++ ให้อัตโนมัติเมื่อรัน

FORWARD L 50 R 50

MOTOR สั่งเดินหน้า ถอยหลัง แยกล้อ หมุน เลี้ยว หยุด และรอเวลา ค่าความเร็วใช้ช่วง 0–100

ระยะหน้า (cm)

Sensors อ่าน IR line, TOF, สี, Encoder และ Gyro เพื่อนำไปใช้เป็นเงื่อนไข

วนซ้ำตลอดเวลา

LOOP ใช้วนซ้ำ, while, repeat, for รวมถึง break และ continue

ถ้า ... ให้ทำ

Logic / Math เปรียบเทียบค่า, and/or/not, คำนวณ และสร้างเงื่อนไขตัดสินใจ

หน่วง 500 ms

TIME หน่วงเวลาและอ่าน millis() โดย 1,000 ms เท่ากับ 1 วินาที

Serial.println Hello

Advanced พิมพ์ข้อความหรือค่าไปที่ Console และใส่บล็อกข้อความ

โครงสร้างบล็อกที่ควรใช้

บล็อกใช้เมื่อ
setupทำงานหนึ่งครั้งตอนเริ่ม เช่น รีเซ็ต Gyro หรือพิมพ์ข้อความเริ่มต้น
loopทำงานวนซ้ำ เหมาะกับการอ่านเซ็นเซอร์และควบคุมหุ่นยนต์ต่อเนื่อง
if / elseเลือกการกระทำตามค่าเซ็นเซอร์ เช่น หากเจอเส้นดำให้เลี้ยว
ตัวแปรเก็บค่าที่อ่านได้ก่อนนำไปคำนวณหรือแสดงผล
💡
เริ่มง่ายที่สุด: ใส่ FORWARDรอ 1000 msหยุด ไว้ใน setup แล้วกด RUN

คำสั่งมอเตอร์

เดินหน้า / ถอยหลัง / หยุด

คำสั่งพารามิเตอร์หน้าที่
fd(speed) int 0–100 เดินหน้า สองล้อเท่ากัน
fd2(speedL, speedR) int -100–100 แต่ละล้อ เดินหน้า ปรับความเร็วแยกล้อซ้าย-ขวา (ค่าลบ = ล้อนั้นถอย)
bk(speed) int 0–100 ถอยหลัง สองล้อเท่ากัน
bk2(speedL, speedR) int 0–100 แต่ละล้อ ถอยหลัง ปรับความเร็วแยกล้อซ้าย-ขวา
ao() หยุดมอเตอร์ทั้งหมด (all off)
stop_motor() หยุดมอเตอร์ทั้งหมด (เหมือน ao)

ล้อเดี่ยว

คำสั่งพารามิเตอร์หน้าที่
motorL(SpeedL) int SpeedL (-100 ถึง 100) สั่งมอเตอร์ซ้ายโดยตรง
บวก = หน้า  |  ลบ = หลัง  |  0 = หยุด
motorR(SpeedR) int SpeedR (-100 ถึง 100) สั่งมอเตอร์ขวาโดยตรง
บวก = หน้า  |  ลบ = หลัง  |  0 = หยุด
fd(80);           // เดินหน้า 80%
delay(1500);

fd2(80, 40);      // ซ้าย 80%, ขวา 40% → เลี้ยวขวาขณะหน้า
delay(500);

bk(60);           // ถอยหลัง 60%
delay(800);

ao();            // หยุด
delay(300);

การหมุน

คำสั่งพารามิเตอร์หน้าที่
sr(speed) int 0–100 หมุนขวา — ล้อซ้ายหน้า ล้อขวาหลัง (จุดหมุนกลางหุ่น)
sl(speed) int 0–100 หมุนซ้าย — ล้อขวาหน้า ล้อซ้ายหลัง (จุดหมุนกลางหุ่น)
tr(speed) int 0–100 เทินขวา — ล้อซ้ายหมุนหน้า ล้อขวาหยุด (จุดหมุนอยู่ล้อขวา)
tl(speed) int 0–100 เทินซ้าย — ล้อขวาหมุนหน้า ล้อซ้ายหยุด (จุดหมุนอยู่ล้อซ้าย)
Beep() เสียงบัซเซอร์ (Buzzer)
sr(speed)
หมุนขวา — จุดหมุนกลางหุ่น
🤖
ล้อซ้าย=+speed   ล้อขวา=−speed
sl(speed)
หมุนซ้าย — จุดหมุนกลางหุ่น
🤖
ล้อซ้าย=−speed   ล้อขวา=+speed
tr(speed)
เทินขวา — จุดหมุนที่ล้อขวา
🤖
ล้อซ้าย=+speed   ล้อขวา=0
tl(speed)
เทินซ้าย — จุดหมุนที่ล้อซ้าย
🤖
ล้อซ้าย=0   ล้อขวา=+speed
sr(80);   delay(500);   ao();   // หมุนขวา 90°
sl(80);   delay(500);   ao();   // หมุนซ้าย 90°
tr(70);   delay(600);   ao();   // เทินขวา (วงกว้างกว่า)
💡
sr/sl — หุ่นหมุนรอบจุดกึ่งกลาง เหมาะสำหรับกลับทิศในที่แคบ
tr/tl — วงกว้างกว่า เหมาะสำหรับเลี้ยวมุมฉาก (intersection ในสนามกริด)

เซ็นเซอร์ & I/O

analogRead — เซ็นเซอร์เส้น

คืนค่า 0–1023 — ค่าต่ำ = เจอเส้นดำ, ค่าสูง = พื้นขาว สำหรับ RazorBot Basic และ RAZOR-S3 มี IR 4 ตัวตามตำแหน่งด้านล่าง (Razor Gripper S1 มี 8 ตัวหน้าและ 8 ตัวหลัง)

A0
pin 14
หน้า-ซ้าย
A1
pin 15
หน้า-ขวา
A2
pin 16
หลัง-ซ้าย
A3
pin 17
หลัง-ขวา
~25
เจอเส้นดำ
~960
พื้นขาว (ไม่เจอ)
⚠️
ใช้ THRESHOLD = 500 เป็นเกณฑ์ — ค่าน้อยกว่า 500 = เส้น, มากกว่า = พื้น
#define THRESHOLD 500

int val = analogRead(A2);        // อ่านเซ็นเซอร์กลาง
if (val < THRESHOLD) {
  // เจอเส้นดำ
} else {
  // พื้นขาว ไม่เจอเส้น
}

digitalRead — ปุ่ม / สวิตช์

คำสั่งPins ที่ใช้ได้ค่าที่คืน
analogRead(pin) A0–A7   (หรือ 14–21) int 0–1023
digitalRead(pin) 0–13   A0–A7   (หรือ 14–21) 0 หรือ 1 (LOW / HIGH)
analogWrite(pin, val) pin PWM, val 0–255 ส่ง PWM ออก
digitalWrite(pin, val) 0–13, val = HIGH/LOW ส่งดิจิทัลออก
pinMode(pin, mode) mode = INPUT / OUTPUT ตั้งโหมดขา

หน่วงเวลา

คำสั่งพารามิเตอร์หน้าที่
delay(ms) int ms หยุดรอ n มิลลิวินาที  1000 ms = 1 วินาที
millis() เวลาที่ผ่านมานับแต่เริ่ม (ms) — ใช้จับเวลาโดยไม่ block
micros() เวลาที่ผ่านมา (microseconds)
fd(80);
delay(2000);   // วิ่งหน้า 2 วินาที
ao();

// ── จับเวลาแบบ non-blocking ──
long t = millis();
while (millis() - t < 3000) {
  // ทำต่อเนื่อง 3 วินาที
  fd(70);
  delay(20);
}
ao();

Serial / พิมพ์

คำสั่งหน้าที่
Serial.println(val) พิมพ์ข้อความหรือตัวเลข พร้อมขึ้นบรรทัดใหม่
Serial.print(val) พิมพ์ต่อเนื่องไม่ขึ้นบรรทัดใหม่
Serial.println("สวัสดี!");
Serial.print("ค่า: ");  Serial.println(sensorVal);
Serial.println(3.14);  // พิมพ์ตัวเลขได้ด้วย

ฟังก์ชัน Math

คำสั่งความหมายตัวอย่าง
abs(x)ค่าสัมบูรณ์ |x|abs(-50) → 50
constrain(v, lo, hi)จำกัดค่าไม่ให้เกินขอบเขตconstrain(300,0,255) → 255
map(v, a, b, c, d)แปลงช่วงค่า a-b → c-dmap(512,0,1023,0,100) → 50
min(a, b)ค่าน้อยสุดจากสองmin(30,50) → 30
max(a, b)ค่ามากสุดจากสองmax(30,50) → 50
sqrt(x)รากที่สองsqrt(9) → 3
pow(x, y)x ยกกำลัง ypow(2,8) → 256
random(lo, hi)สุ่มในช่วง lo–hi-1random(0,10) → 0..9
sin(rad) / cos(rad)ตรีโกณ (หน่วยเรเดียน)sin(PI/2) → 1.0
// ค่าคงที่ Math
PI       // 3.14159…
TWO_PI   // 6.28318…
HALF_PI  // 1.57079…

Control Flow

// ─── if / else if / else ─────────────────────────
if (x > 100) {
  fd(80);
} else if (x > 50) {
  fd(40);
} else {
  ao();
}

// ─── for loop ────────────────────────────────────
for (int i = 0; i < 5; i++) {
  Beep();  delay(200);
}

// ─── while loop ──────────────────────────────────
while (analogRead(A2) > 500) {
  fd(60);
  delay(20);
}
ao();

// ─── break / continue ────────────────────────────
for (int i = 0; i < 100; i++) {
  if (i == 50) break;
}

โครงสร้างโปรแกรม

ทุกโปรแกรมต้องมี setup() และ loop()

void setup() {
  // รันครั้งเดียวตอนเริ่ม — ใส่การตั้งค่าที่นี่
  Serial.println("เริ่มแล้ว!");
}

void loop() {
  // รันซ้ำๆ ไม่หยุด — ใส่ logic หลักที่นี่
}

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

1. เดินหน้า-ถอยหลัง-หมุน

void setup() {
  Serial.println("พร้อมแล้ว!");
}

void loop() {
  fd(80);          // เดินหน้า
  delay(1500);

  ao();  delay(200);

  sr(80);          // หมุนขวา 90°
  delay(450);

  ao();  delay(200);
}

2. Line Following 2 เซ็นเซอร์หน้า

#define SEN_L      A0
#define SEN_R      A1
#define THRESHOLD  500

void setup() {
  Serial.println("Line Follower เริ่ม!");
}

void loop() {
  int L = analogRead(SEN_L);
  int R = analogRead(SEN_R);

  if      (L < THRESHOLD && R < THRESHOLD) fd(70);
  else if (L < THRESHOLD) fd2(35, 70);   // เลี้ยวซ้าย
  else if (R < THRESHOLD) fd2(70, 35);   // เลี้ยวขวา
  else                     ao();

  delay(20);
}

3. PID Line Following 5 เซ็นเซอร์

#define THRESHOLD 500

float Kp = 10.0, Ki = 0.0, Kd = 3.0;
int   baseSpeed = 80;
float lastError = 0, integral = 0;

void loop() {
  int s0=analogRead(A0), s1=analogRead(A1), s2=analogRead(A2);
  int s3=analogRead(A3), s4=analogRead(A4);

  float sum=0; int cnt=0;
  if (s0<THRESHOLD){ sum+=-2; cnt++; }
  if (s1<THRESHOLD){ sum+=-1; cnt++; }
  if (s2<THRESHOLD){ sum+= 0; cnt++; }
  if (s3<THRESHOLD){ sum+=+1; cnt++; }
  if (s4<THRESHOLD){ sum+=+2; cnt++; }

  if (cnt==0){ ao(); return; }

  float error = sum / cnt;
  integral  += error;
  float corr  = Kp*error + Ki*integral + Kd*(error-lastError);
  lastError   = error;

  fd2(baseSpeed - (int)corr,
      baseSpeed + (int)corr);
  delay(10);
}