Atmega328 to Attiny85

Hello, hope everyone is doing well doing well.

I have a piece of code that reads an infared signal and turns on an LED and I want to write it to the Attiny85.

The circuit works well with the Atmega328.
I got the Attiny85 working with a simple LED blink sketch.
I made sure that I have the right pins selected.
I also tried burning the bootloader in 1, 8 & 16 Mhz.

The program does not seem to work, what am I missing here?
Does the Attiny have some limitations that I don’t know about?

#include <IRremote.h>

const int IR_PIN=3;
const int SIGNAL=4;
int togglestate=0; 

unsigned long last=millis();

const unsigned long A=0xE0E036C9;

IRrecv irrecv(IR_PIN);
decode_results results;

void TOGGLE(){
  if(togglestate==0){
    digitalWrite(SIGNAL, HIGH);
    togglestate=1;
  }else{
    digitalWrite(SIGNAL, LOW);
    togglestate=0;
  }
}

void setup() {
  
irrecv.enableIRIn();
pinMode(SIGNAL, OUTPUT);

}

void loop() {

if(irrecv.decode(&results)){

if(millis()-last>200){
switch(results.value){
  case A:
    TOGGLE();
      break;
  }    
}
  last=millis();
  irrecv.resume();
}
}

Thank you all.
-Dennis

The Attiny85 is a bit more complicated. I think that the problem is in the IRRemote library. I think that it is only compiatable with other Arduinos and not the Attiny85 one. I suggest you to find any other library or any alternatives and other versions of the library which are compiatable with Attiny85. And try the sketch.

here maybe is a solution...

Thank you all. It’s never simple haha.

The instructable is for an older arduino version. I will have to mess around with that.

Ty

dennisdgi:
Thank you all. It’s never simple haha.

The instructable is for an older arduino version. I will have to mess around with that.

Ty

I've done a LOT of work with that IR library ... even modified it for some things that I needed that it didn't provide ... it's super picky about which pin you put your receiver on ... of course on the 328 it likes pin 2, but I'm not sure what that equates to on the tiny and looking at the instructable, it looks like timing might be different altogether on the tiny ... so its probably more complicated than simply receiving on the correct pin ... then again ... I see here that the current library does seem to have timing definitions for the ATTiny in boarddefs.h

// ATtiny84
#elif defined(AVR_ATtiny84)
#define IR_USE_TIMER1 // tx = pin 6
//ATtiny85
#elif defined(AVR_ATtiny85)
#define IR_USE_TIMER_TINY0 // tx = pin 1

And it even comments on a pin number ... might be worth a shot!

I also found this ...

IRRemote Ported To The Tiny

EasyGoing1:
I've done a LOT of work with that IR library ... even modified it for some things that I needed that it didn't provide ... it's super picky about which pin you put your receiver on ... of course on the 328 it likes pin 2, but I'm not sure what that equates to on the tiny and looking at the instructable, it looks like timing might be different altogether on the tiny ... so its probably more complicated than simply receiving on the correct pin ... then again ... I see here that the current library does seem to have timing definitions for the ATTiny in boarddefs.h

// ATtiny84
#elif defined(AVR_ATtiny84)
#define IR_USE_TIMER1 // tx = pin 6
//ATtiny85
#elif defined(AVR_ATtiny85)
#define IR_USE_TIMER_TINY0 // tx = pin 1

And it even comments on a pin number ... might be worth a shot!

I really appreciate the reply, I am getting desperate haha.

I tried the library that you linked as well as a few others including z3t0's library.
I tried putting the receiver on different pins, including 1 as you mentioned.
I tried different Attiny85 cores, and tried burning the bootloader in 8mhz internal.
I tried following a few available tutorials on a few different Arduino IDE versions.

I tested pins on the t85 with a simple LED blink sketch and works flawlessly using every configuration.

I also tried the sketch with the atm328 with different configurations and it works perfectly.

At this point I am ready to throw in the towel, this tiny project is becoming a mega pain in the ass haha.

Hello everyone, hope everyone is still doing good.

I managed to get it working. :slight_smile:

It was my millis argument that was causing problems, works fine without it.

I need the millis argument to give some more time between toggles when holding down a key.

Anybody know why my tiny doesn’t want to work with millis and is there anything I could do.

Thanks

In your sketch you have declared a variable, an unsigned long named "last" and telling it it's = millis()
> > > > unsigned long last=millis();

The IDE won't ding you for it, but that isn't the way things work.

but that isn't the way things work.

It sort of is though, but the issue is more that the line further down

if(irrecv.decode(&results)){

if(millis()-last>200){
switch(results.value){
  case A:
    TOGGLE();
      break;
  }   
}
  last=millis();
  irrecv.resume();
}

should be one nest further in. If the elapsed time exceeds 200, then you should reset the time. (use ctrl-T to auto-format and it becomes a bit more clear)

