0 前言
🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。
为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是
🚩 基于单片机的桌面炫酷律动灯条
🥇学长这里给一个题目综合评分(每项满分5分)
- 难度系数:2分
- 工作量:2分
- 创新点:3分
1 简介
esp8285芯片ESP-01F模块为主控,MAX9814音频采集模块,WS2812 2020rgb灯珠,Arduino编程环境简单制作一个律动灯条。
2 主要器件
直接用MAX9814音频采集模块焊在板子上,效果非常好。
esp8266模块所以可以做http服务,所以就可以做个页面把所有参数都拿出来自定义。
光绘棒部分会专门再做个长的,这里就没讲了,原理很简单就是按图像像素点的行或者列顺序修改灯珠对应的颜色就行了。
- esp8285芯片ESP-01F模块
- MAX9814音频采集模块
- WS2812 2020rgb灯珠
3 实现效果
整体展示
可调RGB
灯光效果随音乐律动
4 设计原理
模块简介
esp8285 和 ESP8266一样,都是由乐鑫公司开发,提供了⼀套⾼度集成的 Wi-Fi SoC 解决⽅案,其低功耗、紧凑设计和⾼稳定性可以满⾜⽤户的需求。
esp8266的代码同样适合在esp8285上运行的,也就是支持nonos和 rtos。
MAX9814音频采集模块
通过MAX9814进行音频采集模拟值,上面标注了DC offset(直流偏移):1.2v。而esp8285或者8266的ADC采样只能接收1v,所以采集的ADC信号要进行串联电阻分压。
主要原理图
5 部分核心代码
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include<FastLED.h>
#include<MegunoLink.h> //滤波库 https://www.megunolink.com/documentation/arduino-library/
#include<Filter.h> //项目-加载库-库管理 搜索 MegunoLink 安装
#ifndef STASSID
#define STASSID "********"
#define STAPSK "********"
#endif
const char* ssid = STASSID;
const char* password = STAPSK;
ESP8266WebServer server(80);
// define necessary parameters
#define N_PIXELS 30 //led灯珠数量
#define MIC_PIN A0 //音频采集模块接口
#define LED_PIN 13 //led灯带接口
#define NOISE 60 //噪音底线
#define TOP (N_PIXELS+2)
#define LED_TYPE WS2812
#define BRIGHTNESS 100 //灯珠亮度
#define COLOR_ORDER GRB
#define SW1 4 //按钮IO
#define SW2 0
#define SW3 5
CRGB leds[N_PIXELS];
uint16_t R[4]={255,0,0,0};
uint16_t G[4]={0,255,0,0};
uint16_t B[4]={0,0,255,0};
int lvl = 0, minLvl = 10, maxLvl = 256; // 设置最大最小限值
ExponentialFilter<long> ADCFilter(10,0);
String postForms()
{
String htmlCode = "<!DOCTYPE html><html>\n";
htmlCode += "<head>\n";
htmlCode += "<title>调色</title>\n";
htmlCode += "<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>\n";
htmlCode += "<meta name='viewport' content='width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0'/>\n";
htmlCode += "<style>\n";
htmlCode += "body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }\n";
htmlCode += "</style>\n";
htmlCode += "</head>\n";
htmlCode += "<body>\n";
htmlCode += "<h1>输入RGB值</h1><br>\n";
htmlCode += "<form method=\"post\" enctype=\"application/x-www-form-urlencoded\" action=\"/\">\n";
htmlCode += "R G B <br>\n";
htmlCode += "0 \n";
htmlCode += "<input type=\"text\" name=\"G0\" value= \"";
htmlCode += R[0];
htmlCode += "\" size=\"5\" initial-scale = 2.0 autocomplete=\"off\">\n";
htmlCode += "<input type=\"text\" name=\"R0\" value= \"";
htmlCode += G[0];
htmlCode += "\" size=\"5\" initial-scale = 2.0 autocomplete=\"off\">\n";
htmlCode += "<input type=\"text\" name=\"B0\" value= \"";
htmlCode += B[0];
htmlCode += "\" size=\"5\" initial-scale = 2.0 autocomplete=\"off\"><br>\n";
htmlCode += "1 \n";
htmlCode += "<input type=\"text\" name=\"G1\" value= \"";
htmlCode += R[1];
htmlCode += "\" size=\"5\" initial-scale = 2.0 autocomplete=\"off\">\n";
htmlCode += "<input type=\"text\" name=\"R1\" value= \"";
htmlCode += G[1];
htmlCode += "\" size=\"5\" initial-scale = 2.0 autocomplete=\"off\">\n";
htmlCode += "<input type=\"text\" name=\"B1\" value= \"";
htmlCode += B[1];
htmlCode += "\" size=\"5\" initial-scale = 2.0 autocomplete=\"off\"><br>\n";
htmlCode += "2 \n";
htmlCode += "<input type=\"text\" name=\"G2\" value= \"";
htmlCode += R[2];
htmlCode += "\" size=\"5\" initial-scale = 2.0 autocomplete=\"off\">\n";
htmlCode += "<input type=\"text\" name=\"R2\" value= \"";
htmlCode += G[2];
htmlCode += "\" size=\"5\" initial-scale = 2.0 autocomplete=\"off\">\n";
htmlCode += "<input type=\"text\" name=\"B2\" value= \"";
htmlCode += B[2];
htmlCode += "\" size=\"5\" initial-scale = 2.0 autocomplete=\"off\"><br>\n";
htmlCode += "<input type=\"submit\" value=\"修改\"><br>\n";
htmlCode += "</form>\n";
htmlCode += "</body>\n";
htmlCode += "</html>\n";
return htmlCode;
}
void handleRoot() {
String message = "";
for (uint8_t i = 0; i < server.args(); i++) {
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
if(server.args()>0){
R[0] = (server.arg(0)).toInt();
G[0] = (server.arg(1)).toInt();
B[0] = (server.arg(2)).toInt();
R[1] = (server.arg(3)).toInt();
G[1] = (server.arg(4)).toInt();
B[1] = (server.arg(5)).toInt();
R[2] = (server.arg(6)).toInt();
G[2] = (server.arg(7)).toInt();
B[2] = (server.arg(8)).toInt();
}
for(uint8_t i = 0; i < N_PIXELS; i++) {
leds[N_PIXELS-1-i] = colour(i);
}
FastLED.show();
server.send(200, "text/html", postForms());
}
void setup() {
Serial.begin(115200);
pinMode(SW1, INPUT_PULLUP);
pinMode(SW2, INPUT_PULLUP);
pinMode(SW3, INPUT_PULLUP);
server.on("/", handleRoot);
server.begin();
Serial.println("HTTP server started");
FastLED.addLeds<LED_TYPE,LED_PIN,COLOR_ORDER>(leds,N_PIXELS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(BRIGHTNESS);
}
uint16_t samnum;
int maxtemp;
uint8_t sta,mode_num;
void loop() {
switch(sta){
case 0:
int n, height;
n = analogRead(MIC_PIN);
n = abs(512 - n);
n = (n <= NOISE) ? 0 : abs(n - NOISE);
ADCFilter.Filter(n);
lvl = ADCFilter.Current();
// Serial.print("n: ");
// Serial.print(n);
// Serial.print(" lvl: ");
// Serial.print(lvl);
// Serial.print(" maxLvl: ");
// Serial.println(maxLvl);
if(samnum<200){
maxtemp = max(maxtemp,lvl);
samnum++;
}else{
if(maxtemp < 50){
maxLvl = 50;
}else{
maxLvl = maxtemp;
}
maxtemp = 0;
samnum = 0;
}
height = TOP * (lvl - minLvl) / (long)(maxLvl - minLvl);
if(height < 0L) height = 0;
else if(height > TOP) height = TOP;
switch(mode_num){
case 0:
for(uint8_t i = 0; i < N_PIXELS; i++) {
if(i >= height) leds[N_PIXELS-1-i] = CRGB(0,0,0);
else leds[N_PIXELS-1-i] = colour(i);
}
break;
case 1:
for(uint8_t i = 0; i < N_PIXELS/2; i++) {
// turn off LEDs above the current level
if(i >= height/2) {
leds[N_PIXELS/2-1-i] = CRGB(0,0,0);
leds[N_PIXELS/2+i] = CRGB(0,0,0);
}
else {
leds[N_PIXELS/2-1-i] = colour(i);
leds[N_PIXELS/2+i] = colour(i);
}
}
break;
}
FastLED.show();
break;
case 1:
server.handleClient();
break;
}
if(digitalRead(SW1) == LOW){
delay(5);
if(digitalRead(SW1) == LOW){
sta++;
if(sta>1)sta = 0;
while(digitalRead(SW1) == LOW);
if(sta == 1){
for(uint8_t i = 0; i < N_PIXELS; i++) {
leds[N_PIXELS-1-i] = CRGB(0,0,0);
}
FastLED.show();
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("");
// Wait for connection
int j ;
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
leds[N_PIXELS-1-j] = CRGB(255,0,0);
FastLED.show();
j++;
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
for(uint8_t i = 0; i < N_PIXELS; i++) {
leds[N_PIXELS-1-i] = colour(i);
}
FastLED.show();
}
}
}
if(digitalRead(SW2) == LOW){
delay(5);
if(digitalRead(SW2) == LOW){
mode_num++;
if(mode_num>1)mode_num = 0;
while(digitalRead(SW2) == LOW);
}
}
}
}