Სარჩევი:

Arduino და PCF8591 ADC DAC IC: 7 ნაბიჯი
Arduino და PCF8591 ADC DAC IC: 7 ნაბიჯი

ვიდეო: Arduino და PCF8591 ADC DAC IC: 7 ნაბიჯი

ვიდეო: Arduino და PCF8591 ADC DAC IC: 7 ნაბიჯი
ვიდეო: Arduino და რელეს კონტროლი | "Intermediate" ნაკრების სასწავლო კურსი 2024, ივლისი
Anonim
Arduino და PCF8591 ADC DAC IC
Arduino და PCF8591 ADC DAC IC

ოდესმე გსურდათ თქვენი Arduino პროექტზე მეტი ანალოგური შეყვანის ქინძისთავები, მაგრამ არ გინდოდათ მეგაზე გამოძახება? ან გსურთ შექმნათ ანალოგური სიგნალები? შემდეგ გადახედეთ ჩვენი გაკვეთილის საგანს - NXP PCF8591 IC.

ის წყვეტს ორივე ამ პრობლემას, რადგან მას აქვს ერთი DAC (ციფრული ანალოგური) გადამყვანი, ასევე ოთხი ADC (ციფრული გადამყვანების ანალოგი) - ყველა ხელმისაწვდომია I2C ავტობუსის საშუალებით. PCF8591 ხელმისაწვდომია DIP, ზედაპირზე და მოდულის სახით, რაც აადვილებს ექსპერიმენტებს.

სანამ გადახვალთ, გადმოწერეთ მონაცემთა ფურცელი. PCF8591 შეუძლია იმუშაოს როგორც 5V, ასევე 3.3V, ასე რომ, თუ თქვენ იყენებთ Arduino Due, Raspberry Pi ან სხვა 3.3 V განვითარების დაფას, კარგად ხართ. ახლა ჩვენ განვმარტავთ DAC– ს, შემდეგ ADC– ს.

ნაბიჯი 1: DAC (ციფრულ-ანალოგიურ გადამყვანად) გამოყენება

DAC (ციფრულ-ანალოგურ გადამყვანად) გამოყენება
DAC (ციფრულ-ანალოგურ გადამყვანად) გამოყენება

PCF8591– ს DAC– ს აქვს 8 ბიტიანი გარჩევადობა-ასე რომ მას შეუძლია წარმოქმნას თეორიული სიგნალი ნულოვან ვოლტსა და საცნობარო ძაბვას შორის (Vref) 255 საფეხურზე. სადემონსტრაციო მიზნებისთვის ჩვენ გამოვიყენებთ 5V Vref- ს, ხოლო თქვენ შეგიძლიათ გამოიყენოთ ქვედა Vref, როგორიცაა 3.3V ან რაც გსურთ, რომ იყოს მაქსიმალური მნიშვნელობა … თუმცა ის უნდა იყოს ნაკლები მიწოდების ძაბვაზე.

გაითვალისწინეთ, რომ როდესაც იტვირთება ანალოგიურ გამომავალზე (რეალურ სიტუაციაში), მაქსიმალური გამომავალი ძაბვა დაეცემა-მონაცემთა ფურცელი (რომელიც თქვენ გადმოწერეთ) აჩვენებს 10% -იან ვარდნას 10kΩ დატვირთვაზე. ახლა რაც შეეხება ჩვენს სადემონსტრაციო წრეს.

ყურადღება მიაქციეთ 10kΩ გამწევ რეზისტორებს I2C ავტობუსზე და 10μF კონდენსატორს 5V და GND შორის. I2C ავტობუსის მისამართი მითითებულია A0 ~ A2 ქინძისთავების კომბინაციით და ყველა მათგანთან GND მისამართი 0x90. ანალოგური გამომუშავება შეიძლება ამოღებულ იქნას პინი 15 -დან (და არის ცალკე ანალოგი GND პინ 13 -ზე). ასევე, დაუკავშირეთ პინი 13 GND- ს და ჩართეთ GND Arduino GND- თან.