Deva_Rishi:
It sort of is though, but the issue is more that the line further down

if(irrecv.decode(&results)){

if(millis()-last>200){
switch(results.value){
 case A:
   TOGGLE();
     break;
 }  
}
 last=millis();
 irrecv.resume();
}



should be one nest further in. If the elapsed time exceeds 200, then you should reset the time. (use ctrl-T to auto-format and it becomes a bit more clear)

Hey thanks for suggestion, but no luck.

Here’s the code i tried:
It changed a bit since last time but it’s essentially the same.

#include <IRremote.h>

const int RECV_PIN = 1;
const int SIGNAL = 2;

int togglestate = 0;
int delaystate = 0;
unsigned long last = millis();

IRrecv irrecv(RECV_PIN);
decode_results results;

void setup() {
  irrecv.enableIRIn();
  pinMode(SIGNAL, OUTPUT);
}

void loop() {

  if (irrecv.decode(&results)) {

    if (millis() - last > 200) {
      if (results.value == 0xE0E036C9 || results.value == 0xDAEA83EC) {
        if (togglestate == 0) {
          digitalWrite(SIGNAL, HIGH);
          togglestate = 1;
        } else {
          digitalWrite(SIGNAL, LOW);
          togglestate = 0;
        }
      }
      last = millis();
    }
    irrecv.resume();
  }
}

I tried putting irrecv.resume(); further in and out, but no results.
Without millis() works like a charm.

BTW I had no idea about auto format :-\ thanks for that.

Without millis() works like a charm.

Why is the millis() in there to begin with ?
the(irrecv.decode(&results))checks if 'any' valid value has been decoded already, why would 200 ms need to pass first ?

Deva_Rishi:
Why is the millis() in there to begin with ?
the(irrecv.decode(&results))checks if 'any' valid value has been decoded already, why would 200 ms need to pass first ?

Well the remote continuously sends the signal, so holding down the button will continuously toggle my relay on/off pretty fast. I have to press and release the button quickly to get the relay to toggle properly.

So i figured adding a millis delay would be a good way to combat that. Giving me some space between presses.

I also tried adding a delay(200); after toggle=1 and toggle=0. And with that the relay turned on but would not turn off. As if the delay was stuck in a loop.

Since results is a 32-bit (unsigned Int) you could just do a proper de-bounce results.value == 0xE0E036C9like this:

void loop() {
  static uint32_t oldvalue =0;
  if (irrecv.decode(&results)) {

    if (results.value != oldvalue) {
      oldvalue = results.value;
      if (results.value == 0xE0E036C9 || results.value == 0xDAEA83EC) {

Deva_Rishi:
Since results is a 32-bit (unsigned Int) you could just do a proper de-bounce results.value == 0xE0E036C9like this:

void loop() {

static uint32_t oldvalue =0;
  if (irrecv.decode(&results)) {

if (results.value != oldvalue) {
      oldvalue = results.value;
      if (results.value == 0xE0E036C9 || results.value == 0xDAEA83EC) {

Thank you, that kind of works, but still an issue.

So the button on the remote switches between two values at random:
0xDAEA83EC & 0xE0E036C9

And with your code, it toggles the relay only if the HEX value switches.
You can see it more clearly in the serial monitor which I posted at the bottom.

This is the main code:

#include <IRremote.h>

const int RECV_PIN = 4;
const int SIGNAL = 5;

int togglestate = 0;
int delaystate = 0;

IRrecv irrecv(RECV_PIN);
decode_results results;

void setup() {
  irrecv.enableIRIn();
  pinMode(SIGNAL, OUTPUT);
  Serial.begin(9600);
}

void loop() {

  static uint32_t oldvalue = 0;

  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    if (results.value != oldvalue) {
      oldvalue = results.value;
      if (results.value == 0xE0E036C9 || results.value == 0xDAEA83EC) {
        if (togglestate == 0) {
          digitalWrite(SIGNAL, HIGH);
          togglestate = 1;
          Serial.println("    RELAY ON");
        } else {
          digitalWrite(SIGNAL, LOW);
          togglestate = 0;
          Serial.println("    RELAY OFF");
        }
      }
    }
    irrecv.resume();
  }
}

Here is the serial monitor: (Button is being held down).

E0E036C9
E0E036C9
E0E036C9
E0E036C9
E0E036C9
E0E036C9
E0E036C9
E0E036C9
E0E036C9
E0E036C9
E0E036C9
E0E036C9
DAEA83EC
    RELAY ON
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
E0E036C9
    RELAY OFF
E0E036C9
DAEA83EC
    RELAY ON
DAEA83EC
DAEA83EC
E0E036C9
    RELAY OFF
DAEA83EC
    RELAY ON
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
E0E036C9
    RELAY OFF
DAEA83EC
    RELAY ON
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
E0E036C9
    RELAY OFF
DAEA83EC
    RELAY ON
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
E0E036C9
    RELAY OFF
DAEA83EC
    RELAY ON
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
E0E036C9
    RELAY OFF
DAEA83EC
    RELAY ON
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
E0E036C9
    RELAY OFF
DAEA83EC
    RELAY ON
DAEA83EC
DAEA83EC
DAEA83EC
DAEA83EC
E0E036C9
    RELAY OFF
DAEA83EC
    RELAY ON
DAEA83EC
DAEA83EC
DAEA83EC
E0E036C9
    RELAY OFF
E0E036C9
E0E036C9
E0E036C9
E0E036C9

And yes, if I tap the button instead of holding it down it does the same thing, only switches when there is a change in the HEX signal.

Is there a way to combat this?

And thank you for the proper de-bounce example, very simple.

So the button on the remote switches between two values at random:
0xDAEA83EC & 0xE0E036C9

Well that is not very nice of it. I actually suspect that if you don't hold down the button it doesn't send anything, so that is probably not quite what you want either because then if (irrecv.decode(&results))this condition may not be true, The snag is a little in the IRrec library which requires the resume() to be called after the decode() has returned 'true' , and because there is no clear indication of how long the transmission takes (also by the remote, i think it varies depending on the code it sends even) So back to the millis() based method, and see if it works when you put the elapsed time condition here

void loop() {
  static uint32_t lastValuePrc = 0;
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    if ((results.value == 0xE0E036C9 || results.value == 0xDAEA83EC) && (millis() - lastValuePrc > 1000)) {
      lastValuePrc = millis();
      Serial.println("Results Processed");
      
      if (togglestate == 0) {
        digitalWrite(SIGNAL, HIGH);
        togglestate = 1;
        Serial.println("    RELAY ON");
      } 
      else {
        digitalWrite(SIGNAL, LOW);
        togglestate = 0;
        Serial.println("    RELAY OFF");
      }
    }
    irrecv.resume();
  }
}

Deva_Rishi:
Well that is not very nice of it. I actually suspect that if you don’t hold down the button it doesn’t send anything, so that is probably not quite what you want either because then if (irrecv.decode(&results))this condition may not be true, The snag is a little in the IRrec library which requires the resume() to be called after the decode() has returned ‘true’ , and because there is no clear indication of how long the transmission takes (also by the remote, i think it varies depending on the code it sends even) So back to the millis() based method, and see if it works when you put the elapsed time condition here

void loop() {

static uint32_t lastValuePrc = 0;
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    if ((results.value == 0xE0E036C9 || results.value == 0xDAEA83EC) && (millis() - lastValuePrc > 1000)) {
      lastValuePrc = millis();
      Serial.println(“Results Processed”);
     
      if (togglestate == 0) {
        digitalWrite(SIGNAL, HIGH);
        togglestate = 1;
        Serial.println("    RELAY ON");
      }
      else {
        digitalWrite(SIGNAL, LOW);
        togglestate = 0;
        Serial.println("    RELAY OFF");
      }
    }
    irrecv.resume();
  }
}

I apologize for the late response, I didn’t see the page 2 hyperlink :\

The code works great on the atmega328 but again doesn’t do anything on the tiny85. Seems like the there is no problem with the code.

Delay and millis functions work when used in a simple blink sketch, but when I use delay and millis within the IRremote library, the tiny just stops responding.

I am using an internal oscillator @ 8Mhz, I know IR signals need a specific frequency to operate properly right? Could that be the problem? Then again it reads the signal fine without millis.

Also when I tried uploading a blink sketch with delay(1000) in between blinks, the frequency changes sometimes. Usually a 1000ms blink sketch blinks at around 200ms in reality. (Since I am using a different frequency that’s normal right?)
One time I got it to blink at an actual 1000ms with the same preferences! Something spooky is going on.

But either way it seems like the IRremote library doesn’t like time based functions on the tiny.

Thank you.

I am using an internal oscillator @ 8Mhz, I know IR signals need a specific frequency to operate properly right? Could that be the problem? Then again it reads the signal fine without millis.

maybe, that library is quite strange the way it is set up.

Also when I tried uploading a blink sketch with delay(1000) in between blinks, the frequency changes sometimes.

That is wrong, have you burned the bootloader properly ? I don't use the ATtiny85 very often (usually a can make do with a 13) but you should be able to get it to blink at the right speed, try adding the specific frequency at the start of your sketch so the compiler calculates the cycles correctly#define F_CPU 8000000UL

dennisdgi:
I tried t...
I tried putting ...
I tried different ...
I tried following ...

Have you tried a different chip? lol ... why can't you use a standard 328? Too big?

dennisdgi:
At this point I am ready to throw in the towel, this tiny project is becoming a mega pain in the ass haha.

When you just said “Mega” I remembered that they have those new micro mega 2560s out now but then I saw this … why wouldn’t this work? Different flavors too…

Beetle with Mega32U4

USB Keychain Beetle