在本教程中,我們將使用ATMega328P IC制作觸摸電容 PCB來控制新像素LED 燈條。我們將在我們的 PCB 上包含一些功能,例如音樂反應(yīng)模式、隨機(jī)動畫模式和 RGB 控制模式。到目前為止,我們已經(jīng)制作了觸摸電容鋼琴,您可以在其中找到 觸摸電容的基礎(chǔ)知識 技術(shù)?,F(xiàn)在在本教程中,我們將設(shè)計一個基于觸控電容的燈板 PCB,它將具有三種不同的模式來控制 Neo-Pixel 條。這些模式是“環(huán)形模式”,我們可以使用板上的滑塊更改 LED 顏色。第二種模式是“RGB 模式”,我們可以在 RGB 顏色之間更改 LED 燈條的顏色和強度,最后一種模式是“音樂模式”,其中 LED 的顏色和強度會根據(jù)音樂播放而變化。這個優(yōu)雅的項目設(shè)計是由 PCBWay制造的 PCB 板實現(xiàn)的,我們還將向您展示該板是如何設(shè)計和從 PCBway 訂購的
構(gòu)建前面板 PCB 所需的組件
使用 Arduino Nano 構(gòu)建 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,作為以下電路圖中的公共引腳。數(shù)字引腳 PD2 到 PD7 和 PB0 進(jìn)一步連接到每個電阻的其他連接點。在下圖中,剩余的數(shù)字引腳連接到 1x5 引腳接頭并命名為“剩余數(shù)字引腳”。
我們已將八個 22uF 電容器連接到每個電阻器。每個電容器的負(fù)極引腳連接到 Atmega328p IC 的接地引腳。然后我們有一個電源部分,為 ATMega328P IC 和 Neo Pixel 提供適當(dāng)?shù)?5V。
注:如有需要,我們可以加電容。強烈建議使用小電容器 (20pF - 400pF) 來穩(wěn)定檢測到的數(shù)據(jù)。但是,請確保電容器接地,因為這會降低與體電阻的并聯(lián)。就我而言,我沒有使用電容器,因為沒有它們對我來說效果很好。我在上面的示意圖中提到了電容器,因此您可以在實際實施過程中輕松添加它們。按照“ CapacitveSensor ”庫文檔中的規(guī)定,以下電容器的值必須介于 20pF 和 400pF 之間。
電容式傳感器庫如何工作?
這就是 Arduino 庫派上用場的地方。感謝“ CapacitiveSensor ”庫的作者Paul Bagde r 和Paul Stoffregen 。當(dāng)我們觸摸那個導(dǎo)電板時,我們可以使用這個庫來檢測電容的變化。在這個庫中,其中一個數(shù)字引腳用作發(fā)送引腳(作為 OUTPUT),而另一個用作接收引腳(作為 INPUT)。發(fā)送引腳變?yōu)楦唠娖胶徒邮找_變?yōu)楦唠娖街g的持續(xù)時間是檢測電容變化的唯一方法。當(dāng)您將發(fā)送引腳設(shè)置為高電平(或5 伏)時,電阻-電容對會在發(fā)送引腳變?yōu)楦唠娖街g產(chǎn)生延遲 當(dāng)接收引腳從發(fā)送引腳讀取高值時。CapacitiveSensor 庫提供了一個將發(fā)送引腳設(shè)置為高電平的函數(shù),然后等待并計數(shù),直到接收引腳被讀取為高電平。此函數(shù)返回可用于檢測電容變化的時間值。當(dāng)時間值增大或減小時,表明電容值發(fā)生了變化。當(dāng)電容較大時,接收引腳將需要更長的時間才能達(dá)到高電平,而當(dāng)電容較小時,將需要更短的時間才能達(dá)到高電平。因此,我們可以確定正常狀態(tài)是什么,然后在每次發(fā)送引腳切換時檢查更改。
為PCB燈板制造PCB
現(xiàn)在我們有了原理圖,我們可以繼續(xù)為基于觸摸電容的 PCB 燈板布置 PCB。您可以使用您選擇的任何 PCB 軟件來設(shè)計 PCB。在這里,我們使用 EasyEDA 平臺為我們的項目創(chuàng)建原理圖和 PCB。下面是PCB Light Panel頂層和底層的3D模型視圖:
上述電路的 PCB 布局也可以從下面給出的鏈接下載為 Gerber:
項目的 Gerber 文件
組裝觸控電容燈面板 PCB
訂購板后,幾天后,它通過快遞在一個標(biāo)簽整齊且包裝完好的盒子中到達(dá)我的手中。PCB質(zhì)量一如既往的好。板子的頂層和底層如下圖所示:
在確保軌道和腳印是正確的之后。我繼續(xù)組裝PCB。完全焊接的板如下所示:
PCB燈板編程
觸摸電容式 PCB 燈板的完整代碼可以從該項目的 github 存儲庫中下載?!癈apacitiveSensor”庫非常易于使用,并且他們提供了有關(guān)如何使用該庫的很好的文檔。在進(jìn)入程序之前,讓我們在 Arduino IDE 上安裝“CapacitiveSensor”庫。您需要下載庫的 zip 文件。然后轉(zhuǎn)到Arduino IDE 工具欄下的“Sketch -> Include Library ”部分。使用“添加 .Zip 庫...”選項添加 zip 文件,如下圖所示。然后重新啟動 Arduino IDE。類似的方式你也可以安裝ADCTouch.h庫。
現(xiàn)在安裝所需的庫文件后,通過包含所有庫文件來啟動代碼。Adafruit_NeoPixel.h 用于控制基于單線的 LED 像素和燈條。在這里,我們使用它來控制 Neo-Pixel LED 燈條。CapacitiveSensor 庫用于感應(yīng) PCB 焊盤上的觸摸。
#include#include <電容傳感器.h> #include
然后在接下來的幾行中,我們使用CapacitiveSensor()函數(shù)創(chuàng)建了九個實例。這些實例定義了連接觸摸板的引腳。此函數(shù)的語法是CapacitiveSensor(byte sendPin, byte receivePin),其中一個數(shù)字引腳用作發(fā)送引腳(作為 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 條中的像素數(shù),Argument 2 是連接 LED 條的引腳。
Adafruit_NeoPixel strip = Adafruit_NeoPixel(N_PIXELS, PIN, NEO_GRB + NEO_KHZ800);
然后我們定義了一些函數(shù)來檢測墊和環(huán)上的觸摸。前三個函數(shù)ModeMode()、RGBMode()和MusicMode()用于檢測用于在 PCB 不同模式之間切換的焊盤上的觸摸。在第一個函數(shù)中,我們將讀取第一個焊盤的值,即“MODE”,如果檢測到的值大于 500,則它將返回 1,否則返回 0。同樣,我們?yōu)?RGB pad 和 MUSIC pad 定義了另外兩個函數(shù)。
布爾模式模式(){ 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()函數(shù)用于檢測環(huán)上的觸摸。除此之外,它還存儲環(huán)位置。這些環(huán)位置用于檢測環(huán)上的順時針或逆時針旋轉(zhuǎn)。同樣,我們定義了另一個函數(shù)來檢查滑塊位置,并且我們還使用滑塊上的焊盤位置檢查滑動方向。
字符 Check_Ring_Pos() { char ring_pos = 0; 字符結(jié)果 = 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) 結(jié)果 = 1; 如果 ((current_ring_pos - pvs_ring_pos) == -1) 結(jié)果=2; if (current_ring_pos != pvs_ring_pos); pvs_ring_pos = current_ring_pos; 返回結(jié)果; }
現(xiàn)在我們知道是否觸摸了特定的墊子,如果是,那么在哪個方向上,我們將使用這些讀數(shù)在三種模式之間切換。在RGB 模式下,我們可以使用滑塊來增加或減少燈光的強度。如果我們從左向右滑動,強度會增加,如果我們從右向左滑動,強度會降低。同樣,我們可以使用順時針或逆時針方向的環(huán)形墊來改變顏色。在模式模式下,環(huán)形墊將用于順時針和逆時針方向旋轉(zhuǎn)燈。
無效 RGB_Mode(){ Serial.print("我們已進(jìn)入 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(亮度); } …………………………………………..
現(xiàn)在,如果觸摸音樂模式鍵盤,Arduino 將開始讀取麥克風(fēng)讀數(shù),并根據(jù)音樂隨機(jī)改變燈光的強度和顏色。
無效音樂模式(){ Serial.print("我們已經(jīng)進(jìn)入音樂模式"); 嘟(); 而(1){ 如果(數(shù)字讀?。ˋ5)==低) { Serial.print("TAP"); for(int i=0; i< 48; i++) { strip.setBrightness(隨機(jī)(100,255)); strip.setPixelColor(i, strip.Color(隨機(jī) (0,255), 隨機(jī) (0,255), 隨機(jī) (0,255))); 剝離.show(); }
3D打印觸控電容式PCB燈板外殼
現(xiàn)在的想法是將這個 PCB 燈板掛在墻上,為此,我打印了一個 PCB 支架。我用我的游標(biāo)測量了裝置的尺寸來設(shè)計一個外殼。完成后,我的設(shè)計如下所示。STL 文件也可以從Thingiverse下載,您可以使用它打印您的外殼。
測試觸控電容式 PCB 燈板
組裝好 PCB 并對 ATMega328 進(jìn)行編程后,我們現(xiàn)在可以測試設(shè)置了。為此,將 3D 打印支架安裝在 PCB 上并包裹 Neo-pixel 條,如下所示:
現(xiàn)在使用 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 // 麥克風(fēng)連接在引腳 A5
#define N 10 // 樣本數(shù)
#define fadeDelay 25 // 淡入淡出量
#define noiseLevel 25 // 我們想要切斷的噪音量
int參考 1,參考 2,參考 3,參考 4,參考 5;//使用模擬引腳消除偏移的參考值是電容觸摸
char pvs_slider_pos = 0;
字符 pvs_ring_pos = 0;
整數(shù)樣本[N];// 存儲樣本
int periodFactor = 0; // 用于周期計算
詮釋 t1 = -1;
詮釋T;
坡度;
字節(jié) 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);
//創(chuàng)建一個 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;
字符結(jié)果 = 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)
結(jié)果 = 1; //Serial.print(“順時針觸摸環(huán)”);
如果 ((current_ring_pos - pvs_ring_pos) == -1)
結(jié)果 =2; //Serial.print(“環(huán)逆時針觸摸”);
if (current_ring_pos != pvs_ring_pos);
pvs_ring_pos = current_ring_pos;
返回結(jié)果;
}
char Check_Slider_Pos()
{
char slider_pos = 0;
字符結(jié)果 = 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)
結(jié)果 = 1; //Serial.print(“滑塊從左到右”);
if ((current_slider_pos - pvs_slider_pos) == -1)
結(jié)果 =2; //Serial.print(“滑塊從右到左”);
if (current_slider_pos != pvs_slider_pos);
pvs_slider_pos = current_slider_pos;
返回結(jié)果;
}
void RGB_Mode(){
Serial.print(“我們已進(jìn)入 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 = 隨機(jī)(0,255);
j = 隨機(jī) (0,255);
k=隨機(jī)(0,255);
}
if (Ring_Status==2) {//返回 0 表示不移動,返回 2 表示逆時針
Serial.println (“Ring in Counter-Clockwise”);
嘟();
i = 隨機(jī)(0,255);
j = 隨機(jī) (0,255);
k=隨機(jī)(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(“我們已進(jìn)入 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(“我們已進(jìn)入音樂模式”);
嘟();
while(1){ //保持 RGB 模式
if (digitalRead(A5)==LOW)
{
Serial.print(“TAP”);
for(int i=0; i《 48; i++)
{
strip.setBrightness(隨機(jī)(100,255));
strip.setPixelColor(i, strip.Color(隨機(jī) (0,255), 隨機(jī) (0,255), 隨機(jī) (0,255)));
剝離.show();
}
延遲(100);
}
else
{
for(int i=0; i《 48; i++)
{
strip.setBrightness(0);
strip.setPixelColor(i, strip.Color(隨機(jī) (0,255), 隨機(jī) (0,255), 隨機(jī) (0,255)));
剝離.show();
}
}
if ( RGBMode() || ModeMode() || MusicMode() )
中斷;
}
}
void setup() {
// 啟動條帶并將其
清空 strip.begin();
//strip.show();
//cs_4_2.set_CS_AutocaL_Millis(0xFFFFFFFF); // 關(guān)閉通道 1 上的自動校準(zhǔn) - 僅作為示例
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
+關(guān)注
關(guān)注
4309文章
22868瀏覽量
395069 -
LED燈條
+關(guān)注
關(guān)注
2文章
100瀏覽量
13272 -
Atmega328P
+關(guān)注
關(guān)注
4文章
56瀏覽量
17190
發(fā)布評論請先 登錄
相關(guān)推薦
評論