上網找了一下,應該要用更小規格的
LilyPad Arduino
規格如下,不過看了價格.....還是 Nano有優勢.
Microcontroller | ATmega168 or ATmega328V |
Operating Voltage | 2.7-5.5 V |
Input Voltage | 2.7-5.5 V |
Digital I/O Pins | 14 |
PWM Channels | 6 |
Analog Input Channels | 6 |
DC Current per I/O Pin | 40 mA |
Flash Memory | 16 KB (of which 2 KB used by bootloader) |
SRAM | 1 KB |
EEPROM | 512 bytes |
Clock Speed | 8 MHz |
上回的code把全部的digital pin都用掉了,剩下的pin為Analog,不用上就可惜了.
以下圖為Touch Switch的接法,經測試,不接5V以及PNP電晶體,也是可以有一樣的功能.
重新改寫Code,採用sub function的方式撰寫,方便有興趣的朋友進行修改.
追加一段閃爍控制,主要功能是用來強化LED 揮舞時出現閃爍的感受
追加Analog Touch SW的sub function.實際功能等想到再規畫吧!
效果要實際測試調整delay的速度.
Code展開如下.
#include "softwareserial.h"
#include "dfplayer_mini_mp3.h"
int LEDstatus = 0; //定義變量為LEDstatus
int Touchstatus = 0;
bool hum[4];
int sensorValue;
int prevValue;
const int LEDdelay = 20; //定義延遲0.020秒進行一次LED升降50FPS
const int BreatheStep = 5;
const int PowerSW = 12;
const int WaveSW = 13;
const int LEDMartix[10] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2} ; //設定LED Martix
const int PWMpin[10] = {1, 1, 1, 0, 0, 1, 1, 0, 1, 0}; // PWM: 3, 5, 6, 9, 10, 11. Provide 8-bit PWM output with the analogWrite() function.
int CheckTouch(int AnalogPin) {
prevValue = sensorValue;
sensorValue = analogRead(AnalogPin);
if (sensorValue >= 1023 && sensorValue >= prevValue) {
return 1;
}
if (sensorValue < 1010 & prevValue <= 1010) {
return 0;
}
}
void SaberInital() {
for (int i = 9; i >= 0; i--) {
digitalWrite(LEDMartix[i], LOW);
}
LEDstatus = 0;
}
void SaberON() {
for (int i = 0; i <= 9; i++) {
digitalWrite(LEDMartix[i], HIGH);
delay(LEDdelay);
LEDstatus = 1;
}
}
void SaberOFF() {
for (int i = 9; i >= 0; i--) {
digitalWrite(LEDMartix[i], LOW);
delay(LEDdelay);
LEDstatus = 0;
}
}
void SaberFlickON() {
for (int j = 0 ; j <= 100; j++) {
for (int i = 0; i <= 10; i++) {
if (i != 10) {
digitalWrite(LEDMartix[i], LOW);
}
if (i != 0) {
digitalWrite(LEDMartix[i - 1], HIGH);
}
}
delay( LEDdelay / 2); //定義延遲0.01秒進行
}
LEDstatus = 1;
}
void SaberBreatheON() {
for (int j = -255 ; j <= 255 ; j + BreatheStep) {
for (int i = 0; i <= 10; i++) {
if (PWMpin[i] == 0) {
if (i != 10) {
digitalWrite(LEDMartix[i], LOW);
}
if (i != 0 || PWMpin[i - 1] != 1 ) {
digitalWrite(LEDMartix[i - 1], HIGH);
}
}
if (PWMpin[i] == 1) {
analogWrite(LEDMartix[i], abs(j));
}
}
delay( LEDdelay); //定義延遲0.02秒進行
}
LEDstatus = 1;
}
void setup () {
Serial.begin (9600);
mp3_set_serial (Serial); //set Serial for DFPlayer-mini mp3 module
mp3_set_volume (10);
pinMode(2, OUTPUT); //設定D2為輸出端,劍尾端
pinMode(3, OUTPUT); //設定D3為輸出端
pinMode(4, OUTPUT); //設定D4為輸出端
pinMode(5, OUTPUT); //設定D5為輸出端
pinMode(6, OUTPUT); //設定D6為輸出端
pinMode(7, OUTPUT); //設定D7為輸出端
pinMode(8, OUTPUT); //設定D8為輸出端
pinMode(9, OUTPUT); //設定D9為輸出端
pinMode(10, OUTPUT); //設定D10為輸出端
pinMode(11, OUTPUT); //設定D11為輸出端,劍首端,接近劍柄
pinMode(PowerSW, INPUT); //設定LED啟動開關接腳在D12,為輸入端
pinMode(WaveSW, INPUT); //設定震動開關接腳在D13,為輸入端
SaberInital();
}
void loop() {
if (LEDstatus == 0 && digitalRead(PowerSW) == HIGH) { //當有開關觸發LED亮
mp3_play (random(6, 8)); //先將光劍啟動的音效檔定為0006.mp3 或0007.mp3, 藉由亂數處理任意播放
SaberON();
delay (1000 - LEDdelay * 9); //播放1秒音效
}
if (LEDstatus == 1 && digitalRead(PowerSW) == HIGH) { //當有開關觸發LED暗
mp3_play (random(9, 11)); //先將光劍關閉的音效檔定為0009.mp3 或0010.mp3, 藉由亂數處理任意播放
SaberOFF();
delay (1000 - LEDdelay * 9); //播放1秒音效
}
if (LEDstatus == 1 && CheckTouch(A0) == 1) {
mp3_play (2); //播放揮光劍的音效檔定為0002.mp3
SaberBreatheON();
delay (2000 - LEDdelay * 255 / BreatheStep * 2);
}
if (LEDstatus == 1) { //當光劍啟動時紀錄震動開關觸發狀態
for (int i = 0; i < 4; i++) {
hum[i] = digitalRead(WaveSW);
delay(250);
}
if ((hum[0] != 0 && hum[1] != 0 && hum[2] != 0 && hum[3] != 0) || (hum[0] != 1 && hum[1] != 1 && hum[2] != 1 && hum[3] != 1)) {
mp3_play (1); //播放揮光劍的音效檔定為0001.mp3
SaberFlickON();
delay (1000 - LEDdelay * 9 / 2);
}
}
}