在本教程中,我們將使用ATMega328P IC制作觸摸電容 PCB來控制新像素LED 燈條。我們將在我們的 PCB 上包含一些功能,例如音樂反應模式、隨機動畫模式和 RGB 控制模式。到目前為止,我們已經制作了觸摸電容鋼琴,您可以在其中找到 觸摸電容的基礎知識 技術。現在在本教程中,我們將設計一個基于觸控電容的燈板 PCB,它將具有三種不同的模式來控制 Neo-Pixel 條。這些模式是“環形模式”,我們可以使用板上的滑塊更改 LED 顏色。第二種模式是“RGB 模式”,我們可以在 RGB 顏色之間更改 LED 燈條的顏色和強度,最后一種模式是“音樂模式”,其中 LED 的顏色和強度會根據音樂播放而變化。這個優雅的項目設計是由 PCBWay制造的 PCB 板實現的,我們還將向您展示該板是如何設計和從 PCBway 訂購的
構建前面板 PCB 所需的組件
使用 Arduino Nano 構建 PCB 鋼琴需要以下組件。
ATMega328P IC(DIP 封裝)
貼片電阻器 (1Mega Ohm, 0805) X 9
貼片電阻 (1K, 0805)x1
壓電蜂鳴器
貼片78M05集成電路
貼片電解電容 (10uF,16V,4x45mm) x 2
貼片電容 ( 22pF 0805) x 11
晶體振蕩器 (16 MHz)
PCB燈板的電路圖
9 個 1Mega Ohm 電阻器連接到 ATMega328P IC 的引腳編號 PB1,作為以下電路圖中的公共引腳。數字引腳 PD2 到 PD7 和 PB0 進一步連接到每個電阻的其他連接點。在下圖中,剩余的數字引腳連接到 1x5 引腳接頭并命名為“剩余數字引腳”。
我們已將八個 22uF 電容器連接到每個電阻器。每個電容器的負極引腳連接到 Atmega328p IC 的接地引腳。然后我們有一個電源部分,為 ATMega328P IC 和 Neo Pixel 提供適當的 5V。
注:如有需要,我們可以加電容。強烈建議使用小電容器 (20pF - 400pF) 來穩定檢測到的數據。但是,請確保電容器接地,因為這會降低與體電阻的并聯。就我而言,我沒有使用電容器,因為沒有它們對我來說效果很好。我在上面的示意圖中提到了電容器,因此您可以在實際實施過程中輕松添加它們。按照“ CapacitveSensor ”庫文檔中的規定,以下電容器的值必須介于 20pF 和 400pF 之間。
電容式傳感器庫如何工作?
這就是 Arduino 庫派上用場的地方。感謝“ CapacitiveSensor ”庫的作者Paul Bagde r 和Paul Stoffregen 。當我們觸摸那個導電板時,我們可以使用這個庫來檢測電容的變化。在這個庫中,其中一個數字引腳用作發送引腳(作為 OUTPUT),而另一個用作接收引腳(作為 INPUT)。發送引腳變為高電平和接收引腳變為高電平之間的持續時間是檢測電容變化的唯一方法。當您將發送引腳設置為高電平(或5 伏)時,電阻-電容對會在發送引腳變為高電平之間產生延遲 當接收引腳從發送引腳讀取高值時。CapacitiveSensor 庫提供了一個將發送引腳設置為高電平的函數,然后等待并計數,直到接收引腳被讀取為高電平。此函數返回可用于檢測電容變化的時間值。當時間值增大或減小時,表明電容值發生了變化。當電容較大時,接收引腳將需要更長的時間才能達到高電平,而當電容較小時,將需要更短的時間才能達到高電平。因此,我們可以確定正常狀態是什么,然后在每次發送引腳切換時檢查更改。
為PCB燈板制造PCB
現在我們有了原理圖,我們可以繼續為基于觸摸電容的 PCB 燈板布置 PCB。您可以使用您選擇的任何 PCB 軟件來設計 PCB。在這里,我們使用 EasyEDA 平臺為我們的項目創建原理圖和 PCB。下面是PCB Light Panel頂層和底層的3D模型視圖:
上述電路的 PCB 布局也可以從下面給出的鏈接下載為 Gerber:
項目的 Gerber 文件
組裝觸控電容燈面板 PCB
訂購板后,幾天后,它通過快遞在一個標簽整齊且包裝完好的盒子中到達我的手中。PCB質量一如既往的好。板子的頂層和底層如下圖所示:
在確保軌道和腳印是正確的之后。我繼續組裝PCB。完全焊接的板如下所示:
PCB燈板編程
觸摸電容式 PCB 燈板的完整代碼可以從該項目的 github 存儲庫中下載。“CapacitiveSensor”庫非常易于使用,并且他們提供了有關如何使用該庫的很好的文檔。在進入程序之前,讓我們在 Arduino IDE 上安裝“CapacitiveSensor”庫。您需要下載庫的 zip 文件。然后轉到Arduino IDE 工具欄下的“Sketch -> Include Library ”部分。使用“添加 .Zip 庫...”選項添加 zip 文件,如下圖所示。然后重新啟動 Arduino IDE。類似的方式你也可以安裝ADCTouch.h庫。
現在安裝所需的庫文件后,通過包含所有庫文件來啟動代碼。Adafruit_NeoPixel.h 用于控制基于單線的 LED 像素和燈條。在這里,我們使用它來控制 Neo-Pixel LED 燈條。CapacitiveSensor 庫用于感應 PCB 焊盤上的觸摸。
#include#include <電容傳感器.h> #include
然后在接下來的幾行中,我們使用CapacitiveSensor()函數創建了九個實例。這些實例定義了連接觸摸板的引腳。此函數的語法是CapacitiveSensor(byte sendPin, byte receivePin),其中一個數字引腳用作發送引腳(作為 OUTPUT),而另一個用作此庫中的接收引腳(作為 INPUT)。
CapacitiveSensor Mode_Pad = CapacitiveSensor(9,8); CapacitiveSensor RGB_Pad = CapacitiveSensor(9,7); CapacitiveSensor Music_Pad = CapacitiveSensor(9,6); 電容傳感器 Ring_L_Pad = 電容傳感器(9,5); 電容傳感器 Ring_LT_Pad = 電容傳感器(9,4); 電容傳感器 Ring_T_Pad = 電容傳感器(9,3); 電容傳感器 Ring_TR_Pad = 電容傳感器(9,2);
之后,聲明 Neo Pixel 條對象,其中 Argument 1 是 Neo Pixel 條中的像素數,Argument 2 是連接 LED 條的引腳。
Adafruit_NeoPixel strip = Adafruit_NeoPixel(N_PIXELS, PIN, NEO_GRB + NEO_KHZ800);
然后我們定義了一些函數來檢測墊和環上的觸摸。前三個函數ModeMode()、RGBMode()和MusicMode()用于檢測用于在 PCB 不同模式之間切換的焊盤上的觸摸。在第一個函數中,我們將讀取第一個焊盤的值,即“MODE”,如果檢測到的值大于 500,則它將返回 1,否則返回 0。同樣,我們為 RGB pad 和 MUSIC pad 定義了另外兩個函數。
布爾模式模式(){ long Mode_Pad_Value = Mode_Pad.capacitiveSensor(30; 如果 (Mode_Pad_Value>500) 返回 1; 別的 返回0; } 布爾 RGBMode(){ 長 RGB_Pad_Value = RGB_Pad.capacitiveSensor(30); 如果(RGB_Pad_Value>500) 返回 1; 別的 返回0; } 布爾音樂模式(){ 長 Music_Pad_Value = Music_Pad.capacitiveSensor(30); 如果(Music_Pad_Value>500) 返回 1; 別的 返回0; }
Check_Ring_Pos()函數用于檢測環上的觸摸。除此之外,它還存儲環位置。這些環位置用于檢測環上的順時針或逆時針旋轉。同樣,我們定義了另一個函數來檢查滑塊位置,并且我們還使用滑塊上的焊盤位置檢查滑動方向。
字符 Check_Ring_Pos() { char ring_pos = 0; 字符結果 = 0; 長 Ring_L_Pad_Value = Ring_L_Pad.capacitiveSensor(30); 長 Ring_LT_Pad_Value = Ring_LT_Pad.capacitiveSensor(30); 長 Ring_T_Pad_Value = Ring_T_Pad.capacitiveSensor(30); 長 Ring_TR_Pad_Value = Ring_TR_Pad.capacitiveSensor(30); 如果(Ring_L_Pad_Value>500) ring_pos = 1; 如果(Ring_LT_Pad_Value>500) ring_pos = 2; 如果(Ring_T_Pad_Value>500) ring_pos = 3; 如果(Ring_TR_Pad_Value>500) ring_pos = 4; char current_ring_pos = ring_pos; Serial.println(current_ring_pos - pvs_ring_pos); 如果 ((current_ring_pos - pvs_ring_pos) == 1) 結果 = 1; 如果 ((current_ring_pos - pvs_ring_pos) == -1) 結果=2; if (current_ring_pos != pvs_ring_pos); pvs_ring_pos = current_ring_pos; 返回結果; }
現在我們知道是否觸摸了特定的墊子,如果是,那么在哪個方向上,我們將使用這些讀數在三種模式之間切換。在RGB 模式下,我們可以使用滑塊來增加或減少燈光的強度。如果我們從左向右滑動,強度會增加,如果我們從右向左滑動,強度會降低。同樣,我們可以使用順時針或逆時針方向的環形墊來改變顏色。在模式模式下,環形墊將用于順時針和逆時針方向旋轉燈。
無效 RGB_Mode(){ Serial.print("我們已進入 RGB 模式"); 嘟(); uint16_t i, j, k; 亮度 = 255; 而(1){ char Sider_Status = Check_Slider_Pos(); char Ring_Status = Check_Ring_Pos(); if (Sider_Status ==1){ // 不移動返回 0,從右到左返回 2 Serial.println("從左向右移動"); 嘟(); 亮度=亮度+50; Serial.print(亮度); } …………………………………………..
現在,如果觸摸音樂模式鍵盤,Arduino 將開始讀取麥克風讀數,并根據音樂隨機改變燈光的強度和顏色。
無效音樂模式(){ Serial.print("我們已經進入音樂模式"); 嘟(); 而(1){ 如果(數字讀取(A5)==低) { Serial.print("TAP"); for(int i=0; i< 48; i++) { strip.setBrightness(隨機(100,255)); strip.setPixelColor(i, strip.Color(隨機 (0,255), 隨機 (0,255), 隨機 (0,255))); 剝離.show(); }
3D打印觸控電容式PCB燈板外殼
現在的想法是將這個 PCB 燈板掛在墻上,為此,我打印了一個 PCB 支架。我用我的游標測量了裝置的尺寸來設計一個外殼。完成后,我的設計如下所示。STL 文件也可以從Thingiverse下載,您可以使用它打印您的外殼。
測試觸控電容式 PCB 燈板
組裝好 PCB 并對 ATMega328 進行編程后,我們現在可以測試設置了。為此,將 3D 打印支架安裝在 PCB 上并包裹 Neo-pixel 條,如下所示:
現在使用 12V 適配器為電路板供電。您可以使用 MODE、RGB 和 MUSIC 三個觸摸板在不同模式之間切換,并使用滑塊來更改燈光的強度和顏色。
代碼
#include 《Adafruit_NeoPixel.h》
#include 《CapacitiveSensor.h》
#include 《ADCTouch.h》
#define PIN 10 //Neo 像素連接到引腳 10
#define BUZZER 13 //BUZZER 連接到引腳 D13
#define N_PIXELS 23 / /48 neopixel in led strip
#define MIC A5 // 麥克風連接在引腳 A5
#define N 10 // 樣本數
#define fadeDelay 25 // 淡入淡出量
#define noiseLevel 25 // 我們想要切斷的噪音量
int參考 1,參考 2,參考 3,參考 4,參考 5;//使用模擬引腳消除偏移的參考值是電容觸摸
char pvs_slider_pos = 0;
字符 pvs_ring_pos = 0;
整數樣本[N];// 存儲樣本
int periodFactor = 0; // 用于周期計算
詮釋 t1 = -1;
詮釋T;
坡度;
字節 periodChanged = 0;
詮釋亮度=0;
int led_position=0;
CapacitiveSensor Mode_Pad = CapacitiveSensor(9,8);
CapacitiveSensor RGB_Pad = CapacitiveSensor(9,7);
CapacitiveSensor Music_Pad = CapacitiveSensor(9,6);
電容傳感器 Ring_L_Pad = 電容傳感器(9,5);
電容傳感器 Ring_LT_Pad = 電容傳感器(9,4);
電容傳感器 Ring_T_Pad = 電容傳感器(9,3);
電容傳感器 Ring_TR_Pad = 電容傳感器(9,2);
//創建一個 NeoPixel 條帶
Adafruit_NeoPixel strip = Adafruit_NeoPixel(N_PIXELS, PIN, NEO_GRB + NEO_KHZ800);
布爾模式模式(){
long Mode_Pad_Value = Mode_Pad.capacitiveSensor(30);
如果 (Mode_Pad_Value》500)
返回 1;
否則
返回 0;
}
boolean RGBMode(){
long RGB_Pad_Value = RGB_Pad.capacitiveSensor(30);
如果 (RGB_Pad_Value》500)
返回 1;
否則
返回 0;
}
boolean MusicMode(){
long Music_Pad_Value = Music_Pad.capacitiveSensor(30);
如果 (Music_Pad_Value》500)
返回 1;
否則
返回 0;
}
char Check_Ring_Pos()
{
char ring_pos = 0;
字符結果 = 0;
長 Ring_L_Pad_Value = Ring_L_Pad.capacitiveSensor(30);
長 Ring_LT_Pad_Value = Ring_LT_Pad.capacitiveSensor(30);
長 Ring_T_Pad_Value = Ring_T_Pad.capacitiveSensor(30);
長 Ring_TR_Pad_Value = Ring_TR_Pad.capacitiveSensor(30);
如果 (Ring_L_Pad_Value》500)
ring_pos = 1;
如果 (Ring_LT_Pad_Value》500)
ring_pos = 2;
如果 (Ring_T_Pad_Value》500)
ring_pos = 3;
如果 (Ring_TR_Pad_Value》500)
ring_pos = 4;
char current_ring_pos = ring_pos;
Serial.println(current_ring_pos - pvs_ring_pos);
if ((current_ring_pos - pvs_ring_pos) == 1)
結果 = 1; //Serial.print(“順時針觸摸環”);
如果 ((current_ring_pos - pvs_ring_pos) == -1)
結果 =2; //Serial.print(“環逆時針觸摸”);
if (current_ring_pos != pvs_ring_pos);
pvs_ring_pos = current_ring_pos;
返回結果;
}
char Check_Slider_Pos()
{
char slider_pos = 0;
字符結果 = 0;
int sensorValue1 = ADCTouch.read(A0);
int sensorValue2 = ADCTouch.read(A1);
int sensorValue3 = ADCTouch.read(A2);
int sensorValue4 = ADCTouch.read(A3);
int sensorValue5 = ADCTouch.read(A4);
傳感器值1-= ref1;
傳感器值2-= ref2;
傳感器值3-= ref3;
傳感器值4-= ref4;
傳感器值5-= ref5;
如果(sensorValue1》50)
slider_pos = ‘1’;
如果(sensorValue2》50)
slider_pos = ‘2’;
if (sensorValue3》50)
slider_pos = ‘3’;
如果(sensorValue4》50)
slider_pos = ‘4’;
如果(sensorValue5》50)
slider_pos = ‘5’;
char current_slider_pos = slider_pos;
if ((current_slider_pos - pvs_slider_pos) == 1)
結果 = 1; //Serial.print(“滑塊從左到右”);
if ((current_slider_pos - pvs_slider_pos) == -1)
結果 =2; //Serial.print(“滑塊從右到左”);
if (current_slider_pos != pvs_slider_pos);
pvs_slider_pos = current_slider_pos;
返回結果;
}
void RGB_Mode(){
Serial.print(“我們已進入 RGB 模式”);
嘟();
uint16_t i, j, k;
亮度 = 255;
while(1){ //保持 RGB 模式
char Sider_Status = Check_Slider_Pos();
char Ring_Status = Check_Ring_Pos();
if (Sider_Status ==1){ // 不移動返回 0,從右到左返回 2
Serial.println (“Moved Left to Right”);
嘟();
亮度=亮度+50;
Serial.print(亮度);
}
if (Sider_Status==2){ // 不移動返回 0,從右到左返回 2
Serial.println (“Moved Right to Left”);
嘟();
亮度 = 亮度-50;
Serial.print(亮度);
}
if (Ring_Status==1) {//返回 0 表示不移動,2 表示逆時針
Serial.println (“Ring in Clockwise”);
嘟();
i = 隨機(0,255);
j = 隨機 (0,255);
k=隨機(0,255);
}
if (Ring_Status==2) {//返回 0 表示不移動,返回 2 表示逆時針
Serial.println (“Ring in Counter-Clockwise”);
嘟();
i = 隨機(0,255);
j = 隨機 (0,255);
k=隨機(0,255);
}
for(int x=0; x《N_PIXELS; x++) {
strip.setBrightness(Brightness);
strip.setPixelColor(x, strip.Color(i,j,k));
剝離.show();
}
if ( RGBMode() || ModeMode() || MusicMode())
中斷;
}
}
void Mode_Mode(){
Serial.print(“我們已進入 MODE 模式”);
嘟();
while(1){ //保持 RGB 模式
char Ring_Status = Check_Ring_Pos();
if (Ring_Status==1) {//返回 0 表示不移動,2 表示逆時針
Serial.println (“Ring in Clockwise”);
嘟();
}
for(int i=0; i《 48; i++) {
strip.setBrightness(255);
strip.fill(255,(i+0),(1+i));
strip.fill(0,0,i);
剝離.show();
延遲(20);
}
if (Ring_Status==2){ // 不移動返回 0,逆時針返回 2
Serial.println (“Ring in Anti- Clockwise”);
嘟();
for(int i=48; i》0; i--) {
strip.setBrightness(255);
strip.fill(255,(i+0),(1+i));
strip.fill(0,0,i);
剝離.show();
延遲(20);
}
}
if ( RGBMode() || ModeMode() || MusicMode())
中斷;
}
}
void Music_Mode(){
Serial.print(“我們已進入音樂模式”);
嘟();
while(1){ //保持 RGB 模式
if (digitalRead(A5)==LOW)
{
Serial.print(“TAP”);
for(int i=0; i《 48; i++)
{
strip.setBrightness(隨機(100,255));
strip.setPixelColor(i, strip.Color(隨機 (0,255), 隨機 (0,255), 隨機 (0,255)));
剝離.show();
}
延遲(100);
}
else
{
for(int i=0; i《 48; i++)
{
strip.setBrightness(0);
strip.setPixelColor(i, strip.Color(隨機 (0,255), 隨機 (0,255), 隨機 (0,255)));
剝離.show();
}
}
if ( RGBMode() || ModeMode() || MusicMode() )
中斷;
}
}
void setup() {
// 啟動條帶并將其
清空 strip.begin();
//strip.show();
//cs_4_2.set_CS_AutocaL_Millis(0xFFFFFFFF); // 關閉通道 1 上的自動校準 - 僅作為示例
Serial.begin(9600);
ref1 = ADCTouch.read(A0, 500);
ref2 = ADCTouch.read(A1, 500);
ref3 = ADCTouch.read(A2, 500);
ref4 = ADCTouch.read(A3, 500);
ref5 = ADCTouch.read(A4, 500);
pinMode(蜂鳴器,輸出);
}
void loop() {
//strip.clear();
剝離.show();
if (ModeMode()==1)
Mode_Mode();
if (RGBMode()==1)
RGB_Mode();
if (MusicMode()==1)
Music_Mode();
}
無效嗶(){
音(蜂鳴器,400);
延遲(50);
無音(蜂鳴器);
}
-
pcb
+關注
關注
4317文章
23013瀏覽量
396374 -
LED燈條
+關注
關注
2文章
100瀏覽量
13309 -
Atmega328P
+關注
關注
4文章
56瀏覽量
17204
發布評論請先 登錄
相關推薦
評論