我已将使用I2C的1.3英寸OLED显示器连接到Arduino Uno,并使用上拉电阻器将两个按钮用作在不同图像之间切换的“上一个”和“下一个”箭头。我使用u8g2库与之通信并在屏幕上绘制内容:
#include <U8g2lib.h>
#include <Wire.h>
#define MAX_STATES 9
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
const char COPYRIGHT_SYMBOL[] = {0xa9, '\0'};
void u8g2_prepare() {
u8g2.setFont(u8g2_font_6x10_tf);
u8g2.setFontRefHeightExtendedText();
u8g2.setDrawColor(1);
u8g2.setFontPosTop();
u8g2.setFontDirection(0);
}
void u8g2_box_frame() {
u8g2.drawStr(0, 0, "drawBox");
u8g2.drawBox(5, 10, 20, 10);
u8g2.drawStr(60, 0, "drawFrame");
u8g2.drawFrame(65, 10, 20, 10);
}
void u8g2_r_frame_box() {
u8g2.drawStr(0, 0, "drawRFrame");
u8g2.drawRFrame(5, 10, 40, 15, 3);
u8g2.drawStr(70, 0, "drawRBox");
u8g2.drawRBox(70, 10, 25, 15, 3);
}
void u8g2_disc_circle() {
u8g2.drawStr(0, 0, "drawDisc");
u8g2.drawDisc(10, 18, 9);
u8g2.drawStr(60, 0, "drawCircle");
u8g2.drawCircle(70, 18, 9);
}
void u8g2_string_orientation() {
u8g2.setFontDirection(0);
u8g2.drawStr(5, 15, "0");
u8g2.setFontDirection(3);
u8g2.drawStr(40, 25, "90");
u8g2.setFontDirection(2);
u8g2.drawStr(75, 15, "180");
u8g2.setFontDirection(1);
u8g2.drawStr(100, 10, "270");
}
void u8g2_line() {
u8g2.drawStr(0, 0, "drawLine");
u8g2.drawLine(7, 20, 77, 32);
}
void u8g2_triangle() {
u8g2.drawStr(0, 0, "drawTriangle");
u8g2.drawTriangle(14, 20, 45, 30, 10, 32);
}
void u8g2_unicode() {
u8g2.drawStr(0, 0, "Unicode");
u8g2.setFont(u8g2_font_unifont_t_symbols);
u8g2.setFontPosTop();
u8g2.setFontDirection(0);
u8g2.drawUTF8(10, 20, "☀");
u8g2.drawUTF8(30, 20, "☁");
u8g2.drawUTF8(50, 20, "☂");
u8g2.drawUTF8(70, 20, "☔");
u8g2.drawUTF8(95, 20, COPYRIGHT_SYMBOL); //COPYRIGHT SIMBOL
u8g2.drawUTF8(115, 15, "\xb0"); // DEGREE SYMBOL
}
#define image_width 128
#define image_height 21
static const unsigned char image_bits[] U8X8_PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x1f, 0x00, 0x00,
0xfc, 0x1f, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xfe, 0x1f, 0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x00, 0x00, 0x0c, 0x60, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x18, 0x00, 0x00,
0x0c, 0xc0, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x18, 0x00, 0x00, 0x0c, 0xc0, 0xf0, 0x1f, 0x06, 0x63, 0x80, 0xf1,
0x1f, 0xfc, 0x33, 0xc0, 0x03, 0x18, 0x00, 0x00, 0x0c, 0xc0, 0xf8, 0x3f,
0x06, 0x63, 0xc0, 0xf9, 0x3f, 0xfe, 0x33, 0xc0, 0x03, 0x18, 0x00, 0x00,
0x0c, 0xc0, 0x18, 0x30, 0x06, 0x63, 0xc0, 0x18, 0x30, 0x06, 0x30, 0xc0,
0xff, 0xff, 0xdf, 0xff, 0x0c, 0xc0, 0x18, 0x30, 0x06, 0x63, 0xe0, 0x18,
0x30, 0x06, 0x30, 0xc0, 0xff, 0xff, 0xdf, 0xff, 0x0c, 0xc0, 0x98, 0x3f,
0x06, 0x63, 0x60, 0x98, 0x3f, 0x06, 0x30, 0xc0, 0x03, 0x18, 0x0c, 0x00,
0x0c, 0xc0, 0x98, 0x1f, 0x06, 0x63, 0x70, 0x98, 0x1f, 0x06, 0x30, 0xc0,
0x03, 0x18, 0x06, 0x00, 0x0c, 0xc0, 0x18, 0x00, 0x06, 0x63, 0x38, 0x18,
0x00, 0x06, 0x30, 0xc0, 0x03, 0x18, 0x03, 0x00, 0x0c, 0xe0, 0x18, 0x00,
0x06, 0x63, 0x1c, 0x18, 0x00, 0x06, 0x30, 0xc0, 0x00, 0x80, 0x01, 0x00,
0xfc, 0x7f, 0xf8, 0x07, 0x1e, 0xe3, 0x0f, 0xf8, 0x07, 0x06, 0xf0, 0xcf,
0x00, 0xc0, 0x00, 0x00, 0xfc, 0x3f, 0xf0, 0x07, 0x1c, 0xe3, 0x07, 0xf0,
0x07, 0x06, 0xe0, 0xcf, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x30, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xe0, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0xfc, 0x1f, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f
};
void u8g2_bitmap() {
u8g2.drawXBMP(0, 5, image_width, image_height, image_bits);
}
void setup(void) {
pinMode(8, INPUT_PULLUP);
pinMode(7, INPUT_PULLUP);
Serial.begin(9600);
u8g2.begin();
u8g2_prepare();
}
float i = 0.0;
int state = 0;
typedef struct Button
{
char state_old;
char state_new;
bool pressed;
Button ()
{
state_old = LOW;
state_new = LOW;
pressed = false;
}
} Button;
Button prevButton;
Button nextButton;
void loop(void) {
prevButton.state_new = digitalRead(8);
nextButton.state_new = digitalRead(7);
if (prevButton.state_new != prevButton.state_old)
{
prevButton.pressed = prevButton.state_new == LOW;
if (prevButton.pressed)
{
Serial.println("Previous");
state = ((state - 1) + MAX_STATES) % MAX_STATES;
}
}
if (nextButton.state_new != nextButton.state_old)
{
nextButton.pressed = nextButton.state_new == LOW;
if (nextButton.pressed)
{
Serial.println("Next");
state = (state + 1) % MAX_STATES;
}
}
prevButton.state_old = prevButton.state_new;
nextButton.state_old = nextButton.state_new;
switch (state)
{
case 0:
u8g2.clearBuffer();
u8g2_prepare();
u8g2_box_frame();
u8g2.sendBuffer();
break;
case 1:
u8g2.clearBuffer();
u8g2_disc_circle();
u8g2.sendBuffer();
break;
case 2:
u8g2.clearBuffer();
u8g2_r_frame_box();
u8g2.sendBuffer();
break;
case 3:
u8g2.clearBuffer();
u8g2_prepare();
u8g2_string_orientation();
u8g2.sendBuffer();
break;
case 4:
u8g2.clearBuffer();
u8g2_line();
u8g2.sendBuffer();
break;
case 5:
u8g2.clearBuffer();
u8g2_triangle();
u8g2.sendBuffer();
break;
case 6:
u8g2.clearBuffer();
u8g2_prepare();
u8g2_unicode();
u8g2.sendBuffer();
break;
case 7:
u8g2.clearBuffer();
u8g2_bitmap();
u8g2.sendBuffer();
break;
case 8:
u8g2.clearBuffer();
u8g2.setCursor(0, 0);
u8g2.print(i);
i = i + 1.5;
u8g2.sendBuffer();
break;
}
Serial.print("Current state:");
Serial.println(state);
delay(100);
}
[这个问题(至少我认为)不是来自图书馆本身。如您所见,我创建了一个非常简单的状态序列,可以在使用按钮之间进行切换。前一个按钮递减,而下一个按钮递减状态。当然,因为我希望具有环绕行为(在最后一个状态之后再进入一个状态会将状态更改为最低状态,反之亦然),所以我使用模数。
它在某种程度上有效。当我到达状态0(最低状态)并按下上一个按钮时,我希望“当前状态:8”显示在串行监视器中,并且相应的图像数据将加载到OLED的缓冲区中。相反,我得到以下行为:
我在串行监视器中得到输出:
Pre?
OLED不会将其缓冲区更改为最后一个状态
[停止工作,我的意思是我既不能使用按钮也不可以增加或减少状态,并且连续输出“当前状态:...”不会被打印。我实际上只是检查过,并且增量也会发生相同的问题。
我已经使用了很多次模,所以对于为什么会发生这种情况我感到非常困惑。我可以理解得到(由于某种原因)不正确的状态,但是整个事情都会冻结...
刷新微控制器时我注意到的一件事是Arduino IDE中的警告:
Sketch使用24852字节(77%)的程序存储空间。最大为32256字节。
全局变量使用1945字节(94%)的动态内存,剩下103字节用于局部变量。最大为2048个字节。
可用的内存不足,可能会出现稳定性问题。
是否有可能发生这种情况?如果是这样,它与整数的简单递减有何关系?
我在MAX_STATES
中输入了错误的值。应该是8。