โวลต์มิเตอร์บน Arduino เพื่อการวัดแรงดันไฟฟ้าที่แม่นยำ โวลต์มิเตอร์แบบดิจิตอลบน Arduino ที่มีการเชื่อมต่อกับพีซีผ่านพอร์ตอนุกรม

มีการนำเสนอแผนภาพที่เป็นประโยชน์สำหรับผู้ที่ชื่นชอบการทดลองกับ Arduino นี่คือโวลต์มิเตอร์แบบดิจิตอลอย่างง่ายที่สามารถวัดแรงดันไฟฟ้ากระแสตรงในช่วง 0 - 30V ได้อย่างน่าเชื่อถือ ตามปกติบอร์ด Arduino สามารถใช้พลังงานจากแบตเตอรี่ 9V ได้

ดังที่คุณคงทราบแล้วว่าอินพุตแบบอะนาล็อกของ Arduino สามารถใช้วัดแรงดันไฟฟ้ากระแสตรงในช่วง 0 - 5V และช่วงนี้สามารถเพิ่มได้
โดยใช้ตัวต้านทานสองตัวเป็นตัวแบ่งแรงดันไฟฟ้า ตัวแบ่งจะลดแรงดันไฟฟ้าที่วัดได้ให้เหลือระดับอินพุตอะนาล็อก Arduino จากนั้นโปรแกรมจะคำนวณค่าแรงดันไฟฟ้าจริง

เซ็นเซอร์แอนะล็อกบนบอร์ด Arduino ตรวจจับแรงดันไฟฟ้าที่อินพุตแอนะล็อก และแปลงเป็นรูปแบบดิจิทัลเพื่อประมวลผลต่อไปโดยไมโครคอนโทรลเลอร์ ในรูป แรงดันไฟฟ้าจะจ่ายให้กับอินพุตแบบอะนาล็อก (A0) ผ่านตัวแบ่งแรงดันไฟฟ้าอย่างง่ายซึ่งประกอบด้วยตัวต้านทาน R1 (100 kOhm) และ R2 (10 kOhm)

ด้วยค่าตัวแบ่งเหล่านี้ บอร์ด Arduino จึงสามารถจ่ายแรงดันไฟฟ้าได้ตั้งแต่ 0 ถึง
55V. ที่อินพุต A0 เรามีแรงดันไฟฟ้าที่วัดได้หารด้วย 11 เช่น 55V / 11=5V กล่าวอีกนัยหนึ่ง เมื่อวัด 55V ที่อินพุต Arduino เราจะมีค่าสูงสุดที่อนุญาตคือ 5V ในทางปฏิบัติ ควรเขียนช่วง "0 - 30V" บนโวลต์มิเตอร์นี้เพื่อให้คงอยู่จะดีกว่า
ขอบความปลอดภัย!

หมายเหตุ

หากการอ่านจอแสดงผลไม่ตรงกับการอ่านโวลต์มิเตอร์ทางอุตสาหกรรม (ห้องปฏิบัติการ) จำเป็นต้องวัดค่าความต้านทาน R1 และ R2 ด้วยเครื่องมือที่แม่นยำและใส่ค่าเหล่านี้แทน R1=100000.0 และ R2=10,000.0 ในโค้ดโปรแกรม จากนั้นคุณควรวัดแรงดันไฟฟ้าจริงระหว่างพิน 5V และ "กราวด์" ของบอร์ด Arduino ด้วยโวลต์มิเตอร์ในห้องปฏิบัติการ ผลลัพธ์ที่ได้จะเป็นค่าน้อยกว่า 5V เช่น จะเป็น 4.95V ควรใส่มูลค่าที่แท้จริงนี้ในบรรทัดของโค้ด
vout = (ค่า * 5.0) / 1,024.0 แทนที่จะเป็น 5.0
นอกจากนี้ ให้ลองใช้ตัวต้านทานที่มีความแม่นยำซึ่งมีความทนทาน 1%

ตัวต้านทาน R1 และ R2 ช่วยป้องกันแรงดันไฟฟ้าขาเข้าที่เพิ่มขึ้น อย่างไรก็ตาม โปรดจำไว้ว่าแรงดันไฟฟ้าที่สูงกว่า 55V อาจทำให้บอร์ด Arduino เสียหายได้ นอกจากนี้ การออกแบบนี้ไม่ได้ให้การป้องกันประเภทอื่น (จากแรงดันไฟกระชาก การกลับขั้ว หรือแรงดันไฟเกิน)

โปรแกรมโวลต์มิเตอร์แบบดิจิตอล

/*
ดีซีโวลท์มิเตอร์
Arduino DVM ตามแนวคิดตัวแบ่งแรงดันไฟฟ้า
ที.เค.หเรนทรัน
*/
#รวม
จอแอลซีดีลิควิดคริสตัล (7, 8, 9, 10, 11, 12);
อินพุทอนาล็อกอินพุท = 0;
ลอยตัว = 0.0;
ลอยวิน = 0.0;
ลอย R1 = 100,000.0; // แนวต้าน R1 (100K) -ดูข้อความ!
ลอย R2 = 10,000.0; // แนวต้าน R2 (10K) – ดูข้อความ!
ค่า int = 0;
การตั้งค่าเป็นโมฆะ())(
pinMode (อินพุตอะนาล็อก, อินพุต);
จอแอลซีดี. เริ่มต้น (16, 2);
lcd.print("DC โวลต์มิเตอร์");
}
เป็นโมฆะวน()
// อ่านค่าที่อินพุตแบบอะนาล็อก
ค่า = analogRead (analogInput);
vout = (ค่า * 5.0) / 1,024.0; //ดูข้อความ
vin = โวต์ / (R2/(R1+R2));
ถ้า (วิน<0.09) {
vin=0.0;//คำสั่งเพื่อยุติการอ่านที่ไม่ต้องการ !
}
จอแอลซีดี setCursor (0, 1);
lcd.print("อินพุต V= ");
จอแอลซีดีพิมพ์(วิน);
ล่าช้า (500);
}

แผนผังของ Arduino-โวลต์มิเตอร์

รายการส่วนประกอบ

บอร์ด Arduino Uno
ตัวต้านทาน 100 โอห์ม
ตัวต้านทาน 10 kOhm
ตัวต้านทาน 100 โอห์ม
ตัวต้านทานทริมเมอร์ 10kOhm
จอ LCD 16?2 (ฮิตาชิ HD44780)

ความคิด

ความคิด อุปกรณ์สำหรับวัดแรงดัน กระแส ความจุ การคายประจุ และประจุอาจมีมานานแล้วและไม่ใช่แค่สำหรับฉันเท่านั้น คุณจะพบของเล่นมากมายที่เรียกว่า USB Tester (Doctor) สำหรับทดสอบอุปกรณ์ USB ต่างๆ ฉันสนใจอุปกรณ์ที่เป็นสากลมากกว่า โดยไม่ขึ้นอยู่กับอินเทอร์เฟซ แต่ออกแบบมาเพื่อแรงดันและกระแสบางอย่างเท่านั้น ตัวอย่างเช่น 0 - 20.00v, 0 - 5.00a, 0 - 99.99Ah. ส่วนฟังก์ชั่นผมเห็นแบบนี้ครับ

  • แสดงแรงดันและกระแสปัจจุบัน นั่นคือ มิเตอร์โวลต์-แอมแปร์ โดยหลักการแล้วคุณสามารถสะท้อนพลังได้ทันที
  • การนับและการแสดงความจุสะสม ในหน่วยแอมแปร์ชั่วโมงและส่วนใหญ่เป็นหน่วยวัตต์ชั่วโมง
  • การแสดงเวลากระบวนการ
  • และเป็นไปได้มากว่าสามารถปรับค่าเกณฑ์การตัดแรงดันไฟฟ้าต่ำและบนได้ (ขีดจำกัดการคายประจุและการชาร์จ)

การพัฒนา

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

  • เราจะไม่ประสานมากในโครงการนี้ โดยพื้นฐานแล้ว เราจะใช้โมดูล Arduino Pro Mini สำเร็จรูป เนื่องจากชาวจีนพร้อมที่จะจำหน่ายในราคาขายปลีก 1.5 ดอลลาร์
  • อุปกรณ์แสดงผลจะเป็นจอแสดงผล 1602 - อีก 1.5 ดอลลาร์ ฉันมีตัวเลือกสำหรับโมดูลอินเทอร์เฟซ I2C แต่ในโปรเจ็กต์นี้ไม่จำเป็นจริงๆ ($0.7)
  • เพื่อการพัฒนาเราจำเป็นต้องมีเขียงหั่นขนม ในกรณีของฉัน นี่คือ BreadBoard ขนาดเล็กราคา $1
  • แน่นอนว่าคุณจะต้องมีสายไฟและตัวต้านทานหลายตัวที่มีค่าต่างกัน สำหรับจอแสดงผล 1602 ที่ไม่มี I2C คุณต้องเลือกคอนทราสต์ด้วย - ซึ่งทำได้ด้วยตัวต้านทานแบบปรับได้ที่ 2 - 20 kOhm
  • ในการใช้แอมป์มิเตอร์ คุณจะต้องมีการแบ่งส่วน ในการประมาณค่าครั้งแรก อาจเป็นตัวต้านทาน 0.1 โอห์ม 5 วัตต์
  • หากต้องการปิดเครื่องอัตโนมัติ คุณจะต้องมีรีเลย์พร้อมหน้าสัมผัสที่ออกแบบมาสำหรับกระแสสูงสุดของอุปกรณ์และแรงดันไฟฟ้าเท่ากับแรงดันไฟฟ้า ในการควบคุมรีเลย์ คุณต้องมีทรานซิสเตอร์ NPN และไดโอดป้องกัน
  • อุปกรณ์จะใช้พลังงานจากแหล่งพลังงานภายนอก ซึ่งเห็นได้ชัดว่าอย่างน้อย 5 V หากแหล่งจ่ายไฟมีความแตกต่างกันอย่างมากก็จำเป็นต้องใช้ตัวกันโคลงแบบรวมประเภท 7805 ซึ่งจะเป็นตัวกำหนดแรงดันไฟฟ้าของรีเลย์
  • เมื่อไร Arduino Pro Mini ต้องใช้ตัวแปลง USB-TTL เพื่ออัปโหลดเฟิร์มแวร์
  • ในการตั้งค่าคุณจะต้องมีมัลติมิเตอร์

โวลต์มิเตอร์

ฉันกำลังใช้โวลต์มิเตอร์แบบธรรมดาโดยมีช่วงประมาณ 0 - 20V หมายเหตุนี้มีความสำคัญเนื่องจาก ADC ของคอนโทรลเลอร์ของเรามีความจุ 10 บิต (ค่าแยก 1,024 ค่า) ดังนั้นข้อผิดพลาดจะมีอย่างน้อย 0.02 V (20/1024) ในการใช้ฮาร์ดแวร์เราจำเป็นต้องมีอินพุตแบบอะนาล็อกของคอนโทรลเลอร์ตัวแบ่งที่ทำจากตัวต้านทานคู่หนึ่งและเอาต์พุตบางประเภท (จอแสดงผลในเวอร์ชันที่เสร็จแล้วสามารถใช้พอร์ตอนุกรมสำหรับการดีบัก)

