Overview
คนเป็นพ่อเป็นแม่น่ะนะ เค้าก็ห่วงลูกหลานเป็นธรรมดา อยากให้ไปโรงเรียนให้ทันเวลา แถมต้องกลับบ้านให้ตรงเส้นทางที่วางไว้ด้วย
เจ้าโปรเจกต์ SmartWay ตัวนี้แหละจะมาช่วยปลดล็อกความกังวลพวกนี้เอง พี่จะพาพวกแกมาทำเครื่องคอยส่อง (Monitor) พิกัดตอนไป-กลับโรงเรียน เพื่อให้มั่นใจว่าเด็กๆ เดินตามเส้นทางที่เหมาะสมเพื่อไปให้ถึงจุดหมายอย่างปลอดภัย
เจ้า SWay จะคอย Monitor พิกัด Geolocation โดยใช้ GPS และจะยิง e-mail ไปบอกผู้ปกครองทันทีถ้าเด็กดันออกนอกเส้นทางที่กำหนดไว้ นอกจากนี้ SmartWay ยังส่ง e-mail รายงานตอนถึงบ้านหรือถึงโรงเรียน รวมถึงฟ้องด้วยนะถ้าไปสาย! ทีนี้ผู้ปกครองก็จิบกาแฟรอชิลล์ๆ ได้เลย เพราะรู้ว่าลูกหลานถึงที่หมายปลอดภัยหายห่วง
Functionality
SmartWay จะคอยเช็กพิกัด Geolocation ตลอดเวลาตั้งแต่ตื่นยันถึงบ้านเลยว่ะน้อง ตัวเครื่องยังมี RGB LED กับ Vibrating motor (มอเตอร์สั่น) เอาไว้คอยเตือนน้องๆ ถ้าเกิดเดินออกนอกเส้นทางหรือไปสาย และจะแสดงความยินดีด้วยไฟสวยๆ เมื่อถึงโรงเรียน
ไอ้เจ้าเครื่องนี้ทำงานผ่านหลายฟังก์ชันเพื่อให้มั่นใจว่าปลอดภัยชัวร์


- Loop แรก
if(off track)เอาไว้เช็กว่าเด็กออกนอกเส้นทางที่วางไว้หรือเปล่า ระบบจะนับจำนวนครั้งที่เกิดขึ้นด้วยนะ ถ้าออกนอกเส้นทางครั้งแรก เครื่องจะเตือนด้วยไฟ LED สีแดงและสั่นมอเตอร์ พี่ให้เวลาแก้ตัว 2 นาทีนะเว้ยให้รีบกลับมาเข้าเส้นทาง แต่ถ้ายังดื้ออยู่นอกทางเกิน 2 นาที ระบบจะยิง e-mail เตือนผู้ปกครองพร้อมพิกัด GPS ทันที และจะส่งซ้ำทุกๆ 2 นาทีจนกว่าจะกลับเข้าที่เข้าทางหรือถึงจุดหมาย - Loop
if(school time)และif(home time)จะเช็กว่าถึงเวลาไปเรียนหรือกลับบ้านหรือยัง จากนั้น Board จะเช็กว่าเด็กถึงโรงเรียนหรือบ้านหรือยัง ถ้าถึงทันเวลา ไฟ LED จะติดเป็นสีเขียวและส่ง e-mail บอกที่บ้านพร้อมเวลาที่มาถึง แต่ถ้าถึงเวลาเรียนแล้วยังไม่โผล่ไปโรงเรียนล่ะก็... โดนฟ้องแน่!
ตัวเครื่องส่งข้อมูลได้แค่ 12 bytes นะน้อง เพราะฉะนั้นเราต้องบีบ Packet ข้อมูลให้เล็กที่สุด ส่วน Variable อื่นๆ เดี๋ยวเราไปตั้งค่ากันใน SigFox backend เอา



มี 4 Packet หลักๆ ที่เครื่องจะส่งได้:
- เด็กออกนอกเส้นทาง - ("off course")
- เด็กถึงบ้านแล้ว - ("at home")
- เด็กถึงโรงเรียนแล้ว - ("at school")
- เด็กมาสาย - ("late")
ระบบการแจ้งเตือน (Warning System) น้องที่พกเครื่องนี้จะโดนสะกิดเตือนทุกครั้งที่ถึงโรงเรียน, ถึงบ้าน, มาสาย หรือเผลอเดินออกนอกเส้นทาง
ดูตอนใช้งานจริงกันหน่อย
Benefits
ใช้เครื่องนี้แล้วดียังไง:
- มั่นใจว่าเด็กๆ เดินทางไป-กลับโรงเรียนอย่างปลอดภัย
- ฝึกความตรงต่อเวลา
- คอยดูไม่ให้เด็กออกนอกเส้นทาง (ห้ามหนีเที่ยว!)
- ประหยัดพลังงานและราคาถูก - แบตเตอรี่อึด ใช้ได้นาน
Constructing the Project
Step 1: เตรียมของ (ห้ามลืมนะน้อง) ก่อนจะเริ่มลุย ต้องรวมรวมอุปกรณ์ให้ครบก่อน จัดไปวัยรุ่น:
- สาย Jumper wires
- 1, NPN transistor
- 1, Ceramic capacitor (0.1µF)
- 3, Resistors (220Ω)
- 1, Resistor (1KΩ)
- 1, RGB LED
- 1, GPS Module
- 1, Vibrating Motor Cell (มอเตอร์สั่น)
- 1, Arduino MKR1200 fox
- 1, รางถ่าน 2x AAA/AA
- 2, ถ่าน AA
Step 2: ต่อวงจร ขั้นตอนต่อมาคือการประกอบร่างวงจร ดูภาพจาก Fritzing ด้านล่างได้เลย พี่แยกส่วนการเดินสายไว้หลายรูป จะได้ไม่งง

