banner
面具熊

面具熊

萌新胶佬|折腾爱好者

DIY單片機並愉快地“偷數”據吧!

DIY 個單片機,優雅地 “偷” 數據吧!#

起因#

最近因為個人專案需要,要將不允許聯網的主機裡資料庫的數據發送至遠程伺服器。考慮到既然主機無法聯網,不如用單片機作為中間人,通過串口將數據發送給單片機,再由聯網的單片機將數據發送至伺服器。這不就完美實現 “偷數據” 的操作了麼!說幹就幹!

主機數據抓取#

既然要將數據發送至單片機,那首先我得先拿到數據。由於主機是離線且最高權限狀態,果斷裝一個 python 環境(這樣可以先分析一波數據,將異常值與有效的數據進行區分後選擇發送),通過 pyserial 和 pymssql 進行數據抓取。詳細的代碼就不列了,說下在過程中碰到的一個坑。

最開始由於 python 程序中沒有設計發送截至符,所以測試時,單片機無法確定數據截至位置在哪,導致發送至遠端伺服器的數據都是斷斷續續的。而在主程序中添加截至符發送後,完美解決該問題。

import serial
import json
import pymssql

def get_data():
    """
    """
    return(data)

#後續增加截至符的發送
def deliver_data():
    myChar='#'
    #設置對應串口號與通訊波特率
    ser = serial.Serial(port="COM4", baudrate=115200)

    # 將json格式進行轉換後,發送
    data=get_data()
    comdata=json.dumps(data)
    write_len = ser.write(comdata.encode())
    ser.write(myChar.encode())
    print("串口發出{}個字節。".format(write_len)) 
    ser.close()
    
def main():
    deliver_data()
    print('傳輸完畢')

if __name__=='__main__':
    main()

對了,由於主機無法聯網而且還是 windows7 操作系統,其實配置 python 環境也格外艱難!在趟過了各種坑後,成功運行抓數據的腳本時,我的眼角都濕潤了。

單片機程序編寫#

由於 esp8266 可以非常愉快的使用 arduino 框架進行開發,大大降低了我們這種萌新的上手難度。參考《arduino (2)-- 通過 ESP8266 模塊實現串口接收數據,使用 TCP 協議進行局域網通信》文章,略作修改,就成功實現了串口數據的讀取與發送。

#include "ESP8266WiFi.h"
#define led 2
const char *ssid     = "wifi名稱";
const char *password = "wifi密碼";
const char *host = "伺服器地址";
WiFiClient client;
const int tcpPort = 伺服器端口;
static String comdata = "";
char myChar='#';
void setup()
{
    Serial.begin(115200);    
    pinMode(led,OUTPUT);
    delay(10);
    Serial.println();
    Serial.print("Connecting to ");
    Serial.println(ssid);
    WiFi.begin(ssid, password);//啟動
     //在這裡檢測是否成功連接到目標網絡,未連接則阻塞。
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(500);
    }
 //幾句提示
    Serial.println("");
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
}
void loop()
{
/******************串口接受數據************************/
  while (Serial.available() > 0 ) // 串口收到字符數大於零。
  {
    comdata = Serial.readStringUntil(myChar);
  }
 /******************串口打印數據************************/ 
  if(comdata!="")//如果接受到數據
  {
    client.print(comdata);//向伺服器發送數據 
   }
   comdata="";//清空數據
  if (client.connected()) //嘗試訪問目標地址,如果連接後LED燈滅,畢竟這種事情要低調
    digitalWrite(led, HIGH);
  else
    digitalWrite(led, LOW);

  while (!client.connected())//若未連接到服務端,則客戶端進行連接。
  {
    if (!client.connect(host, tcpPort))//實際上這一步就在連接服務端,如果連上,該函數返回true
    {
       Serial.println("連接中....");
       delay(500);
    }    
  }
}

事情到了這一步,整個流程其實已經完全跑通了,也成功實現了 “偷” 數據。但是主機後邊插一根數據線,數據線再連接到一個大大的 NodeMCU 開發板上。實在太不優雅了!令我完全無法接受!

上淘寶看看有沒有更簡約的方案。似乎簡單的 USB 轉 TTL 通訊板 + ESP-01s 就能解決這個問題。果斷買來換掉原方案。

方案升級

然而,想像的很美好,這個方案卻有一個致命問題,那就是通訊不穩定。導致主機的數據無法正確發送到單片機上。為此我還特地找來兩台主機上分別實驗了一下,其中一台能夠正常通訊,另一台就一直失敗。而舊方案相比之下就非常穩定,都能成功偷發數據。初步懷疑可能是新方案供電不穩定導致的,但是沒有繼續驗證,如果有大佬懂得,麻煩告知一下,謝謝!

DIY 單片機#

既然現有方案無法滿足我的需求,那只有一條路了!自己製作一個小巧玲瓏,性能穩定的單片機。像我這樣的萌新,直接開幹,那肯定是不可能的了,還是得上開源硬體平台看看有沒有大佬已經做過類似的專案。成功仿造一個,不就成了麼!

usb-esp8266 - 嘉立創 EDA 開源硬體平台 (oshwhub.com)

感謝 moguiliue 大佬開源的專案,直接打板,開幹!

鐵板燒

仿造

大佬的方案確實可以!成品能夠穩定運行,完美滿足我的需求。不過過程中發現原設計 USB 公頭位置的 PCB 會有干涉問題(不知道是不是我買的元器件不對🤦‍)。每套主板前端都要把干涉的位置用銼刀磨掉,才能焊上 USB 頭。有點費力

而且這個方案只能滿足最基本的數據通訊,沒有將其他 GPIO 口引出,導致後續無法外接傳感器或者顯示屏。雖然優雅,但可玩性又差點意思。怎麼辦?

DIY 單片機 2.0#

既要優雅,又要能擴展,不如參考大佬的思路,自己再從頭設計一版!

新設計

自己從頭設計的開發板,將原有 CH340G 的方案改為 CH340C,省下外圍晶振電路的空間,增加一個 4pin 母座用於引出 I2C 通訊。由於原設計的走線和佈局很難改動了,只能重構整體。目前進度是已打板,但還未製作。希望等材料到了之後,這塊自己第一次從頭設計的單片機能成功運行!

2023/4/23 update:#

今天終於把自己第一次設計的單片機做出來了,一切運行正常,開心~
新設計
新設計

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。