Arduino代码异常 - LCD因多个'if'语句而失败

时间:2013-01-28 14:57:16

标签: c++ arduino

我对某些代码和奇怪的异常有疑问。此代码放在Digispark上。 Digispark的代码大小限制为6,010字节。使用嵌套的if语句时,文本不会输出到LCD屏幕(请参阅下面的链接)。通过单独评论每一组,我能够让它再次运作。

基本LCD功能:

  1. LCD输出内部啤酒温度和环境空气温度。 http://imgur.com/S0rYvaa
  2. LCD清除
  3. LCD输出目标温度和加热器(继电器)状态http://imgur.com/OtFXG1K
  4. 变量属于浮点型。

    float inside_temp;
    float outside_temp;
    float target = 74.00;
    
    //inside_temp and outside_temp are values from 2 ds18b20's
    inside_temp = 70.70;
    outside_temp = 70.81;
    

    当使用此代码时,LCD会工作,并将其注释掉。编译后的大小为5,928字节。

    if(inside_temp < target){
        //Create a limit so heater isn't crazy hot as 5 gallons takes a while to change temperature.
        // float limit = target + 1;
        // if(outside_temp > limit){
        //     digitalWrite(RELAY_PIN, LOW);
        //     lcd.print("OFF");
        // }
        // else{
        digitalWrite(RELAY_PIN, HIGH);
        lcd.print("ON");
        // }
      }
      else{
          digitalWrite(RELAY_PIN, LOW);
          lcd.print("OFF");
      }
    

    LCD也适用于此代码。编译后的大小为5,590字节。

    // if(inside_temp < target){
        //Create a limit so the heater isn't crazy hot as 5 gallons takes a while to change temperature.
        float limit = target + 1;
        if(outside_temp > limit){
            digitalWrite(RELAY_PIN, LOW);
            lcd.print("OFF");
        }
        else{
           digitalWrite(RELAY_PIN, HIGH);
           lcd.print("ON");
        }
        // }
        // else{
        //     digitalWrite(RELAY_PIN, LOW);
        //     lcd.print("OFF");
        // }
    

    取消注释时LCD不起作用。编译后的大小为5,992字节。所有这一切都是坐在那里背光,没有文字。 http://imgur.com/xPAzY0N,DdGdYoI

    if(inside_temp < target){
        //create a limit so heater isn't crazy hot as 5 gallons takes a while to change temperature.
        float limit = target + 1;
        if(outside_temp > limit){
            digitalWrite(RELAY_PIN, LOW);
            lcd.print("OFF");
        }
        else{
            digitalWrite(RELAY_PIN, HIGH);
            lcd.print("ON");
        }
    }
    else{
        digitalWrite(RELAY_PIN, LOW);
        lcd.print("OFF");
    }
    

    我不明白为什么会这样。这是否发生因为我太接近最大尺寸限制了?我可以不构造这样的代码吗?

2 个答案:

答案 0 :(得分:0)

我认为很难以一种结论性的方式回答这个问题,而无法在本地进行测试。

虽然它听起来非常可疑,但是当代码大小接近最大值时会中断。另一方面,它似乎表明工具中的一个错误,如果超出某些限制,它就不会“破坏”。

有关如何减少代码大小的一些提示:

  • 不要使用float,因为CPU必须模拟它。对于温度,定点格式应该没问题。
  • 将函数调用分解为digitalWrite()lcd.print(),因为函数调用会产生大量代码。

将这些调用分解出来的一种方法就是做这样的事情:

uint8_t relay_pin = LOW;
const char *lcd_text = "OFF";
if(inside_temp < target) {
    float limit = target + 1;
    if(outside_temp > limit) {
    }
    else {
      relay_pin = HIGH;
      lcd_text = "ON";
    }
}
digitalWrite(RELAY_PIN, relay_pin);
lcd.print(lcd_text);

这使用了我们想要始终更新LCD和继电器的事实,因此我们总是可以调用这些功能。然后我们使用变量来保存所需的值,因为赋值通常比函数调用更便宜(就代码大小而言)。

答案 1 :(得分:0)

不要忘记小尺寸的RAM,因为与328的2K相比,Attiny85只有512字节的SRAM。你可能只是用完了RAM。我了解到,当它耗尽时,它只是坐在那里。

我建议从这个库中读取readme来获取FreeRAM。它提到了“.print”如何消耗RAM和ROM。

我现在总是使用

Serial.print(F("HELLO")); 

Serial.print("HELLO"); 

因为它节省了RAM,对于lcd.print来说应该是这样。我一直在哪里

Serial.println(freeMemory(), DEC);  // print how much RAM is available.

在代码的开头,并注意。注意到需要有空间来运行实际代码并进入它。

展开将.print分解为仅一个实例的示例,是使用变量。实际上与F()(旧的getPSTR())类似,因为它不再是一个const字符串。所以它实际上也使用较少的RAM。