การทดลองที่ 6 อ่านค่าอุณหภูมิ DS1820

ในการทดลองนี้เราจะมาเรียนรู้การอ่านค่าอุณหภูมิจากไอซี DS1820 ซึ่งเป็นตัวแปลงอุณหภูมิ ให้เป็นค่าดิจิตอล สำหรับการอ่านค่าอุณหภูมิ ใช้สายสัญญาณเพียง 1 เส้น (1-Wire?) เท่านั้น ถ้ารวม VCC, GND เข้าไปด้วยก็จะมีขาใช้งานเพียง 3 ขาเท่านั้น รูปร่างหน้าตาก็จะคล้ายกับทรานซิสเตอร์ตัวถัง TO-92 จริงๆแล้วมันไม่ใช่แค่เซนเซอร์อุณหภูมิเท่านั้น แต่ยังมี LASERED ROM ขนาด 64 บิตโดย DS1820 ในแต่ละตัวจะมีค่า LASERED ROM ไม่ซ้ำกัน ทำให้สามารถต่อ DS1820 (1-Wire?) หลายๆตัวในสายสัญญาณเส้นเดียวกันได้

ย่านการวัดอุณหภูมิจะอยู่ในช่วง -55 C ถึง +125 C

ยังไม่หมดแค่นั้นครับ ยังมี Alarm Triger TH, TL ไว้คอยเตือนเราด้วยว่าอุณหภูิมิเกิด เกิด range ที่เราต้องการควบคุม

รูปที่ 1 ไอซี DS1820

ในการต่อใช้งานจะมีอยู่ 2 วิธีด้วยกัน

1. ใช้ไฟเลี้ยงจาก R Pull-up (PARASITE POWER) วิธีนี้ขา VDD จะต้องต่อลง GND ทำให้ต่อสายเพียง 2 เส้นเท่านั้น

รูปที่ 2 การต่อแบบใช้ไฟเลี้ยง R Pull-up

2. ต่อไฟเลี้ยงให้กับขา VDD (External power supply) วิธีนี้จะเป็นที่นิยมใช้กันมากกว่า

รูปที่ 3 การต่อแบบจ่ายไฟเลี้ยงให้กับขา VDD

ค่าอุณหภูมิที่อ่านได้จาก DS1820 จะมีความละเอียดสเตปละ 0.5 C ขนาด 9 บิต

ตารางที่ 1 ความสัมพันธ์ระหว่างอุณหภูมิกับค่าที่อ่านได้

การทำงานของ Alarm TH, TL

หลังจากที่ DS1820 ได้ทำการแปลงอุณหภูิมิออกมาเป็นตัวเลขแล้ว ค่าอุณหภูมิก็จะถูกนำไปเปรียบเทียบกับ TH, TL ค่าอุณหภูมิมีขนาด 9 บิต ส่วนค่า TH, TL มีขนาด 8 บิต แล้วจะเปรียบเทียบกันยังไงละ? เฉลยครับ มันก็จะตัดบิต LSB ของ DS1820 ทิ้งไปนั่นเอง หลังจากเปรียบเทียบแล้วค่าอุณหภูมิมากกว่า TH หรือน้อยกว่า TL ค่า Alarm Flag ก็จะถูกเซต เมื่อใดก็ตามที่ Alarm Flag ถูกเซตอยู่ มันก็จะแสดงตัวออกมาให้รู้ในช่วงของคำสั่ง Search command เราจึงเข้าไปอ่าน DS1820 ตัวนั้นได้ทันที โดยไม่ต้องไล่อ่าน DS1820 ทีละตัว

ขั้นตอนการสื่อสารกับ DS1820

Initialization (เริ่มต้นสื่อสาร)

เริ่มแรกการสื่อสารด้วย reset pulse โดยตัวมาสเตอร์(ไมโครคอนโทรลเลอร์)จะส่งสัญญาณไปรีเซต DS1820 จากนั้น DS1820 ก็ตอบกลับด้วย present pulse เสมือนเป็นก่อนบอกว่ามัน “พร้อมแล้ว” ถ้าขั้นตอนนี้ DS1820 ไม่ส่ง present pulse กลับมาก็ให้ยกเลิกการสื่อสารได้เลยครับ

