磁流體音箱
為什麼會研究這個話題呢?也就是划到了一個廣告:磁流體音樂節奏…還不帶喇叭的,心想這不就是弄個聲音感測嗎?為何要三四千大洋!然後我注意到了「磁流體」這個詞,以及那坨黑黑的,查了一下網,這東西真的很有學問的,也有做成藍芽喇叭形態的(價格更是高),會隨音樂跳動,很酷的樣子,我不是想買一個,而是想知道這是怎麼弄的…(※以下圖片取自網路)
想研究的第一個行動當然就是上網科普,然後買來看看(就是花錢啦!)…在蝦x上查一下,發現我們這兒很少賣,多是對岸的賣家,原來鐵磁流體可不是很好做出來,一開始我的A計劃想生成看看,但看了方法之後就算了!應該要有化工底子的比較好,能買到人家弄好的就不錯了,若想拿來做音響專題,還得注意別買教具用的(專給小朋友看像玩具),要挑低密度磁流體,含量也不要太少,至少要3ml以上的,價格也都是幾百大洋起跳!
鐵磁流體
鐵磁流體的主要原料是10奈米四氧化三鐵。它是「對磁有反應的液體」,由美國航太總署(NASA)工程師Steve Papell在1960年代研發而成。磁流體的研發,原始目的在克服太空「無重力」所產生的許多困擾。例如,液體燃料產生飄浮狀態變得難以控制,造成機器在太空無法運作。其解決方法是添加磁流體,使液體受磁力控制,以克服飄浮現象。
參考資料:
維基百科:zh.wikipedia.org/zh-tw/%E9%93%81%E7%A3%81%E6%B5%81%E4%BD%93
臺灣網路科教館:www.ntsec.edu.tw/liveSupply/detail.aspx?a=6829&cat=6844&p=1&lid=19958
我一開始認為,那些音箱上的磁流體隨著音樂跳動是因為喇叭的磁力(事實証明這個想法是錯的!),當然它也不是因為音波的關係,經過努力的搜尋,找到一文章:www.xjishu.com/zhuanli/62/202121668320.html (一种磁流体音箱的制作方法),我了解了一點:是運用「電磁鐵」,可以自己想像一下,電磁鐵通電產生磁力吸引磁流體,那如果能操縱電磁鐵的電流大小就能動態改變磁力的大小,但想的有道理跟實作是有距離的~後來我又找到了另一篇:zhuanlan.zhihu.com/p/563216885?utm_id=0 (如何用esp32做一个磁流体音箱),這位大神使用ESP32和L298n來控制電磁鐵,還真是神來一筆,所以我就模仿他的方法來做一個…
我的磁流體音響
看這段影片就知我做出來了,這個Case在接線及程式上的難度並不高我可以看懂(可能是我之前有做過Esp32 BluetoothAudio和音頻分析儀),比較困難的反而是湊齊所需的零件吧!而我與所參考的原作也有許多不同,我比較重視音響播音的部份,所以我採用的喇叭及功放比較大,連帶影響了電源供應的部份…
磁流體瓶
除非你有化工經驗及對應的材料,不然建議上網買一買吧!到淘x是便宜許多的,像我手上這瓶,裡頭的水溶液(不是純水)100ml,磁流體3ml左右,我的case用的是5ml的,不一定只有黑色的,有各種色彩(人家真厲害)
電磁鐵
這種電磁鐵我們這兒也不容易買(買到了也是上圖右那顆小的不夠力),是對岸的廠做的,所以淘x買也是比較便宜的,我使用這顆是朗碩P50/30圓形强吸力60KG直流12V
電源模組
為了使用較大的功放推喇叭,我採用這塊龍邱多電源模組,它的電容做得很不錯,能承受較大的電流,在我們這兒的商家買會比淘x多100元,我這音響電源接入DC12V 2A,然後靠這電源模組供應三種電壓:12V,5V,3.3V
※如果你使用一般常見的電源模組,音樂開大聲點可能就會跳電了
L298N馬達模組
利用這個模組來輸出電壓給電磁鐵,例如把電磁鐵的二條線接OUT3和OUT4,那麼就會用到IN3,IN4及ENB三個Pin來收從esp32傳來的訊號
ESP32-Wroom-32
這兒用的esp32模組是30pin的就可以了,雖然它也可以直接做成藍芽音樂接收器,但音質及推力都不夠,所以只使用它的ADC(Analog-to-Digital Converter)及運算PWM輸出
L358訊號放大模組
從功放板傳出的訊息是非常微弱的,直接到ESP32可能會偵測不到,所以需要加一個L358來把訊號放大100倍
我的音箱做成分離式的設計,到電子材料行可以買到小小的香蕉接頭(也稱燈籠接頭),兩對母接頭是要接二顆喇叭的,焊一下線是免不了的(線的另一頭是準備接到功放板的),其中一個正極的接頭多焊一條杜邦出來,是準備接到L358去的。
我買的這顆單體是4 Ω 5W的(這可以很大聲了)只要60大洋,自己設計個音箱殼裝進去,瞬間質感就提升了!喇叭線就焊上香蕉公接頭,這樣就可以很方便插拔
做個主控中心盒子
一樣就是練習測量及畫畫的時間,這個盒子是整個電路的集中點,TM1637模組及0.91吋oled其實是用來增加一點表面效度的(要不然esp32板子的功能不太有發揮,之後還有以加聲音感測之類的…),在這個設計裡,我感得最重要的就是電源模組了,它有很多pin位可以讓所有零件的電源都接上去
畫一組可以密合的設計圖,一半放電磁鐵一半放磁流體瓶,我有一個小巧思就是順著磁流體瓶的旁邊預留可以塞燈條的溝
接線測試
不管想得設計得多美好,能運作才是王道,所以在組裝之前一定先測試電機部份的運作,以前也沒玩過這種電磁鐵,是不是真的得用這麼大顆的才行呢?經過實際實驗,這顆的磁力剛好,理論上給12v的電壓它的磁力最強,可是供應它的L298N未必能一真提供那麼高的電壓,我想電磁電的等級至少要是30KG吸力的才夠,我們也可透過ESP32的程式來調整輸出的強度…
ZK-502M功放板
在這個系統中,如果想直接用ESP32建Bluetooth Audio也行,但光靠ESP32板子的推力,頂多能接1W的小喇叭吧!(很小聲而且音質不會太好),想大聲一樣得外接擴大機(功放板),不如就直接使用等級好一點的功放板常藍芽音樂接收器,放過ESP32吧!這塊ZK-502M不到200元,效能跟音質卻很不錯,我直接讓它接在主機外,它的供電一樣吃電源板,這種作法,不僅可以使用藍芽音樂也可以用AUX IN,本身又附有聲音旋鈕,我覺得很適合…
接線圖
音樂的來源是功放板,所以ZK-502M的喇叭線其中一條正極接到L358信號放大器的IN,OUT出去接到ESP32的D32,功放板和L298N都是接12V的電源,ESP32的D2,D4,D15分別接L298N的ENB,IN3,IN4,這是電磁鐵的電壓隨音樂波動的重點;其他帶點的七段顯示器CLK接D19,DIO接D18(是用來顯示時間的),OLED模組的SCL和SDA就接ESP32的SCL和SDA
ESP32的程式碼(Arduino)
由於要抓時間,所以程式啟動時要連網,原作者的範例是寫死WIFI連線,但我改成使用WifiManager模組,這樣子的話喇叭拿到不同的地方,連不到原來的wifi會跑ap模式,用手機連上它就可以設定那兒的連線資訊
#include <U8g2lib.h>
#include "TM1637.h"
#include <WiFiManager.h>
#include <WiFiClientSecure.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
const char* ntpServer = "time.google.com";
const long gmtOffset_sec = 28800; //台灣時區+8hr,28800=8*60*60
const int daylightOffset_sec = 0; //台灣無日光節約時間
TM1637 tm1637(CLK, DIO); //set up the 4-Digit Display.
int numCounter = 0;
bool dian = false;
void setClock() {
struct tm timeinfo;
if (!getLocalTime(&timeinfo))
{
Serial.println("Failed to obtain time");
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
}
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
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); //打開時鐘點
tm1637.set(BRIGHT_TYPICAL);
pinMode(ANALOG_PIN_0,INPUT_PULLUP); //設定ADC腳位
/********PWM配置**************/
ledcSetup(0,5000,8);
ledcAttachPin(2,0);
/***********OLED***************/
u8g2.begin();
u8g2.enableUTF8Print();
x = 0;
clearY();
/**************************/
u8g2.clearBuffer(); // clear the internal memory
u8g2.setFont(u8g2_font_unifont_t_chinese2); // 使用中文字型
u8g2.setCursor(0, 20);
u8g2.print("咖啡虫磁流体音箱");
u8g2.sendBuffer();
delay(1000);
u8g2.clearBuffer();
u8g2.drawStr(0,20,"SSID:CW_Speaker"); // 顯示SSID名稱
u8g2.sendBuffer();
/*******************WiFiManager初始化*****************/
WiFiManager wifiManager;
wifiManager.setTimeout(180);
//第一個參數是SSID的名稱,第二個參數是密碼
if(!wifiManager.autoConnect("CW_Speaker","12345678")) {
Serial.println("failed to connect and hit timeout");
delay(3000);
ESP.restart();
delay(5000);
}
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
setClock();
WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);//关闭网络
Serial.println("WiFi disconnected!");
}
void loop() {
/***********讀取類比訊號*********************/
int analog_value = 0;
analog_value = analogRead(ANALOG_PIN_0);
Serial.println(analog_value);
/*******OLED波形顯示******************/
y[x] = map(analog_value, 0, 4095, HEIGHT-1, 0);
Serial.write(y[x]);
u8g2.firstPage();
do {
drawY();
} while( u8g2.nextPage() );
x++;
if(x >= WIDTH){
x = 0;
clearY();
}
int PWM = map(analog_value,0,4095,0,255); //這行是轉換ADC波的信號到L298N的PWM強度
digitalWrite(4,LOW);
digitalWrite(15,HIGH);
ledcWrite(0,PWM); //送出PWM
/*********顯示時間**************/
setClock();
}