user29594: I am using an ATTiny85 for the first time and at compile I receive the following errors
Arduino: 1.6.11 (Windows 10), Board: "Digispark (Default - 16.5mhz)"

C:\Users\Steve\AppData\Local\Temp\build129e80c0e73568918bca55047472d138.tmp/Smoke_Auto-ATtiny.ino.ino.elf section `.text' will not fit in region `text'

c:/program files (x86)/arduino/hardware/tools/avr/bin/../lib/gcc/avr/4.9.2/../../../../avr/bin/ld.exe: region `text' overflowed by 562 bytes

collect2.exe: error: ld returned 1 exit status

exit status 1
Error compiling for board Digispark (Default - 16.5mhz).

The chip is 
Atmel 1344
Tiny85
20SF

I think what is happening is that my code is too big for the board.  Am I right?
Assuming so, ignoring any obvious programming errors (I can't debug for this board until I can upload :P ) how can I squeeze code like this onto an ATTiny?  I am not looking for someone to rewrite it for me, I am more interested in learning where there is any obvious bloat - I suspect the IR library (IRremote Version 2.0.1 June, 2015 by Ken Shirriff : 11Kb)
FWIW this is a project to convert a manually operated smoke machine into an automatic one and be able to manipulate the smoke time and delay via a remote. It works on a Mega, proof of concept complete, I want to shrink the board to fit into the mouse-sized controller if that is possible.
#include <IRremote.h>

long smokeTimeInit = 5000;  // initial smoke time
long smokeWaitInit = 60000;  // initial interval between smoke

long smokeIncrement = 1000; // timer increment value
long delayIncrement = 5000; // timer increment value

unsigned long previousMillis = 0; // this is our stored time
unsigned long currentMillis;  //where we keep count of time

const int smokeOnPin = 2;  // output to relay
int smokeStopped = false; // flag to stop smoke
const int LED = 0;
const long RECV_PIN = 1;  // input from IR receiver

IRrecv irrecv(RECV_PIN); 

decode_results results;

long  smokeTime = smokeTimeInit;
long  smokeWait = smokeWaitInit;  

void setup() {
  pinMode(smokeOnPin, OUTPUT);
  pinMode(LED, OUTPUT); 

  irrecv.enableIRIn(); // Start the receiver 

  digitalWrite(smokeOnPin, LOW);  // start with the smoke on
  digitalWrite(LED, HIGH);

}

void loop() {
  if (irrecv.decode(&results)) {

    switch(results.value){
      case 284157975 :
      //more smoke time
        smokeTime = smokeTime + smokeIncrement;
        smokeStopped = false; // smoke on

      break;
      case 284104935 :
      //less smoke time
        if(smokeTime > smokeIncrement){ // don't let the smoke time become less than the increment value i.e. negative
          smokeTime = smokeTime - smokeIncrement;
        }
        else{
          smokeTime = 1000;
        }
        smokeStopped = false;

      break;    
      case 284125335 :
      //reduce interval
        if(smokeWait > delayIncrement){ 
          smokeWait = smokeWait - delayIncrement;
        }
        else{
          smokeWait = 1000;
        }
        smokeStopped = false;  // smoke on

      break; 
      case 284141655 :
      // increase interval
        smokeWait = smokeWait + delayIncrement;
        smokeStopped = false;  // smoke on

      break;
      case 284140125 :
      // reset to initial time values
        smokeTime = smokeTimeInit;
        smokeWait = smokeWaitInit;
        smokeStopped = false;  // smoke on

      break;
      case 284148285 :
      // reset but with shorter smoke time
        smokeTime = 1000;
        smokeWait = 60000;
        smokeStopped = false;  // smoke on

      break;
      case 284123805 :
      // reset with short smoke and shorter interval
        smokeTime = 2000;
        smokeWait = 30000;
        smokeStopped = false;  // smoke on

      break;      
      case 284131965 :
      // stop
        smokeStopped = true;
      break;

    }

    irrecv.resume();
  }
currentMillis = millis();  

if(smokeStopped){  // don't even do this if smoke stopped
    if (currentMillis - previousMillis >= smokeTime && digitalRead(smokeOnPin)==0) {
      digitalWrite(smokeOnPin, HIGH); // turn the smoke on
      digitalWrite(LED, LOW);
      previousMillis = currentMillis;
    }
    else if (currentMillis - previousMillis >= smokeWait && digitalRead(smokeOnPin)==1 ) {
      digitalWrite(smokeOnPin, LOW); // turn the smoke off
      digitalWrite(LED, HIGH);
      previousMillis = currentMillis;
    }  
}

}


user7859: The avr-nm tool is great for figuring out what is using up all your memory. 
You need to get to a command-line in the temporary directory where your program is compiled. You can find this directory by looking at the scrolling bottom window when you compile your program.
You run the tool like this...

C:\Users\passp\AppData\Local\Temp\arduino_build_965235>"C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\avr-nm" -S --size-sort blink.ino.elf

...where in my case...
C:\Users\passp\AppData\Local\Temp\arduino_build_965235 is  the temporary directory that the Arduino was using
C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\ and the directory where the Arduino toolchain was installed 
blink.ino.elf is the output generated from compiling my blink.ino sketch. 
The -S parameter tells the tool to output the sizes of the symbols listed. By looking at these sizes, we can figure out what is using up all the memory and where to focus our reduction efforts.
The --size-sort shorts the symbols in size order so we can easily see which are the biggest.   
The output of the tool on my program looks like...

0080010b 00000001 b click
0080008e 00000001 B datLen
00800088 00000001 b IRcount.1978
00800089 00000001 B msgNum
00800086 00000001 b prevVals.1995
0080008f 00000001 B progDir
00800087 00000001 b sendState.1979
00800109 00000001 b state
0080010a 00000001 b sync
00800092 00000001 B wake
00800066 00000002 D buttonCB
00800068 00000002 D clickCB
0080010c 00000002 B comBuf
00800115 00000002 B datBuf
0000006a 00000002 T emptyCB
00800075 00000002 D holdoff
0080008c 00000002 B ledMode
00800062 00000002 D longButtonCB
0080006f 00000002 d longPressTime
00800090 00000002 b longPressTimer
00000068 00000002 T loop
0080006a 00000002 D mode
00000d00 00000002 T setPort
00800064 00000002 D timerCB
0080008a 00000002 B timerCBcount
00800060 00000002 D timerCBtime
0080007d 00000003 D black
0080007a 00000003 D dark
0080006c 00000003 D outColor
00800077 00000003 D wakeColor
00000da6 00000004 T __mulsidi3
00800093 00000004 b powerDownTimer
00800131 00000004 B prevTimer
00800097 00000004 B sleepTimer
0080009b 00000004 b startTime
00800071 00000004 D timeout
00800105 00000004 b timer
00000a7a 00000006 T disAD
00800080 00000006 b pulseCount.1996
0080009f 00000006 b timeBuf
0080010e 00000007 B blinking
00800117 00000007 B pulsing
00000a80 00000008 T enAD
000000d4 0000000c T setColorRGB
00000a88 0000000e T initTimer
0000005a 0000000e T setup
00000044 00000010 T __do_clear_bss
0080011e 00000013 B fading
0000002e 00000016 T __do_copy_data
00000d66 00000018 T __udivmodqi4
00000a5c 0000001e T initIO
00000ce0 00000020 t sendByte
00000d44 00000022 T __mulhi3
00000822 00000022 T __vector_3
0000006c 00000022 T getTimer
00000d7e 00000028 T __udivmodhi4
00000e18 00000036 T __epilogue_restores__
00000daa 00000036 T __umulsidi3
00000de0 00000038 T __prologue_saves__
000003e8 00000038 T updateLed
0000027c 0000003a T blink
00000d02 00000042 T sendColor
0000008e 00000046 T tileSetup
00000e4e 0000005c T __muldi3
008000a5 00000060 b times
0000035e 0000008a T pulsingUpdate
000002b6 000000a8 T blinkUpdate
00000a96 000000d4 T hsv2rgb
00000b6a 00000176 T main
000000e0 0000019c T fadeUpdate
00000844 00000218 T __vector_2
00000420 00000402 T __vector_9

The second column is the amount of space used by the symbol. 
So just looking at the bottom of our list, we can see that much of the space is being used by the functions main, fadeUpdate, __vector_2 , and __vector_9.
main and fadeUpdate are obvious, but the __vector_x functions are actualy interrupt service routines. The actual mapping of numbers to interrupt sources can be different for different chips, so probably the easiest way to figure out what a given vector is would be to comment out the ISR in your code and then do the above process and see which vector evaporates in size. 
You will have to look at each function carefully and individually to see how to possible reduce its size, but at least with this procedure  you know where too look!

29594: <p>I am using an ATTiny85 for the first time and at compile I receive the following errors</p>

<pre><code>Arduino: 1.6.11 (Windows 10), Board: "Digispark (Default - 16.5mhz)"

C:\Users\Steve\AppData\Local\Temp\build129e80c0e73568918bca55047472d138.tmp/Smoke_Auto-ATtiny.ino.ino.elf section `.text' will not fit in region `text'

