7:23 PM
0
1. แนะนำไอซีเบอร์ DS1820

ไอซีดิจิตอลเบอร์ DS1820 เป็นเซนเซอร์วัดอุณหภูมิที่มีข้อมูลขนาด 9 บิตเพื่อแสดงค่าอุณหภูมิของไอซี สามารถเชื่อมต่อกับไมโครคอนโทรลเลอร์ผ่านมาตรฐานการเชื่อมต่อแบบ 1-wireTM ซึ่งใช้สายในการเชื่อมต่อข้อมูลเพียงเส้นเดียวร่วมกับกราวด์และไฟเลี้ยง สามารถอ่าน เขียน และแปลงค่าอุณหภูมิโดยใช้คำสั่งผ่านสายเส้นเดียวกันกับข้อมูลได้โดยไม่จำเป็นต้องใช้ไฟเลี้ยงจากภายนอก


เนื่องจากไอซี DS1820 ที่ผลิตออกแต่ละตัวมีเลขประจำตัวเฉพาะ ทำให้สามารถเชื่อมต่อบนสายข้อมูลเส้นเดียวกันได้หลายตัว ทำให้สามารถนำไปประยุกต์ใช้ในงานด้านการตรวจวัดในบริเวณต่างๆ ได้อย่างหลากหลาย อาทิเช่น ในงานด้านการควบคุมความร้อน การระบายอากาศ ระบบปรับอากาศ เซนเซอร์วัดอุณหภูมิภายในอาคาร ติดตั้งกับเครื่องจักรกล และในกระบวนการที่มีการตรวจสอบอุณหภูมิตลอดเวลา เป็นต้น

รูปที่ 1 การจัดเรียงขาของไอซีตรวจวัดอุณหภูมิเบอร์ DS1820

 2. วงจรการเชื่อมต่อกับไมโครคอนโทรลเลอร์

การเชื่อมต่อจะใช้สายข้อมูลเพียงเส้นเดียวต่อเข้ากับ พอร์ตอินพุตเอาท์พุทของไมโครคอนโทรลเลอร์ดังแสดงในรูปที่ 2

รูปที่ 2 การเชื่อมต่อไอซีตรวจวัดอุณหภูมิเบอร์ DS1820 กับไมโครคอนโทรลเลอร์ตระกูล AVR เบอร์ATtiny2313

3. การพัฒนาโปรแกรม
          ในส่วนนี้เป็นการอธิบายขั้นตอนการพัฒนาโปรแกรมเพื่ออ่านและเขียนค่า สำหรับเชื่อมต่อไมโครคอนโทรลเลอร์ตระกูล AVR กับเซนเซอร์ตรวจวัดอุณหภูมิ โดยไม่กล่าวถึงขั้นตอนการพัฒนาโปรแกรมที่เป็นพื้นฐาน สำหรับการแสดงผลของอุณหภูมิที่วัดได้นั้น จะแสดงผ่านหน้าจอเทอร์มินอลมอนิเตอร์ ซึ่งเป็น ส่วนเพิ่มขยายของ Atmel Studio 6.0 เบื้องต้นจะกล่าวถึงการเชื่อมต่อในกรณีที่มีเซนเซอร์ต่ออยู่กับสายข้อมูลเพียงเส้นเดียวก่อนเท่านั้น

3.1 การจัดการเรื่องเวลา
          เนื่องจากการเชื่อมต่อกับเซนเซอร์ใช้เพียงสายเส้นเดียว จึงจำเป็นอย่างยิ่งที่ต้องทำให้ช่วงจังหวะเวลาในการอ่านหรือเขียนค่านั้นมีความแม่นยำ โดยในแต่ละช่วงเวลาอ่านเขียนนั้น จะมีการอธิบายอย่างชัดเจนในเอกสารอธิบายข้อมูลของไอซี และพบว่าต้องมีความแม่นยำในระดับไมโครวินาทีเลยทีเดียว ซึ่งมีค่าน้อยมากเลยทีเดียว ดังนั้นจึงจำเป็นต้องเข้าใจในระดับหนึ่งเรื่องฐานเวลาเพื่อนำมาจัดการให้ได้ช่วงเวลาที่ต้องการอย่างแม่นยำ
          สำหรับ Atmel Studio 6.0 มีการเตรียมไลบรารีเรื่องหน่วงเวลา ซึ่งสามารถนำมาใช้ได้เลยคือ delay.h โดยภายในจะมีฟังก์ชันการหน่วงเวลาที่มีความแม่นยำในระดับ ไมโครวินาที (_delay_us()) และ มิลลิวินาที (_delay_ms()) ไว้ให้ใช้งาน แต่ต้องมีการเพิ่มเข้ามาในส่วนเริ่มต้นของโปรแกรม และกำหนดความถี่เริ่มต้นของระบบที่นำมาใช้ ก่อนที่จะเรียกใช้งาน ดังนี้