ROM FUNCTION COMMANDS (คำสั่งต่างๆ)

หลังจากที่มาสเตอร์ได้รับสัญญาณตอบกลับ (present pulse) เราก็สามารถส่ง command ต่อไปนี้ไปยัง DS1820 ได้

Read ROM[33h]
Command นี้ใช้อ่านค่า 64 บิต (Lasers ROM) แต่ command นี้จะใช้ได้ก็ต่อเมื่อต่อ DS1820 ไว้ตัวเดียวในเท่านั้น ถ้าขืนต่อหลายๆตัวแล้วใช้ command นี้ DS1820 แต่ละตัวก็จะส่งข้อมูลออกมาชนกัน
Match ROM[55h]
Command นี้แล้วตามด้วย 64 บิต (Lasers ROM) เป็นการที่มาสเตอร์ระบุว่าจะให้ DS1820 ตัวไหนทำงาน จะใช้ก็ต่อเมื่อต่อ DS1820 หลายตัวในสายเส้นเดียวกัน
Skip ROM[CCh]
ถ้าเราต่อ DS1820 เพียงตัวเดียวใน BUS เราก็ไม่ต้องระบุ 64 บิต (Lasers ROM) เราสามารถใช้ command นี้เพื่อลดขั้นตอนในการสื่อสาร
Search ROM[F0h]
เมื่อเริ่มทำการ initial ไปแล้วตัวมาสเตอร์อาจจะยังไม่รู้ว่ามี DS1820 อยู่กี่ตัว command Search ROM ทำให้มาสเตอร์สามารถแยกแยะ DS1820 แต่ละตัวได้้
Write Scratchpad[4Eh]
command นี้ใช้ในการเขียนข้อมูลลง DS1820 เริ่มต้นที่ตำแหน่งของ TH register การเขียนจะสิ้นสุดลงเมื่อไหร่ก็ได้ด้วยการส่งสัญญาณรีเซต
Read Scratchpad[48h]
command นี้ใช้ในการ copy ข้อมูล scratchpad ไปยัง EE memory
Convert T[44h]
เป็น command ที่ใช้ในการเริ่มต้นแปลงค่าอุณหภูมิ
Recall E2[B8h]
command นี้จะอ่านค่า Temperature trigger ที่เก็บไว้ใน EE memory ขึ้นมา
Read Power Supply [B4h]
หลังจากส่ง command นี้ไปแล้ว DS1820 จะส่ง สัญญาณกลับมา ส่ง 0 = parasite power, ส่ง 1 = external power supply

คลิกที่ภาพเพื่อดูขนาดใหญ่

รูปที่ 4 Timming การรีเซต และการตอบกลับ(Presence Pulse) ของ DS1820

unsigned char tempresbit()
{
DQ = 0; ??????????//Bit = 0
delay_600us();

DQ = 1; ??????????//Input
delay_60us();

if (DQ)
return 0;

delay_600us(); ???//Delay 480 uSes minimum
return 1;
}

การเขียนโปรแกรมในส่วนของการรีเซต เริ่มจากให้ DQ = 0 (ดูสัญญาณเส้นสีเขียวประกอบ) แล้วหน่วงเวลาประมาณ 600 uS จึงดึงสัญญาณให้ DQ = 1 ถ้าเป็นไมโครคอนโทรลเลอร์ตระกูล PIC, AVR ต้องกำหนดให้ขาทำงานเป็นอินพุตด้วย ไม่งั้น DS1820 จะไม่สามารถึุงสัญญาณลง 0 ได้ ใน datasheet บอกว่า DS1820 จะปล่อย presence pulse ออกมาในช่วง 60-240 uS ก็เลยหน่วงเวลาไป 60 uS แล้วเช็ค DQ ว่าเป็น 0 หรือยัง(ดูสัญญาณเส้นสีแดงประกอบ) ถ้ายังเป็น 1 อยู่แสดงว่าไม่สามารถติดต่อ DS1820 ได้

