Problem with attiny13 programming extreme space constraint?

Hello,

I'm having seriuos problems with programming the attiny13 with this arduino core:

and trying to compile this code is says I'm exeeding over 150% of the space.

#define IR_PIN 2
#define OUT_INDICATOR_PIN 3


int Frequancy = 0;//, LDFrecuancy; 


void setup() {

  pinMode(IR_PIN, INPUT);
  pinMode(OUT_INDICATOR_PIN, OUTPUT);

  //Serial.begin(115200);
}

void loop() {

  //static float Duration = pulseIn(IR_PIN, HIGH);
  static float Duration = 0, LDDuration;
  static bool PinState, LPinState;

  PinState = digitalRead(IR_PIN);
  static long Timer = millis();
  
  if(PinState != LPinState){
    delayMicroseconds(2);
    
    if (PinState){

      Duration = millis() - Timer;
      Timer = millis();
      Frequancy =  1/(Duration / 1000);
      
    }
  }
  
  if(Duration != LDDuration){
    
    //Serial.print("Dur:");
    //Serial.print(Duration);

    //Serial.print(", F:");
    //Serial.println(Frequancy);

    if(Frequancy > 95 && Frequancy < 105){

  
    //Serial.println("Probably an LTi 20-20");
    
      digitalWrite(OUT_INDICATOR_PIN, HIGH);
      delay(20);
      digitalWrite(OUT_INDICATOR_PIN, LOW);
      
    
    }
    
    else if(Frequancy > 120 && Frequancy < 130){
      
      
      digitalWrite(OUT_INDICATOR_PIN, HIGH);
      delay(20);
      digitalWrite(OUT_INDICATOR_PIN, LOW);
      
      //Serial.println("Probably an LTi 100LR");
      
    }

    LDDuration = Duration;

  }

  
}

Any solution?

MikeLemon:
Any solution?

Yes. Don't use floating point: work with durations instead of frequencies.

(deleted)

  static long Timer = millis();

Wrong datatype.

millis always returns zero at that point. That's a bit of wasted Flash.

I believe the delays (20 ms) are large enough that Frequency can be pushed from the higher range to the lower range.

How critical is the fractional portion of the frequency? If you follow Coding Badly, change the floats to uint32_t, do direct port read/write (get rid of the digitalRead/Write) and a couple of other small changes...

Sketch uses 472 bytes (46%) of program storage space. Maximum is 1024 bytes.
Global variables use 18 bytes (28%) of dynamic memory, leaving 46 bytes for local variables. Maximum is 64 bytes.

  static float Duration = 0;

Wrong datatype.

static is the wrong storage.

Initialization is pointless.

Just did a few more tweaks...

Sketch uses 290 bytes (28%) of program storage space. Maximum is 1024 bytes.
Global variables use 6 bytes (9%) of dynamic memory, leaving 58 bytes for local variables. Maximum is 64 bytes.

You realize that 1 / ( Duration / 1000 ) is the same as 1000/Duration and then if you are going to test for (1000/Duration) being between 95 and 105 it's just as easy to test for values of Duration between 9 and 10. If you need more resolution, use micros().

spycatcher2k:

digitalWrite(OUT_INDICATOR_PIN, HIGH);

You could use direct port access to replace this type of command - will save a lot of space!

Do you have an example for that?

DKWatson:
...it's just as easy to test for values of Duration between 9 and 10. If you need more resolution, use micros().

Excellent observation.

@MikeLemon...

The granularity of millis is too course. You need to use micros.

Bear in mind that with the t13 neither millis nor micros may be accurate.

What do you mean by may not be accurate?

Also how come 2 floating points variable eat 600bytes of SRAM?!?

How is it wrong? what do mean? I want only the main function to access it and what's wrong with me declaring it static to make the program alittle more efficient?

MikeLemon:
What do you mean by may not be accurate?

The base clock for a t13 is 9.6 MHz. There is no way to configure an AVR timer to divide that down to a 1 millisecond nor a 1 microsecond clock.

I'll use microseconds for the example. To get microseconds from a 9.6 MHz clock you would have to divide by 9.6. There is no way to perform a fractional (the "0.6" part) division with an AVR timer. You could divide by 9. You could divide by 10. But you cannot divide by exactly 9.6.

One strategy is to tune the processor (using OSCCAL) to run at 8 MHz.

MikeLemon:
Also how come 2 floating points variable eat 600bytes of SRAM?!?

Flash. The floating-point support, as far as I know, consumes zero SRAM.

Floating-point has to be emulated (performed entirely by lots of integer operations).

Sounds complicates,

Also why did they manufacture it to work with 9.6MHz internal oscillator if it's so problematic?

Ugh sucks... that that apply to all AVR MCUs?

MikeLemon:
How is it wrong? what do mean?

The correct datatype for values return from millis / micros is always an unsigned integer; typically unsigned long. Using any other datatype causes problems.

...what's wrong with me declaring it static to make the program alittle more efficient?

Duration is ephemeral. The value only has meaning for one pass through loop.

Making Duration static forces the value to be stored in SRAM. Something that is not just unnecessary but a waste of SRAM.

Saving Duration to SRAM requires code. If Duration is not stored to SRAM that code is eliminated.

But from what I understood that static allows you to declare a variable with an initial value in a loop still using it throughout(changing it and stuff) and won't be re declared to that initial one at next cycle.

Also Tryed some of this port manipulation this but when I try to write a binary value to it it says that:

57: error: 'B00000000' was not declared in this scope

PORTB = B00000000;

No idea why.

MikeLemon:
Sounds complicates,

At one time it was fairly easy. This should get you started...
https://www.google.com/search?q=attiny+tiny+tuner
http://ernstc.dk/arduino/tinytuner.html

Also why did they manufacture it to work with 9.6MHz internal oscillator if it's so problematic?

The frequency is only problematic for you.

I have no idea why that frequency. It could be they were targeting a specific market. It could be a side-effect of the oscillator design.

Ugh sucks... that that apply to all AVR MCUs?

Most have an 8 MHz internal oscillator that is ±10% from the factory and can be tuned to ±1%.