這段時間實(shí)在是太忙了,又是忙于本科畢業(yè)論文,考研的事情也才落下帷幕。
五一期間高中的一位老師聯(lián)系我商量著設(shè)計(jì)一款《基于薄膜式應(yīng)變片的壓力測量裝置》用于科創(chuàng)大賽,但是大概要做成類似于電子秤一樣的裝置。
一般來說呢,電子秤的方案是不會用薄膜式壓力傳感器的作為傳感器#壓力傳感器,大部分會選擇懸臂梁式傳感器、電阻應(yīng)變片或者S型傳感器,薄膜應(yīng)變片來測重這個方案顯然不是明智之選。可是在賽事方要求下,必須采用薄膜式壓力傳感器且測量裝置應(yīng)該搭在底部平臺,那可謂是挑戰(zhàn)頗大。
1、薄膜應(yīng)變片特性
薄膜壓力傳感器不像常規(guī)金屬應(yīng)變片,其電阻有一個觸發(fā)力,當(dāng)壓力大于觸發(fā)力時,電阻值將會驟降繼而保持一定規(guī)律。
在未觸發(fā)之前,薄膜壓力傳感器電阻將近20M,常規(guī)的應(yīng)變片電阻則相對較小,通常為120Ω,在受到形變后電阻發(fā)生變化。所以薄膜壓力傳感器不能像應(yīng)變片那樣使用差分放大電路實(shí)現(xiàn)精準(zhǔn)測量。
礙于時間緊張,于是采用最簡單的電路分壓方案先進(jìn)行測量。
2、主控和軟件部分
主控制器打算使用#ESP32?使用藍(lán)牙和手機(jī)APP傳輸,經(jīng)過測試后發(fā)現(xiàn)ESP32能夠正常的采集電壓和傳輸,這里不過多贅述,主要是ESP32開啟#BLE?如何和手機(jī)進(jìn)行通訊,代碼如下:
#include<BLEDevice.h>
#include<BLEServer.h>
#include<BLEUtils.h>
#include<BLE2902.h>
#include<driver/adc.h>
// BLE 配置
#define?SERVICE_UUID ? ? ? ?"4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define?CHARACTERISTIC_UUID?"beb5483e-36e1-4688-b7f5-ea07361b26a8"
constint adc2_pin =?4;?
BLECharacteristic *pCharacteristic;
bool?deviceConnected =?false;
// BLE 連接狀態(tài)回調(diào)
classMyServerCallbacks :public?BLEServerCallbacks {
voidonConnect(BLEServer* pServer){
? ? ? ? deviceConnected =?true;
? ? }
voidonDisconnect(BLEServer* pServer){
? ? ? ? deviceConnected =?false;
? ? ? ? pServer->startAdvertising();?// 斷開后重新廣播
? ? }
};
voidsetup(){
? ? Serial.begin(115200);
? ??adc2_config_channel_atten(ADC2_CHANNEL_0, ADC_ATTEN_DB_11);
// 初始化BLE
? ? BLEDevice::init("ESP32-ADC");
? ? BLEServer *pServer = BLEDevice::createServer();
? ? pServer->setCallbacks(new?MyServerCallbacks());
? ? BLEService *pService = pServer->createService(SERVICE_UUID);
? ? pCharacteristic = pService->createCharacteristic(
? ? ? ? ? ? ? ? ? ? ? ? CHARACTERISTIC_UUID,
? ? ? ? ? ? ? ? ? ? ? ? BLECharacteristic::PROPERTY_READ |
? ? ? ? ? ? ? ? ? ? ? ? BLECharacteristic::PROPERTY_NOTIFY
? ? ? ? ? ? ? ? ? ? ? );
? ? pCharacteristic->addDescriptor(new?BLE2902());
? ? pService->start();
? ? BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
? ? pAdvertising->addServiceUUID(SERVICE_UUID);
? ? pAdvertising->setScanResponse(true);
? ? pAdvertising->setMinPreferred(0x06);?
? ? BLEDevice::startAdvertising();
? ? Serial.println("BLE 已啟動,等待連接...");
}
voidloop(){
if?(deviceConnected) {
int?sum =?0;
int?validSamples =?0;
// 連續(xù)讀取10次ADC并求平均
for?(int?i =?0; i <?10; i++) {
int?raw;
esp_err_t?result =?adc2_get_raw(ADC2_CHANNEL_0, ADC_WIDTH_BIT_12, &raw);
if?(result == ESP_OK) {
? ? ? ? ? ? ? ? sum += raw;
? ? ? ? ? ? ? ? validSamples++;
? ? ? ? ? ? }
? ? ? ? ? ??delay(5); ?// 每次采樣之間稍作延遲,避免過快
? ? ? ? }
if?(validSamples >?0) {
int?avgRaw = sum / validSamples;
float?voltage = (float)avgRaw *?3.3?/?4096;
unsignedlong runTimeSec =?millis() /?1000;
// 發(fā)送格式:ADC:平均值 Time:秒
char?txString[32];
sprintf(txString,?"ADC:%.2f",voltage);
? ? ? ? ? ? pCharacteristic->setValue(txString);
? ? ? ? ? ? pCharacteristic->notify();
? ? ? ? ? ? Serial.printf("Avg ADC: %d,Time: %lusn", avgRaw, runTimeSec);
? ? ? ? }
? ? ? ??delay(100); ?// 控制發(fā)送頻率
? ? }
? ??delay(1);
}
APP采用#NETMAUI?框架,也不做過多贅述。
3、技術(shù)難點(diǎn)
經(jīng)過實(shí)際的測試,發(fā)現(xiàn)要實(shí)現(xiàn)精準(zhǔn)的壓力(承重)測量有幾個難點(diǎn):
首先是受力不均勻的問題,由于薄膜傳感器有效區(qū)域是一個圓形大小受力面積對它的影響很大。
為了解決受力問題,利用3D打印制作一個受力板,讓承重受力能夠均勻的施加到傳感器的有效工作區(qū)中。
其次就是我發(fā)現(xiàn)同樣的重物下,傳感器的電阻值會隨著時間而發(fā)生變化(這個非常麻煩)。不同時間下傳感器的值不統(tǒng)一,這讓數(shù)據(jù)處理造成了很大的麻煩。經(jīng)過測量,其變化百分比趨勢如下:
大小相差6%以上,后來經(jīng)過細(xì)心觀察發(fā)現(xiàn),大概是這個傳感器在發(fā)生本征形變,經(jīng)過重物受壓一段時間后,這種自身數(shù)值變化將會趨于穩(wěn)定,因此可以選擇考慮選擇經(jīng)過工作(受壓)一段時間后的傳感器數(shù)據(jù)作為擬合源,將承重和傳感器數(shù)值進(jìn)行擬合。
4、數(shù)據(jù)擬合
將工作一段時間后的傳感器輸出電壓值和承重壓力進(jìn)行擬合,我們可以得到下圖所示曲線。
它的具體函數(shù)是這樣子的:
其中x是0~4096也就是ESP32原始的數(shù)字電壓,我們不難發(fā)現(xiàn),它的函數(shù)曲線近似反曲函數(shù),并且它的壓力-電阻曲線也是一條近似反曲函數(shù)。于是在這個的基礎(chǔ)上,我們對其進(jìn)行數(shù)據(jù)處理。
利用這個方法,我們就可以近似的得到電壓和承重力關(guān)系。