Step 3: ทำความเข้าใจ Code Code ของเราประกอบด้วยหลายฟังก์ชัน แต่ละส่วนก็มีหน้าที่เฉพาะของมัน:
- Warn System (ระบบเตือน)
- Get GPS (ดึงพิกัด)
- Synch RTC (ซิงค์เวลา)
- Process Location (ประมวลผลตำแหน่ง)
- Send Package (ส่งข้อมูล)
- Do Actions (สั่งการ)
เดี๋ยวพี่จะอธิบายแต่ละส่วนให้ฟัง
- Warn System
void setOutputs()
{
pinMode(R, OUTPUT);
pinMode(G, OUTPUT);
pinMode(B, OUTPUT);
pinMode(motorPin, OUTPUT);
}
void vibrateMotor() // สั่งมอเตอร์สั่น
{
digitalWrite(motorPin, HIGH);
delay(1000);
digitalWrite(motorPin, LOW);
}
void ledGreen() // ไฟเขียวผ่านตลอด
{
analogWrite(R, 0);
analogWrite(G, 255);
analogWrite(B, 0);
}
void ledOrange() // ไฟส้ม เตือนหน่อย
{
analogWrite(R, 255);
analogWrite(G, 45);
analogWrite(B, 0);
}
void ledRed() // ไฟแดง อันตราย!
{
analogWrite(R, 255);
analogWrite(G, 0);
analogWrite(B, 0);
}
void resetLED() // ปิดไฟ
{
analogWrite(R, 0);
analogWrite(G, 0);
analogWrite(B, 0);
}
Code ส่วนนี้อยู่ในไฟล์ functions.h เอาไว้คอยเตือนสถานะต่างๆ ให้คนใส่เครื่องรู้ผ่าน RGB LED และมอเตอร์สั่นนั่นเอง
- Get GPS
bool getGPS(int run)
{
while(Serial1.available() > 0)
{
if(gps.encode(Serial1.read()))
{
if(run == 1)
{
processData();
}
else if(run == 2)
{
synchRTC();
}
if(gps.location.isValid() && gps.time.isValid() && gps.date.isValid())
{
return true;
}
else
{
return false;
}
}
}
if(millis() > 10000 && gps.charsProcessed() < 10)
{
Serial.println("Error - GPS Module Responded with Error");
Serial.println(" Terminating Code");
Serial.println("________________________________________");
while(1) {};
}
}
Loop นี้มีหน้าที่รับพิกัดและเวลาจาก GPS Module โดยใช้ใน setup loop เพื่อซิงค์ GPS และซิงค์ RTC ในตัว Board ให้ตรงกับ GPS และใช้ใน Loop หลักเพื่อหาตำแหน่งเครื่องตลอดเวลา
- Synch RTC
void synchRTC()
{
Serial.println("Synching RTC");
Serial.println("________________________________________");
Serial.println(" OK - Initialising RTC");
rtc.begin();
Serial.println(" OK - Synching Time");
// ต้องตัด 2 หลักแรกของปีออกหน่อย (2018 -> 18)
uint16_t yearRAW = gps.date.year();
String yearString = String(yearRAW);
yearString.remove(0,1);
uint16_t year = yearString.toInt();
rtc.setTime(gps.time.hour(), gps.time.minute(), gps.time.second());
rtc.setDate(gps.date.day(), gps.date.month(), year);
Serial.println(" Success - RTC Synched");
Serial.println("________________________________________");
Serial.println("");
Serial.println("");
Serial.println("");
}
ส่วนนี้คือการซิงค์เวลาของ RTC ใน Board ให้ตรงกับเวลาที่ได้จาก GPS Module เพื่อความแม่นยำ
- Process Location
bool processData()
{
if(gps.location.isValid())
{
latitude = gps.location.lat();
longitude = gps.location.lng();
latitude = 53.355504;
longitude = -6.258452;
if(check.isOut())
{
if(check.track())
{
Serial.println("OUT OF BOUNDS");
warn.offTrackLoop();
}
}
if(check.isHomeTime() && arrivedSchool)
{
if(check.isHome())
{
Serial.println("AT HOME");
warn.arrivedHomeLoop();
}
else
{
Serial.println("LATE -> HOME");
warn.lateLoop();
}
}
else if(check.isSchoolTime() && arrivedHome)
{
Serial.println(".");
if(check.isSchool())
{
Serial.println("AT SCHOOL");
warn.arrivedSchoolLoop();
}
else
{
Serial.println("LATE -> SCHOOL");
warn.lateLoop();
}
}
else
{
Serial.println("ON WAY");
}
}
}
Loop นี้จะประมวลผลตำแหน่งของเครื่องเทียบกับเวลาปัจจุบัน เพื่อดูว่าตอนนี้เด็กควรจะอยู่ที่ไหน แล้วสั่งการตามผลลัพธ์ที่ได้
- Do Actions
struct Do
{
void offTrackLoop()
{
if(offTrackVar)
{
parseData(0);
}
vibrateMotor();
ledRed();
delay(1000);
vibrateMotor();
resetLED();
offTrackVar = true;
delay(120000);
}
void lateLoop()
{
if(!lateVar)
{
parseData(1);
}
vibrateMotor();
ledOrange();
delay(1000);
resetLED();
lateVar = true;
}
void arrivedHomeLoop()
{
lateVar = false;
offTrackVar = false;
vibrateMotor();
ledGreen();
delay(1000);
resetLED();
parseData(2);
arrivedHome = true;
arrivedSchool = false;
}
void arrivedSchoolLoop()
{
lateVar = false;
offTrackVar = false;
vibrateMotor();
ledGreen();
delay(1000);
resetLED();
parseData(3);
arrivedHome = false;
arrivedSchool = true;
}
};
Struct ตัวนี้จะถูกเรียกมาใช้งานหลังจากประมวลผลตำแหน่งเสร็จ เพื่อคอยเตือนเด็กด้วย RGB LED และมอเตอร์สั่น รวมถึงส่ง Packet ไปที่ SigFox ถ้าจำเป็นด้วยนะ
- Send Package
void parseData(int state)
{
SigFox.beginPacket(); // เริ่มกระบวนการส่งข้อความ
if(state == 0) // ออกนอกทาง
{
SigFox.print("off track");
}
else if(state == 1) // สาย
{
SigFox.print("late");
}
else if(state == 2) // ถึงบ้าน
{
SigFox.print("at home");
}
else // ถึงโรงเรียน
{
SigFox.print("at school");
}
SigFox.endPacket();
}
ฟังก์ชันนี้จัดการส่งข้อมูลขึ้น SigFox โดยจะเลือกค่าที่เหมาะสมตามสถานะส่งออกไป
การตั้งค่าตัวแปร (Variables) ใน Code จะมีหลายตัวแปรที่มีคอมเมนต์ว่า TODO ต่อท้าย แกต้องแก้ให้ตรงตามความต้องการนะน้อง สิ่งที่ต้องตั้งค่าคือ:
- เวลาเข้าเรียน
- เวลาที่ใช้ในการเดินทาง
- เวลาเลิกเรียน
- จะ Debug หรือเปล่า?
- พิกัดโรงเรียน (LAT, LNG)
- พิกัดบ้าน (LAT, LNG)
ดูตามไกด์ด้านล่างนี้ได้เลย:











Libraries จัดเครดิตให้เค้าหน่อย:
- SigFox - copyright (c) 2016 Arduino LLC
- ctype - copyright (c) 2006 Free Software Foundation
- RTCZero - copyright (c) 2015 Arduino LLC
- String - copyright (c) 2009-10 Hernando Barragan
- TinyGPS++ - copyright (c) 2008-13 Mikal Hart
Setup เช็กให้ชัวร์ว่าต่อวงจรเป๊ะแล้ว สำหรับวิธี Setup MKR fox ไปดูเพิ่มได้ที่ Arduino tutorial นะน้อง ส่วนเรื่อง SigFox library ก็อ่านเพิ่มได้ที่หน้า Reference เลย
Backend Program แกต้องมี Arduino MKR1200 fox ที่ลงทะเบียนแล้วถึงจะเล่น Backend ได้นะ
- Step 1: เข้าไปที่ SigFox backend แล้ว Login ให้เรียบร้อย
- Step 2: เลือก "Device Type" ในเมนูข้างบน

- Step 3: เลือก Board Arduino MKRfox ของแกแล้วกด Edit

- Step 4: เลือกเมนู Callbacks ทางซ้าย แล้วกดปุ่ม "New" ตรงมุมขวาบน

- Step 5: เลือก Custom Callbacks

จากนั้นกรอกฟอร์มตามนี้เพื่อสร้าง Callback:
ตั้ง Type เป็น Data, Uplink ตั้ง Channel เป็น email Custom payload จะเป็นตัวอ่านข้อมูลจาก Board แล้วจัด Format ให้แกต้องประกาศ Variable
strตามด้วย::และชนิดcharกำหนดจำนวนตัวอักษรเป็น10จะได้ประมาณนี้str::char:10ตั้ง Recipient เป็น email ที่จะให้รับข้อมูล ตั้ง Subject ตามใจชอบเลย ในช่อง Message มี Variable สำเร็จรูปให้ใช้เยอะเลย เราจะใช้{device}(ID เครื่อง),{lat}(พิกัดรุ้ง),{lng}(พิกัดแวง) ข้อมูลพวกนี้จะส่งไป SigFox พร้อมกับ 12 bytes payload อัตโนมัติ และอย่าลืมใส่{customData#str}เพื่อดึงข้อความที่เราเขียนไว้จาก Arduino มาโชว์ด้วย พี่จะแถมลิงก์ Google Maps ให้ด้วย จะได้กดดูพิกัดได้ทันที:https://www.google.com/maps/?q={lat},{lng}
สุดท้ายหน้าตาจะประมาณนี้:

กด OK แล้วก็จบงาน!
Final สุดท้ายคือการ Upload code อย่าลืมแก้ตัวแปร "TODO" ให้เรียบร้อยด้วยล่ะ พอไฟสีฟ้าที่ GPS Module กระพริบปุ๊บ ก็ถอดสายจากคอมแล้วใส่ถ่านได้เลย เรียบร้อย!
พี่ออกแบบเคส (Enclosure) ให้มันดูหล่อๆ ด้วยแผ่นอะคริลิค ดัดขอบ 90 องศา เอาวงจรใส่ข้างใน วางรางถ่านไว้ข้างล่าง แล้วรัดด้วย Cable ties ให้แน่นหนา
ตบท้ายด้วยการปิดส่วนบนด้วยวัสดุโปร่งแสงเพื่อซ่อนสายไฟที่รุงรัง ให้เห็นแค่ตัวสมองของโปรเจกต์ก็พอ
Background
พี่เข้าใจเลยว่าการส่งลูกไปโรงเรียนมันลุ้นแค่ไหน ใครๆ ก็ห่วงว่าระหว่างทางจะเกิดอะไรขึ้นบ้าง
โปรเจกต์นี้ตั้งใจทำมาเพื่อช่วยลดความเครียดตรงนี้แหละ SWay จะช่วยให้ทุกคนสบายใจขึ้น เพราะรู้ว่าลูกหลานถึงโรงเรียนอย่างปลอดภัยแน่นอน
EXPANDED TECHNICAL DETAILS
Low-Power LPWAN Logistics Tracker
SmartWay คือโปรเจกต์ติดตามตัวระยะไกลขั้นเทพที่ใช้การเชื่อมต่อแบบ Sigfox เพื่อเฝ้าดูทรัพย์สินหรือบุคคลในพื้นที่ห่างไกลที่ WiFi หรือสัญญาณมือถือเข้าไม่ถึง
- Sigfox Zero-Payload Communication: ตัว Arduino จะส่งข้อความขนาดจิ๋วที่เข้ารหัสพิกัด GPS ไปยังเครือข่าย Sigfox เทคโนโลยี LPWAN แบบนี้ช่วยให้แบตเตอรี่ LiPo ก้อนเล็กๆ ใช้งานได้นานเป็นปีๆ เลยนะน้อง
- Geofencing Alert Logic: (ฟีเจอร์เด็ด) Arduino ถูกโปรแกรมด้วย "รั้วดิจิทัล" (Digital Fence) ถ้าตัวเครื่องข้ามพิกัด GPS ที่กำหนดไว้ปุ๊บ มันจะยิงเตือน "Out of Bounds" ไปที่ Dashboard ของเราทันที
Interaction
- Web Editor validated: ระบบ Radio-handshake ของ Sigfox และวงจรการหลับแบบประหยัดพลังงาน (Sleep Mode) ถูกปรับแต่งผ่าน Arduino Web Editor มาอย่างดี เพื่อให้กินไฟน้อยที่สุดในระดับไมโครแอมป์ (sub-microamp) เลยทีเดียว สู้งานนะน้อง!