2024年10月5日 星期六

BQ40Z50電池管理IC研發履

 

使用I2C 通信外部的電線長度千萬不要太長否則會造成資料接收錯誤

程式設計:李進衛

/**

  Example of how to read battery fuel percentage, total voltage, cell voltages and current

  from TI BQ4050 fuel gauge chip.

  Fuel percentage reading will not be correct unless the battery has been calibrated for this chip

  2002-09-02 Arduino UNO 記憶體不足無法使用本程式

  2022-09-02 改為使用Wemos D1 ESP8266 開發板

  2022-09-02 建立繁體中文字庫以及焊接12864 LCD

  2022-09-03 撰寫中文字庫

  2022-09-04 debug

  2022-09-06 改為12863 LCD 增加剩餘電量判斷式

  2022-09-07 增加顯示core 電壓

  CV4 筆誤成CV2 修正回來 2022-09-07 by leecw

2022-10-03 開始使用WEMOS D1 I2C讀取資料都是錯誤的目前還沒有查出原因 2024/02/16 李進衛處理好了降低clock速度就可以解決

2022-10-05 使用ESP32 開發板但是當接上充電時就會讀到錯誤的資料,2024/02/16李進衛 查出原因,是clock速度太快,傳輸資料出現錯誤

           只要將頻率由內定的400KHZ-->降為100KHZ 就可以了

2024/02/02 使用Waveshare RP2040 Zero 剛compier 完成時我不知道上次的毛病是I2C不能使用,所以影響到OLED的顯示,我修改bq4050 lib 的內容將Wirw.being() mark

起來。之後OLED恢復正常,功能是否正常要跟同事確認。

2024/02/16 使用Waveshare RP2040 Zero 同事拿給我電池,我所讀到的資料為0,我查到最底層的程式依然沒有結果,我問SKYPE AI,

AI的回覆如下:我所得到的ack值是04 其他錯誤,因此我就將I2C的clock速度從400KHZ降到100KHZ我就可以正常的得到數值


Wire.beginTransmission( 0x0B/devAddress/ ) 這個函數是用來開始向一個 I2C 裝置發送資料的。

您需要在這個函數之後使用 Wire.write() 函數來寫入要傳送的字節,

然後使用 Wire.endTransmission() 函數來結束傳輸。 

https://reference.arduino.cc/reference/en/language/functions/communication/wire/begintransmission/ 

https://www.arduino.cc/en/Reference/WireBeginTransmission 

http://www.taichi-maker.com/homepage/reference-index/arduino-library-index/wire-library/arduino-wire-begintransmission/


當您使用 Wire.endTransmission() 函數時,Arduino 會自動等待裝置的 ACK bit 回應,並且返回一個錯誤代碼來表示傳輸的狀態。錯誤代碼的含義如下:


•  0: 成功


•  1: 傳輸過程中發生數據衝突


•  2: 裝置沒有回應 ACK bit


•  3: 裝置回應了 NACK bit


•  4: 其他錯誤 https://dotblogs.com.tw/April_Notes/2021/11/24/165906


因此,您可以使用 Wire.endTransmission() 函數的返回值來判斷裝置是否有正常回應。如果返回值為 0,則表示裝置已經接收了您的資料並且回應了 ACK bit。如果返回值為 2 或 3,則表示裝置沒有回應或者拒絕了您的資料,這時您可以檢查您的裝置地址和資料格式是否正確,或者嘗試重新傳輸。如果返回值為 1 或 4,則表示傳輸過程中發生了錯誤,這時您可以檢查您的連接線路和電源是否穩定,或者減少傳輸的速度和距離


如果您使用示波器來觀察 I2C 的通訊波形,您需要注意以下幾點:


•  您需要同時連接 SDA 和 SCL 線到示波器的兩個通道,並且設置合適的觸發條件和時間基準。


•  您需要確保您的示波器的探頭和接地線與 Arduino 和裝置的接地線相連,否則可能會產生雜訊或者偏移。


•  您需要確保您的示波器的探頭和接地線的長度盡量短,否則可能會影響 I2C 的信號品質。


•  您需要確保您的示波器的探頭和接地線不要與其他的線路或元件相交或靠近,否則可能會產生干擾或者耦合。


如果您按照以上的方法操作,您應該可以正確地讀取 I2C 的通訊波形,並且看到裝置的 ACK bit 回應。如果您仍然看到 ACK bit 是 HIGH,那麼可能是因為您的裝置有問題,或者您的示波器有問題。您可以嘗試更換其他的裝置或者示波器,或者使用其他的 I2C 工具來檢測您的裝置的狀態。



void Lcd_display(void)

{

//  Wire.beginTransmission(0x0b);  // Transmit to device number 44 (0x2C)

  digitalWrite(P_debug, LOW);

   Wire.setClock(100000); // 設定 i2c 的速率為 100 KHz RP2040 

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^          

  BQ4050.readReg(registers.relativeStateOfCharge);

  digitalWrite(P_debug,HIGH);

**/

新增加這個程式【紅框處】我測試200KHZ還是偶爾會有錯誤,因此改為100KHZ可能是因為電池的線路太長了導致。

當SCK速度太快時就不會傳出資料,在OLED看到的都是0,如果偶爾正確也會出現錯誤的數值例如:105% 4.4V

降頻為100KHZ之後

400KHZ降為200KHZ仍然發現電壓數值錯誤


沒有留言:

如何使用終端機軟體收集來自於Arduino的資料

  將治具使用Micro USB cable 連上電腦 開啟終端機軟體 選擇 Serial🡪按下OK File🡪Log…  設定log file要存放位置,建議檔案名稱直接取名為*.CSV 例如:20231224.csv 按下治具Reset按鍵開始收集資料