* สิ่งสำคัญของการสื่อสารแบบ 1 Wire คือ Time slot ต้องมีค่าเปะๆ ตรงช่วง delay ต่างๆควรจะใช้ timer มาจับเวลา หรือใช้คำสั่ง _nop_() จะช่วยให้คำนวณ delay ได้แม่นยำ

คลิกที่ภาพเพื่อดูขนาดใหญ่

รูปที่ 5 Timming การเขียนข้อมูลจากมาสเตอร์ไปยัง DS1820

//————————————————————
//Write DS1820
//————————————————————

void tempwrbyte (unsigned char dat)
{
unsigned char i;

for (i = 0;i < 8;i++){
DQ = 0; //Bit = 0

_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); ?????????????????????????//Delay 15 uSec

if (dat & 0×01)
DQ = 1;
else
DQ = 0;

delay_60us(); ?????????????????????????????//Delay 60 uSEC
DQ = 1;
dat >>= 1;

_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); //Delay 10 uSEC
}

}

หลังจากที่ได้รับ presence pulse จาก DS1820 ที่นี้เรามาดู Timing การเขียนข้อมูลไปยัง DS1820 กันนะครับ เริ่มแรกเลยเราดึงสัญญาณให้เป็น 0 ประมาณ 15 uS จากนั้นก็ส่ง logic ที่ต้องการออกมา ในช่วงหลังจากนี้ ภายใน 45 uS DS1820 จะเข้ามาอ่านสัญญาณ ผมเลย delay 60 uS (จริงๆจะ 45 uS เป๊ะๆก็ได้นะ) เพื่อไม่เห็นการทำงานเร็วเกินไปจึงมีการ delay ที่ช่วงเป็น logic มีการเปลี่ยนแปลง

คลิกที่ภาพเพื่อดูขนาดใหญ่

รูปที่ 6 Timming การอ่านข้อมูล

//————————————————————
//Read DS1820
//————————————————————
unsigned char temprdbyte (void){
unsigned char dat,i;

for (i = 0;i < 8;i++)
{
dat >>= 1;
DQ = 0; //Bit = 0

_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
_nop_(); _nop_(); //Delay 15 uSec

DQ = 1;
if (DQ)
dat |= 0×80; //Input = 1
else
dat &= 0x7f; //Input = 0;

delay_30us(); //Delay 60 uSEC
_nop_(); _nop_();

}
return dat;
}

สำหรับการอ่านข้อมูลก็ไม่ยากครับ เราก็ดึง DQ ลง 0 แล้วก็ปิดตานับเลขในใจไป 15 uS พอลืมตาขึ้นมามองเห็น DQ เป็น logic อะไรก็นำไปเก็บไว้ แล้วก็เอาข้อมูล 8 บิตมาเรียงกันก็จะได้ค่าออกมา

//————————————————————
//Read Temperature DS1820
//————————————————————

unsigned int rdtemp(void)
{
unsigned int dat;

if (tempresbit()){
tempwrbyte(0xcc); //Skip ROM
tempwrbyte(0×44); //Temperature Convert
dmsec(500);
tempresbit();
tempwrbyte(0xcc); //Skip ROM
tempwrbyte(0xbe); //Read scratchpad

dat = temprdbyte()*5;
return dat;
}

return 0;
}

มาถึงขั้นตอนสุดท้าย คือการอ่านค่าอุณหภูมิ จากตารางที่ 1 จะเห็นว่าข้อมูลจะมีขนาด 2 ไบต์โดยไบต์แรกจะเป็นอุณหภูมิที่อ่านได้ อีกไบต์นึงจะเป็นเครื่องหมาย เราจึงอ่านข้อมูลมาไบต์เดียวก็ได้ อุณหภูมิที่แท้จริงที่ได้จากฟังก์ชัน temprdbyte() จะต้องถูกหารด้วย 2 (เพราะ Step ละ 0.5 C) จึงจะเป็นอุณหภูมิที่แท้จริง เพื่อเป็นการเลี่ยงไม่ให้เกิดทศนิยมผมจึงเอาไปคูณด้วย 5 แทน จากนั้นจึงตัดเอาตัวเลขในแต่ละหลักไปแสดงผลที่ LCD

รูปที่ 7 วงจรที่ใช้ในการทดลอง

รูปที่ 8 การทดลอง

บทสรุป

สำหรับผมแล้วนะ DS1820 มีจุดเด่นตรงเรื่องขนาดเราสามารถ wire สายจากบอร์ดเพียง 2 หรือ 3 เส้นลากสายได้ยาวเกือบเมตร(จากการใช้งานจริง) แถมยังต่อขนานพ่วงกันได้หลายตัว ทำให้สามารถวัดอุณหภูมิได้หลายๆตำแหน่ง แต่ข้อเสียก็คือ 1-Wire เป็นการสื่อสารแบบ Time Stot คือเวลาต้องเปะๆ ระหว่างการอ่าน/เขียน ไม่สามารถกระโดดไปอินเตอร์รัพได้เลย ต่างจากพวก SPI, I2C ซึ่งระหว่างสื่อสารสามารถกระโดดไปอินเตอร์รัพและกลับมาอ่าน/เขียน บิตที่ยังค้างอยู่ได้ และไมโครคอนโทรลเลอร์บางตระกูลก็มีโมดูล SPI, I2C อยู่ในตัวเลยจึงทำให้การสื่อสารแบบ SPI, I2C ง่ายและยืดหยุ่นกว่า

Download Code การทดลองที่ 6

เขียนโปรแกรมไมโครคอนโทรลเลอร์ด้วยภาษา C

จากประสบการณ์ที่ผ่านมาการเขียนโปรแกรมให้ไมโครคอนโทรลเลอร์ด้วยภาษาแอสเซมบลีมีการทำงานที่รวดเร็วดี แต่กว่าจะเขียนได้แต่ละโปรแกรมนั้นใช้เวลามาก อีกทั้งยังไม่สามารถเขียนภาษาแอสเซมบลีในระบบใหญ่ๆได้อีกด้วย เพราะมันจะยุ่งยาก เมื่อลองศึกษาดูแล้วมีโปรแกรมที่ช่วยแปลงภาษา C เป็น HEX code ได้เลย โปรแกรมที่ว่านี้คือ KEIL C51 ซึ่งสามารถดาวน์โหลดได้ที่ http://www.keil.com เป็นเวอร์ชั่นทดลองใช้ หลายคนสงสัยว่าจะทำไงถึงจะแปลงภาษา C เป็น HEX code ได้ เอาละมาลองเขียนกันเลยดีกว่าครับ

สร้างโปรเจค

  • เปิดโปรแกรม u Vision2, สร้างไฟล์โปรเจคและเลือก CPU ที่จะใช้จาก device database
  • เขียน source code และเพิ่มเข้าไปใน source file ของโปรเจค
  • ตั้งค่า tool option สำหรับฮาร์ดแวร์ปลายทาง
  • สร้างโปรเจคและ HEX ไฟล์สำหรับ PROM

อ่านดูอาจจะงงลองมาทำ step-by-step ดีกว่าครับผมจะบอกขั้นตอนอย่างละเอียด

เปิด u Vision2 และ สร้างไฟล์โปรเจค

เมื่อเปิดโปรแกรมมาแล้วถ้าต้องการสร้างโปรเจคให้คลิกที่เมนู Project – New Project… มันจะมีหน้าต่างถามชื่อโปรเจค ตัวอย่างนี้จะตั้งชื่อว่า test.uv2 ซึ่งคุณอาจจะตั้งชื่ออื่นก็ได้ เมื่อ OK ไปแล้วจะมีหน้าต่าง Select Device for Target ให้คุณเลือก CPU สำหรับโปรเจคของคุณ ในตัวอย่างนี้ผมเลือก Atmel – 89C51

รูปที่ 1 Select device

รูปภาพทางขวามือด้านล่างจะมี File,Regs,Books เราเรียกว่า Project Window คุณสามารถดูคู่มือ CPU ได้จากหน้าต่าง Project Windows – Books

เขียนโปรแกรม