#define F_CPU 12000000UL          //define CPU clock
#include <util/delay.h>           //include delay library

ทั้งนี้ ต้องกำหนดตัวแปร F_CPU ก่อนเป็นอันดับแรกเพื่อให้ได้ฐานเวลาที่ตรงกับผู้ใช้งานจริง โดยในที่นี้กำหนดความถี่ที่ใช้เป็น 12MHz แต่ถ้าผู้เขียนโปรแกรมไม่มีการกำหนดค่าดังกล่าวนี้ ไลบรารีจะกำหนดเองซึ่งจะมีค่าปกติเท่ากับ 1MHz และสามารถเรียกใช้งานได้ดังนี้ เมื่อต้องการหน่วงเวลา 480 ไมโครวินาที

_delay_us(480);      // if we want to make 480 us delay

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


รูปที่ 3 แผนผังเวลาสำหรับกระบวนการเริ่มต้นรับส่งข้อมูล

จากรูปที่ 3 พบว่ามาสเตอร์ส่งค่าเพื่อทำให้สายข้อมูลมีค่าเป็นศูนย์เป็นระยะเวลาอย่างน้อย 480 ไมโครวินาที และตามด้วยการคืนค่าสายข้อมูล ถัดจากนั้น 15-60 ไมโครวินาที ตัวอุปกรณ์ที่เป็นไอซีตรวจวัดอุณหภูมิก็จะทำให้สายข้อมูลมีค่าเป็นศูนย์เป็นเวลา 60-240 ไมโครวินาที ซึ่งเรียกว่าพัลส์ตอบสนอง โดยในส่วนหลังนี้ก็ใช้เวลา 480 ไมโครวินาที เช่นกัน เมื่อใช้ PORTD PIND6 จะสามารถนำมาเขียนเป็นโปรแกรมได้ดังนี้

uint8_t reset()                                
{
       uint8_t i;
       PORTD &= ~(1 << PIND6);    //Pull line low and wait for 480 us
       DDRD |= (1<<PIND6);
       _delay_us(480);                         
      
       DDRD &= ~(1 << PIND6);     //Release line and wait for 60us
       _delay_us(60);
      
i = (PORTD &(1<<PIND6));   //Store line value and wait until the //completion of 480us period
       _delay_us(420);
      
return i;                  //Return the value read from the //presence pulse (0 is OK & 1 is WRONG)
}

3.3 การเขียนและอ่านค่าข้อมูล
          ในส่วนนี้เป็นการเขียนฟังก์ชันเพื่อเขียนและอ่านค่าข้อมูลลงบนสายข้อมูลทีละบิตก่อน จากนั้นจึงเขียนฟังก์ชันเพื่อเขียนและอ่านค่าข้อมูลเป็นไบต์โดยเรียกใช้ฟังก์ชันก่อนหน้า
          3.3.1 การอ่านและเขียนค่าทีละบิต
          พิจารณาจากแผนผังเวลาในเอกสารอธิบายรายละเอียดอุปกรณ์ดังในรูปที่ 4


รูปที่ 4 แผนผังเวลาการอ่านและเขียนข้อมูลแต่ละบิต

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