c:/program files (x86)/arduino/hardware/tools/avr/bin/../lib/gcc/avr/4.9.2/../../../../avr/bin/ld.exe: region `text' overflowed by 562 bytes

collect2.exe: error: ld returned 1 exit status

exit status 1
Error compiling for board Digispark (Default - 16.5mhz).
</code></pre>

<p>The chip is </p>

<pre><code>Atmel 1344
Tiny85
20SF
</code></pre>

<p>I think what is happening is that my code is too big for the board.  Am I right?</p>

<p>Assuming so, ignoring any obvious programming errors (I can't debug for this board until I can upload :P ) how can I squeeze code like this onto an ATTiny?  I am not looking for someone to rewrite it for me, I am more interested in learning where there is any obvious bloat - I suspect the IR library (IRremote Version 2.0.1 June, 2015 by Ken Shirriff : 11Kb)</p>

<p>FWIW this is a project to convert a manually operated smoke machine into an automatic one and be able to manipulate the smoke time and delay via a remote. It works on a Mega, proof of concept complete, I want to shrink the board to fit into the mouse-sized controller if that is possible.</p>

<pre><code>#include &lt;IRremote.h&gt;

long smokeTimeInit = 5000;  // initial smoke time
long smokeWaitInit = 60000;  // initial interval between smoke

long smokeIncrement = 1000; // timer increment value
long delayIncrement = 5000; // timer increment value

unsigned long previousMillis = 0; // this is our stored time
unsigned long currentMillis;  //where we keep count of time

const int smokeOnPin = 2;  // output to relay
int smokeStopped = false; // flag to stop smoke
const int LED = 0;
const long RECV_PIN = 1;  // input from IR receiver

IRrecv irrecv(RECV_PIN); 

decode_results results;

long  smokeTime = smokeTimeInit;
long  smokeWait = smokeWaitInit;  

void setup() {
  pinMode(smokeOnPin, OUTPUT);
  pinMode(LED, OUTPUT); 

  irrecv.enableIRIn(); // Start the receiver 

  digitalWrite(smokeOnPin, LOW);  // start with the smoke on
  digitalWrite(LED, HIGH);

}

void loop() {
  if (irrecv.decode(&amp;results)) {

    switch(results.value){
      case 284157975 :
      //more smoke time
        smokeTime = smokeTime + smokeIncrement;
        smokeStopped = false; // smoke on

      break;
      case 284104935 :
      //less smoke time
        if(smokeTime &gt; smokeIncrement){ // don't let the smoke time become less than the increment value i.e. negative
          smokeTime = smokeTime - smokeIncrement;
        }
        else{
          smokeTime = 1000;
        }
        smokeStopped = false;

      break;    
      case 284125335 :
      //reduce interval
        if(smokeWait &gt; delayIncrement){ 
          smokeWait = smokeWait - delayIncrement;
        }
        else{
          smokeWait = 1000;
        }
        smokeStopped = false;  // smoke on

      break; 
      case 284141655 :
      // increase interval
        smokeWait = smokeWait + delayIncrement;
        smokeStopped = false;  // smoke on

      break;
      case 284140125 :
      // reset to initial time values
        smokeTime = smokeTimeInit;
        smokeWait = smokeWaitInit;
        smokeStopped = false;  // smoke on

      break;
      case 284148285 :
      // reset but with shorter smoke time
        smokeTime = 1000;
        smokeWait = 60000;
        smokeStopped = false;  // smoke on

      break;
      case 284123805 :
      // reset with short smoke and shorter interval
        smokeTime = 2000;
        smokeWait = 30000;
        smokeStopped = false;  // smoke on

      break;      
      case 284131965 :
      // stop
        smokeStopped = true;
      break;

    }

    irrecv.resume();
  }
currentMillis = millis();  

if(smokeStopped){  // don't even do this if smoke stopped
    if (currentMillis - previousMillis &gt;= smokeTime &amp;&amp; digitalRead(smokeOnPin)==0) {
      digitalWrite(smokeOnPin, HIGH); // turn the smoke on
      digitalWrite(LED, LOW);
      previousMillis = currentMillis;
    }
    else if (currentMillis - previousMillis &gt;= smokeWait &amp;&amp; digitalRead(smokeOnPin)==1 ) {
      digitalWrite(smokeOnPin, LOW); // turn the smoke off
      digitalWrite(LED, HIGH);
      previousMillis = currentMillis;
    }  
}

}
</code></pre>
 7859: <p>The <code>avr-nm</code> tool is great for figuring out what is using up all your memory. </p>

<p>You need to get to a command-line in the temporary directory where your program is compiled. You can find this directory by looking at the scrolling bottom window when you compile your program.</p>

<p>You run the tool like this...</p>

<p><code>
C:\Users\passp\AppData\Local\Temp\arduino_build_965235&gt;"C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\avr-nm" -S --size-sort blink.ino.elf
</code></p>

<p>...where in my case...</p>

<p><code>C:\Users\passp\AppData\Local\Temp\arduino_build_965235</code> is  the temporary directory that the Arduino was using</p>

<p><code>C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\</code> and the directory where the Arduino toolchain was installed </p>

<p><code>blink.ino.elf</code> is the output generated from compiling my <code>blink.ino</code> sketch. </p>

<p>The <code>-S</code> parameter tells the tool to output the sizes of the symbols listed. By looking at these sizes, we can figure out what is using up all the memory and where to focus our reduction efforts.</p>

<p>The <code>--size-sort</code> shorts the symbols in size order so we can easily see which are the biggest.   </p>

<p>The output of the tool on my program looks like...</p>

<p><code>
0080010b 00000001 b click
0080008e 00000001 B datLen
00800088 00000001 b IRcount.1978
00800089 00000001 B msgNum
00800086 00000001 b prevVals.1995
0080008f 00000001 B progDir
00800087 00000001 b sendState.1979
00800109 00000001 b state
0080010a 00000001 b sync
00800092 00000001 B wake
00800066 00000002 D buttonCB
00800068 00000002 D clickCB
0080010c 00000002 B comBuf
00800115 00000002 B datBuf
0000006a 00000002 T emptyCB
00800075 00000002 D holdoff
0080008c 00000002 B ledMode
00800062 00000002 D longButtonCB
0080006f 00000002 d longPressTime
00800090 00000002 b longPressTimer
00000068 00000002 T loop
0080006a 00000002 D mode
00000d00 00000002 T setPort
00800064 00000002 D timerCB
0080008a 00000002 B timerCBcount
00800060 00000002 D timerCBtime
0080007d 00000003 D black
0080007a 00000003 D dark
0080006c 00000003 D outColor
00800077 00000003 D wakeColor
00000da6 00000004 T __mulsidi3
00800093 00000004 b powerDownTimer
00800131 00000004 B prevTimer
00800097 00000004 B sleepTimer
0080009b 00000004 b startTime
00800071 00000004 D timeout
00800105 00000004 b timer
00000a7a 00000006 T disAD
00800080 00000006 b pulseCount.1996
0080009f 00000006 b timeBuf
0080010e 00000007 B blinking
00800117 00000007 B pulsing
00000a80 00000008 T enAD
000000d4 0000000c T setColorRGB
00000a88 0000000e T initTimer
0000005a 0000000e T setup
00000044 00000010 T __do_clear_bss
0080011e 00000013 B fading
0000002e 00000016 T __do_copy_data
00000d66 00000018 T __udivmodqi4
00000a5c 0000001e T initIO
00000ce0 00000020 t sendByte
00000d44 00000022 T __mulhi3
00000822 00000022 T __vector_3
0000006c 00000022 T getTimer
00000d7e 00000028 T __udivmodhi4
00000e18 00000036 T __epilogue_restores__
00000daa 00000036 T __umulsidi3
00000de0 00000038 T __prologue_saves__
000003e8 00000038 T updateLed
0000027c 0000003a T blink
00000d02 00000042 T sendColor
0000008e 00000046 T tileSetup
00000e4e 0000005c T __muldi3
008000a5 00000060 b times
0000035e 0000008a T pulsingUpdate
000002b6 000000a8 T blinkUpdate
00000a96 000000d4 T hsv2rgb
00000b6a 00000176 T main
000000e0 0000019c T fadeUpdate
00000844 00000218 T __vector_2
00000420 00000402 T __vector_9
</code>
The second column is the amount of space used by the symbol. </p>

<p>So just looking at the bottom of our list, we can see that much of the space is being used by the functions <code>main</code>, <code>fadeUpdate</code>, <code>__vector_2</code> , and <code>__vector_9</code>.</p>

<p><code>main</code> and <code>fadeUpdate</code> are obvious, but the <code>__vector_x</code> functions are actualy interrupt service routines. The actual mapping of numbers to interrupt sources can be different for different chips, so probably the easiest way to figure out what a given vector is would be to comment out the ISR in your code and then do the above process and see which vector evaporates in size. </p>

<p>You will have to look at each function carefully and individually to see how to possible reduce its size, but at least with this procedure  you know where too look!</p>
