使用模数递增/递减值时程序冻结。可能的原因是内存不足?

问题描述 投票:0回答:1

我已将使用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个字节。

可用的内存不足,可能会出现稳定性问题。

是否有可能发生这种情况?如果是这样,它与整数的简单递减有何关系?

arduino arduino-uno arduino-ide
1个回答
0
投票

我在MAX_STATES中输入了错误的值。应该是8。

© www.soinside.com 2019 - 2024. All rights reserved.