DAC– ის გასაკონტროლებლად ჩვენ უნდა გამოვაგზავნოთ ორი ბაიტი მონაცემები. პირველი არის საკონტროლო ბაიტი, რომელიც უბრალოდ ააქტიურებს DAC- ს და არის 1000000 (ან 0x40) და შემდეგი ბაიტი არის მნიშვნელობა 0 -დან 255 -მდე (გამომავალი დონე). ეს ნაჩვენებია შემდეგ ესკიზში:

// მაგალითი 52.1 PCF8591 DAC დემო

#მოიცავს "Wire.h" #განსაზღვრეთ PCF8591 (0x90 >> 1) // I2C ავტობუსის მისამართი void setup () {Wire.begin (); } void loop () {for (int i = 0; i <256; i ++) {Wire.beginTransmission (PCF8591); // გაიღვიძე PCF8591 Wire.write (0x40); // კონტროლის ბაიტი - ჩართეთ DAC (ორობითი 1000000) Wire.write (i); // მნიშვნელობა DAC Wire.endTransmission- ში გაგზავნისთვის (); // გადაცემის დასრულება}

for (int i = 255; i> = 0; --i)

{Wire.beginTransmission (PCF8591); // გაიღვიძე PCF8591 Wire.write (0x40); // კონტროლის ბაიტი - ჩართეთ DAC (ორობითი 1000000) Wire.write (i); // მნიშვნელობა DAC Wire.endTransmission- ში გაგზავნისთვის (); // გადაცემის დასრულება}}

შეამჩნიეთ ავტობუსის მისამართის ცოტა ცვლა #განსაზღვრულ განცხადებაში? Arduino აგზავნის 7 ბიტიან მისამართებს, მაგრამ PCF8591– ს სურს 8 ბიტიანი, ამიტომ ჩვენ ვცვლით ბაიტს ერთი ბიტით.

ნაბიჯი 2:

გამოსახულება
გამოსახულება

ესკიზის შედეგები ნაჩვენებია სურათზე, ჩვენ დავუკავშირეთ Vref 5V- ს და ოსცილოსკოპის ზონდს და GND შესაბამისად ანალოგურ გამოსავალს და GND- ს.

ნაბიჯი 3:

გამოსახულება
გამოსახულება

თუ მოგწონთ მოსახვევები, შეგიძლიათ წარმოქმნათ სინუსური ტალღები ქვემოთ მოცემული ესკიზით. იგი იყენებს საძიებო ცხრილს მასივში, რომელიც შეიცავს საჭირო წინასწარ გამოთვლილ მონაცემებს:

// მაგალითი 52.2 PCF8591 DAC დემო - სინუსური ტალღა

# მოიცავს "Wire.h" განსაზღვრავს PCF8591 (0x90 >> 1) // I2C ავტობუსი მისამართი uint8_t sine_wave [256] = {0x80, 0x83, 0x86, 0x89, 0x8C, 0x90, 0x93, 0x96, 0x99, 0x9C, 0x9F, 0xA2, 0xa5, 0xA8, 0xAB, 0xAE, 0xB1, 0xB3, 0xB6, 0xB9, 0xBC, 0xBF, 0xC1, 0xC4, 0xC7, 0xC9, 0xCC, 0xCE, 0xD1, 0xD3, 0xD5, 0xD8, 0xDA, 0xDC, 0xDE, 0xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEB, 0xED, 0xEF, 0xF0, 0xF1, 0xF3, 0xF4, 0xF5, 0xF6, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF8, 0xF6, 0xF5, 0xF4, 0xF3, 0xF1, 0xF0, 0xEF, 0xED, 0xEB, 0xEA, 0xE8, 0xE6, 0xE4, 0xE2, 0xE0, 0xDE, 0xDC, 0xDA, 0xD8, 0xD5, 0xD3, 0xD1, 0xCE, 0xCC, 0xC9, 0xC7, 0xC4, 0xC1, 0xBF, 0xBC, 0xB9, 0xB6, 0xB3, 0xB1, 0xAE, 0xAB, 0xA8, 0xa5, 0xA2, 0x9F, 0x9C, 0x99, 0x96, 0x93, 0x90, 0x8C, 0x89, 0x86, 0x83, 0x80, 0x7D, 0x7A, 0x77, 0x74, 0x70, 0x6D, 0x6A, 0x67, 0x64, 0x61, 0x5E, 0x5B, 0x58, 0x55, 0x52, 0x4F, 0x4D, 0x4A, 0x47, 0x44, 0x41, 0x3F, 0x 3C, 0x39, 0x37, 0x34, 0x32, 0x2F, 0x2D, 0x2B, 0x28, 0x26, 0x24, 0x22, 0x20, 0x1E, 0x1C, 0x1A, 0x18, 0x16, 0x15, 0x13, 0x11, 0x10, 0x0F, 0x0D, 0x0C, 0x0B, 0x0A, 0x08, 0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x03, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0F, 0x10, 0x11, 0x13, 0x15, 0x16, 0x18, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2B, 0x2D, 0x2F, 0x32, 0x34, 0x37, 0x39, 0x3C, 0x3F, 0x41, 0x44, 0x47, 0x4A, 0x4D, 0x4F, 0x52, 0x55, 0x58, 0x5B, 0x5E, 0x61, 0x64, 0x67, 0x6A, 0x6D, 0x70, 0x74, 0x77, 0x7A, 0x7D}; void setup () {Wire.begin (); } void loop () {for (int i = 0; i <256; i ++) {Wire.beginTransmission (PCF8591); // გაიღვიძე PCF8591 Wire.write (0x40); // კონტროლის ბაიტი - ჩართეთ DAC (ორობითი 1000000) Wire.write (sine_wave ); // მნიშვნელობა DAC Wire.endTransmission- ში გაგზავნისთვის (); // გადაცემის დასრულება}}

ნაბიჯი 4:

გამოსახულება
გამოსახულება

მომდევნო DSO გამოსახულების ნაგავსაყრელისთვის, ჩვენ Vref შევიცვალეთ 3.3V - შენიშნეთ სინუსის ტალღაზე მაქსიმალურ ცვლილება.

ახლა თქვენ შეგიძლიათ ექსპერიმენტი ჩაატაროთ DAC– ში, რათა შექმნათ ხმოვანი ეფექტები, სიგნალები ან გააკონტროლოთ სხვა ანალოგური სქემები.

ნაბიჯი 5: ADC– ების გამოყენება (ანალოგური-ციფრული გადამყვანები)

თუ თქვენ იყენებთ analogRead () ფუნქციას თქვენს Arduino– ზე (გზა პირველ თავში), თქვენ უკვე იცნობთ ADC– ს. PCF8591– ის გარეშე ჩვენ შეგვიძლია წავიკითხოთ ძაბვა ნულსა და Vref– ს შორის და ის დააბრუნებს მნიშვნელობას ნულიდან 255 – მდე, რაც პირდაპირპროპორციულია ნულისა და Vref– ისა.

მაგალითად, 3.3V გაზომვა უნდა დააბრუნოს 168. ADC– ის გარჩევადობა (8 ბიტიანი) უფრო დაბალია, ვიდრე ბორტზე არსებული Arduino (10 ბიტიანი), თუმცა PCF8591– ს შეუძლია გააკეთოს ის, რაც Arduino– ს ADC– ს არ შეუძლია. მაგრამ ჩვენ ამას მივაღწევთ მომენტში. პირველ რიგში, თითოეული ADC პინის მნიშვნელობების უბრალოდ წასაკითხად, ჩვენ ვგზავნით საკონტროლო ბაიტს, რომ PCF8591- ს ვუთხრათ რომელი ADC– ის წაკითხვა გვინდა. ნულიდან სამამდე ADC– ებისთვის საკონტროლო ბაიტი არის 0x00, 0x01, ox02 და 0x03 შესაბამისად.

შემდეგ ჩვენ ვითხოვთ ორი ბაიტი მონაცემს ADC– დან და ვინახავთ მეორე ბაიტს გამოსაყენებლად. რატომ ორი ბაიტი? PCF8591 აბრუნებს ადრე გაზომულ მნიშვნელობას - შემდეგ მიმდინარე ბაიტს. (იხ. სურათი 8 მონაცემების ფურცელში). დაბოლოს, თუ თქვენ არ იყენებთ ყველა ADC პინს, დაუკავშირეთ გამოუყენებელი GND. შემდეგი მაგალითი ესკიზი უბრალოდ იღებს მნიშვნელობებს თითოეული ADC პინიდან ერთდროულად, შემდეგ აჩვენებს მათ სერიულ მონიტორში:

#მოიცავს "Wire.h"

#განსაზღვრეთ PCF8591 (0x90 >> 1) // I2C ავტობუსის მისამართი #განსაზღვრეთ ADC0 0x00 // აკონტროლეთ ბაიტები ინდივიდუალური ADC– ების კითხვისთვის #განსაზღვრეთ ADC1 0x01 #განსაზღვრეთ ADC2 0x02 #განსაზღვრეთ ADC3 0x03 ბაიტი მნიშვნელობა 0, მნიშვნელობა 1, მნიშვნელობა 2, მნიშვნელობა 3; void setup () {Wire.begin (); სერიული.დაწყება (9600); } void loop () {Wire.beginTransmission (PCF8591); // გაიღვიძე PCF8591 Wire.write (ADC0); // კონტროლის ბაიტი - წაიკითხეთ ADC0 Wire.endTransmission (); // გადაცემის დასრულება Wire.requestFrom (PCF8591, 2); მნიშვნელობა 0 = Wire.read (); მნიშვნელობა 0 = Wire.read (); Wire.beginTransmission (PCF8591); // გაიღვიძე PCF8591 Wire.write (ADC1); // კონტროლის ბაიტი - წაიკითხეთ ADC1 Wire.endTransmission (); // გადაცემის დასრულება Wire.requestFrom (PCF8591, 2); მნიშვნელობა 1 = Wire.read (); მნიშვნელობა 1 = Wire.read (); Wire.beginTransmission (PCF8591); // გაიღვიძე PCF8591 Wire.write (ADC2); // კონტროლის ბაიტი - წაიკითხეთ ADC2 Wire.endTransmission (); // გადაცემის დასრულება Wire.requestFrom (PCF8591, 2); მნიშვნელობა 2 = Wire.read (); მნიშვნელობა 2 = Wire.read (); Wire.beginTransmission (PCF8591); // გაიღვიძე PCF8591 Wire.write (ADC3); // კონტროლის ბაიტი - წაიკითხეთ ADC3 Wire.endTransmission (); // გადაცემის დასრულება Wire.requestFrom (PCF8591, 2); მნიშვნელობა 3 = Wire.read (); მნიშვნელობა 3 = Wire.read (); Serial.print (მნიშვნელობა 0); Serial.print (""); Serial.print (მნიშვნელობა 1); Serial.print (""); Serial.print (მნიშვნელობა 2); Serial.print (""); Serial.print (მნიშვნელობა 3); Serial.print (""); Serial.println (); }

ესკიზის გაშვებისას თქვენ წარმოგიდგენთ თითოეული ADC- ს მნიშვნელობებს სერიულ მონიტორში. მიუხედავად იმისა, რომ ეს იყო მარტივი დემონსტრირება იმის საჩვენებლად, თუ როგორ უნდა წაიკითხოთ თითოეული ADC ინდივიდუალურად, ეს არის რთული მეთოდი, რომ მიიღოთ ერთზე მეტი ბაიტი ერთდროულად კონკრეტული ADC– დან.

ნაბიჯი 6:

ამისათვის შეცვალეთ საკონტროლო ბაიტი ავტომატური გაზრდის მოთხოვნით, რაც კეთდება საკონტროლო ბაიტის ბიტი 2 – ის დაყენებით 1. ასე რომ ADC0– დან დასაწყებად ვიყენებთ ორობითი 00000100 ან თექვსმეტობითი 0x04 ახალი საკონტროლო ბაიტს. შემდეგ მოითხოვეთ მონაცემების ხუთი ბაიტი (ჩვენ კიდევ ერთხელ ვაიგნორებთ პირველ ბაიტს), რაც გამოიწვევს PCF8591 ყველა მნიშვნელობის დაბრუნებას ერთ ჯაჭვში ბაიტებში. ეს პროცესი ნაჩვენებია შემდეგ ესკიზში:

#მოიცავს "Wire.h"

#განსაზღვრეთ PCF8591 (0x90 >> 1) // I2C ავტობუსის მისამართი ბაიტი მნიშვნელობა 0, მნიშვნელობა 1, მნიშვნელობა 2, მნიშვნელობა 3; void setup () {Wire.begin (); სერიული.დაწყება (9600); } void loop () {Wire.beginTransmission (PCF8591); // გაიღვიძე PCF8591 Wire.write (0x04); // კონტროლის ბაიტი - წაიკითხეთ ADC0 შემდეგ ავტომატურად გაზარდეთ Wire.endTransmission (); // გადაცემის დასრულება Wire.requestFrom (PCF8591, 5); მნიშვნელობა 0 = Wire.read (); მნიშვნელობა 0 = Wire.read (); მნიშვნელობა 1 = Wire.read (); მნიშვნელობა 2 = Wire.read (); მნიშვნელობა 3 = Wire.read (); Serial.print (მნიშვნელობა 0); Serial.print (""); Serial.print (მნიშვნელობა 1); Serial.print (""); Serial.print (მნიშვნელობა 2); Serial.print (""); Serial.print (მნიშვნელობა 3); Serial.print (""); Serial.println (); }

ადრე ჩვენ აღვნიშნეთ, რომ PCF8591– ს შეუძლია ისეთი რამის გაკეთება, რაც არდუინოს ADC– ს შეუძლია და ეს არის დიფერენციალური ADC– ის შეთავაზება. არდუინოს ერთპიროვნული მოქმედებისგან განსხვავებით (ანუ ის აბრუნებს განსხვავებას სიგნალის დადებით ძაბვასა და GND- ს შორის, დიფერენციალური ADC იღებს ორ სიგნალს (რომელიც სულაც არ არის აუცილებელი მინიშნებული იყოს მიწაზე) და აბრუნებს განსხვავებას ორ სიგნალს შორის ეს შეიძლება იყოს მოსახერხებელი დატვირთვის უჯრედებში ძაბვის მცირე ცვლილებების გასაზომად და ასე შემდეგ.

ნაბიჯი 7:

გამოსახულება
გამოსახულება

PCF8591 დიფერენციალური ADC– ს დაყენება არის საკონტროლო ბაიტის შეცვლის მარტივი საკითხი. თუ გადახვალთ მონაცემთა ფურცლის მეშვიდე გვერდზე, მაშინ განიხილეთ სხვადასხვა ტიპის ანალოგური შეყვანის პროგრამირება. ადრე ჩვენ ვიყენებდით რეჟიმს '00' ოთხი შეყვანისთვის, თუმცა თქვენ შეგიძლიათ აირჩიოთ დანარჩენები, რომლებიც ნათლად არის ილუსტრირებული, მაგალითად სურათი.

ორი დიფერენციალური შეყვანისთვის საკონტროლო ბაიტის დასაყენებლად გამოიყენეთ ორობითი 00110000 ან 0x30. მაშინ ეს არის მარტივი საკითხი, მოითხოვოს მონაცემთა ბაიტები და მათთან მუშაობა. როგორც ხედავთ, ასევე არსებობს ერთჯერადი/დიფერენციალური და რთული სამდიფერენციალური შეყვანა. თუმცა ჩვენ მათ დროებით დავტოვებთ.

ვიმედოვნებთ, რომ ეს თქვენთვის საინტერესო აღმოჩნდა, დაემატება DAC თქვენს ექსპერიმენტებს თუ ცოტა მეტს შეიტყობთ ADC– ების შესახებ. გთხოვთ გაითვალისწინოთ თქვენი PCF8591 შეკვეთა PMD Way– დან.

ეს პოსტი მოგიტანათ pmdway.com– ით - ყველაფერი მწარმოებლებისთვის და ელექტრონიკის მოყვარულთათვის, უფასო მიწოდებით მთელს მსოფლიოში.

გირჩევთ: