สารบัญ:

การควบคุมวงแหวน LED Neopixel ด้วยเซ็นเซอร์ท่าทางสัมผัส: 3 ขั้นตอน (พร้อมรูปภาพ)
การควบคุมวงแหวน LED Neopixel ด้วยเซ็นเซอร์ท่าทางสัมผัส: 3 ขั้นตอน (พร้อมรูปภาพ)

วีดีโอ: การควบคุมวงแหวน LED Neopixel ด้วยเซ็นเซอร์ท่าทางสัมผัส: 3 ขั้นตอน (พร้อมรูปภาพ)

วีดีโอ: การควบคุมวงแหวน LED Neopixel ด้วยเซ็นเซอร์ท่าทางสัมผัส: 3 ขั้นตอน (พร้อมรูปภาพ)
วีดีโอ: How to connect Neopixel ws2812 LED Strip or LED Ring 12bit with Arduino Tutorial 2024, พฤศจิกายน
Anonim
Image
Image
ประกอบ & อัพโหลด
ประกอบ & อัพโหลด

ในบทช่วยสอนนี้ เราจะเล่นกับเซ็นเซอร์ท่าทางสัมผัส (APDS-9960) และวงแหวนนีโอพิกเซลเพื่อเรียนรู้วิธีรวมทั้งสองอย่างเข้าด้วยกันโดยใช้ Arduino UNO

ผลิตภัณฑ์สุดท้ายจะตอบสนองต่อท่าทางซ้าย - ขวาโดยการเคลื่อนไหวแบบ LED ไปทางขวาหรือซ้าย และท่าทางขึ้น-ลงโดยการเปลี่ยนสีไฟ LED

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

ขั้นตอนที่ 1: ส่วนประกอบ

1. Arduino UNO

2.สายusb

3. เซ็นเซอร์ท่าทางสัมผัส APDS9960 (https://www.sparkfun.com/products/12787)

4. 24 led neopixel led แหวน (https://www.adafruit.com/product/1586)

5.สายเขียงหั่นขนมชาย-หญิงชาย-ชาย

6. เขียงหั่นขนม

7. แหล่งจ่ายไฟ 5 V สำหรับวงแหวน LED (ฉันใช้แบตเตอรี 4 ก้อน)

8. ในการติดวงแหวนนีโอพิกเซลเข้ากับเขียงหั่นขนม คุณจะต้องบัดกรีหมุดตัวผู้สามตัวเข้าด้วยกัน: GND, PWR และพินควบคุม สำหรับสิ่งนี้ คุณจะต้องใช้หัวแร้งและฟลักซ์

ส่วนประกอบหลักที่นี่คือเซ็นเซอร์ท่าทางสัมผัส APDS-9960 และวงแหวนนีโอพิกเซล 24 อัน คุณสามารถเปลี่ยน Arduinos, สายไฟ USB และเขียงหั่นขนมได้ตามที่คุณต้องการ

ขั้นตอนที่ 2: ประกอบและอัปโหลด

การประกอบ

ก่อนที่คุณจะเริ่มต้นตรวจสอบให้แน่ใจว่าคุณมีส่วนประกอบทั้งหมดอยู่ในตารางของคุณ เราจะมีขั้นตอนดีๆ ให้ติดตามกัน:) ฉันได้แนบแผนผัง Fritzing เป็นรูปภาพและอยู่ในรูปแบบ fritzing ด้วย

1. บัดกรีหมุดตัวผู้ 3 ตัวเข้ากับวงแหวนนีโอพิกเซล (GND, PWR, พินควบคุม)

2. ติดวงแหวนนีโอพิกเซลเข้ากับเขียงหั่นขนม

3. ติดเซ็นเซอร์ APDS9960 เข้ากับเขียงหั่นขนม

4. เชื่อมต่อกราวด์: ชุดแบตเตอรี่, Arduino UNO, APDS9960 และนีโอพิกเซลกับกราวด์เขียงหั่นขนม

5. เชื่อมต่อพลังงาน: arduino UNO 3V กับพินพลังงาน APDS9960, นีโอพิกเซลเป็นพลังงานของก้อนแบตเตอรี่

6. เชื่อมต่อพินควบคุมนีโอพิกเซลกับ arduino D6 pin

7. เชื่อมต่อ SDA และ SCL ของ APDS9960 กับ A4 และ A5 ตามลำดับ

8. เชื่อมต่อพินขัดจังหวะ APDS9960 กับ arduino D2

อัพโหลดโค้ด

ก่อนอื่น คุณจะต้องดาวน์โหลดและติดตั้งไลบรารี Arduino ที่จำเป็น:

1. ห้องสมุดนีโอพิกเซลริง:

2. ไลบรารีเซ็นเซอร์ท่าทางสัมผัส:

หากคุณไม่ทราบวิธีการติดตั้งไลบรารี่ Arduino ลองดูบทช่วยสอนนี้

หลังจากที่คุณดาวน์โหลดและติดตั้งไลบรารีด้านบนแล้ว คุณสามารถโคลนหรือดาวน์โหลดที่เก็บ Arduino ของฉันได้ที่นี่: https://github.com/danionescu0/arduino และเราจะใช้แบบร่างนี้: https://github.com/danionescu0 /arduino/tree/master/projects/neopixel_ring_gestures

ในส่วนถัดไป ฉันจะฝังโค้ดลงในบทช่วยสอนนี้โดยตรง ดังนั้นหากคุณต้องการ คุณสามารถคัดลอกและวางจากที่นั่นได้

ในที่สุดเชื่อมต่อ Arduino กับคอมพิวเตอร์โดยใช้สาย USB ใส่แบตเตอรี่ 1.5 v ลงในชุดแบตเตอรี่แล้วอัปโหลดภาพร่างไปยัง Arduino

ขั้นตอนที่ 3: มันทำงานอย่างไร ?

ในส่วนสุดท้ายนี้ เราจะมาเรียนรู้ว่าส่วนประกอบเหล่านี้ถูกรวมเข้าด้วยกันอย่างไร วิธีใช้ไลบรารี่อย่างไร และผมจัดโครงสร้างโค้ดอย่างไร:

ขั้นแรก มาดูภาพรวมคร่าวๆ ผ่านเซ็นเซอร์และวิธีการ API ไลบรารีนีโอพิกเซลที่เราจะใช้กัน

1. Neopixel API จาก adafruit

จากไลบรารีนี้ เราจะใช้วิธีการที่ควบคุมสีของ led แต่ละตัวและนำไปใช้

- รวมถึงห้องสมุด:

#รวม

- ประกาศห้องสมุด

#define NEOPIXED_CONTROL_PIN 6

#define NUM_LEDS 24 แถบ Adafruit_NeoPixel = Adafruit_NeoPixel (NUM_LEDS, NEOPIXED_CONTROL_PIN, NEO_RBG + NEO_KHZ800);

- เริ่มต้น

#โดยปกติอยู่ภายในบล็อกการติดตั้ง

การตั้งค่าเป็นโมฆะ () { strip.begin (); # อาจจะมีอย่างอื่นที่นี่ # …. }

- สว่างขึ้นแต่ละพิกเซลจากนั้นใช้การปรับเปลี่ยนทั้งหมดกับแถบ (แสดงผลในทางใดทางหนึ่ง)

# ตั้งค่าพิกเซล 0 ให้เป็นสีแดง

strip.setPixelColor(0, แถบสี(255, 0, 0)); # ตั้งค่าพิกเซล 1 ให้เป็นสีเขียว strip.setPixelColor(1, strip. Color(0, 255, 0)); # ตั้งค่าพิกเซล 2 ให้เป็นแถบสีน้ำเงิน setPixelColor(2, strip. Color(0, 0 255)); แถบ.show();

2. เซ็นเซอร์ท่าทางสัมผัส APDS 9960

จากไลบรารีนี้ เราจะใช้ฟังก์ชัน "อ่านท่าทาง" ฟังก์ชันนี้จะสามารถแยกแยะระหว่างคำสั่งซ้าย-ขวา บน-ล่าง ระยะใกล้ มีเคล็ดลับอยู่ที่นี่ เราจะไม่ถามเซ็นเซอร์อย่างต่อเนื่องสำหรับการรับรู้ท่าทางสุดท้าย บอร์ดมีความสามารถในการ "ping" ผ่านการขัดจังหวะที่พบท่าทางสัมผัส

- รวมห้องสมุดคล้ายกับ neopixel

- ประกาศไลบรารีพินขัดจังหวะและแฟล็กขัดจังหวะ

#define APDS9960_INT 2

SparkFun_APDS9960 apds = SparkFun_APDS9960(); int isr_flag = 0;

- เริ่มต้นไลบรารี โดยทั่วไปจะอยู่ภายในฟังก์ชันการตั้งค่า

การตั้งค่าเป็นโมฆะ ()

{ # ประกาศขาขัดจังหวะเป็น INPUT และแนบฟังก์ชันกับ pinMode (APDS9960_INT, INPUT); AttachInterrupt(0, การขัดจังหวะรูทีน, การล้ม); ถ้า (apds.init () && apds.enableGestureSensor (จริง)) { Serial.println ("การเริ่มต้น APDS-9960 เสร็จสมบูรณ์"); } อื่น { Serial.println("มีบางอย่างผิดพลาดระหว่างการเริ่มต้น APDS-9960!"); } # อาจเริ่มต้นสิ่งอื่น ๆ }

- กำหนดฟังก์ชั่นขัดจังหวะที่นี่เราจะตั้งค่าสถานะเท่านั้น

เป็นโมฆะขัดจังหวะรูทีน () {

isr_flag = 1; }

- ภายในฟังก์ชันวนรอบ ตรวจสอบแฟล็กเป็นระยะเพื่อดูว่ามีการตรวจพบท่าทางหรือไม่

วงเป็นโมฆะ ()

{ # ตรวจสอบแฟล็ก if(isr_flag == 1) { # หากตั้งค่าแฟล็ก ลบการขัดจังหวะ ทำการประมวลผลที่จำเป็นภายในฟังก์ชัน handleGesture() # จากนั้นรีเซ็ตแฟล็กและแนบอินเตอร์รัปต์ detachInterrupt(0); จัดการท่าทาง (); isr_flag = 0; แนบInterrupt(0, ขัดจังหวะกิจวัตร ล้ม); } # รหัสอื่น ๆ ที่นี่อาจจะ }

- กำหนดฟังก์ชั่น handleGesture() ที่เราสามารถขอท่าทางสุดท้ายได้

โมฆะ handleGesture () {

# หากไม่มีท่าทางสัมผัสที่ส่งคืนได้ นี่เป็นเพียงการตรวจสอบอย่างปลอดภัยว่า (!apds.isGestureAvailable()) { return; } # อ่านท่าทางสุดท้ายเปรียบเทียบกับท่าทางที่รู้จักและพิมพ์สวิตช์ข้อความ (apds.readGesture ()) { กรณี DIR_UP: Serial.println ("UP"); หยุดพัก; กรณี DIR_DOWN: Serial.println("DOWN"); หยุดพัก; กรณี DIR_LEFT: Serial.println("LEFT"); หยุดพัก; กรณี DIR_RIGHT: Serial.println("RIGHT"); หยุดพัก; กรณี DIR_FAR: Serial.println("FAR"); หยุดพัก; } }

ทีนี้มาดูการทำงานของโค้ดทั้งหมดกัน:

ฉันได้อธิบาย API พื้นฐานของเซ็นเซอร์ท่าทางสัมผัสและวงแหวนนีโอพิกเซลแล้ว ตอนนี้มารวมกัน:

อัลกอริทึมทำงานดังนี้:

- เริ่มต้นไลบรารี (ดูรหัสด้านบน)

- สร้างอาร์เรย์ของความเข้มนำที่เรียกว่า "ledStates" อาร์เรย์นี้จะมีความเข้มนำ 24 แบบที่จัดเรียงจากมากไปหาน้อยจาก 150 ถึง 2

- ภายในลูปหลักตรวจสอบว่าพินอินเทอร์รัปต์ได้รับการแก้ไขหรือไม่หากถึงเวลาต้องเปลี่ยนภาพเคลื่อนไหวหรือสีของไฟ LED

- ฟังก์ชัน "handleGesture()" ตรวจสอบท่าทางสัมผัสสุดท้ายและเรียกใช้ฟังก์ชัน "toggleColor" สำหรับท่าทาง UP -DOWN หรือตั้งค่าตัวแปรทั่วโลก "ledDirection" สำหรับท่าทางซ้าย - ขวา

- ฟังก์ชัน "toggleColor()" เพียงแค่เปลี่ยนตัวแปรโกลบอลชื่อ "colorSelection" ด้วยค่าใดค่าหนึ่ง 0, 1, 2

- ยังอยู่ในฟังก์ชันลูปหลักอีกฟังก์ชันหนึ่งชื่อ "animateLeds();" ถูกเรียก. ฟังก์ชันนี้จะตรวจสอบว่า 100 มิลลิวินาทีผ่านไปหรือไม่ และหากเป็นเช่นนั้น ไฟ LED จะหมุนโดยใช้ฟังก์ชัน "rotateLeds()" แล้ววาดใหม่

- "rotateLeds()" จะ "หมุน" ไฟ LED ไปข้างหน้าหรือข้างหลังโดยใช้อาร์เรย์อื่นที่เรียกว่า "intermediateLedStates"

"เอฟเฟกต์" ของการหมุนจะมีลักษณะดังนี้:

#หลังจากเริ่มต้น

{150, 100, 70, 50, 40, 30, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; # หลังจากการหมุนLeds() เรียกว่า {0, 150, 100, 70, 50, 40, 30, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; # หลังจากการหมุนLeds() ถูกเรียกอีกครั้ง {0, 0, 150, 100, 70, 50, 40, 30, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; #และอื่นๆ

สำหรับสิ่งนี้ก่อนอื่น ให้สร้างอาร์เรย์ใหม่และคัดลอกความเข้มนำเก่าในตำแหน่งใหม่ (เพิ่มตำแหน่งหรือลดระดับลง) หลังจากนั้นจะเขียนทับอาร์เรย์ "ledStates" ด้วย "intermediateLedStates" ดังนั้นกระบวนการจะดำเนินต่อไปหลังจากอีก 100 มิลลิวินาที

#รวม "SparkFun_APDS9960.h"

#รวม "Adafruit_NeoPixel.h"

#include "Wire.h" #define NEOPIXED_CONTROL_PIN 6 #define NUM_LEDS 24 #define APDS9960_INT 2 #define LED_SPEED_STEP_INTERVAL 100 Adafruit_NeoPixel แถบ = Adafruit_NeoPixel(NUM_LEDS, NEOPIXED_CONTROL_PIN, NEO_RBG); SparkFun_APDS9960 apds = SparkFun_APDS9960(); LastLedChangeTime ที่ไม่ได้ลงนามนาน = 0; led สั้นทิศทาง = 0; การเลือกสีสั้น = 0; ไบต์ ledStates = {150, 100, 70, 50, 40, 30, 10, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int isr_flag = 0; การตั้งค่าเป็นโมฆะ () { Serial.begin (9600); Serial.println("เริ่มโปรแกรม"); แถบ.begin(); โหมดพิน (APDS9960_INT, INPUT); AttachInterrupt(0, การขัดจังหวะรูทีน, การล้ม); ถ้า (apds.init () && apds.enableGestureSensor (จริง)) { Serial.println ("การเริ่มต้น APDS-9960 เสร็จสมบูรณ์"); } อื่น { Serial.println("มีบางอย่างผิดพลาดระหว่างการเริ่มต้น APDS-9960!"); } lastLedChangeTime = มิลลิวินาที (); Serial.println("เริ่มต้นได้สำเร็จ"); } วงเป็นโมฆะ () { ถ้า (isr_flag == 1) { detachInterrupt (0); จัดการท่าทาง (); isr_flag = 0; AttachInterrupt(0, การขัดจังหวะรูทีน, การล้ม); } ภาพเคลื่อนไหวLeds(); } โมฆะ interruptRoutine () { isr_flag = 1; } /** * สิ่งนี้จะจัดการท่าทางสัมผัสจากเซ็นเซอร์ APDS9960 * ท่าทางสัมผัสขึ้นและลงจะเรียกใช้ฟังก์ชัน toggleColor * ท่าทางสัมผัสซ้ายและขวาจะเปลี่ยนภาพเคลื่อนไหวที่นำ */ void handleGesture() { if (!apds.isGestureAvailable()) { return; } สวิตช์ (apds.readGesture ()) { กรณี DIR_UP: Serial.println ("UP"); สลับสี(); หยุดพัก; กรณี DIR_DOWN: Serial.println("DOWN"); สลับสี(); หยุดพัก; กรณี DIR_LEFT: ledDirection = 1; Serial.println("ซ้าย"); หยุดพัก; กรณี DIR_RIGHT: ledDirection = -1; Serial.println("ขวา"); หยุดพัก; กรณี DIR_FAR: ledDirection = 0; Serial.println("ไกล"); หยุดพัก; } } /** * เปลี่ยนสีไฟ LED ปัจจุบัน * ทุกครั้งที่เรียกใช้ฟังก์ชันนี้จะเปลี่ยนสถานะไฟ LED */ void toggleColor() { if (colorSelection == 0) { colorSelection = 1; } อื่น ๆ ถ้า (colorSelection == 1) { colorSelection = 2; } อื่น ๆ { colorSelection = 0; } } /** * แอนิเมชั่นจะทำงานหลังจาก LED_SPEED_STEP_INTERVAL มิลลิวินาที * ขั้นแรกให้เรียกใช้ฟังก์ชัน turnsLeds จากนั้นสีไฟ LED จะถูกตั้งค่าโดยใช้แถบ api */ void animateLeds() { if (millis() - lastLedChangeTime < LED_SPEED_STEP_INTERVAL) { return; } หมุนLeds(); สำหรับ (int i = 0; i < NUM_LEDS; i ++) { strip.setPixelColor (i, getColor (ledStates )); แถบ.show(); } lastLedChangeTime = มิลลิวินาที (); } /** * การใช้อาร์เรย์รอง "intermediateLedStates" ความเข้มของไฟ LED จะเคลื่อนไหว * ขั้นแรก ค่าจาก "ledStates" จะถูกคัดลอกบน "intermediateLedStates" เช่นนั้น * ให้ลองตั้งค่าอาร์เรย์ "ledStates" ก่อน คือ {100, 80, 60, 0, 0, 0} และ ledDirection คือ 1 * จากนั้นหลังจากฟังก์ชันนี้เรียกว่า "ledStates" อาร์เรย์คือ {0, 100, 80, 60, 0, 0} จำลองเอฟเฟกต์การหมุน */ voidrotatedLeds() { byte intermediateLedStates[NUM_LEDS]; สำหรับ (int i=0; i < NUM_LEDS; i++) { intermediateLedStates = 0; } สำหรับ (int i=0; i < NUM_LEDS; i++) { if (ledDirection == 1) { if (i == NUM_LEDS -1) { intermediateLedStates[0] = ledStates; } อื่น ๆ { intermediateLedStates[i + 1] = ledStates; } } อื่น { ถ้า (i == 0) { intermediateLedStates [NUM_LEDS - 1] = ledStates ; } อื่น ๆ { intermediateLedStates[i - 1] = ledStates; } } } สำหรับ (int i=0; i < NUM_LEDS; i++) { ledStates = intermediateLedStates; } } uint32_t getColor (ความเข้ม int) { สวิตช์ (colorSelection) { กรณี 0: แถบกลับ. สี (ความเข้ม, 0, 0); กรณีที่ 1: แถบกลับ. สี(0, ความเข้ม, 0); ค่าเริ่มต้น: แถบกลับ. สี(0, 0, ความเข้ม); } }

ฉันหวังว่าคุณจะสนุกกับสิ่งนี้ คุณสามารถใช้ส่วนความคิดเห็นเพื่อถามคำถาม

แนะนำ: