How to Shrinkify this code for a 433.92 Mhz receiver

Hi guys!!
I sniffed my garage door remote with my arduino UNO( and a 433 cheap receiver) and i wired it to a relay, so it can performs a lot of actions ( lamps, garden irrigation pump, etc etc ) . All is working fine but..... i definitely don't want to use my UNO board statically to do that. So i thought about shrinking my project to a standalone atmega328....but... why using atmega328 for this really simple task?
So i decided to use Attiny85. And here comes the matter : i tried to shrink my code as far as i can ( i'm just a basic programmer) but i can't fit the 8kb size of attiny memory.
So here's my request : can someone take a look at my code and help me shrinkifying it more ? Does someone know a lighter library to do that? Is it possible to operate in the library code to get rid of unnecessary features and make a lightweight version?

Here's my code:

#include <RCSwitch.h>

RCSwitch mySwitch = RCSwitch();
boolean prev=false;
boolean act=false;

void setup() {
  Serial.begin(9600);
  mySwitch.enableReceive(0);  // Receiver on inerrupt 0 => that is pin #2
  pinMode(13,OUTPUT);
}


void loop() {
  if (mySwitch.available()) {
    
    int value = mySwitch.getReceivedValue();
    
    if (value == 0) {
      Serial.print("Unknown encoding");
    } 
    else if(value==1361) {
      !prev ? digitalWrite(13,HIGH) : digitalWrite(13,LOW);  
     act= digitalRead(13);
     act ? prev=true : prev=false;
      
    }
     
    mySwitch.resetAvailable();
  }
}

So i decided to use Attiny85

Why?

Main reasons :
1.Cheap
2.Already in my parts box
3. actual program size is about 8,600 Kb so i thought it could fit shrinking the code.
:smiley:

Buy a 328 and spend the time you save doing something pleasant - like having a beer.

...R

A quick look, does this still do what you want?

#include <RCSwitch.h>

RCSwitch mySwitch = RCSwitch();

boolean state = false;

void setup() 
{
  Serial.begin(9600);
  mySwitch.enableReceive(0);  // Receiver on inerrupt 0 => that is pin #2
  pinMode(13, OUTPUT);
  digitalWrite(13, state);
}


void loop() 
{
  if (mySwitch.available()) 
  {
    int value = mySwitch.getReceivedValue();

    if (value == 0) 
    {
      Serial.print("Unknown encoding");
    } 
    else if (value == 1361) 
    {
      state = !state;
      digitalWrite(13, state);
    }
    mySwitch.resetAvailable();
  }
}

Hello funksoulbrother,

For many of my smaller projects, I will use an ATtiny85. They work great for basic commands, but I believe you are limited in the code/libraries that they will handle. Are you sure you can use #include <RCSwitch.h> with the ATtiny85?

For my own more complex projects, requiring more memory, or more libraries than the ATTiny85 can handle, I looked at two options:

  1. Make a stand alone ATmega328. This requires the ATmega, a crystal, voltage regulator, etc. In addition, you need to spend time soldering everything together.
  2. A Pro Mini. To program the Pro Mini you need to get a FTDI TTL-232R USB connector, but in my opinion, it is absolutely worth it.

Even without taking into account your time fiddling around making the stand alone ATmega328, the Pro Mini ends up being around the same price (you can get them for $ 3-4 on ebay), is approximately the same size as a stand alone ATmega328, and is just far simpler to work with. Of course, since the Pro Mini uses a surface mounted ATmega328 (or 168, depending on the model) it gives you far more memory than the ATtiny85.

If you can use the <RCSwitch.h> library with the ATtiny85, then the ATtiny85 may be a good option. If not, I strongly suggest purchasing a Pro Mini for a few dollars and saving yourself a lot of time. Since discovering these mini boards, I have never gone back to making my own stand alone ATmega328.

Dustin

I think you're going to have to slim down the RCSwitch library to make it fit. It has code paths for multiple styles of OOK protocols, of which you likely only need one to work, so there's some fat to trim.

Also look at:

// Number of maximum High/Low changes per packet.
// We can handle up to (unsigned long) => 32 bit * 2 H/L changes per bit + 2 for sync
#define RCSWITCH_MAX_CHANGES 67

    /* 
     * timings[0] contains sync timing, followed by a number of bits
     */
    static unsigned int timings[RCSWITCH_MAX_CHANGES]

That's 140 bytes right there. Maybe in your case RCSWITCH_MAX_CHANGES can be smaller.

First of all, thank you for your support.

As i said before , i've got just basic programming skills , so talking about shrinking the library , i don't know from where to start :roll_eyes:

But i got @gardner suggestion and i'll try that. I will look at my signal with my really cheap&dumb-but-always-useful logic analyzer and i'm quite sure i can reduce that parameter.

Noob part of the question : i tried to modify the library deleting the "Send" part( in RCSwitch.cpp), 'cause my goal is to receive a signal and i'm not interested in sending anything. I tried to brutally remove al the functions about "sending" but of course , when compiling, i got a lot of errors. Do i need to modify also RCSwitch.h or keywords file?

Here is an easy way to reduce code size:
Change

Serial.print("Unknown encoding");

To

Serial.print(F("Unknown encoding"));

The reason this works is because the string does not need to be copied to ram.
It is stored in flash memory. Whenever you use a constant string with the .print family of functions you should use the F() macro. Otherwise you are wasting ram and making your code take up more flash memory.
Also this could can easily fit on the Attiny85.
Your best bet would be to slim down the library.
Also remove the digitalWrite and pinMode and replace it with port manipulation.

If you remove things from the CPP, you will have to get rid of the declaration in the .h also.

Just removing methods you don't use is unlikely to help much though, since the compiler and linker will do that automatically for the most part.