資料介紹
描述
需要在距離您的項目太遠的傳感器位置添加 OLED 屏幕以獲取有意義的報告?
I2C 總線上連接的傳感器太多?那么你需要IO 擴展器!使用1-Wire? 到 I2C適配器,可以根據需要在 1-Wire? 總線上添加任意數量的 I2C 總線。
需要多條 1-Wire? 總線?IO Expander最多可同時支持 16 個。
需要更多?然后將最多 255 個IO 擴展器連接在一起;IO 擴展器真正提供了極致的連接性!
功能列表
- 使用便宜的 128x64 OLED 屏幕。
- 在單個 1-Wire? 總線上使用多個 OLED 屏幕。
- 使用不同的 OLED 屏幕尺寸。
- 根據需要添加盡可能多的 I2C 總線。
- 永遠不要用完 I2C 地址。只需添加另一個 I2C 總線。
- 易于使用的圖形命令。
- 1-Wire? 標準和過載,可實現快速屏幕更新。
- 無需 1-Wire? 驅動器。節省代碼空間。
- 無需 OLED 驅動程序。節省代碼空間。
- 不需要 OLED 字體。節省代碼空間。
- 無需 DS18B20 溫度驅動器。節省代碼空間。
- 無需 I2C 傳感器驅動程序。節省代碼空間。
- 不需要額外的電源。
- 易于連接 RJ11 電話線。
- 易于在 1-Wire? 總線上添加傳感器。
- 熱插拔 1-Wire? 總線。
用于構建 OLED 演示的部件
- IO 擴展器
- 1-Wire? 至 I2C。
- 1-Wire? 接頭
- 分路器
- 阿杜諾納米。
- RJ11 Keystone 螺絲端子插孔。
- 50 英尺 4C4P RJ11 線。
- 7 英尺 4C4P RJ11 線。
- DHT22 溫度/濕度傳感器。
- I2C Si7021 溫度/濕度傳感器。
- SSD1306 128x32 OLED 0.91"。
- SSD1306 128x64 OLED 0.96"。
- SSD1106 128x64 OLED 1.3"。注意:屏幕易碎!確保您訂購它們以裝箱。
- SSD1309 128x64 OLED 2.42"。
- 2.54 毫米頭線。
接線圖
俯視圖
運行此演示的 Arduino 代碼。
/* IO Expander OLED sketch
*
* Make sure you increase the SERIAL_RX_BUFFER_SIZE in Arduino/hardware/arduino/avr/cores/arduino/HardwareSerial.h
* from 64 to 256.
*/
#define SERIAL_RX_BUFFER_SIZE 256
#include
#include
#include "IOExpander.h"
#define FAHRENHEIT
#define OLED_SCREENS 5
#define TEMP_SENSORS 4
#define HUMIDITY_SENSORS 2
#define ONEWIRE_TO_I2C_ROM1 "i4s51"
#define ONEWIRE_TO_I2C_ROM2 "i4s2e"
#define ONEWIRE_TO_I2C_ROM3 "i4s24"
#define ONEWIRE_TO_I2C_ROM4 "i4sc0"
#define ONEWIRE_TO_I2C_ROM5 "i2see"
#define ONEWIRE_TEMP_CONVERSION "t4s0;tt"
#define TEMP_SENSOR1 "t4r4c"
#define TEMP_SENSOR2 "t4r57"
#define TEMP_SENSOR3 "t4r76"
#define TEMP_SENSOR4 "t4r0300"
#define HUMIDITY_SENSOR1 "st8"
#define HUMIDITY_SENSOR2 "s6t5"
#define INIT_OLED_SSD1306_32 "st10;si128,32"
#define INIT_OLED_SSD1306_64 "st10;si128,64"
#define INIT_OLED_SSD1106 "st13;si128,64"
#define INIT_OLED_SSD1309 "g1o0,10;s2t10;si128,64"
#define SERIAL_DEBUG
#ifdef SERIAL_DEBUG
SoftwareSerial swSerial(8,7);
#endif
struct TS {
bool update;
float temp;
bool error;
};
struct HS {
bool update;
float temp;
float humidity;
bool error;
};
int led = 13;
#ifdef FAHRENHEIT
#define C2F(temp) CelsiusToFahrenheit(temp)
float CelsiusToFahrenheit(float celsius)
{
return ((celsius*9)/5)32;
}
#else
#define C2F(temp) (temp)
#endif
bool init_oled[OLED_SCREENS] = {true, true, true, true, true};
TS ts[TEMP_SENSORS];
HS hs[HUMIDITY_SENSORS];
void ReadTempSensor(TS* ts, char* ts_read)
{
float temp = ts->temp;
SerialCmd(ts_read);
ts->error = !SerialReadFloat(&ts->temp);
SerialReadUntilDone();
ts->temp = roundf(ts->temp * 10) / 10;
ts->update = (temp != ts->temp);
}
void ReadHumiditySensor(HS* hs)
{
float temp = hs->temp;
float humidity = hs->humidity;
SerialCmd("sr");
hs->error = !(SerialReadFloat(&hs->temp) && SerialReadFloat(&hs->humidity));
SerialReadUntilDone();
hs->temp = roundf(hs->temp * 10) / 10;
hs->humidity = roundf(hs->humidity * 10) / 10;
hs->update = (temp != hs->temp || humidity != hs->humidity);
}
void SerialPrintDecimal(const char* str, float decimal, char error)
{
Serial.print(str);
if (error) Serial.print(F("NA"));
else Serial.print(decimal, 1);
Serial.print(""");
}
void SerialPrintUnits(void)
{
Serial.print(",248,""
#ifdef FAHRENHEIT
"F"
#else
"C"
#endif
""");
}
void SerialDrawBorder(uint8_t height)
{
if (height == 32) Serial.print(";sh0,0,128;sh0,31,128;sv0,1,30;sv127,1,30");
else Serial.print(";sh0,0,128;sh0,63,128;sv0,1,62;sv127,1,62");
}
void setup() {
Serial.begin(115200);
Serial.setTimeout(5000); // 5 sec delay between DHT22 reads
#ifdef SERIAL_DEBUG
swSerial.begin(115200);
swSerialEcho = &swSerial;
#endif
pinMode(led, OUTPUT);
wdt_enable(WDTO_8S);
}
void loop() {
uint8_t i;
static uint32_t last_millis = 0;
static TS ts[TEMP_SENSORS];
static HS hs[HUMIDITY_SENSORS];
while (Serial.available()) Serial.read(); // Flush RX buffer
Serial.println();
if (SerialReadUntilDone()) {
// First do a 1-Wire temperature measurement on all DS18B20 sensors
SerialCmdDone(ONEWIRE_TEMP_CONVERSION);
// Read the Si7020 humidity sensor
if (SerialCmdNoError(ONEWIRE_TO_I2C_ROM4)) {
if (SerialCmdDone(HUMIDITY_SENSOR1)) {
ReadHumiditySensor(&hs[0]);
}
}
else init_oled[3] = true;
// Read DHT22 humidity sensor every 2 seconds
if (millis() - last_millis >= 2000) {
SerialCmdDone(HUMIDITY_SENSOR2);
ReadHumiditySensor(&hs[1]);
last_millis = millis();
}
// Read 1-Wire temperature sensors
ReadTempSensor(&ts[0], TEMP_SENSOR1);
ReadTempSensor(&ts[1], TEMP_SENSOR2);
ReadTempSensor(&ts[2], TEMP_SENSOR3);
ReadTempSensor(&ts[3], TEMP_SENSOR4);
if (SerialCmdNoError(ONEWIRE_TO_I2C_ROM1)) {
if (init_oled[0]) {
if (SerialCmdNoError(INIT_OLED_SSD1306_32)) {
init_oled[0] = false;
ts[0].update = true;
}
}
if (!init_oled[0] && ts[0].update) {
SerialPrintDecimal("st10;sc;sf1;sa2;sd63,8,"", C2F(ts[0].temp), ts[0].error);
if (!ts[0].error) SerialPrintUnits();
SerialDrawBorder(32);
SerialCmdDone(";sd");
ts[0].update = false;
}
}
else init_oled[0] = true;
if (SerialCmdNoError(ONEWIRE_TO_I2C_ROM2)) {
if (init_oled[1]) {
if (SerialCmdNoError(INIT_OLED_SSD1306_64)) {
init_oled[1] = false;
ts[1].update = true;
}
}
if (!init_oled[1] && ts[1].update) {
SerialPrintDecimal("st10;sc;sf2;sa2;sd63,19,"", C2F(ts[1].temp), ts[1].error);
if (!ts[1].error) SerialPrintUnits();
SerialDrawBorder(64);
SerialCmdDone(";sd");
ts[1].update = false;
}
}
else init_oled[1] = true;
if (SerialCmdNoError(ONEWIRE_TO_I2C_ROM3)) {
if (init_oled[2]) {
if (SerialCmdNoError(INIT_OLED_SSD1106)) {
init_oled[2] = false;
ts[2].update = true;
}
}
if (!init_oled[2] && ts[2].update) {
SerialPrintDecimal("st13;sc;sf2;sa2;sd63,19,"", C2F(ts[2].temp), ts[2].error);
if (!ts[2].error) SerialPrintUnits();
SerialDrawBorder(64);
SerialCmdDone(";sd");
ts[2].update = false;
}
}
else init_oled[2] = true;
if (SerialCmdNoError(ONEWIRE_TO_I2C_ROM4)) {
if (init_oled[3]) {
if (SerialCmdNoError(INIT_OLED_SSD1106)) {
init_oled[3] = false;
ts[3].update = true;
}
}
if (!init_oled[3] && (ts[3].update || hs[0].update)) {
SerialPrintDecimal("st13;sc;sf1;sa1;sd60,12,"", C2F(hs[0].temp), hs[0].error);
SerialPrintUnits();
SerialPrintDecimal(";sd60,32,"", hs[0].humidity, hs[0].error);
Serial.print(","%"");
SerialPrintDecimal(";sd121,12,"", C2F(ts[3].temp), ts[3].error);
SerialPrintUnits();
SerialDrawBorder(64);
SerialCmdDone(";sd");
ts[3].update = false;
hs[0].update = false;
}
}
else init_oled[3] = true;
if (SerialCmdNoError(ONEWIRE_TO_I2C_ROM5)) {
if (init_oled[4]) {
if (SerialCmdNoError(INIT_OLED_SSD1309)) {
init_oled[4] = false;
hs[1].update = true;
}
}
if (!init_oled[4] && hs[1].update) {
SerialPrintDecimal("st10;sc;sf1;sa2;sd63,12,"", C2F(hs[1].temp), hs[1].error);
SerialPrintUnits();
SerialPrintDecimal(";sd63,32,"", hs[1].humidity, hs[1].error);
Serial.print(","%"");
SerialDrawBorder(64);
SerialCmdDone(";sd");
hs[1].update = false;
}
}
else init_oled[4] = true;
#ifdef SERIAL_DEBUG
#endif
}
else {
digitalWrite(led, HIGH); // blink Arduino led for IO Expander failure
delay(500);
digitalWrite(led, LOW);
delay(500);
for (i = 0; i < OLED_SCREENS; i++) init_oled[i] = true;
}
wdt_reset();
}
SSD1309 128x64 OLED 2.42"。
較大的 2.42" OLED 的文檔不好,所以我添加了一些關于如何正確使用1-Wire? 到 I2C適配器的附加信息。
顯示器默認為 SPI,因此您要做的第一件事就是將其轉換為 I2C。這意味著您需要取出烙鐵并移除并添加一些 SMD 0603 電阻器。
- 取下 R4 并將其放在 R3 上。
- 在 R5 和 R7 處添加 0 歐姆電阻。
- 將跳線添加到 CS-DS。這將有效地為 0x3C 的 I2C 地址選擇提供 GND DC。如果您想使用 0x3D 的備用 I2C 地址,請移除跳線并將 DC 連接到 VCC (3V3)。
- 將一根電線從 RES 引腳連接到1-Wire? 到 I2C適配器上 PL1 (D2) 的未跳線引腳。這將用作 GPIO 線,以在 OLED 顯示器上電后發送所需的復位脈沖。
此顯示控制器需要在 VCC 穩定后發送 RES 引腳上的復位脈沖。根據SSD1309 顯示控制器,您必須將 RES LOW 設置為至少 3us,然后再設置為 HIGH。在面板鎖定的情況下訪問此顯示器上的重置線也很有用,您可以在其中重置和重新初始化它,而無需關閉整個系統的電源。
要使用 IO 擴展器發送復位脈沖,請在所選引腳上使用 gpio 命令并指定持續時間。這里我們使用引腳 [1] 上的 [g]pio 命令作為 [0] 的 [o] 輸出或 [ 10]毫秒。持續時間之后,該引腳將保持高電平。
>g1o0,10
ok
>
較大的 2.42 OLED 顯示器使用一個簡單的內部開關電容電荷泵,可將輸入的 3V3 轉換為 OLED 的 15V 高電壓驅動。顯示器平均從 3.3V 電源汲取約 50mA 電流,但所需的浪涌電流,特別是在較長的電纜長度上,需要在輸入 3V3 的 VCC 和 GND 之間添加一個額外的 470uF 電解電容器。確保將負極連接到 GND!如果您使用的是插頭連接器,只需將電容器插入引腳即可。
對于較小的 SSD1106 1.3",它還使用內部電荷泵將輸入的 3V3 轉換為 7V 以驅動 OLED,因此對于更長的電纜長度,您還需要在輸入的 3V3 處添加一個額外的 100uF 電解電容器。該演示使用分路器作為 1-Wire? 短截線,將1-Wire? 到 I2C適配器連接到 OLED 顯示器和 I2C Si7021 傳感器。
分路器用作 D1 和 D2 上的兩個 1-Wire? 分接器,R1 和 R2 為 100Ω
為了將盡可能多的 1-Wire? 傳感器連接到一根導線上,OLED 屏幕和傳感器作為短截線連接到 1-Wire? 總線,但在分支點存在阻抗不匹配。來自短截線末端的反射返回到主干線,僅延遲信號通過短截線長度所需的時間。這些反射可能會導致網絡上的其他從站出現問題。與短截線串聯的電阻器將降低失配的嚴重程度和反射能量的幅度。該電阻器減輕了主干上的短截線產生的反射的不利影響
1-Wire協議
為了有效地運行 OLED 顯示器,IO 擴展器支持在 100 英尺以上高達 75.47kHz 的主動驅動 1-Wire? Overdrive 速度!如果您需要走幾百英尺,那么您仍然可以退回到較慢的標準速度 15.38kHz。像 DS18B20 這樣的原生溫度傳感器不支持 Overdrive 速度,因此您可以混合具有不同速度的設備,IO 擴展器將自動改變速度以匹配同一 1-Wire 總線上的設備。Overdrive 速度低于連接到 OLED 屏幕的 I2C 總線上的 400kHz,但對于在傳感器位置報告傳感器狀態來說已經足夠快了。
為了使用 Overdrive 速度,您必須在盡可能靠近 CPU IO 引腳的地方使用 2.2k 的強上拉電阻。在這個演示中,我們使用了帶有 2.2k 上拉電阻的引腳 4,但對于引腳 2,我們需要添加一個。最簡單的方法是在 IO 擴展器 PCB 底部端口的 RJ11 插頭上的引腳之間焊接一個 2.2k 0603 電阻。
IO 擴展器支持三種不同的命令來控制 1-Wire? 設備。
o - [o] 線直接控制。
i - 1-Wire? [i]2c 控制。
t - 1-Wire? [t] 溫度傳感器。
在引腳 [4] 上的 [o]newire 總線上,[f]找到所有 ROM。
>o4f
28ffe835c3160376
28ffea20c316034c
28ff19f4c2160300
28fffd34c3160357
197a28030000002e
19ad200300000051
19ed200300000024
198f1103000000c0
>
[i] 2c 引腳 [4] 上的設備,[f] 查找所有 ROM。
>i4f
197a28030000002e
19ad200300000051
19ed200300000024
198f1103000000c0
>
[t] 引腳 [4] 上的溫度設備,[f] 找到所有 ROM。
>t4f
28ffe835c3160376
28ffea20c316034c
28ff19f4c2160300
28fffd34c3160357
>
那么使用IO Expander到底有多難呢?以身作則,自行判斷。
[t] 引腳 [4] 上的溫度傳感器 [s] 選擇 ROM [76]。執行 [t] 溫度轉換 [t],最后執行 [t] 溫度 [r] 讀取。
>t4s76;tt;tr
28ffe835c3160376
ok
17.9375
>
就這么容易!
可熱插拔!
IO 擴展器的獨特功能之一是它旨在支持熱插拔設備。這意味著,如果您的傳感器或 OLED 顯示屏出現故障,您無需關閉系統即可更換它。當它仍然通電時,移除 RJ11 插頭并重新連接新的傳感器或 OLED 屏幕。此外,為了實現這一點,您必須確保您的代碼已被編寫為檢測和重新初始化。一些傳感器沒有必要的保護,所以這樣做需要您自擔風險。任何 1-Wire 連接都應該沒問題,因為IO 擴展器上的 1-Wire 驅動程序是專門為支持這一獨特功能而編寫的。因此,立即獲取您的 IO 擴展器并構建您的系統!
- 使用MSP430 MCU簡化溫度、濕度和光學I2C傳感器
- TMP100-EP帶I2C接口的數字溫度傳感器數據表
- XV4001BC車載用SPI/I2C輸出接口的數字輸出
- 帶LCD 1602 I2C顯示的溫濕度傳感器
- APM32F103XE_I2C_加入六軸傳感器后,I2C通訊EEPROM會掛
- 帶補償的I2C超聲波傳感器
- 硬件I2C與模擬I2C
- 傳感器i2c與arduino連接_Nodemcu I2C接口連接Arduino
- 基于距離傳感器的I2C通信(二)
- 使用單片機實現I2C接口溫度傳感器DS1621應用測試的C語言實例 10次下載
- ADT7420:±0.25°C精度、16位數字I2C溫度傳感器
- STM32單片機實現的TMP102溫度傳感器I2C讀取的程序合集免費下載 140次下載
- 使用MPU6050傳感器讀取I2C總線數據的程序免費下載 15次下載
- STM32硬件i2c,CubeMX,Hal庫 66次下載
- I2C Guid I2C指南
- I2C通信協議及其工作原理 4481次閱讀
- Hi3861硬件i2c驅動oled 1106次閱讀
- Linux I2C驅動入門知識科普 1516次閱讀
- 長距離SPI/I2C通信解決方案 5269次閱讀
- 如何操作I2C去顯示oled屏幕 5368次閱讀
- 什么是I2C通信協議? 7572次閱讀
- i2c總線用來做什么_i2c總線數據傳輸過程 7086次閱讀
- dfrobotSHT20 I2C防水型溫濕傳感器簡介 2920次閱讀
- I2C總線的工作原理以及優缺點解析 1.4w次閱讀
- 基于MCS-51單片機I2C總線接口電路的設計 3245次閱讀
- I2C總線的工作原理解析 6415次閱讀
- I2C總線的特點與構成詳解 1w次閱讀
- 基于使用STM8單片機I2C方式實現讀寫操作 1.1w次閱讀
- 詳細講解RT-Thread I2C設備驅動框架及相關函數 2w次閱讀
- 基于I2C接口與上級無線傳感器網絡通信的環境監測系統 3240次閱讀
下載排行
本周
- 1山景DSP芯片AP8248A2數據手冊
- 1.06 MB | 532次下載 | 免費
- 2RK3399完整板原理圖(支持平板,盒子VR)
- 3.28 MB | 339次下載 | 免費
- 3TC358743XBG評估板參考手冊
- 1.36 MB | 330次下載 | 免費
- 4DFM軟件使用教程
- 0.84 MB | 295次下載 | 免費
- 5元宇宙深度解析—未來的未來-風口還是泡沫
- 6.40 MB | 227次下載 | 免費
- 6迪文DGUS開發指南
- 31.67 MB | 194次下載 | 免費
- 7元宇宙底層硬件系列報告
- 13.42 MB | 182次下載 | 免費
- 8FP5207XR-G1中文應用手冊
- 1.09 MB | 178次下載 | 免費
本月
- 1OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費
- 2555集成電路應用800例(新編版)
- 0.00 MB | 33566次下載 | 免費
- 3接口電路圖大全
- 未知 | 30323次下載 | 免費
- 4開關電源設計實例指南
- 未知 | 21549次下載 | 免費
- 5電氣工程師手冊免費下載(新編第二版pdf電子書)
- 0.00 MB | 15349次下載 | 免費
- 6數字電路基礎pdf(下載)
- 未知 | 13750次下載 | 免費
- 7電子制作實例集錦 下載
- 未知 | 8113次下載 | 免費
- 8《LED驅動電路設計》 溫德爾著
- 0.00 MB | 6656次下載 | 免費
總榜
- 1matlab軟件下載入口
- 未知 | 935054次下載 | 免費
- 2protel99se軟件下載(可英文版轉中文版)
- 78.1 MB | 537798次下載 | 免費
- 3MATLAB 7.1 下載 (含軟件介紹)
- 未知 | 420027次下載 | 免費
- 4OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費
- 5Altium DXP2002下載入口
- 未知 | 233046次下載 | 免費
- 6電路仿真軟件multisim 10.0免費下載
- 340992 | 191187次下載 | 免費
- 7十天學會AVR單片機與C語言視頻教程 下載
- 158M | 183279次下載 | 免費
- 8proe5.0野火版下載(中文版免費下載)
- 未知 | 138040次下載 | 免費
評論
查看更多