0

いくつかのコードと奇妙な異常について質問があります。このコードはDigisparkに配置されます。Digispark のコード サイズは 6,010 バイトに制限されています。ネストされたifステートメントを使用する場合、テキストは LCD 画面に出力されません (以下のリンクを参照)。各セットを個別にコメントアウトすることで、再び機能させることができます。

基本的な LCD 機能:

  1. LCDは、内部ビール温度と周囲空気温度を出力します。http://imgur.com/S0rYvaa
  2. LCD クリア
  3. LCDは目標温度とヒーター(リレー)の状態を出力http://imgur.com/OtFXG1K

変数は float 型です。

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");
}

なぜこれが起こるのかわかりません。これは、最大サイズ制限に近づきすぎているために発生していますか? このようなコードを構築することはできませんか?

4

2 に答える 2

0

ローカルでテストすることができずに、決定的な方法でこれに答えるのはかなり難しいと思います.

ただし、コードサイズが最大に近づくと壊れるというのは非常に疑わしいように思えます。一方、何らかの制限を超えた場合に「ハード」に壊れないというツールのバグを示しているようです。

コードサイズを縮小する方法に関するいくつかのヒント:

  • floatCPU がエミュレートする必要があるため、使用しないでください。温度には固定小数点形式で十分です。
  • 関数呼び出しは非常に多くのコードを生成するため、digitalWrite()およびへの関数呼び出しを除外します。lcd.print()

これらの呼び出しを因数分解する 1 つの方法は、次のようなことです。

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 とリレーを常に更新したいという事実を利用しているため、常に関数を呼び出すことができます。次に、変数を使用して目的の値を保持します。これは、割り当ては通常、関数呼び出しよりも (コード サイズの点で) 安価であるためです。

于 2013-01-28T15:06:11.210 に答える
0

328 の 2K と比較して、Attiny85 には 512 バイトの SRAM しかないため、RAM のサイズが小さいことを忘れないでください。RAMが不足している可能性があります。それがなくなると、ただそこに座っているだけだということを学びました。

FreeRAM を取得するには、このライブラリのreadmeを読むことをお勧めします。「.print」がRAMとROMの両方を消費する方法について言及しています。

今はいつも使っています

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

Serial.print("HELLO"); 

これは RAM を節約するためであり、これは lcd.print にも当てはまります。いつも置いているところ

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

コードの冒頭で、注意してください。実際のコードを実行して再帰する余地が必要であることに注意してください。

.print out を 1 つのインスタンスのみに因数分解する unwind の例では、変数を使用しています。const 文字列ではないという点で、実際には F() (古い getPSTR()) と似ています。したがって、実際にはRAMの使用量も少なくなります。

于 2013-01-28T16:02:28.650 に答える