# 【Q小奇】3cm*7cm 雙面噴鍚玻纖洞洞板 厚1.6mm 孔距2.54mm $8
記得好像在禾樺看過, 突發奇想說, 是否用此板會更容易布局與布線呢? 我用 Google 雲端硬碟又畫了一張 10*24 的洞洞板模擬圖來嘗試, 發現還不錯, 雙面佈線似乎更方便哩. 參考上週用 4.5cm*4.5cm 所做的布局 :
# 以 Arduino + ESP8266 物聯網模組重作 NTP 實驗 (二)
週六中午載姊姊去畫室回程特地再去禾樺找此種洞洞板, 結果發現有點不一樣, 禾樺的是 9*24=216 洞, 少了一排. 不確定這樣是否容易佈線, 但還是買回兩塊來試試看 (一片 20 元, 打 8 折還要 16 元, 好貴!).
重新以 9*24 洞佈線發現也 OK, 而且整個板子布局看來更對稱, 因為 Nano 上下排針是跨七格, 加上上下各一排插槽剛好九排, 若買露天賣的 10*24 則會空出一格, 整體看來會較不平均, 但也還是可用啦! 我嘗試幾次後找出最佳佈局方式如下 (只是將元件擺上去而已) :
這塊洞洞板的好處是不用像之前用的那塊必須裁切跟鑽洞, 整塊拿來用剛剛好, 其次是橫排上方有 A~X, 縱排左方有 1~9 的座標, 找焊點核對較方便 (但背面沒有是美中不足之處) :
3cm*7cm 216 洞洞板
經過幾次琢磨修改, 最後定稿的元件布局佈線圖如下 (背面無座標, 下圖之背面是我用 Picpick 直接將正面做水平旋轉而得) :
正面
背面
這裡棕色線為元件 (電阻) 的端線, 藍色線條代表背面 (無座標面) 的焊接線, 而橘色線代表正面 (有座標面) 的跳線. 我在禾樺找到一種更細的包覆線, 九公尺才 30 元, 比較好焊不占空間 :
此次佈線時又為了 ESP8266 的 CH_PD 要越過 RST 接腳接 3.3V 電源而煩惱, 我查了資料, RST 接 LOW 是讓 ESP8266 重置, 正常工作時必須接 HIGH (以前我都讓 RST 懸在那邊沒接, 這樣應該預設為 HIGH). 參考 :
# ESP8266 Wi fi module explain and connection : step 3
這樣就好辦啦! 因為 VCC, RST, 以及 CH_PD 相鄰連成一線, 乾脆用跨焊接在一起, 不需要跳過 RST 連接 VCC 與 CH_PD.
因為把跳線都放在正面, 所以必須先把正面的三個電阻, 模式 Jumper 先固定好 (蜂鳴器要等正面六條跳線完成後焊背面時再焊, 因為它會蓋住部分跳線, 必須驗證跳線連接性 ok 後再處理). 先在正面擺好電阻與 Jumper 並用三秒膠固定, 再到背面焊接固定. 然後焊接跳線, 這裡要注意, 跳線不要太緊, 留一些些餘裕可以稍微把線挑起來即可, 因背面焊錫時, 錫水可能經過洞流到正面, 必要時可把跳線稍微拉起避免包覆的絕緣皮被燙破.
焊好後用電表量看看各跳線接點是否都有確實接通. 接著放上排母與滑動開關, 用三秒膠稍微固定後, 翻到背面也用三秒膠將 AMS1117 稍微固定後進行焊接 (滑動開關不要用三秒膠, 要用膠帶, 因為三秒膠若滲入裡面會使開關變康固力-報廢囉) :
呵呵, 真不錯, 把跳線移到正面後, 背面就乾淨多了! 注意, 蜂鳴器要放到最後跟背面左下方圓圈處的 GND 金屬線一起焊, 蜂鳴器的負極剛好就跟該金屬線在轉折處相接, 若先焊 GND 金屬線, 則蜂鳴器的負極就無法插進洞裡了. 另外 ESP8266 的 3.3V 是從 AMS1117 的上方頭接點接出去, 中間腳因跳線麻煩就用不到了.
這次製作新模組經過縝密的規劃與注意焊接程序, 一次就 OK, 修長的外型比前一版要好看, 而且綠色電路板看起來較有質感. 事實上兩個面積差不多, 舊版是 4.5*4.5=20.25 平方公分, 此次新版是 3*7=21 平方公分, 新版雖然大了 0.75 平方, 但因為各元件模組緊密相鄰, 感覺比較精巧 :
這片新模組只花了兩天就規劃與製作完成, 速度比上回快. 舊版的目前有三片不會再製作了, 新版的還會再做 1 片即夠用矣. 這片背面的保護用壓克力板規格如下圖 :
跟台南紅蘋果訂的壓克力板打算改為舊版的 5 片, 新版的 8 片, 總共 13*11=143+運費55=198 元. 今天下班後又順路跑去禾樺買要鎖壓克力底板的螺絲 (平頭細牙 2*8) 螺帽 (六角細牙 2*4), 牙寬都是 2mm, 長度 8mm 的螺絲剛剛好 (塑膠的沒這麼小, 而且比較貴), 而 4mm 的螺帽直徑則剛好與洞洞板四角的圓孔大小吻合.
上週四做完三片物聯網模組後, 本以為就此打住, 沒想到又製做了新版的, 我覺得已經很滿意了, 似乎也沒必要花時間去洗 PCB, 因為那還要去鑽洞, 也還是要焊接, 只是省下布線的時間而已.
製作程序爰記如上, 以備來日重製時參考. 這個禮拜都在瘋造板子, 真是夠了.
此模組的程式架構更新如下 :
#include <SoftwareSerial.h>
#define DEBUG true
//-----application include & def listed HERE-----
//system use please do not edit
SoftwareSerial esp8266(7,8); //(RX,TX)
const int SW_PIN=4; //Pin to switch configuration or working mode
const int MAX_PAGE_NAME_LEN=48; //buffer size
char buffer[MAX_PAGE_NAME_LEN + 1]; //store page_name/ssid/pwd
int mode; //store current mode(LOW=wifi setup, HIGH=working)
//-----application global variables listed HERE-----
void setup() {
//system use please do not edit
Serial.begin(9600);
esp8266.begin(9600);
sendData("AT+RST\r\n",2000,DEBUG); // reset ESP8266
pinMode(SW_PIN, INPUT);
mode=digitalRead(SW_PIN);
sendData("AT+GMR\r\n",1000,DEBUG);
if (mode==LOW) { //setup mode : for wifi configuration
sendData("AT+CWMODE=3\r\n",1000,DEBUG); //configure as access point
sendData("AT+CIPMUX=1\r\n",1000,DEBUG); //enable multiple connections
sendData("AT+CIPSERVER=1,80\r\n",2000,DEBUG); //turn on server 80 port
}
else { //working mode : for running application
sendData("AT+CWMODE=1\r\n",1000,DEBUG); //configure as a station
delay(3000); //wait for wifi connection to get local ip
}
sendData("AT+CIFSR\r\n",1000,DEBUG); //get ip address
//-----application setup codes listed HERE-----
}
void loop() {
if (mode==LOW) {setupWifi();} //system use please do not edit
else { //-----application loop codes listed HERE-----
//show ESP8266 response char to serial monitor window
if (esp8266.available()) {Serial.write(esp8266.read());}
//send char to ESP8266 if got char from serial monitor window
if (Serial.available()) {esp8266.write(Serial.read());}
}
}
void setupWifi() { //system use please do not edit
if (esp8266.available()) { // check if the esp is sending a message
if (esp8266.find("+IPD,")) {
delay(1000);
//esp8266 link response : +IPD,0,498:GET / HTTP/1.1
//retrieve connection ID from response (0~4, after "+IPD,")
int connectionId=esp8266.read()-48; //from ASCII to number
//subtract 48 because read() returns ASCII decimal value
//and in ASCII, "0" (the first decimal number) starts at 48
if (esp8266.find("GET /")) { //retrieve page name (router)
memset(buffer, 0, sizeof(buffer)); //clear buffer (all set to 0)
if (esp8266.readBytesUntil('/', buffer, sizeof(buffer))) {
if (strcmp(buffer, "update") == 0) { //update wifi
//"?ssid=aaa&pwd=bbb HTTP/1.1"
esp8266.find("?ssid="); //skip ssid token
memset(buffer, 0, sizeof(buffer)); //clear buffer (all set to 0)
esp8266.readBytesUntil('&', buffer, sizeof(buffer)); //retrieve ssid
String ssid=buffer;
esp8266.find("pwd="); //skip pwd token
memset(buffer, 0, sizeof(buffer)); //clear buffer (all set to 0)
esp8266.readBytesUntil(' ', buffer, sizeof(buffer)); //retrieve pwd
String pwd=buffer;
//configure as a station
String res=sendData("AT+CWJAP=\"" + ssid + "\",\"" + pwd + "\"\r\n",6000,DEBUG);
//show setup result
String webpage="<html>Wifi setup ";
if (res.indexOf("OK") != -1) {webpage += "OK!</html>";}
else {webpage += "Failed!</html>";}
String cipSend="AT+CIPSEND=";
cipSend += connectionId;
cipSend += ",";
cipSend +=webpage.length();
cipSend +="\r\n";
sendData(cipSend,1000,DEBUG);
sendData(webpage,2000,DEBUG);
String closeCommand = "AT+CIPCLOSE=";
closeCommand+=connectionId; // append connection id
closeCommand+="\r\n";
sendData(closeCommand,3000,DEBUG);
}
else { //show setup page
String webpage="<html><form method=get action='/update/'>SSID ";
webpage += "<input name=ssid type=text><br>";
String cipSend = "AT+CIPSEND=";
cipSend += connectionId;
cipSend += ",";
cipSend +=webpage.length();
cipSend +="\r\n";
sendData(cipSend,1000,DEBUG);
sendData(webpage,2000,DEBUG);
webpage="PWD <input name=pwd type=text> ";
cipSend = "AT+CIPSEND=";
cipSend += connectionId;
cipSend += ",";
cipSend +=webpage.length();
cipSend +="\r\n";
sendData(cipSend,1000,DEBUG);
sendData(webpage,2000,DEBUG);
webpage="<input type=submit value=Connect></form></html>";
cipSend = "AT+CIPSEND=";
cipSend += connectionId;
cipSend += ",";
cipSend +=webpage.length();
cipSend +="\r\n";
sendData(cipSend,1000,DEBUG);
sendData(webpage,2000,DEBUG);
String closeCommand = "AT+CIPCLOSE=";
closeCommand+=connectionId; // append connection id
closeCommand+="\r\n";
sendData(closeCommand,3000,DEBUG);
}
}
}
}
}
}
//system use please do not edit
String sendData(String command, const int timeout, boolean debug) {
String response="";
esp8266.print(command); // send the read character to the esp8266
long int time=millis();
while ((time+timeout) > millis()) {
while(esp8266.available()) {
// The esp has data so display its output to the serial window
char c=esp8266.read(); // read the next character.
response += c;
}
}
if (debug) {Serial.print(response);}
return response;
}
編譯後記憶體耗用情形 :
草稿碼使用了 9,078 bytes (29%) 的程式存儲空間。最大值為 30,720 bytes。
全域變數使用了 730 bytes (35%) 的動態記憶體,剩餘 1,318 bytes 供局部變數。最大值為 2,048 bytes 。
最後整理一下我這塊模組的保留腳位, 開發應用時不要使用這四個數位腳, 若用不到蜂鳴器, 可用尖嘴鉗拔掉被 Nano 蓋住的 Jumper (位於 USB 插槽正下方), 這樣 D9 就與蜂鳴器斷開可自由使用了.
Nano 腳位 | 保留用途 |
D4 | 模式選擇, LOW(上)=Wifi 設定, HIGH(下)=工作 |
D7 | 軟體序列埠 Rx (接 ESP8266 Tx) |
D8 | 軟體序列埠 Tx (接 ESP8266 Rx) |
D9 | 蜂鳴器輸出 (可拔掉 Jumper 斷開) |
2016-07-08 補充 :
跟 Q 小奇買的 3*7 cm 洞洞板到貨了, 跟禾樺買的大小一樣, 但洞多一排, 是 10*24 :
其實我買這一塊只是要比較看看哪裡不同而已, 我還是會用禾樺的 9*24 這塊, 因為布局與布線起來剛剛好.
另外訂製的壓克力保護板收到了, 雷射切割非常平整, 只是四個角的孔有些誤差, 螺絲鎖上去時不是很對稱, 所以改用塑膠螺母當墊片, 以三秒膠黏緊就好了 :
這樣其實四個角根本就不需要鑽洞啦!
沒有留言 :
張貼留言