ตรวจสอบอุณหภูมิผ่าน Browser
 |
ในอดีตการติดต่อสื่อสารระหว่างอุปกรณ์ภายนอกที่อยู่ห่างกันมากๆ นิยมใช้ RS-485 หรือ RS-422 ซื่งเป็นการติดต่อสื่อสารแบบ Pear to Pear แต่ในโครงการนี้เราจะเปลี่ยนรูปแบบการสื่อสารไปใช้ CAN (Controller Area Network) ในสื่อสารระหว่างอุปกรณ์ 2 ตัวแทน ข้อดีของการติดต่อสื่อสารแบบ CAN สามารถติดต่อสื่อสารกันแบบ Multicast ได้คือสามารถติดต่อกันได้หลายจุดพร้อมกันและมีความทนทานต่อสัญญาณรบกวนได้สูง
โครงการนี้จะเป็นการทดสอบการสื่อสารผ่าน CAN โดยจำลองการส่งอุณหภูมิจากหลายๆ จุด มายัง SNAP และ โดยสามารถตรวจสอบ อุณหภูมิ ในจุดต่างๆ ผ่าน Browser |
อุปกรณ์ในการทดลอง
- SNAP board และ Baseboard
- Temperature Board
|
 |
ความรู้เบื้องต้นของโครงงาน
| เมื่อเราจะวัดอุณหภูมิดังนั้นเราก็ต้องหา Censor ก่อน ตัวที่นิยมกันในท้องตลาดก็เห็นจะไม่พ้น DS1820 [1?WireTM Digital Thermometer](ดูตอนแรกก็นึกว่าเป็น Transister) งั้นเรามาทำความรู้จักกับ DS1820 กันเสียเล็กน้อย |
Features.
- Unique 1?WireTM interface requires only one port pin for communication
- Multidrop capability simplifies distributed temperature sensing applications
- Measures temperatures from ?55oC to +125oC in 0.5oC increments.
- Temperature is read as a 9?bit digital value.
- Converts temperature to digital word in 200 ms
|
 |
| เมื่อได้ Censor แล้วก็ต้องการ CPU สักตัวที่้ต้องมี CAN Controller(เน้นมากๆ) ดังนั้นในตัวอย่างนี้ ผมจะเลือกใช้ 18F258 ของ Microchip ซึ่งหาซื้อได้ง่ายในตลาดบ้านเรา เพื่อใช้ในการอ่านอุณหภูมิจาก DS1820 และ 7'Segment board ซึ่งเป็น I2C เืืพื่อแสดงค่าของอุณหภูมิ |
Features.
- 4 MHz-10 MHz oscillator/clock input with PLL active
- Memory FLASH: 32 Kbytes, SRAM: 1536 Bytes, EEPROM: 256 Bytes
- Master Synchronous Serial Port (MSSP) with two modes of operation:
- - 3-wire SPITM (Supports all 4 SPI modes)
- - I2C Master and Slave mode
- CAN 2.0B Active Spec with:
- - Message bit rates up to 1 Mbps
- - 29-bit Identifier Fields
- - 8-byte message length
- - 3 Transmit Message Buffers with prioritization
- - 2 Receive Message Buffers
- - Advanced Error Management Features
- 10-bit, up to 8-channel Analog-to-Digital Converter module (A/D) with:
- - Conversion available during Sleep
- - Up to 8 channels available
|
 |
| ตัวสุดท้ายที่เราต้องศึกษาคือ CAN Transceivers ซึงเป็นตัวกลางระหว่าง PIC 18F258 กับ คู่สายที่ใช้งานจริง ในที่นี้เราเืลือกใช้ MAX3050 เป็นตัวกลางในการติดต่อสื่อสารบนโครงข่าย CAN
|
Features.
- Four Operating Modes
- - High-Speed Operation Up to 2Mbps
- - Slope-Control Mode to Reduce EMI (40Kbps to 50Kbps)
- - Standby Mode
- - Low-Current Shutdown Mode
- Automatic Wake-Up from Shutdown
- Thermal Shutdown
- Current Limiting
- Fully Compatible with the ISO 11898 Statndard
|
 |