หลักการวัด ADC คือการเปรียบเทียบแรงดันไฟฟ้าที่อินพุตแบบอะนาล็อกกับ VRef อ้างอิง เอาต์พุต ADC จะเป็นจำนวนเต็มเสมอ - 0 สอดคล้องกับ 0V, 1023 สอดคล้องกับแรงดันไฟฟ้า VRef การวัดจะดำเนินการโดยชุดการอ่านแรงดันไฟฟ้าตามลำดับและการเฉลี่ยในช่วงเวลาระหว่างการอัปเดตค่าบนหน้าจอ การเลือกแรงดันไฟฟ้าอ้างอิงมีความสำคัญเนื่องจากค่าเริ่มต้นจะเป็นแรงดันไฟฟ้าที่จ่ายซึ่งอาจไม่เสถียร สิ่งนี้ไม่เหมาะกับเราเลย - เราจะใช้แหล่งอ้างอิงภายในที่เสถียรซึ่งมีแรงดันไฟฟ้า 1.1V เป็นพื้นฐานโดยเริ่มต้นโดยการเรียกอนาล็อกอ้างอิง(ภายใน) จากนั้นเราจะปรับเทียบค่าโดยใช้การอ่านมัลติมิเตอร์

แผนภาพด้านซ้ายแสดงตัวแปรที่มีการควบคุมจอแสดงผลโดยตรง (ควบคุมได้ง่าย - ดูร่างมาตรฐานของ LiquidCrystal\HelloWorld) ทางด้านขวาคือตัวเลือก I2C ซึ่งฉันจะใช้เพิ่มเติม I2C ช่วยให้คุณประหยัดสายไฟ (ซึ่งในรุ่นปกติมี 10 เส้นไม่นับแบ็คไลท์) แต่ต้องใช้โมดูลเพิ่มเติมและการเริ่มต้นที่ซับซ้อนมากขึ้น ไม่ว่าในกรณีใด จะต้องตรวจสอบการแสดงอักขระบนโมดูลก่อนและปรับความคมชัด - ในการดำเนินการนี้ คุณเพียงแค่ต้องแสดงข้อความใด ๆ หลังจากการกำหนดค่าเริ่มต้น ความเปรียบต่างถูกปรับโดยตัวต้านทาน R1 หรือตัวต้านทานที่คล้ายกันของโมดูล I2C

อินพุตเป็นตัวแบ่ง 1:19 ซึ่งช่วยให้คุณได้รับแรงดันไฟฟ้าสูงสุดประมาณ 20V ที่ Vref = 1.1 (โดยปกติแล้วตัวเก็บประจุ + ซีเนอร์ไดโอดจะถูกวางขนานกับอินพุตเพื่อป้องกัน แต่ตอนนี้สิ่งนี้ไม่สำคัญสำหรับเรา ). ตัวต้านทานมีการแพร่กระจาย และ Vref อ้างอิงของคอนโทรลเลอร์ก็เช่นกัน ดังนั้นหลังจากการประกอบ เราจำเป็นต้องวัดแรงดันไฟฟ้า (อย่างน้อยแหล่งจ่ายไฟ) ขนานกับอุปกรณ์ของเราและมัลติมิเตอร์อ้างอิง และเลือก Vref ในโค้ดจนกว่าค่าที่อ่านได้จะตรงกัน นอกจากนี้ ยังเป็นที่น่าสังเกตว่า ADC ใดๆ มีแรงดันออฟเซ็ตเป็นศูนย์ (ซึ่งทำให้การอ่านค่าที่จุดเริ่มต้นของช่วงเสียไป) แต่เราจะไม่พูดถึงเรื่องนั้นในตอนนี้

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

ในการควบคุม I2C จะใช้เวอร์ชันของไลบรารี LiquidCrystal_I2C - ในกรณีของฉันจะมีการระบุ pinout เฉพาะของโมดูล I2C (โมดูลการผลิตของจีนที่มีการควบคุมที่แตกต่างกัน) ฉันยังทราบด้วยว่า I2C ใน Arduino ต้องใช้พิน A4 และ A5 - บนบอร์ด Pro Mini พวกเขาไม่ได้อยู่ที่ขอบซึ่งไม่สะดวกสำหรับการสร้างต้นแบบบน BreadBoard

แหล่งที่มา