void write_bitdata(uint8_t bitData)            
{
       PORTD &= ~(1 << PIND6);           //Pull line low for 1 us
       DDRD |= (1 << PIND6);
       _delay_us(1);
      
if(bitData) DDRD &= ~(1 << PIND6);
//release the line if Bit = 0 and //write 1 if Bit = 1
      
       _delay_us(60);                    //wait for 60 uS and release line
              DDRD &= ~(1 << PIND6);
}

ในทางตรงกันข้าม สำหรับการอ่านค่าข้อมูลจะดูเหมือนคล้ายกันแต่ต่างกันเล็กน้อย โดยจะเริ่มด้วยการทำให้สายข้อมูลเป็นลอจิกต่ำ 1 ไมโครวินาที จากนั้นคืนค่าสายข้อมูลและรอเป็นเวลา 14 ไมโครวินาที ดังแสดงตามแผนผังเวลาในรูปที่ 4 หลังจากนั้นก็สามารถอ่านค่าข้อมูลบนสายข้อมูลได้ โดยจะมีค่าเป็นลอจิกสูงถ้าอุปกรณ์ส่งค่า 1 ออกมา และจะมีค่าเป็นลอจิกต่ำถ้าอุปกรณ์ส่งค่า 0 ออกมา ซึ่งจะต้องหน่วงเวลารอ 45 ไมโครวินาที เพื่อให้ครบ 60 ไมโครวินาที ซึ่งจะได้ฟังก์ชันการอ่านค่าข้อมูลทีละบิตดังนี้

uint8_t read_bitdata(void)
{
       uint8_t bit = 0;
      
              PORTD &= ~(1 << PIND6);    //Pull line low for 1 us
              DDRD |= (1 << PIND6);
              _delay_us(1);
             
              DDRD &= ~(1 << PIND6);     //release line and wait for 1 us
              _delay_us(14);
             
              if (PIND&(1<<PIND6)) bit =1;      //read line value
             
              _delay_us(45);       //wait for 45 us and return read value
              return bit;
      
}

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

void write_bytedata(uint8_t byte)
{
       uint8_t i = 8;
       while (i--)
       {
write_bitdata(byte &1);    //write bit and shift one position //for next write
              byte >>=1;
       }
}

uint8_t read_bytedata()
{
       uint8_t i = 8, n = 0;
      
       while(i--)
       {
              n>>=1;        //shift one position right and store read value
              n|=(read_bitdata()<<7);
       }
       return n;
}

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