คุณสามารถสร้างโปรแกรมขึ้นใหมได้โดยคลิกที่เมนู File – New หลังจากนั้นจะมีหน้าต่างว่างๆ ไว้ให้คุณพิมพ์โปรแกรมภาษา C ใส่ลงไป โปรแกรม u Vision จะมีสีบ่งบอกคำสั่งในโปรแกรม เมื่อต้องการ save โปรแกรม ให้ไปที่ File – Save As… ไฟล์ที่บันทึกจะมีนามสกุลเป็น *.C. สมมติผมตั้งชื่อว่า main.c จะได้

รูปที่ 2 หน้าต่างเขียน code

หลังจากนั้นให้เราเอา source file ใส่ลงไปในโปรเจค ให้คุณเข้าไปคลิกที่เครื่องหมาย + หน้า Target 1 ในหน้าต่าง Project window – Files มันจะแตกย่อยออกมาเป็น Source Group 1 ให้คลิกขวาที่ตรงนี้ แล้วเลือก Add Files to Group ‘Source Group 1′ เลือก main.c ที่คุณเพิ่งสร้างไป

รูปที่ 3 Project window

สร้าง Startup Code

ไฟล์ STARTUP.A51 เป็นไฟล์ Startup Code สำหรับ CPU ตระกูล 8051 ไฟล์นี้มีไว้สำหรับเคลียร์หน่วยความจำต่างๆ และตั้งค่าเริ่มต้น (Initial) ให้กับฮาร์ดแวร์ ไฟล์ STARTUP.A51 จะอยู่ที่โฟลเดอร์ C:\KEIL\C51\LIB

เพื่อป้องกันข้อผิดพลาดจากข้อมูลที่ค้างอยู่ใน CPU เราควรจะใส่ตัว Startup ไว้ด้วย ขั้นตอนมีดังนี้ ให้คุณไปที่ Project Window – File แล้วคลิกขวาที่ main.c เลือก Targets,Groups,Files… แล้วพิมพ์ System Files ในหน้าต่าง Groups/Add File แล้วกด Add จากนั้นเลิอกที่ System Files แล้วกด Add Files to Group เลือก STARTUP.A51

??

รูปที่ 4 Start up code

การตั้งค่าอุปกรณ์ต่างๆ

u Vision 2 ให้คุณได้สามารถตั้งค่าฮารด์แวร์ปลายทางได้โดยคลิกที่ปุ่ม Options for Target คุณสามารถตั้งค่าหน่วยความจำได้ใหม่

รูปที่ 5 Options for Target

สร้างโปรเจคและ HEX ไฟล์

มาถึงขั้นตอนสุดท้ายแล้วครับ ให้เช็คดูว่าโปรแกรมถูกต้องหรือเปล่าจากนั้นให้กดปุ่ม Build Target ถ้าไม่มีอะไรผิดพลาดก็จะปรากฎหน้าต่างแบบนี้ขึ้นมาแสดงว่าโปรเจคที่เราสร้างมาใช้ได้แล้ว ให้ทดสอบดูโดยการ Simulate ดูว่าทำงานถูกต้องหรือเปล่า

รูปที่ 6 หน้าต่าง Output

ถ้าต้องการ HEX ไฟล์ไปใช้งานให้กด Option for Target – Output แล้วคลิกที่ Create HEX file แล้วกดที่ Build Target อีกทีคุณจะได้ HEX ไฟล์ไปโปรแกรมลง microcontroller ตัว HEX ไฟล์นี้จะอยู่ในโฟลเดอร์ที่คุณเซฟ ลองทำดูนะครับ

นาฬิกา DotMatrix

เมื่อประมาณ 2 ปีที่ผ่านมา (ปี 2005) จะเห็นแผง DotMatrix ขายอยู่เกลื่อนบ้านหม้อสนนราคาตั้งแต่ 150 บาทจนถึง 400 บาท แล้วแต่ใครจะโชคดีเจอราคาถูก ครั้งแรกผมเห็นว่ามันน่าสนใจดีมี driver มาให้เรียบร้อยแล้ว เพียงต่อเข้าไมโครคอนโทรลเลอร์แล้วเขียนโปรแกรมก็ใช้ได้