#รวม #รวม // โวลต์มิเตอร์อย่างง่ายพร้อมจอแสดงผล i2c 1602 V 16.11 // การตั้งค่าสำหรับจอแสดงผล i2c 1602 พร้อม pinout ที่ไม่ได้มาตรฐาน #define LCD_I2C_ADDR 0x27 #define BACKLIGHT 3 #define LCD_EN 2 #define LCD_RW 1 #define LCD_RS 0 #define LCD_D4 4 #define LCD_D5 5 #กำหนด LCD_D6 6 #กำหนด LCD_D7 7 LiquidCrystal_I2C lcd(LCD_I2C_ADDR,LCD_EN,LCD_RW,LCD_RS,LCD_D4,LCD_D5,LCD_D6,LCD_D7); // อ่านเวลาอัปเดต, ms (200-2000) #define REFRESH_TIME 330 // อินพุตแบบอะนาล็อก #define PIN_VOLT A0 // แรงดันอ้างอิงภายใน (เลือก) const float VRef = 1.10; // ค่าสัมประสิทธิ์ตัวแบ่งความต้านทานอินพุต (Rh + Rl) / Rl ใน<-[ Rh ]--(analogInPin)--[ Rl ]--|GND const float VoltMult = (180.0 + 10.0) / 10.0; float InVolt, Volt; void setup() { analogReference(INTERNAL); // Инициализация дисплея lcd.begin (16, 2); lcd.setBacklightPin(BACKLIGHT, POSITIVE); lcd.setBacklight(HIGH); // включить подсветку lcd.clear(); // очистить дисплей lcd.print("Voltage"); } void loop() { unsigned long CalcStart = millis(); int ReadCnt = 0; InVolt = 0; // Чтение из порта с усреднением while ((millis() - CalcStart) < REFRESH_TIME) { InVolt += analogRead(PIN_VOLT); ReadCnt++; } InVolt = InVolt / ReadCnt; // Смещение 0 для конкретного ADC (подобрать или отключить) if (InVolt >0.2) อินโวลท์ += 3; // แปลงเป็นโวลต์ (ค่า: 0..1023 -> (0..VRef) ปรับขนาดโดย Mult) Volt = InVolt * VoltMult * VRef / 1023; // ข้อมูลเอาต์พุต lcd.setCursor (0, 1); จอแอลซีดีพิมพ์(โวลต์); จอแอลซีดีพิมพ์("V"); -

สวัสดีฮับ! วันนี้ฉันต้องการที่จะสานต่อหัวข้อ "การข้าม" Arduino และ Android ฉันพูดถึงในสิ่งพิมพ์ก่อนหน้านี้และวันนี้เราจะพูดถึงโวลต์มิเตอร์แบบบลูทู ธ DIY อุปกรณ์อื่นดังกล่าวสามารถเรียกว่าโวลต์มิเตอร์อัจฉริยะ โวลต์มิเตอร์ "อัจฉริยะ" หรือเพียงแค่โวลต์มิเตอร์อัจฉริยะ โดยไม่มีเครื่องหมายคำพูด นามสกุลไม่ถูกต้องจากมุมมองของไวยากรณ์รัสเซีย แต่มักพบในสื่อ ในตอนท้ายของบทความจะมีการลงคะแนนในหัวข้อนี้ แต่ฉันขอแนะนำให้เริ่มต้นด้วยการสาธิตการทำงานของอุปกรณ์เพื่อทำความเข้าใจว่าบทความจะเกี่ยวกับอะไร


ข้อจำกัดความรับผิดชอบ: บทความนี้มีไว้สำหรับผู้ที่ชื่นชอบ Arduino โดยเฉลี่ยซึ่งมักจะไม่คุ้นเคยกับการเขียนโปรแกรม Android ดังนั้นเราจะสร้างแอปพลิเคชันสำหรับสมาร์ทโฟนโดยใช้สภาพแวดล้อมการพัฒนาภาพของ App Inventor 2 สำหรับแอปพลิเคชัน Android เช่นเดียวกับในบทความที่แล้ว
ในการสร้างโวลต์มิเตอร์แบบบลูทู ธ DIY เราต้องเขียนโปรแกรมที่ค่อนข้างอิสระสองโปรแกรม: แบบร่างสำหรับ Arduino และแอปพลิเคชันสำหรับ Android เริ่มจากแบบร่างกันก่อน
ก่อนอื่นคุณควรรู้ว่ามีสามตัวเลือกหลักในการวัดแรงดันไฟฟ้าโดยใช้ Arduino ไม่ว่าคุณจะต้องส่งข้อมูลไปที่ใด: ไปยังพอร์ต com ไปยังหน้าจอที่เชื่อมต่อกับ Arduino หรือไปยังสมาร์ทโฟน
กรณีแรก: วัดแรงดันไฟฟ้าได้สูงสุด 5 โวลต์ โค้ดหนึ่งหรือสองบรรทัดก็เพียงพอแล้ว และใช้แรงดันไฟฟ้ากับพิน A0 โดยตรง:
int value = analogRead(0); // อ่านค่าที่อ่านได้จาก A0
แรงดันไฟฟ้า = (ค่า / 1,023.0) * 5; // จริงเฉพาะในกรณีที่ Vcc = 5.0 โวลต์
กรณีที่สอง: ในการวัดแรงดันไฟฟ้าที่มากกว่า 5 โวลต์ จะใช้ตัวแบ่งแรงดันไฟฟ้า วงจรนั้นง่ายมาก และโค้ดก็เช่นกัน

ร่าง

อินพุทอนาล็อกอินพุท = A0;
วาลลอยตัว = 0.0;
แรงดันลอย = 0.0;
ลอย R1 = 100,000.0; //แบตเตอรี่ Vin-> 100K -> A0
ลอย R2 = 10,000.0; // แบตเตอรี่ Gnd -> Arduino Gnd และ Arduino Gnd -> 10K -> A0
ค่า int = 0;

การตั้งค่าเป็นโมฆะ() (
อนุกรมเริ่มต้น(9600);
pinMode (อินพุตอะนาล็อก, อินพุต);
}

โมฆะวน() (
ค่า = analogRead (analogInput);
วาล = (ค่า * 4.7) / 1,024.0;
แรงดันไฟฟ้า = วาล / (R2/(R1+R2));
Serial.println (แรงดันไฟฟ้า);
ล่าช้า (500);
}


