前言 需求 一个小键盘,有四个按键,想要在每一个键帽上安装一个0.49寸的oled灯。主控使用esp32,如果直接使用软件iic,那么需要4个通道也就是8个引脚来控制。由于还有许多其他功能,导致io不足以如此挥霍。
解决方法 屏幕全部使用同一个iic通道。SCL时钟线接在一起,SDA数据线由主设备出发分别经过一个二极管连接到每个从设备。然后从设备的SDA经过一个pnp三极管连接到一个单片机io引脚。如果希望不修改这个屏幕的数据,就把这个从设备的引脚拉高,无法再接收数据,就可以实现单独控制。
实验 上电后两个屏幕都会在c和v之间循环切换,如果串口输入0,一个屏幕就会暂停,另一个屏幕正常闪烁,串口输入1恢复正常
顺便实测当字号使用24时候刷新时间是2500us左右,字号16的刷新时间大概是1600us,这个速度已经可以和foc的循环放在一个函数里了笑死(foc控制循环建议速度1kHz)
电路连接
控制程序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 #include <Wire.h> #include "SSD1306.h" SSD1306 display(0x3c, 22, 23); String comStr = ""; long comInt=1; void setup(){ pinMode(21, OUTPUT); digitalWrite(21, HIGH); Serial.begin(115200); display.init(); display.setFont(ArialMT_Plain_16); display.drawString(32, 0, "ctrl+v"); display.display(); while(Serial.read()>=0){} } void loop(){ unsigned int time; time = micros(); display.clear(); display.drawString(32, 0, "ctrl+c"); display.display(); Serial.println(micros()-time); display.clear(); display.drawString(32, 0, "ctrl+v"); display.display(); if (Serial.available() > 0){ comStr = Serial.readString(); comInt = comStr.toInt(); if (comInt==0){digitalWrite(21, LOW);} if (comInt==1){digitalWrite(21, HIGH);} } }