พอซื้อกลับมาบ้านก็พลิกดูหารายละเอียดว่าจะต่อตรงไหนยังไง เห็น screen ไว้ที่ PCB ว่า ALPHA DEVICE CO.,LTD AD-501-B ลองหาข้อมูลไอซีตัวที่เป็น driver เบอร์ LC7932M

รูปที่ 1 ตำแหน่งขา LC7932

download datasheet LC7932

จากนั้นก็นั่งไล่ขาเอาว่าขาไหนไฟเลี้ยง ขาไหนจ่ายไฟ

รูปที่ 2 ตำแหน่งขาของบอร์ด DotMatrix

ตอนแรกก็เอามาต่อเล่นกับบอร์ดตัวอื่นไปก่อน ทำไปทำมาชักสนุกเลยทำ PCB ขึ้นมาเอง เอามาใส่กล่องให้มันสวย

รูปที่ 3 ประกอบลงกล่อง

รูปที่ 4 วงจร (คลิกเพื่อดูภาพขยาย)

หลักการสแกน Dotmatrix

รูปที่ 6 หลักการสแกน

อุปกรณ์แสดงผลพวก LED Dot Matrix เป็นอุปกรณ์แสดงผลที่ประกอบด้วย LED เอามาเรียงต่อกัน ถ้าเกิดทุกดวงติดพร้อมกันคงจะกินไฟมาก แล้วก็ภาค drive LED ก็จะมีขนาดใหญ่ แล้วก็จะสิ้นเปลืองมาก ทีนี้ก็เค้าเลยใช้การสแกน โดยการให้มันติดทีละ ROW แล้วสแกนความความถี่สูงที่ตาคนเราแยกไม่ออกว่ามันสแกน อย่างพวกโทรทัศน์, จอคอมพิวเตอร์ CRT พวกนี้ก็ใช้การสแกน ลองเอาพวกกล้องดิจิตอลหรือกล้องวีดีโอไปถ่ายดูจะเห็นจอมันกระพริบชัดเจน

อย่างรูปที่ 6 จะให้ ROW1 ติดที่เหลือดับจากนั้นให้ ROW2 ติด ที่เหลือดับ เป็นอย่างนี้เรื่อยๆจนถึง ROW8 แล้วจึงวนกลับมาที่ ROW1

การทดลอง

พอทำ PCB เสร็จแล้วเลยลองเอามาเขียนโปรแกรมง่ายๆ สุดท้ายก็หนีไม่พ้นนาฬิกาครับ โดยผมจะใช้ RTC เจ้าเก่า เบอร์ DS1307 เป็นฐานเวลา ทีนี้ต้องสแกน Dot matrix ไปด้วยอ่านค่า RTC ไปด้วยเห็นทีจะกระตุกแย่ ถ้าจะปล่อยให้ display ส่งแบบ interrupt ก็อาจจะไม่เร็วพอ ผมเลยตั้ง Timer มา 1 ตัวโดยให้ฐานเวลา Timer เป็น 30 วินาที เพื่อไว้กระพริบ “:” ทุก 30 วินาที ทีนี้เมื่อเวลาผ่านไป 1 นาทีผมก็ให้อ่านค่า RTC 1 ครั้งยังไงมันก็ต้องมีการเปลี่ยนแปลงค่าทุก 1 นาที

การตั้งเวลา

ตั้งชั่วโมงให้เลื่อน DIPSW ที่ต่อกับ P2.7 ขึ้นและลง

ตั้งนาทีให้เลื่อน DIPSW ที่ต่อกับ P2.6 ขึ้นและลง

การทดลองนี้เราก็ได้รู้้ถึงการเขียนโปรแกรมสแกนไปแล้ว แต่การทดลองนี้ยังเป็นตัวเลขที่ไม่เคลื่อนที่ การทดลองหน้าจะเป็นการทำไฟวิ่งแบบตัวอักษร ติดตามตอนต่อไปครับ

ป.ล. ถ้า LED มีไฟติดเป็นตัวเลข แต่ดูเลอะๆ ให้ลองเอา C 150pF คร่อม STR กับ GND ดูครับ

Download Code DotClock