Decent藍牙秤在出廠時已使用1000g和2000g砝碼進行過校準。
- 但是,校準可能會受到運輸的影響。
- 請參閱用戶手冊或此校準視頻 a> 了解更多信息。
- 重量數值以10hz的頻率發送。
- 電池狀態在重量數據傳輸中返回,以響應LED開啟或關閉藍牙命令。
- 請參閱“發送命令以打開或關閉 LED”視頻。
- 電池電量不足3%或更低時,秤會在開機時顯示LO信息。
- 我們不建議在秤上長時間放置重物,否則會慢慢使稱重傳感器變形,使其無法校準。
- 秤可以無限次重新校準。
- 沒有用於設置秤顯示克與盎司的藍牙命令。
- 必須手動操作,打開秤後立即同時按下○和□按鈕。更多信息,請參閱用戶手冊。
- 通過讀取LED開啟或關閉的藍牙命令的響應,您可以發現電子秤顯示的是克還是盎司。請參閱“發送打開或關閉LED的命令”
- 如果在執行完第一條命令之前向秤發送了第二條藍牙命令,則秤將忽略第二條命令。
- 例如:一個去皮命令緊跟一個計時啟動命令。
- 建議發送到秤的命令之間有200毫秒的間隔。
- 或者,您可以延遲發送第二個命令,直到您確認第一個命令已執行。
- 例如:在去皮(或LED開/關命令)之後,設置一個6字節的FE響應被發送回您的應用程序,以執行成功。
藍牙介紹
“0000FFF4-0000-1000-8000-00805F9B34FB”體現了decent藍牙秤的數據包
所有Decent秤的藍牙數據包都具有以下7字節結構
第一個字節 | 第二個字節 | 第三個字節 | 第四個字節 | 第五個字節 | 第六個字節 | 第七個字節 |
型號 03 = Decent | 類型 0A=LED開啟/關閉 0B=計時開始/關閉 0F=去皮 | 命令/數據 (1) | 命令/數據 (2) | 命令/數據 (3) | 命令/數據 (4) | 異或驗證 用於驗證的6字節異或條件
|
下面給出了有關每個命令和信息類型的更多詳細信息。
這是一個Tcl過程,它構建了7個字節的二進制數據包以發送到 Decent秤。它首先構建為文本字符串,然後在過程結束時轉換為7字節的二進製文件:
proc decent_scale_make_command {cmdtype cmdddata {cmddata2 {}} } {
if {$cmddata2 == ""} {
msg "1 part decent scale command"
set hex [subst {03${cmdtype}${cmdddata}000000[decent_scale_calc_xor "0x$cmdtype" "0x$cmdddata"]}]
} else {
msg "2 part decent scale command"
set hex [subst {03${cmdtype}${cmdddata}${cmddata2}0000[decent_scale_calc_xor4 "0x$cmdtype" "0x$cmdddata" "0x$cmddata2"]}]
}
msg "hex is '$hex' for '$cmdtype' '$cmdddata' '$cmddata2'"
return [binary decode hex $hex]
}
異或計算
要進行異或計算,應該對前6個字節進行數學異或計算。
下面的Tcl編程代碼,為一個只接受一個參數的簡單命令(例如:去皮)異或計算:
proc decent_scale_calc_xor {cmdtype cmdddata} {
set xor [format %02X [expr {0x03 ^ $cmdtype ^ $cmdddata ^ 0x00 ^ 0x00 ^ 0x00}]]
msg "decent_scale_calc_xor for '$cmdtype' '$cmdddata' is '$xor'"
return $xor
}
這個Tcl編程代碼,是用於計算兩個參數命令的異或計算,例如啟用LED顯示:
proc decent_scale_calc_xor4 {cmdtype cmdddata1 cmdddata2} {
set xor [format %02X [expr {0x03 ^ $cmdtype ^ $cmdddata1 ^ $cmdddata2 ^ 0x00 ^ 0x00}]]
msg "decent_scale_calc_xor4 for '$cmdtype' '$cmdddata1' '$cmdddata2' is '$xor'"
return $xor
}
接收重量
接收重量數據是一種稍微特殊的情況,因為重量是作為克重量*10的兩字節有符號短整數發送的:
固件v1.0和v1.1以7個字節格式發送重量數據。
第一個字節 | 第二個字節 | 第三個字節 | 第四個字節 | 第五個字節 | 第六個字節 | 第七個字節 |
型號 03 = Decent | 類型 CE=重量穩定 CA=重量變化 | Data (1) 克重*10
有符號短整數的高位字節 |
Data (2) 克重*10
有符号短整数的低位字节 | Data (3) 变化*10
有符號短整數的高位字節 |
Data (4) 变化*10
有符号短整数的低位字节 |
異或驗證 用於驗證的6字節異或條件
|
固件v1.2版本以10個字節格式發送帶有時間信息的重量數據。
第一個字節 | 第二個字節 | 第三個字節 | 第四個字節 | 第五個字節 | 第六個字節 | 第七個字節 | 字節 8 | 字節 9 | 字節 10 |
型號 03 = Decent | 類型 CE=重量穩定 CA=重量變化 | Data (1) 克重*10
有符號短整數的高位字節 |
Data (2) 克重*10
有符号短整数的低位字节 |
Data (3) 分鐘 |
Data (4) 秒(0-59 十六進製) |
數據(5) 分秒數(0-9) |
數據(6) 供將來使用 |
數據(7) 供將來使用 |
異或驗證 用於驗證的6字節異或條件
|
注意:
- 您的應用程序應該查看接收到的消息的長度,並支持兩者的解析。 大多數應用程序只需要知道當前的重量:只需查看字節3和4即可,與所有Decent藍牙秤固件兼容。 或者,您可以檢查固件版本是否等於或大於03。
- 當前重量在數據字節1和2上以兩字節短的大端有符號整數的形式傳達。
- 每秒重量變化以兩字節無符號大端字節的形式出現。但是,此功能目前存在問題,不建議使用。如果你需要重量變化數據,您可以自己計算。
自固件v1.2起,重量變化率功能已停用。
- 重量數據以每秒10次的頻率發送。
- 秤嘗試確定重量何時穩定(不再變化)並將第二個字節設置為CE。當重量發生變化時,第二個字節是CA。但是,您可以選擇忽略這一點並實施您自己的邏輯來決定重量何時穩定,因為我們沒有對重量數據做數據平滑或穩定處理。
- 查看本頁頂部的7字節和10字節消息示例。
接收按鈕點擊信號
第一個字節 | 第二個字節 | 第三個字節 | 第四個字節 | 第五個字節 | 第六個字節 | 第七個字節 |
型號 03 = Decent | 類型 AA | Data (1) 01=圓形按鍵 02=方形按鍵 | Data (2) 01=短按
02=長按 | Data (3) | Data (4) | 異或驗證 00 |
注意:
- 當有藍牙連接時,按鈕輕敲無功能相應,並且您可以編程您喜歡的任何功能。
- 在de秤v1.1固件上,按下圓形按鈕不會通過藍牙發送信號。如果您的應用需要去皮,您的應用應向秤發送去皮命令。
以下是Light Blue應用程序日誌中的觸控按鈕示例:
16:59:51.479 - 特徵 (FFF4) 通知: 03aa0101 0000a9 (短按圓形按鈕)
17:35:49.591 - 特徵 (FFF4) 通知: 03aa0102 0000aa (長按圓形按鈕)
17:38:16.702 - 特徵 (FFF4) 通知: 03aa0201 0000aa (短按方形按鈕)
17:39:08.003 - 特徵 (FFF4) 通知: 03aa0202 0000a9 (長按方形按鈕)
發送去皮命令(將重量重置為零)
第一個字節 | 第二個字節 | 第三個字節 | 第四個字節 | 第五個字節 | 第六個字節 | 第七個字節 |
型號 03 = Decent | 類型 0F | Data (1) 遞增整數 (可以一直為零) |
Data (2) 00 | Data (3) 00 | Data (4) 00=disable heartbeat requirement 01=maintain heartbeat | 異或驗證 計算 |
注意:
- “遞增整數”是可選的,並且可以始終為零。
- 030F000000000C字符串將始終為去皮。
- 確保您正確計算了7字節的異或運算,否則去皮命令將被忽略。
- 如果至少每5秒没有接收到“03 0a 03 ff 00 0a”的信号,则薄款Decent蓝牙秤将断开连接。
如果妳想禁用這個要求,字節6應該是00。
如果妳想保持這個要求,字節6應該是01。
將字節6設置為01對不支持心跳功能的模型沒有負面影響。
下面是一段代碼,展示如何構建一個7字節的去皮命令:
proc tare_counter_incr {} {
if {[info exists ::decent_scale_tare_counter] != 1} {
set ::decent_scale_tare_counter 0
} elseif {$::decent_scale_tare_counter >= 255} {
set ::decent_scale_tare_counter 0
} else {
incr ::decent_scale_tare_counter
}
# alternatively: the tare counter can in fact be any not-recently-used integer, such as this random digit-picker
# set ::decent_scale_tare_counter [expr {int(rand() * 255)}]
}
proc decent_scale_tare_cmd {} {
tare_counter_incr
set cmd [decent_scale_make_command "0F" [format %02X $::decent_scale_tare_counter]]
return $cmd
}
Decent秤將在發出去皮命令後發回應答。
該應答具有以下結構:
第一個字節 | 第二個字節 | 第三個字節 | 第四個字節 | 第五個字節 | 第六個字節 | 第七個字節 |
型號 03 = Decent | 類型 0F | Data (1) 去皮計數器 | Data (2) 00 | Data (3) 00 | Data (4) FE | 異或驗證 |
發送命令以打開或關閉LED顯示
第一個字節 | 第二個字節 | 第三個字節 | 第四個字節 | 第五個字節 | 第六個字節 | 第七個字節 |
型號 03 = Decent | 類型 0A | Data (1) 重量LED顯示開/關 00=關 01=開 02=關機 | Data (2) 計時器LED顯示開/關 00=關 01=開 | Data (3) 00=克 01=盎司 | Data (4) 00 | 異或驗證 計算 |
注意:
- 保持LED顯示關閉可延長電池壽命。
- 即使兩個LED顯示都關閉,秤仍將繼續工作。
- 固件v1.2中增加了關機命令。
- 顯示“重量變化”的單個LED 將亮起,即使兩個LED都已關閉。
- 從v1.1固件開始,方形按鈕上方的LED在重量變化時不再亮起。
- 而當按下任一按鈕時,該LED會亮起。
- 這是為了向用戶提供視覺反饋,即秤已感應到按鈕按下。
示例:使用克單位時,所有LED亮起命令:
03 0A 01 01 00 00 09
示例:使用盎司單位時,所有LED亮起命令:[需要 v1.1 固件]
03 0A 01 01 01 00 08
示例:所有LED關閉命令:
03 0A 00 00 00 00 09
示例:關機命令:
03 0A 02 00 00 00 0B
在LED開/關命令(固件 v1.1)後,Decent秤將在重量數據反饋中發回應答,包括克與盎司信息、電池電量和固件版本。
數據結構如下:
第一個字節 | 第二個字節 | 第三個字節 | 第四個字節 | 第五個字節 | 第六個字節 | 第七個字節 |
型號 03 = Decent | 類型 0A | Data (1) 00 | Data (2) 顯示的重量單位 00=克
01=盎司 | Data (3) 電池電量 在3%(低電量)和100%(滿電)之間。 FF (255) = USB供電 | Data (4) 固件版本
FE=V1.0 02=V1.1 03=v1.2固件版本 | 異或驗證 |
由於藍牙秤PCB的限制,電池電量始終顯示為100%。 |
以下是從Light Blue app應用日誌中讀取電池電量的示例:
16:02:36.005 - 特徵(36F5)寫入新值: <030a0101 000009> (我們使用應用程序發送此值,打開LED)
16:02:36.061 - 特徵(36F5)讀取:(空)
16:02:36.135 - 特徵 (FFF4) 通知: 030a0000 64026f (64 hex = 100%, 使用電池運行
15:59:50.421 - 特徵(36F5)寫入新值: <030a0101 000009> (我們使用應用程序發送此值,打開LED)
15:59:50.485 - 特徵(36F5)讀取:(空)
15:59:50.522 - 特徵 (FFF4) 通知: 030a0000ff0ac7 (FF 十六進制 = 255%,使用USB電源供電)
發送命令來控制計時器
第一個字節 | 第二個字節 | 第三個字節 | 第四個字節 | 第五個字節 | 第六個字節 | 第七個字節 |
型號 03 = Decent | 類型 0B | Data (1) 計時開始/停止/重置
00=停止 02=重置归零 03=开始 | Data (2) 00 | Data (3) 00 | Data (4) 00 | 異或驗證 計算 |
例如:計時開始命令
03 0B 03 00 00 00 0B
例如:計時停止命令
03 0B 00 00 00 00 08
例如:計時重置命令
03 0B 02 00 00 00 0A
用於從Decent秤接收各種數據的大型示例代碼
Github上更大的bluetooth.tcl示例
以下代碼(使用 Tcl 語言,但希望您能理解)可以實現:
- 接收重量信息
- 接收按鍵操作信息
- 接收當前時間值
set ::de1(cuuid_decentscale_read) "0000FFF4-0000-1000-8000-00805F9B34FB"
set ::de1(cuuid_decentscale_write) "000036F5-0000-1000-8000-00805F9B34FB"
set ::de1(cuuid_decentscale_writeback) "83CDC3D4-3BA2-13FC-CC5E-106C351A9352"
if {$cuuid eq $::de1(cuuid_decentscale_read)} {
# decent scale
parse_decent_scale_recv $value weightarray
if {[ifexists weightarray(command)] == [expr 0x0F] && [ifexists weightarray(data6)] == [expr 0xFE]} {
# tare cmd success is a msg back to us with the tare in 'command', and a byte6 of 0xFE
msg "- decent scale: tare confirmed"
return
} elseif {[ifexists weightarray(command)] == 0xAA} {
msg "Decentscale BUTTON $weightarray(data3) pressed"
if {[ifexists $weightarray(data3)] == 1} {
# button 1 "O" pressed
decentscale_tare
} elseif {[ifexists $weightarray(data3)] == 2} {
# button 2 "[]" pressed
}
} elseif {[ifexists weightarray(command)] != ""} {
msg "scale command received: [array get weightarray]"
}
if {[info exists weightarray(weight)] == 1} {
set sensorweight [expr {$weightarray(weight) / 10.0}]
#msg "decent scale: ${sensorweight}g [array get weightarray] '[convert_string_to_hex $value]'"
#msg "decentscale recv read: '[convert_string_to_hex $value]'"
::device::scale::process_weight_update $sensorweight $event_time
} else {
msg "decent scale recv: [array get weightarray]"
}
}
proc parse_decent_scale_recv {packed destarrname} {
upvar $destarrname recv
unset -nocomplain recv
::fields::unpack $packed [decent_scale_generic_read_spec] recv bigeendian
if {$recv(command) == 0xCE || $recv(command) == 0xCA} {
unset -nocomplain recv
::fields::unpack $packed [decent_scale_weight_read_spec2] recv bigeendian
} elseif {$recv(command) == 0xAA} {
msg "Decentscale BUTTON pressed: [array get recv]"
} elseif {$recv(command) == 0x0C} {
unset -nocomplain recv
::fields::unpack $packed [decent_scale_timing_read_spec] recv bigeendian
msg "Decentscale time received: [array get recv]"
}
}
proc decent_scale_generic_read_spec {} {
set spec {
model {char {} {} {unsigned} {}}
command {char {} {} {unsigned} {}}
data3 {char {} {} {unsigned} {}}
data4 {char {} {} {unsigned} {}}
data5 {char {} {} {unsigned} {}}
data6 {char {} {} {unsigned} {}}
xor {char {} {} {unsigned} {}}
}
return $spec
}
proc decent_scale_weight_read_spec2 {} {
set spec {
model {char {} {} {unsigned} {}}
wtype {char {} {} {unsigned} {}}
weight {Short {} {} {signed} {}}
rate {Short {} {} {unsigned} {}}
xor {char {} {} {unsigned} {}}
}
return $spec
}