อาร์ดูโน่ อูโน่
โมดูลบลูทูธ
กรณีที่สาม. เมื่อคุณต้องการได้รับข้อมูลที่แม่นยำยิ่งขึ้นเกี่ยวกับแรงดันไฟฟ้า คุณควรใช้เป็นแรงดันไฟฟ้าอ้างอิง ไม่ใช่แรงดันไฟฟ้า ซึ่งสามารถเปลี่ยนแปลงได้เล็กน้อยเมื่อขับเคลื่อนด้วยแบตเตอรี่ เป็นต้น แต่แรงดันไฟฟ้าของตัวป้องกันเสถียรภาพ Arduino ภายในอยู่ที่ 1.1 โวลต์ วงจรก็เหมือนกันที่นี่ แต่โค้ดยาวกว่าเล็กน้อย ฉันจะไม่วิเคราะห์ตัวเลือกนี้โดยละเอียดเนื่องจากมีการอธิบายไว้อย่างดีในบทความเฉพาะเรื่องแล้ว แต่วิธีที่สองก็เพียงพอสำหรับฉันเนื่องจากแหล่งจ่ายไฟของฉันเสถียรจากพอร์ต USB ของแล็ปท็อป
ดังนั้นเราจึงแยกการวัดแรงดันไฟฟ้าออกแล้ว ตอนนี้เรามาดูครึ่งหลังของโครงการกันดีกว่า: การสร้างแอปพลิเคชัน Android เราจะสร้างแอปพลิเคชันโดยตรงจากเบราว์เซอร์ในสภาพแวดล้อมการพัฒนาภาพสำหรับแอปพลิเคชัน Android App Inventor 2 ไปที่เว็บไซต์ appinventor.mit.edu/explore เข้าสู่ระบบโดยใช้บัญชี Google ของคุณ คลิกปุ่มสร้างโครงการใหม่ และโดย เพียงลากและวางองค์ประกอบต่างๆ เราก็จะสร้างการออกแบบเช่นนี้:

ฉันสร้างกราฟิกให้เรียบง่ายมาก หากใครต้องการกราฟิกที่น่าสนใจมากกว่านี้ ฉันขอเตือนคุณว่าสำหรับสิ่งนี้ คุณต้องใช้ไฟล์ .png ที่มีพื้นหลังโปร่งใส แทนไฟล์ .jpeg
ตอนนี้ไปที่แท็บ Blocks และสร้างตรรกะของแอปพลิเคชันดังนี้:


หากทุกอย่างเรียบร้อยดี คุณสามารถคลิกปุ่ม Build และบันทึก .apk ลงในคอมพิวเตอร์ของฉัน จากนั้นดาวน์โหลดและติดตั้งแอปพลิเคชันบนสมาร์ทโฟนของคุณ แม้ว่าจะมีวิธีอื่นในการอัปโหลดแอปพลิเคชันก็ตาม ที่นี่สะดวกกว่าสำหรับทุกคน เป็นผลให้ฉันลงเอยด้วยแอปพลิเคชันนี้:


ฉันเข้าใจว่ามีเพียงไม่กี่คนที่ใช้สภาพแวดล้อมการพัฒนาภาพของ App Inventor 2 สำหรับแอปพลิเคชัน Android ในโครงการของตน ดังนั้นจึงอาจมีคำถามมากมายเกี่ยวกับการทำงานในสภาพแวดล้อมดังกล่าว เพื่อตอบคำถามเหล่านี้ ฉันได้จัดทำวิดีโอโดยละเอียดเกี่ยวกับวิธีสร้างแอปพลิเคชันดังกล่าว "ตั้งแต่เริ่มต้น" (คุณต้องไปที่ YouTube หากต้องการดู):

ป.ล. คอลเลกชันสื่อการเรียนรู้มากกว่า 100 รายการบน Arduino สำหรับผู้เริ่มต้นและมืออาชีพ

ด้วยการเพิ่มเติมบางอย่าง

คุณลักษณะที่ไม่ค่อยมีใครรู้จักของ Arduino และชิป AVR อื่นๆ ก็คือความสามารถในการวัดแรงดันอ้างอิงภายใน 1.1 V คุณสมบัตินี้สามารถ ใช้สำหรับ เพิ่มความแม่นยำฟังก์ชั่น Arduino - อะนาล็อกอ่าน โดยใช้แรงดันไฟฟ้าอ้างอิงมาตรฐาน 5 V (บนแพลตฟอร์มที่มีแรงดันไฟฟ้า 5 V) หรือ 3.3 V (บนแพลตฟอร์มที่มีแรงดันไฟฟ้า 3.3 V)เธออาจจะเป็นก็ได้ ใช้ในการวัด Vcc นำไปใช้กับชิปให้ วิธีการควบคุม แรงดันแบตเตอรี่ โดยไม่ต้องใช้หมุดอะนาล็อกอันล้ำค่า

แรงจูงใจ

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

เป็นเรื่องปกติที่จะสันนิษฐานว่าเมื่อใช้ analogRead() แรงดันไฟฟ้าของแหล่งจ่ายไฟแบบอะนาล็อกของคอนโทรลเลอร์คือ 5.0 โวลต์ ซึ่งในความเป็นจริงอาจไม่เป็นเช่นนั้นเลย (เช่น แหล่งจ่ายไฟจาก 3 องค์ประกอบคือ 1.5 V) เอกสาร Arduino อย่างเป็นทางการอาจทำให้เราไปสู่สมมติฐานที่ไม่ถูกต้องนี้ ความจริงก็คือพลังงานไม่จำเป็นต้องอยู่ที่ 5.0 โวลต์ โดยไม่คำนึงถึงระดับปัจจุบัน พลังงานนี้จะถูกส่งไปยัง Vcc ของชิป หากแหล่งจ่ายไฟของเราไม่เสถียรหรือหากเราใช้พลังงานจากแบตเตอรี่ แรงดันไฟฟ้านี้อาจเปลี่ยนแปลงเล็กน้อย นี่คือตัวอย่างโค้ดที่แสดงให้เห็นถึงปัญหานี้:

Vcc สองเท่า = 5.0; // ไม่จำเป็นต้องเป็นค่า int จริง = analogRead(0); / อ่านค่าที่อ่านได้จาก A0 double volt = (ค่า / 1,023.0) * Vcc; // เป็นจริงเฉพาะเมื่อ Vcc = 5.0 โวลต์ เพื่อวัดแรงดันไฟฟ้าได้อย่างแม่นยำ จำเป็นต้องมีแรงดันอ้างอิงที่แม่นยำ ชิป AVR ส่วนใหญ่มีแรงดันไฟฟ้าอ้างอิงสามแบบ:

  • 1.1 V จากแหล่งภายใน ในเอกสารประกอบนั้นจะส่งผ่านเป็นการอ้างอิง bandgap (บางส่วนเป็น 2.56 V เช่น ATMega 2560) การเลือกทำได้โดยฟังก์ชัน analogReference() พร้อมด้วยพารามิเตอร์ INTERNAL: analogReference(INTERNAL) ;
  • แหล่งแรงดันอ้างอิงภายนอกซึ่งมีป้ายกำกับ AREF บน Arduino เลือก: การอ้างอิงแบบอะนาล็อก (ภายนอก);
  • Vcc คือแหล่งจ่ายไฟของคอนโทรลเลอร์นั่นเอง เลือก: การอ้างอิงแบบอะนาล็อก (ค่าเริ่มต้น)

ใน Arduino คุณไม่สามารถเชื่อมต่อ Vcc เข้ากับพินแอนะล็อกได้โดยตรง โดยค่าเริ่มต้น AREF จะเชื่อมต่อกับ Vcc และคุณจะได้รับค่าสูงสุดที่ 1,023 เสมอ ไม่ว่าคุณจะใช้พลังงานจากแรงดันไฟฟ้าใดก็ตาม การเชื่อมต่อกับแหล่งจ่ายแรงดันไฟฟ้าด้วยแรงดันไฟฟ้าที่เสถียรและเป็นที่รู้จักก่อนหน้านี้จะช่วยได้ แต่นี่เป็นองค์ประกอบเพิ่มเติมในวงจร

คุณยังสามารถเชื่อมต่อ Vcc กับ AREF ผ่านทาง ไดโอด: แรงดันไฟฟ้าตกคร่อมไดโอดเป็นที่ทราบล่วงหน้า ดังนั้นการคำนวณ Vcc จึงไม่ใช่เรื่องยาก อย่างไรก็ตามด้วยวงจรดังกล่าวผ่านไดโอด กระแสไหลอย่างต่อเนื่องทำให้อายุการใช้งานแบตเตอรี่สั้นลงซึ่งก็ไม่ค่อยดีเช่นกัน

การอ้างอิงแรงดันไฟฟ้าภายนอกมีความแม่นยำที่สุด แต่ต้องใช้ฮาร์ดแวร์เพิ่มเติม ไอออนภายในมีเสถียรภาพแต่ไม่แม่นยำ +/- ส่วนเบี่ยงเบน 10% Vcc นั้นไม่น่าเชื่อถือโดยสิ้นเชิงในกรณีส่วนใหญ่ การเลือกแรงดันไฟฟ้าอ้างอิงภายในนั้นมีราคาไม่แพงและเสถียร แต่โดยส่วนใหญ่ เราต้องการวัดแรงดันไฟฟ้ามากกว่า 1.1V ดังนั้น การใช้ Vcc จึงเป็นวิธีที่ใช้งานได้จริงที่สุด แต่ก็มีความแม่นยำน้อยที่สุด ในบางกรณีก็อาจไม่น่าเชื่อถืออย่างมาก!

ทำอย่างไร

ชิป AVR จำนวนมาก รวมถึงซีรีส์ ATmega และ ATtiny เป็นเครื่องมือในการวัดแรงดันอ้างอิงภายใน เหตุใดจึงจำเป็น? เหตุผลง่ายๆ - โดยการวัดแรงดันไฟฟ้าภายใน เราสามารถกำหนดค่าของ Vcc ได้ มีวิธีดังนี้:

  1. ตั้งค่าการอ้างอิงแรงดันไฟฟ้าเริ่มต้น: analogReference(DEFAULT); - เราใช้ Vcc เป็นแหล่งที่มา
  2. อ่านค่า ADC สำหรับแหล่งกำเนิด 1.1 V ภายใน
  3. คำนวณค่า Vcc ตามการวัด 1.1 V โดยใช้สูตร:

Vcc * (อ่านค่า ADC) / 1023 = 1.1 V

ดังต่อไปนี้:

Vcc = 1.1 V * 1,023 / (อ่าน ADC)

เมื่อรวมทุกอย่างเข้าด้วยกันแล้วเราจะได้รหัส:

