精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

電子發燒友App

硬聲App

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示
電子發燒友網>電子資料下載>電子資料>連接100英尺以外的OLED屏幕和I2C傳感器

連接100英尺以外的OLED屏幕和I2C傳感器

2022-11-03 | zip | 0.50 MB | 次下載 | 免費

資料介紹

描述

需要在距離您的項目太遠的傳感器位置添加 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 演示的部件

接線圖

pYYBAGNh7HCAN2tkAAOFZpehZrM013.jpg
?

俯視圖

?
?

運行此演示的 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 電阻器

pYYBAGNh7J2AMDbTAACS0fYwHaM279.jpg
?
  • 取下 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Ω

pYYBAGNh7KOAQQ55AAAi1VJV2C0528.jpg
?

為了將盡可能多的 1-Wire? 傳感器連接到一根導線上,OLED 屏幕和傳感器作為短截線連接到 1-Wire? 總線,但在分支點存在阻抗不匹配。來自短截線末端的反射返回到主干線,僅延遲信號通過短截線長度所需的時間。這些反射可能會導致網絡上的其他從站出現問題。與短截線串聯的電阻器將降低失配的嚴重程度和反射能量的幅度。該電阻器減輕了主干上的短截線產生的反射的不利影響

可靠的長線 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 電阻。

pYYBAGNh7KmAQiPsAABJhwnjt0s259.jpg
?

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 擴展器并構建您的系統!


下載該資料的人也在下載 下載該資料的人還在閱讀
更多 >

評論

查看更多

下載排行

本周

  1. 1山景DSP芯片AP8248A2數據手冊
  2. 1.06 MB  |  532次下載  |  免費
  3. 2RK3399完整板原理圖(支持平板,盒子VR)
  4. 3.28 MB  |  339次下載  |  免費
  5. 3TC358743XBG評估板參考手冊
  6. 1.36 MB  |  330次下載  |  免費
  7. 4DFM軟件使用教程
  8. 0.84 MB  |  295次下載  |  免費
  9. 5元宇宙深度解析—未來的未來-風口還是泡沫
  10. 6.40 MB  |  227次下載  |  免費
  11. 6迪文DGUS開發指南
  12. 31.67 MB  |  194次下載  |  免費
  13. 7元宇宙底層硬件系列報告
  14. 13.42 MB  |  182次下載  |  免費
  15. 8FP5207XR-G1中文應用手冊
  16. 1.09 MB  |  178次下載  |  免費

本月

  1. 1OrCAD10.5下載OrCAD10.5中文版軟件
  2. 0.00 MB  |  234315次下載  |  免費
  3. 2555集成電路應用800例(新編版)
  4. 0.00 MB  |  33566次下載  |  免費
  5. 3接口電路圖大全
  6. 未知  |  30323次下載  |  免費
  7. 4開關電源設計實例指南
  8. 未知  |  21549次下載  |  免費
  9. 5電氣工程師手冊免費下載(新編第二版pdf電子書)
  10. 0.00 MB  |  15349次下載  |  免費
  11. 6數字電路基礎pdf(下載)
  12. 未知  |  13750次下載  |  免費
  13. 7電子制作實例集錦 下載
  14. 未知  |  8113次下載  |  免費
  15. 8《LED驅動電路設計》 溫德爾著
  16. 0.00 MB  |  6656次下載  |  免費

總榜

  1. 1matlab軟件下載入口
  2. 未知  |  935054次下載  |  免費
  3. 2protel99se軟件下載(可英文版轉中文版)
  4. 78.1 MB  |  537798次下載  |  免費
  5. 3MATLAB 7.1 下載 (含軟件介紹)
  6. 未知  |  420027次下載  |  免費
  7. 4OrCAD10.5下載OrCAD10.5中文版軟件
  8. 0.00 MB  |  234315次下載  |  免費
  9. 5Altium DXP2002下載入口
  10. 未知  |  233046次下載  |  免費
  11. 6電路仿真軟件multisim 10.0免費下載
  12. 340992  |  191187次下載  |  免費
  13. 7十天學會AVR單片機與C語言視頻教程 下載
  14. 158M  |  183279次下載  |  免費
  15. 8proe5.0野火版下載(中文版免費下載)
  16. 未知  |  138040次下載  |  免費