ตารางที่ 1 สรุปรายละเอียดของชุดคำสั่งสำหรับ DS1820
ชุดคำสั่ง
รหัสคำสั่ง
คำอธิบาย
ชุดคำสั่งสำหรับรอม
Search ROM
0xF0
สำหรับระบุตัวตนหรือรหัสรอมของ DS1820 แต่ละตัว เพื่อตรวจสอบจำนวนอุปกรณ์ทั้งหมดที่เชื่อมต่ออยู่กับสายข้อมูล
Read ROM
0x33
มีผลเช่นเดียวกันกับ Search ROM เพียงแต่สามารถใช้ได้ในกรณีมีอุปกรณ์เพียงตัวเดียวเท่านั้น ถ้าใช้ในอุปกรณ์เชื่อมต่ออุปกรณ์หลายต่อจะให้ข้อมูลซ้อนทับกัน
Match ROM
0x55
ใช้ร่วมกับรหัสรอม 64 บิต เพื่อระบุว่ามาสเตอร์จะติดต่อกับอุปกรณ์ลูกตัวไหน โดยที่ตัวรหัสรอมตรงกันเพียงตัวเดียวเท่านั้นในสายข้อมูลที่จะตอบสนองกลับ ตัวอื่นจะรอกระบวนรีเซต
Skip ROM
0xCC
ใช้ระบุอุปกรณ์ทุกตัวที่เชื่อมต่ออยู่กับสายข้อมูล ซึ่งใช้ในกรณีต้องการส่งคำสั่งแปลงค่า ในระบบที่มีอุปกรณ์เชื่อมต่อเพียงตัวเดียว
Alarm Search
0xEC
คล้ายกับ Search ROM เพียงแต่อุปกรณ์จะตอบสนองโดยการเซตค่าแจ้งเตือน
ชุดคำสั่งกำหนดหน้าที่
Convert T
0x44
คำสั่งแปลงเริ่มแปลงค่าอุณหภูมิ ซึ่งจะเก็บค่าไว้ที่สองไบต์แรกของ หน่วยความจำ Scratchpad ถ้ามีการอ่านค่าขณะทำการแปลงค่าไม่เสร็จจะทำให้สายข้อมูลมีสถานะเป็นลอจิกต่ำ และแสดงสถานะเป็นลอจิกสูงถ้ากระบวนการแปลงค่าเสร็จสิ้นแล้ว
Write Scratchpad
0x4E
มาสเตอร์เขียนค่าไปที่ หน่วยความจำ 3 ตัว คือ TH TL และ หน่วยความจำสำหรับปรับตั้งค่า (Configuration register)
Read Scratchpad
0xBE
ทำการอ่านค่าจาก Scratchpad ซึ่งมีทั้งหมด 9 ไบต์โดยจะให้ค่าบิตนัยสำคัญต่ำสุดออกมาก่อน ซึ่งสามารถรีเซตได้ตลอดเวลา ถ้าไม่ต้องการอ่านค่าทุกไบต์
Copy Scratchpad
0x48
คัดลอกหน่วยความจำ 3 ตัว คือ TH TL และ หน่วยความจำสำหรับปรับตั้งค่า (Configuration register) ไปที่ EEPROM
Recall E2
0xB8
เรียกคืนค่าหน่วยความจำ 3 ตัว คือ TH TL และ หน่วยความจำสำหรับปรับตั้งค่า (Configuration register) จาก EEPROM
Read Power Supply
0xB4
สำหรับเป็นตัวบ่งชี้ว่าอุปกรณ์เชื่อมต่อใช้แหล่งจากไฟจากภายนอกหรือใช้แบบพาราสิทเพาเวอร์ ถ้าเป็นแบบพาราสิทเพาเวอร์อุปกรณ์เชื่อมต่อจะทำให้สายข้อมูลมีสถานะเป็นลอจิกต่ำหลังจากใช้คำสั่งแต่ถ้าไม่จะให้สถานะเป็นลอจิกสูง

3.6 การอ่านค่าอุณหภูมิ
          ข้อมูลแสดงค่าอุณหภูมิของ DS1820 ถูกเก็บอยู่ใน 2 ไบต์แรกของหน่วยความจำ Scratchpad ซึ่งมีทั้งหมด 9 ไบต์ ประกอบด้วยส่วนต่างๆ ดังแสดงในรูปที่ 5


รูปที่ 5 แผนที่หน่วยความจำ Scratchpad ของ DS1820
          ข้อมูลอุณหภูมิมีขนาด 16 บิต 2 คอมพลีเมนต์แบบมีเครื่องหมาย ในตารางที่ 1 แสดงความสัมพันธ์ของค่าข้อมูลทั้งสองไบต์กับค่าอุณหภูมิที่วัดได้ โดยข้อมูลจะส่งผ่านสายข้อมูล ซึ่งสามารถวัดอุณหภูมิได้ในช่วง -55 ถึง 125 องศาเซลเซียส ความละเอียด 0.5 องศาเซลเซียส ต่อหนึ่งบิตดิจิตอล (สามารถเพิ่มความละเอียดเป็น 0.25 องศาเซลเซียสได้ รายละเอียดในเอกสารแสดงรายละเอียดของ DS1820)

ตารางที่ 2 ความสัมพันธ์ระหว่างค่าข้อมูลกับค่าอุณหภูมิ
Temperature (oC)
Digital Output (Binary)
Digital Output (Hex)
+125
00000000 11111010
00FA
+25
00000000 00110010
0032
+0.5
00000000 00000001
0001
+0
00000000 00000000
0000
-0.5
11111111 11111111
FFFF
-25
11111111 11001110
FFCE
-50
11111111 10010010
FF92

          ดังนั้นในการอ่านค่าอุณหภูมิ สามารถทำได้โดยการตรวจสอบข้อมูลในไบต์สูงว่ามีค่าเป็น 0 หรือ 1 ถ้าเป็น 0 อุณหภูมิที่ได้จะมีค่าเป็นบวกและมีค่าอุณหภูมิเท่ากับค่าของข้อมูลในไบต์ต่ำ (LSB) คูณด้วย 0.5 แต่ถ้ามีค่าเป็น 1 อุณหภูมิที่ได้จะมีค่าเป็นลบและมีค่าอุณหภูมิเท่ากับ การทำ 2 คอมพลีเมนต์ของข้อมูลในไบต์ต่ำ