หลักการทำงาน
เราจะแบ่งการทำงานโครงการนี้เป็น 3 ส่วน ดังนี้
- Temperature Reader ซึ่งประกอบไปด้วย 18F258, DS1820, และ MAX3050 ซึ่งจะทำหน้าที่อ่านอุณหภูมิทุกๆ 1 วินาที โดยการติดต่อสื่อสารระหว่าง 18F258 กับ DS1820 ใช้การสื่อสารแบบ One's Wire (รูปแบบการสื่อแบบอนุกรมรูปแบบหนึ่งโดยมีใช้สายสัญญาณเพียงเส้นเดียว) โดยที่ DS1820 จะสามารถจับอุณภูมิได้ระหว่าง -50 oC ถึง 250 oC และ ส่งผ่านอุณหภูมิที่อ่านได้ไปที่ SNAP อีกครั้งหนึงผ่าน การสื่อสารแบบ CAN
- SNAP board กับ Temperaturn Reader ใช้รูปการสื่อสารแบบ CAN การที่เราเลือกใช้การสื่อสารแบบ CAN เนื่องมาจากคุณสมบัติของ CAN ที่สามารถต่อต่อสื่อสารได้พร้อมๆกันหลายๆจุดพร้อมๆ กัน (Mulitcaste) ทำให้เราสามารถทราบอุณภฺมิที่เปลี่ยนแปลงได้เร็วกว่า การสื่อสารแบบ Polling เนื่องจากเืืมื่อมีการเปลี่ยนแปลงของอุณหภูมิก็จะสามารถส่งผ่านเข้ามาที่ SANP ได้โดยทันที ไม่ต้องรอให้ SNAP ร้องขอในรูปแบบของ Polling เนื่องจาก Temperature Reader สามารถส่งข้อมูลได้พร้อมๆ กันทำให้เราต้องตั้งหมายเลขเครื่องของ Reader และ SNAP เพื่อจะได้ทราบว่ามีการส่งอุณหภูมิมาจาก Reader ตัวไหน และ Reader จะได้รู้ว่าจะต้องส่งข้อมูลไปที่ SNAP ตัวไหน ในที่นี้เรากำหนดให้ SNAP มี ID = 0x550 และ Reader มี ID = 0x350 และ 0x351 ตามลำดับ
- ใช้ Browser เป็นตัวแสดงผล โดย SNAP ทำหน้าที่เป็น Webserver จะทำหน้าทีี่แสดงผลของ อุณหภูิมิของ Reader แต่ละตัวให้กับ User ผ่าน Browser.
|
|
รายละเิีีอียดของโครงงาน
โครงงานนี้จะแบ่งโปรแกรมเป็น 2 ส่วนใหญ่ๆ คือ
- โปรแกรมของ Temperature Reader
- โปรแกรมของ SNAP board
|
| โปรแกรม Temperature Reader ซึ่งจะีมีอยู่ 2 ไฟล์คือ Temperature.c และ Temperature2.c ซึงจะีมี ID เท่ากับ 0x350 และ 0x351 ตามลำดับ ซึ่งในส่วนการทำงานผมไม่ขออธิบายในที่้นี้นะครับ เพราะคิดว่าท่านผู้ใช้งานคงจะสามารถทำความเข้าใจกับ Source code ได้เอง
|
โปรแกรมของ SNAP board ซึ่งมีอยู่ 5 ไฟล์ด้วยกัน ดังต่อไปนี้
- TempReader.java มีหน้าที่รับข้อมูลอุณหภูมิ ที่ส่งมาจาก Temperatrue Reader ผ่านทาง Port Canbus ซึ่งจะถูกส่งมาให้ทุกๆ หนึ่งวินาที โดยเริ่มการจาก
o การ Implement TempReader class จาก CANEventListenner
| public class TempReader implements CANEventListener
|
o กำหนดคุณสมบัติของ CAN Controller บน SNAP board เช่นอัตราความเร็ว รูปแบบการรับส่งข้อมูล
public boolean init() {
boolean canOpen = false;
boolean canEnabled = false;
try {
cp= new CAN();
canOpen = true;
cf= new CANFrame();//create a CAN fream
cp.setSampleRate(3);//single sample point at 85%, 20 clocks per bit
cp.setTSEG1(4);
cp.setTSEG2(3);
cp.setSynchronizationJumpWidth(1);
cp.setBaudRatePrescaler(BRP);
cp.set29BitGlobalIDMask(COM_TO_CAN_ID ^ CAN_SUBMASK);
cp.set29BitGlobalArbitrationID(COM_TO_CAN_ID);
cp.addEventListener(this);
cp.writeRegister(cp.REG_IER,(byte)(cp.readRegister(cp.REG_IER)|CAN.IER_DOIE));
cp.enableController();
canEnabled= true;
}catch (CANException e) {
.......
.......
}
.......
.......
}
|
o ตรวจสอบข้อมูลบน สายสัญญาณ ว่าเป็นข้อมูลที่ส่งมาจาก Reader 0x350 หรือ ว่า Reader 0x351 ว่าถูกต้องตามข้อกำหนดหรือเปล่า และ เป็นข้อมูลที่ต้องการส่งมาให้ SNAP (0x550) หรือเปล่า ถ้าใช้ก็ให้ Unpack ข้อมูลและนำไปเก็บไว้ในตัวแปลสำหรับเก็บข้อมูลของแต่ละ Reader ต่อไป
public void CANEvent(int event) {
// TODO Auto-generated method stub
try {
if ((event & CAN.IR_RI) != 0){
while (cp.receivePoll(cf)){
if (!cf.extendedID && (cf.ID == COM_TO_CAN_ID)){
cf.ID = CAN_TO_COM_ID2;
cp.sendFrame(cf);
}else{//if (!cf.extenedID && (cf.ID == COM_TO_CAN_ID));
//cf.ID = 0x550
if (cf.extendedID && (cf.ID == CAN_TO_COM_ID1)){// Reader 0x350
String datacan = new String(cf.data);
datacan.trim();
Temperature1= datacan.substring(2);
}//if (cf.extendedID && (cf.ID == COM_TO_CAN_ID));
if (cf.extendedID && (cf.ID == CAN_TO_COM_ID2)){//Reader 0x351
String datacan = new String(cf.data);
datacan.trim();
Temperature2= datacan.substring(2);
}//if (cf.extendedID && (cf.ID == CAN_TO_COM_ID2));
}//if (!cf.extendedID && (cf.ID == COM_TO_CAN_ID));
}//while(cp.receivePoll(cf));
}//if ((event & CAN.IR_RI) != 0);
}catch (CANException e){
......
}
}
|
- ThreadCan.java เราต้องการมีการรับข้อมูลจาก Reader ตลอดเวลา เราจึงจะสร้างให้ TempReader ทำงานในสภาวะของ Thread จะสะดวกและควบคุมการทำงานได้ดีกว่าดังตัวอย่าง
class ThreadCan implements Runnable {
TempReader app = new TempReader();
public void run() {
// TODO Auto-generated method stub
if (app.init()){
app.readTempViaCAN();
}//if (app.init());
}
}
|
- ShowTempCgi.java สร้างหน้าจอแสดงผลของการอ่านค่าอุณหภูมิของ Reader ทั้งสอง ให้แสดงข้อมูลบน Browser
public class ShowTempCgi implements HttpCgi {
public ShowTempCgi(){
}
public String getName(){
return("show.cgi");
}
public void execute(Hashtable variables, OutputStream os) throws IOException, HttpException{
String s;
s = "Content-Type: text/html\r\n\r\n\r\n";
s += "<HTML><TITLE>Result for Temperature.</TITLE>\n";
s += "<BODY>\n";
s += "<H1>Temperature Reader(0x350)= "+TempReader.Temperature1+"</H1><br>\n";
s += "<H1>Temperature Reader(0x351)= "+TempReader.Temperature2 +"</H1><br>\n";
s += "</BODY></HTML>\n";
os.write(s.getBytes());
}
}
|
- ShowTempOnWeb.java เป็น Main โปรแกรม 2 Thread ด้วยกัน คือ CAN Thread และ HTTPServer Thread ซึ่ง CAN Thread ใช้สำหรับการรับข้อมูลจาก Temparature Reader ซึ่งจะถูกส่งมาทุกๆ 1 วินาที ส่วน HTTPServer Thread จะให้บริการเี่ี่กี่ยวกับการแสดงผลของข้อมูล อุณหภูมิทั้ง 2 Reader เมื่อมีการร้องข้อมาจาก Browser เืมื่อมีการร้องขอเข้ามา
public static void main(String[] args) {
ThreadCan can = new ThreadCan();
Thread c = new Thread(can);
c.start();
HttpServer hs = new HttpServer();
Thread t = new Thread(hs);
hs.addCgi(new ShowTempCgi());
t.start();
}
|
- index.htm. เป็น Form ที่แสดงผลที่หน้าจอของ Browser และ รอรับการกด Key Test เพื่อจะ submit ส่งผลไปยัง show.cgi เพื่อแสดงผลของ อุณหภูมิของทั้ง 2 Readers. จุุุดสำคัญอยู่ที่ Form Action ดังตัวอย่างข้างล่าง
|
<FORM ACTION="/cgi-bin/show.cgi" METHOD="POST">
|
หมายเหตุ การเรียกชื่อของ CGI จะต้องเหมือนกัน กับ ชื่อที่ประกาศไว้ใน Function getName() ใน Class ของ ShowTempCgi เสมอ
|
ลำดับขั้นการทดลอง
- Upload แฟ้ม TempReader.class, ThreadCan.class, ShowTempCgi.class และ ShowTempOnWeb.class เข้าไปใน Subdirectory /classes
- สร้าง Subdirectory /html ด้วยคำสั่ง mkdir html
- Upload Subdirectory html ทั้งหมดเข้าไปยัง Subdirectory /html
- Upload แฟ้ม index.html เข้าไปที่ Subdirectory /html
- Login เข้าไปยัง SNAP จากนั้นให้เข้าไปที่ /classes Execute ShowTempOnWeb.class ด้วยคำสั่ง java -r ShowTempOnWeb
- เปิด Browser พิมพ์ http://IP Address of SNAP/ ที่ช่อง Address จะปรากฏหน้าจอดังรูปข้างล่าง
|
 |
- ให้กดปุ่ม Test ซึ่งจะแสดงผลลัพท์ตามรูปข้างล่าง
|
 |
|