本次DIY要用到最近挺火的磁流体,制作一个酷炫音箱,效果非常的nice~
一.材料准备:
瓶装磁流体,esp32开发板,12v60kg吸力电磁铁,蓝牙功放板,运算放大模块,L298N电机模块,面包板电源,0.91寸OLED显示屏,4位数码管(TM163X驱动),12V电源适配器,喇叭,10*10洞洞板,亚克力切割外壳,亚克力专用胶水,杜邦线。(还有开关,电位器)
工具要用到电烙铁,胶布,热熔胶枪。
注意是低密度磁流体,有点贵~
电磁铁吸力太大或太小都会导致效果不好,两根线不分正负接L298N控制输出接口
考虑到音质不用esp32自带的蓝牙,5v供电,两个喇叭接口要留一个输出音频信号给开发板ADC引脚(音频信号电压值太小的话开发板检测不到,可以用个信号放大模块)
L298N用来控制电磁铁,12v供电,控制输入引脚接开发板,输出接电磁铁~
用来给各模块和开发板供电,电源输入接电源适配器~
显示屏嘿嘿,用来显示音频波形啥的,增加炫酷值~
数码管可以用来显示时间,功能+1 ~
开发板esp-wroom32,便宜又好用,(ST fu*k 油~)
喇叭选了个便宜的,有点后悔,应该买个好点的~
二.电路连接:
示意图,看个大概
实物图(飞线飞啊飞~):
三:外壳设计
用不起3d打印~,亚克力YYDS~(最后发现亚克力外壳+胶水的效果比打印件还要好看一点~)
以下是亚克力切割图
四:组装:
下面黑色盒子装电路板
乐高和热熔胶万能的~(磁流体两边是灯条)
背面
五:代码:
代码没啥好讲的,数码管,OLED屏幕,wifi都有方便的库可以调用。下面四行代码就是将音频模拟信号转换为PWM信号的过程,改变代码可以可实现不同磁流体效果。
!完整的代码放在文章最后~
六:才艺表演:(声音有点小,大家请调大音量欣赏~)
磁流体音箱
节日快乐~
#include <U8g2lib.h>
#include "TM1637.h"
#include <WiFi.h>
#define CLK 19 //Set the CLK pin connection to the display
#define DIO 18 //Set the DIO pin connection to the display
#define ANALOG_PIN_0 32
#define NTP1 "ntp1.aliyun.com"
#define NTP2 "ntp2.aliyun.com"
#define NTP3 "ntp3.aliyun.com"TM1637 tm1637(CLK, DIO); //set up the 4-Digit Display.
int numCounter = 0;
bool dian = false;
/***********************************************/
填写WIFI入网信息
const char* ssid = "好耶"; // WIFI账户
const char* password = "12345678"; // WIFI密码void setClock() {struct tm timeinfo;if (!getLocalTime(&timeinfo)){//如果获取失败,就开启联网模式,获取时间Serial.println("Failed to obtain time");WiFi.disconnect(false);WiFi.mode(WIFI_STA);//开启网络 WiFi.begin(ssid, password);while (WiFi.status() != WL_CONNECTED){delay(500);Serial.print(".");}configTime(8 * 3600, 0, NTP1, NTP2,NTP3);return;}tm1637.display(0,timeinfo.tm_hour/10);tm1637.display(1,timeinfo.tm_hour%10);tm1637.display(2,timeinfo.tm_min/10);tm1637.display(3,timeinfo.tm_min%10 );tm1637.point(!dian); WiFi.disconnect(true);
}
/********************OLED******************/
U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0,U8X8_PIN_NONE);
const int WIDTH=128;
const int HEIGHT=32;
const int LENGTH=WIDTH;
int x;
int y[LENGTH];
void clearY(){ for(int i=0; i<LENGTH; i++){y[i] = -1;}
}
/***************波形图函数******************/
void drawY(){u8g2.drawPixel(0, y[0]);for(int i=1; i<LENGTH; i++){if(y[i]!=-1){//u8g.drawPixel(i, y[i]);u8g2.drawLine(i-1, y[i-1], i, y[i]);}else{break;}}
} void setup(){Serial.begin(115200);/**************数码管初始化*************************/ tm1637.init();tm1637.point(1);//小数点开关,1为打开,0为关闭tm1637.set(BRIGHT_TYPICAL);
/********************************************************************/pinMode(ANALOG_PIN_0,INPUT_PULLUP);//模数转换引脚
/********pwm配置**************/ ledcSetup(0,5000,8);ledcAttachPin(2,0);
/***********oled***************/
u8g2.begin();
x = 0;
clearY();/*******************wifi初始化*****************/Serial.println();
// 设置ESP32工作模式为无线终端模式WiFi.mode(WIFI_STA);WiFi.begin(ssid, password);while (WiFi.status() != WL_CONNECTED){delay(500);Serial.print(".");}Serial.println("WiFi connected!");configTime(8 * 3600, 0, NTP1, NTP2,NTP3);setClock();
// 从网络时间服务器上获取并设置时间
// 获取成功后芯片会使用RTC时钟保持时间的更新 WiFi.disconnect(true);WiFi.mode(WIFI_OFF);//关闭网络Serial.println("WiFi disconnected!");}void loop() {/***********输出磁场信号*********************/int analog_value = 0;analog_value = analogRead(ANALOG_PIN_0);/*******波形显示******************/y[x] = map(analog_value, 0, 4095, HEIGHT-1, 0);Serial.write(y[x]);u8g2.firstPage(); do {drawY();} while( u8g2.nextPage() );//delay(5);x++;if(x >= WIDTH){x = 0;clearY();}int PWM = map(analog_value,0,4095,0,255);digitalWrite(4,LOW);digitalWrite(15,HIGH);ledcWrite(0,PWM);/*******************数码管**************/setClock();}