กลับไปหน้ารวมไฟล์
smartway-fe4e52.md

Overview

คนเป็นพ่อเป็นแม่น่ะนะ เค้าก็ห่วงลูกหลานเป็นธรรมดา อยากให้ไปโรงเรียนให้ทันเวลา แถมต้องกลับบ้านให้ตรงเส้นทางที่วางไว้ด้วย

เจ้าโปรเจกต์ SmartWay ตัวนี้แหละจะมาช่วยปลดล็อกความกังวลพวกนี้เอง พี่จะพาพวกแกมาทำเครื่องคอยส่อง (Monitor) พิกัดตอนไป-กลับโรงเรียน เพื่อให้มั่นใจว่าเด็กๆ เดินตามเส้นทางที่เหมาะสมเพื่อไปให้ถึงจุดหมายอย่างปลอดภัย

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

SmartWay หล่อเท่เลยงานนี้

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 ด้านล่างได้เลย พี่แยกส่วนการเดินสายไว้หลายรูป จะได้ไม่งง

Schematics (ห้ามต่อช็อตนะตัวนี้)

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" ในเมนูข้างบน
คลิก Device Type เลย
  • Step 3: เลือก Board Arduino MKRfox ของแกแล้วกด Edit
เลือก Board แล้วกด Edit
  • Step 4: เลือกเมนู Callbacks ทางซ้าย แล้วกดปุ่ม "New" ตรงมุมขวาบน
เลือก 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}

สุดท้ายหน้าตาจะประมาณนี้:

Callback Config

กด OK แล้วก็จบงาน!

Final สุดท้ายคือการ Upload code อย่าลืมแก้ตัวแปร "TODO" ให้เรียบร้อยด้วยล่ะ พอไฟสีฟ้าที่ GPS Module กระพริบปุ๊บ ก็ถอดสายจากคอมแล้วใส่ถ่านได้เลย เรียบร้อย!

พี่ออกแบบเคส (Enclosure) ให้มันดูหล่อๆ ด้วยแผ่นอะคริลิค ดัดขอบ 90 องศา เอาวงจรใส่ข้างใน วางรางถ่านไว้ข้างล่าง แล้วรัดด้วย Cable ties ให้แน่นหนา

ตบท้ายด้วยการปิดส่วนบนด้วยวัสดุโปร่งแสงเพื่อซ่อนสายไฟที่รุงรัง ให้เห็นแค่ตัวสมองของโปรเจกต์ก็พอ

Background

พี่เข้าใจเลยว่าการส่งลูกไปโรงเรียนมันลุ้นแค่ไหน ใครๆ ก็ห่วงว่าระหว่างทางจะเกิดอะไรขึ้นบ้าง

โปรเจกต์นี้ตั้งใจทำมาเพื่อช่วยลดความเครียดตรงนี้แหละ SWay จะช่วยให้ทุกคนสบายใจขึ้น เพราะรู้ว่าลูกหลานถึงโรงเรียนอย่างปลอดภัยแน่นอน

SmartWay จัดไปวัยรุ่น

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) เลยทีเดียว สู้งานนะน้อง!

ข้อมูล Frontmatter ดั้งเดิม

title: "SmartWay"
description: "A smarter way to get to school."
author: "andreiflorian"
category: "Internet of Things, BT & Wireless"
tags:
  - "tracking"
  - "security"
  - "internet of things"
views: 13266
likes: 8
price: 699
difficulty: "Intermediate"
components:
  - "1x GPS Module GY-NEO6MV2"
  - "1x Vibrating Motor Cell"
  - "1x Soldering iron (generic)"
  - "1x Ceramic Capacitor 0.1µF"
  - "1x Jumper wires (generic)"
  - "1x 2AA Battery Holder for RTC"
  - "1x Arduino MKR Fox 1200"
  - "1x Resistor 1k ohm"
  - "1x General Purpose Transistor NPN"
  - "1x RGB Diffused Common Cathode"
  - "1x Resistor 221 ohm"
tools: []
apps:
  - "1x Arduino Web Editor"
  - "1x Sigfox"
downloadableFiles:
  - "https://create.arduino.cc/editor/LightPro/13148790-2a42-4281-843a-641a2bfee460"
  - "https://create.arduino.cc/editor/LightPro/13148790-2a42-4281-843a-641a2bfee460"
documentationLinks: []
passwordHash: "9597c862a509143dcc3123945a13485807aee9a6d7c06d1b2e08cd436a38b9dc"
encryptedPayload: "U2FsdGVkX18wW53pY9zw0pCgeb7YqCARDC7ID0GQEwReE/EIkdQbQb7cQmBDuJjy1hogV9zaRHj6hob1J+yQ39uTBj5gZHxRq2GXNL+Hqs5rQw/KxxRXt6Sdnwku83x8"
seoDescription: "SmartWay: A smart Arduino-based project designed to provide a safer and more efficient way for students to get to school."
videoLinks: []
heroImage: "https://cdn.jsdelivr.net/gh/bigboxthailand/arduino-assets@main/images/projects/smartway-fe4e52_cover.JPG"
lang: "th"