4. โปรแกรมอ่านค่าข้อมูลและแสดงผล
          ในที่นี้จะกล่าวถึงการอ่านค่าข้อมูลสำหรับการเชื่อมต่อ DS1820 ในสายข้อมูลเพียง 1 ตัว โดยมีลำดับการเขียนและอ่านข้อมูล ดังแสดงในตารางที่ 3

ตารางที่ 3 ลำดับการแปลงค่าข้อมูลและการอ่านค่าอุณหภูมิ
Master mode
Data (LSB first)
รายละเอียด
ส่ง
รีเซต
พัลส์รีเซต
รับ
ตอบสนอง
พัลส์ตอบสนอง
ส่ง
CCh
คำสั่ง Skip ROM
ส่ง
44h
คำสั่งแปลงค่าอุณหภูมิ
รับ
ข้อมูล 1 ไบต์
อ่านค่าข้อมูลเพื่อตรวจสอบว่าการแปลงค่าเรียบร้อยหรือไม่ โดย 0 ยังไม่เสร็จ 1 เสร็จสมบูรณ์
ส่ง
รีเซต
พัลส์รีเซต
รับ
ตอบสนอง
พัลส์ตอบสนอง
ส่ง
CCh
คำสั่ง Skip ROM
ส่ง
BEh
คำสั่งอ่านค่าข้อมูลใน Scratchpad
รับ
ข้อมูล 9 ไบต์
ข้อมูลทั้งหมด 9 ไบต์ ถูกส่งออกมาบนสายข้อมูล
ส่ง
รีเซต
พัลส์รีเซต
รับ
ตอบสนอง
พัลส์ตอบสนอง เสร็จสิ้นการแปลงและอ่านค่าข้อมูลอุณหภูมิ 1 รอบ
-
-
ไมโครคอนโทรลเลอร์ทำความคำนวณค่าและแสดงผล

ซึ่งสามารถเขียนเป็นโปรแกรม ได้ดังนี้

int main(void)
{
       uint8_t buffTemp[2]; //Temperature buffer for read MSB and LSB
       uint16_t buffInt;
      
       USART_Init(12);      //Initial serial port with 57600 baud rate
      
       while(1)
       {
              reset();             //Reset, Skip ROM and Start conversion
              write_bytedata(0xCC);
              write_bytedata(0x44);
             
              while(!read_bitdata());    //Wait until conversion complete               
             
              reset();             //     Reset, Skip ROM and read Scratchpad
              write_bytedata(0xCC);
              write_bytedata(0xBE);
             
              buffTemp[0] = read_bytedata();    //Read only 2 first Bytes
              buffTemp[1] = read_bytedata();
              reset();
             
              buffInt = buffTemp[0] * 5;        //Convert to degree celcius
              int2terminal(buffInt);            //Display on Terminal window
       }
}

โดยเพิ่มส่วนแสดงผลให้สามารถแสดงค่าอุณหภูมิผ่านหน้าจอเทอร์มินอลของส่วนเพิ่มขยายของ Atmel Studio ดังแสดงในรูปที่ 6


รูปที่ 6 การแสดงค่าอุณหภูมิห้องที่วัดได้ผ่านหน้าจอเทอร์มินอล

5. เอกสารอ้างอิง

[1] DALLAS, DS1820 1WireTM Digital Thermometer Datasheet,
[2] Gerard Marull Paretas, Using DS18B20 digital temperature sensor on AVR microcontrollers,
[3] ATMEL, ATtiny2313 Datasheet, http://www.atmel.com/images/doc2543.pdf, 2015.





0 comments:

Post a Comment