long readVcc() ( // อ่านการอ้างอิง 1.1V เทียบกับ AVcc // ตั้งค่าการอ้างอิงเป็น Vcc และการวัดเป็นการอ้างอิงภายใน 1.1V #if กำหนด(__AVR_ATmega32U4__) || กำหนด(__AVR_ATmega1280__) || กำหนด(__AVR_ATmega2560__) ADMUX = _BV (REFS0) |. _BV(MUX3) |. _BV(MUX1); #elif กำหนด(__AVR_ATtiny85__) ADMUX = _BV(MUX2); อื่น ADMUX = _BV(MUX3) |. MUX2) | _BV(MUX1); // รอให้ Vref ชำระ ADCSRA |= _BV(ADSC) ); ADCL; // ต้องอ่าน ADCL ก่อน - จากนั้นจะล็อค ADCH uint8_t high = ADCH; // ปลดล็อคทั้งผลลัพธ์แบบยาว = (high<<8) | low; result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000 return result; // Vcc in millivolts }

การใช้งาน

การตรวจสอบ Vcc หรือแรงดันแบตเตอรี่

คุณสามารถเรียกใช้ฟังก์ชันนี้ readVcc() หากคุณต้องการตรวจสอบ Vcc ตัวอย่างคือการตรวจสอบระดับประจุแบตเตอรี่ คุณยังสามารถใช้เพื่อตรวจสอบว่าคุณเชื่อมต่อกับแหล่งพลังงานหรือใช้พลังงานจากแบตเตอรี่หรือไม่

การวัด Vcc สำหรับแรงดันอ้างอิง

คุณยังสามารถใช้ค่านี้เพื่อรับค่า Vcc ที่ถูกต้องสำหรับใช้กับ analogRead() เมื่อคุณใช้แรงดันอ้างอิง (Vcc) เว้นแต่ว่าคุณใช้แหล่งจ่ายไฟที่มีการควบคุม คุณจะไม่สามารถแน่ใจได้ว่า Vcc = 5.0 โวลต์ ฟังก์ชั่นนี้ช่วยให้คุณได้รับค่าที่ถูกต้อง มีข้อแม้อยู่ประการหนึ่งว่า...

ในบทความหนึ่ง ฉันได้ประกาศว่าฟังก์ชันนี้สามารถใช้เพื่อปรับปรุงความแม่นยำของการวัดแบบอะนาล็อกในกรณีที่ Vcc ไม่ถึง 5.0 โวลต์ น่าเสียดายที่ขั้นตอนนี้ไม่ได้ให้ผลลัพธ์ที่ถูกต้อง ทำไม ขึ้นอยู่กับความถูกต้องของการอ้างอิงแรงดันไฟฟ้าภายใน ข้อมูลจำเพาะให้แรงดันไฟฟ้าเล็กน้อยที่ 1.1 โวลต์ แต่บอกว่าสามารถเปลี่ยนแปลงได้มากถึง 10% การวัดดังกล่าวอาจมีความแม่นยำน้อยกว่าแหล่งจ่ายไฟ Arduino ของเรา!

เพิ่มความแม่นยำ

แม้ว่าค่าความคลาดเคลื่อนที่สูงของแหล่งจ่ายไฟภายใน 1.1V จะจำกัดความแม่นยำในการวัดอย่างมากเมื่อใช้ในการผลิตจำนวนมาก แต่เราก็สามารถบรรลุความแม่นยำที่มากขึ้นสำหรับโครงการที่กำหนดเองได้ ทำได้ง่ายๆ เพียงวัด Vcc โดยใช้โวลต์มิเตอร์และฟังก์ชัน readVcc() ของเรา จากนั้นแทนที่ค่าคงที่ 1125300L ด้วยตัวแปรใหม่:

scale_constant = ภายใน1.1อ้างอิง * 1,023 * 1,000

Internal1.1Ref = 1.1 * Vcc1 (การอ่านค่าโวลต์มิเตอร์) / Vcc2 (readVcc_function_readings)

ค่าที่ปรับเทียบแล้วนี้จะเป็นตัวบ่งชี้ที่ดีสำหรับการวัดชิป AVR แต่อาจได้รับผลกระทบจากการเปลี่ยนแปลงของอุณหภูมิ รู้สึกอิสระที่จะทดลองกับการวัดของคุณเอง

บทสรุป

คุณสามารถทำอะไรได้มากมายด้วยฟีเจอร์เล็กๆ น้อยๆ นี้ คุณสามารถใช้แรงดันอ้างอิงที่เสถียรใกล้กับ 5.0V โดยไม่ต้องมี 5.0V บน Vcc จริงๆ คุณสามารถวัดแรงดันไฟฟ้าของแบตเตอรี่หรือดูว่าคุณกำลังใช้พลังงานจากแบตเตอรี่หรือพลังงานคงที่

สุดท้ายนี้ โค้ดจะรองรับ Arduino ทั้งหมด รวมถึง Leonardo ใหม่ รวมถึงชิปซีรีส์ ATtinyX4 และ ATtinyX5

บทความนี้แสดงวิธีเชื่อมต่อ Arduino และพีซี และถ่ายโอนข้อมูลจาก ADC ไปยังพีซี โปรแกรมสำหรับ Windows เขียนโดยใช้ Visual C++ 2008 Express โปรแกรมโวลต์มิเตอร์นั้นง่ายมากและยังมีสิ่งที่ต้องปรับปรุงอีกมาก จุดประสงค์หลักคือเพื่อแสดงวิธีการทำงานกับพอร์ต COM และแลกเปลี่ยนข้อมูลระหว่างคอมพิวเตอร์กับ Arduino

การสื่อสารระหว่าง Arduino และพีซี:

  • การอ่านค่าจาก ADC เริ่มต้นเมื่อคอมพิวเตอร์ส่งคำสั่ง Arduino 0xAC และ 0x1y ที่– หมายเลขช่อง ADC (0-2)
  • การอ่านหยุดลงหลังจาก Arduino ได้รับคำสั่ง 0xAC และ 0x00;
  • เมื่ออ่านค่า Arduino จะส่งคำสั่ง 0xAB 0xaa 0xbb ไปยังคอมพิวเตอร์ทุกๆ 50 ms โดยที่ aa และ bb คือผลการวัดสูงสุดและต่ำสุด

โปรแกรมสำหรับ Arduino

คุณสามารถอ่านเพิ่มเติมเกี่ยวกับการสื่อสารแบบอนุกรมได้ที่ arduino.cc โปรแกรมค่อนข้างง่าย ส่วนใหญ่จะใช้เวลาทำงานกับพอร์ตขนาน หลังจากอ่านข้อมูลจาก ADC เสร็จแล้ว เราได้รับค่าแรงดันไฟฟ้า 10 บิต (0x0000 – 0x0400) ในรูปแบบของตัวแปร 16 บิต (INT) พอร์ตอนุกรม (RS-232) อนุญาตให้ส่งข้อมูลในรูปแบบแพ็กเก็ต 8 บิต จำเป็นต้องแบ่งตัวแปร 16 บิตออกเป็น 2 ส่วนๆ ละ 8 บิต

Serial พิมพ์ (แรงดันไฟฟ้า >> 8, ไบต์);

Serial พิมพ์ (แรงดันไฟฟ้า% 256, ไบต์);

เราเลื่อนไบต์ของตัวแปรไปทางขวา 8 บิตแล้วหารด้วย 256 แล้วส่งผลลัพธ์ไปยังคอมพิวเตอร์

คุณสามารถดาวน์โหลดซอร์สโค้ดแบบเต็มสำหรับซอฟต์แวร์ Arduino ได้

วิชวลซี++

ฉันคิดว่าคุณมีความรู้พื้นฐานเกี่ยวกับการเขียนโปรแกรม C++ สำหรับ Windows อยู่แล้ว หากไม่มี ให้ใช้ Google อินเทอร์เน็ตเต็มไปด้วยบทช่วยสอนสำหรับผู้เริ่มต้น

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

หลังจากค้นหาพอร์ตอนุกรมที่มีอยู่แล้ว พอร์ตแรกจะถูกเลือกตามค่าเริ่มต้น ดำเนินการอย่างไร:

อาร์เรย์< String ^>↑ พอร์ตอนุกรม = nullptr;

serialPorts = serialPort1->GetPortNames();

นี้->comboBox1->รายการ->AddRange(serialPorts);

นี้->comboBox1->SelectedIndex=0;

พอร์ตอนุกรมบนพีซีสามารถใช้งานได้ครั้งละหนึ่งแอปพลิเคชันเท่านั้น ดังนั้นจะต้องเปิดพอร์ตก่อนใช้งานและต้องไม่ปิด คำสั่งง่ายๆ สำหรับสิ่งนี้:

พอร์ตอนุกรม1->เปิด();

พอร์ตอนุกรม1->ปิด();

หากต้องการอ่านข้อมูลจากพอร์ตอนุกรมอย่างถูกต้อง คุณต้องใช้เหตุการณ์ (ในกรณีของเราคือการขัดจังหวะ) เลือกประเภทเหตุการณ์:

รายการแบบเลื่อนลงเมื่อดับเบิลคลิก "DataReceived"

รหัสเหตุการณ์จะถูกสร้างขึ้นโดยอัตโนมัติ:

หากไบต์แรกมาถึงพอร์ตอนุกรมคือ 0xAB แสดงว่าไบต์ที่เหลือมีข้อมูลแรงดันไฟฟ้า

ส่วนตัว: System::Void serialPort1_DataReceived (ผู้ส่ง System::Object^, System::IO::Ports::SerialDataReceivedEventArgs^ e) (

ถ่าน data0, data1 ที่ไม่ได้ลงนาม;

ถ้า (serialPort1->ReadByte()==0xAB) (

data0=serialPort1->ReadByte();

data1=serialPort1->ReadByte();

แรงดันไฟฟ้า=คณิตศาสตร์::รอบ((ลอย(data0*256+data1)/1024*5.00),2);

ข้อมูล_จำนวน++;

พอร์ตอนุกรม1->ReadByte();

เขียนและอ่านข้อมูลพอร์ตอนุกรม

ปัญหาเล็กๆ สำหรับฉันคือการส่งข้อมูล RAW ฐานสิบหกผ่านพอร์ตอนุกรม มีการใช้คำสั่ง Write(); แต่มีสามอาร์กิวเมนต์: อาร์เรย์, หมายเลขไบต์เริ่มต้น, จำนวนไบต์ที่จะเขียน

ส่วนตัว: System::Void button2_Click_1 (System::Object^ ผู้ส่ง System::EventArgs^ e) (

ช่องถ่านที่ไม่ได้ลงนาม = 0;

ช่อง=นี่->listBox1->SelectedIndex;

อาร์เรย์^เริ่มต้น =(0xAC,(0x10+ช่อง));

อาร์เรย์^หยุด =(0xAC,0x00);

serialPort1->เขียน (เริ่ม,0,2);

นี้->button2->ข้อความ="หยุด";

) อื่น (

serialPort1->เขียน (หยุด,0,2);

นี้->button2->ข้อความ="Start";

นั่นคือทั้งหมด!

บทความต้นฉบับเป็นภาษาอังกฤษ (แปล: อเล็กซานเดอร์ คัสยานอฟสำหรับเว็บไซต์ cxem.net)



มีคำถามหรือไม่?

แจ้งการพิมพ์ผิด

ข้อความที่จะส่งถึงบรรณาธิการของเรา: