Attiny85 Single button device - Help with coding

Everything related to protocols and IR codes
Post Reply
dynamis_dk
Posts: 5
Joined: Wed Dec 04, 2013 7:44 pm

Attiny85 Single button device - Help with coding

Post by dynamis_dk »

Hi Forum, Having got the software this afternoon and briefly mentioning my intended use Chris advised I pop over to the forum and see what help I can get.

I'm looking to create a small Attiny85 based IR PC on PCB which will allow my HTPC to power up from 'off' using the same remote which works fine once in the 'booted' state. As it stands I can resume from IR remote just fine and suspending also works but I would like to have it so I can boot from nothing using the remote.

My plan is to connect the PCB I make to the always on 5v from the PC PSU. The PCB sits waiting for the right signal (PC Power Button on MCE remote) and once detected it trigger turning the PC on. Once on, in code the PCB will check if the PC is powered up and if its, basically skip past all the IR code. Then at the point the PC shuts down to nothing, the PCB will see the power to the PC has gone allowing the IR code to check for the IR (PC power button) signal to be received to power up again.

Most of the coding I should be able to figure from examples and I have spent a few years programming when I was younger but the IR part is giving me a headache! I used a IR Library but it makes my total sketch size too big for me to transfer from the Arduino to the Attiny85 so I'm looking for something small that will fit into the 8k I've got to play with.

Chris suggested you would be able to help design some code which would look for the specific IR signal/code/input I wish to use which would remove the need for a full protocol decoder as it will only ever look for the one button.

I've tried to capture the two different codes to MCE remote sends pressing the same button as I understand the RC6 protocol uses some kind of bit to change the code to differentiate a long press or multiple presses.

Make sense :)
You do not have the required permissions to view the files attached to this post.
User avatar
AnalysIR
Site Admin
Posts: 776
Joined: Sat Aug 31, 2013 3:51 pm
Location: Dublin, Ireland
Contact:

Re: Attiny85 Single button device - Help with coding

Post by AnalysIR »

Great

It looks pretty straight forward - except it is also a bit unusual.

You say you get these 2 different signals from pressing the same 'power key' (Please confirm)
(Normally the toggle function is much earlier in the signal for RC6 typpe signals)

Can you post a link to the remote control you are using.

Could you also upload a saved history file of a selection of signals from this remote.
If you can record the key names in the 'Key' column of the on-screen History.
First record the signals.
Then Save the session Menu->File->Save Session.

Then upload the saved file to this post (Menu->File->Explore to find the file).

Once you upload the history, we will do up some code to detect the power, which will be much trimmer than decoding a full blown IR protocol.

Question: Do you need to know which key was pressed or just that any key (or subset of keys) on the remote was pressed?

Tip: Think of it a a square wave rather than an IR protocol!
dynamis_dk
Posts: 5
Joined: Wed Dec 04, 2013 7:44 pm

Re: Attiny85 Single button device - Help with coding

Post by dynamis_dk »

Yes, I can confirm the two waves were generated from the same remote key, two presses after each other.

This looks to be the same package I have, doesn't list specifics but the image and IR receiver look the same as mine - http://www.newegg.com/Product/Product.a ... 6880100851

I need to know the Power button on the remote is pressed, anything else can be ignored as I'm only wanting to use the power button to signal the PC start up process. I need it to detect both of the codes created by the remote (so both sides of the toggle)

Here are links to the history files, forum wouldn't let me upload with a .txt extension...

This is a couple of presses of the Power Button I wish to use, just so you can see the states change: http://www.violentangel.net/modding/ele ... istory.txt
This is a bunch of random keys, pressed twice to show the toggles etc: http://www.violentangel.net/modding/ele ... istory.txt

Even now I'm not 100% the output on the history files are the same as I'm sure the wave is longer on these than the first instance I captured?!
User avatar
AnalysIR
Site Admin
Posts: 776
Joined: Sat Aug 31, 2013 3:51 pm
Location: Dublin, Ireland
Contact:

Re: Attiny85 Single button device - Help with coding

Post by AnalysIR »

I have adjusted the forum setting to allow txt files(hopefully got it right).

The links you provided were broken, so please try to upload them again (or email them to me if it doesnt work for you)

I also found an infrared remote control in our box which is also a MS MCE and it seems to be a similar signal. If so it will be useful to test with.

Update: It looks like your server is working again, so I am able to get the files. I uploaded them here for reference.
You do not have the required permissions to view the files attached to this post.
User avatar
AnalysIR
Site Admin
Posts: 776
Joined: Sat Aug 31, 2013 3:51 pm
Location: Dublin, Ireland
Contact:

Re: Attiny85 Single button device - Help with coding

Post by AnalysIR »

Here is some code which should work for your requirements.

There are 2 or 3 buttons on the MCE remote that return the same value as the power button (using this method), but that should suffice for your requirements.

You will be able to get the code to compile well below 1.5k on the ATTiny, by removing all the Serial statements.

It compiles to 1,256 bytes for me on the ATTiny85 (out of 8k) when I remove all the serial statements. I left them in for debugging on the UNO only - you have to remove them to get it to compile on the tiny.

You can then add your own code once you detect the power button is pressed (dummyValueIR is set to 268567048 when 'Power' is pressed).

Post back to let us know how you get on or if you need anything explained.


The AnalysIr Team

Code: Select all

/*
Software to demonstrate how to decode IR signals from a Microsoft style MCE Infrared Remote Control.
 This code detects the keys pressed, with a minimum of overlap between keys.
 The purpose was to have a small footprint of code less using less than 1.5k flash, to fit on to an ATTiny and to detect when the power key was pressed o nthe remote,
 without using up all of the memory on the ATTiny
 .
 Remove the all Serial statements to shrink the code to under 1.5k (UNO)
 
 Author: AnalysIR, http://www.AnalysIR.com/
 Licence: Free to use, without restriction, by people with AnalysIR (excluding demo). 
 Please credit the Author and provide a link to the website above, where feasible.
 
 This code should filter out most other common IR protocols.
 Also, works for Sony protocol and can be adjusted to work for almost any protocol, where a small footprint is required.
 It identifies the keys pressed, but not using the official decoding methods. In some cases two or 3 keys may return the same value (for dummyValueIR)
 If you need to uniquely identify every key then the code must be updated accordingly.
 */

//This is just a simple way to define what we want
#define pin2HIGH digitalRead(2)

const byte IR_Pin =2;//pin to receive demodulated IR signal

unsigned long timeA=0;

unsigned long dummyValueIR=0; //this store the 'dummy' value we calculate for each signal

byte retVal=0;
byte pulseCount=0; //counts the number of high pulses in each signal


void setup(){

  Serial.begin(115200);  //start serial connection

  //configure pin2 as an input and enable the internal pull-up resistor
  pinMode(2, INPUT_PULLUP);
  while (!pin2HIGH); //wait here until pin 2 is high = default idle state
  Serial.println("Get AnalysIR at www.AnalysIR.com");
}

void loop(){

  if (!pin2HIGH) { //we want to measure the low pulses only on the IR Receiver (IR receiver provides the actual signal inverted)
    timeA=micros(); //get the time now
    retVal=getHighTicks(); //return the number of 444 uSecs in the pulse
    if (retVal==2||retVal==3) dummyValueIR =dummyValueIR*2+1;
    else  dummyValueIR =dummyValueIR*2;
    //we are finishedlooking for the Power signal when we get 34 signals
    if (pulseCount>33) delay(1000);//force timeout once we have enough pulses
  }

  if((micros()-timeA)>1000000){ //only report event 1 sec after last pulse
    if (pulseCount>0) {
      Serial.print(pulseCount);
      Serial.println(" Pulses Counted");
      Serial.print(dummyValueIR);
      Serial.println(" Timer Expired");
    }
    dummyValueIR=0;
    timeA=micros();
    pulseCount=0; //reset for next one
  }
}

byte getHighTicks(){ //each tick is 444 uSecs
  while (!pin2HIGH && micros() <(timeA+3500) );//wait here until it goes low or times out
  pulseCount +=1; //keep track of the number of pulse received
  return (micros()-timeA+200)/444;//all RC6 pulses are in multiples of 444 uSecs, the 200 is to round it up to allow for variations caused by IR Receivers
}
dynamis_dk
Posts: 5
Joined: Wed Dec 04, 2013 7:44 pm

Re: Attiny85 Single button device - Help with coding

Post by dynamis_dk »

Thank you very much - wasn't expecting such a quick turn around you guys obviously know what your doing :)

I've tested the code on the Arduino and it works well but there are a few bits I could ideally do with ironing out and what I've found from testing all the buttons on the remote.

Your correct that more then the power button trigger the code I need - The Info Button and Volume Down button also trigger the same code. Is there much work to isolate this? I use the volume key to adjust the TV volume so this may cause me issue down the line. In an ideal world I would like to setup so only the Power Button (or a single press) is recognised but in the short term this code is working more then well.

One behaviour I have noticed is sometimes the power button isn't detected on the first press if pressing another key first, i.e. If I press the stop button then the power button, I have to press power twice and its recognised on the 2nd press.

I plan on having the code check to see if the PC power is already on and if it is to ignore any IR so the extra keys and double press thing shouldn't matter in the greater scheme of things but I would be interested in your thoughts on removing these small issues and what challenges this might present (just cause I'm the curious type lol)
User avatar
AnalysIR
Site Admin
Posts: 776
Joined: Sat Aug 31, 2013 3:51 pm
Location: Dublin, Ireland
Contact:

Re: Attiny85 Single button device - Help with coding

Post by AnalysIR »

One behaviour I have noticed is sometimes the power button isn't detected on the first press if pressing another key first, i.e. If I press the stop button then the power button, I have to press power twice and its recognised on the 2nd press.
You will notice there is a one second timeout(1000000 uSecs). This means there has to be a gap of 1 sec between presses.

You can just drop this down to 250000 to make the gap one quarter of a second and so on.

Go ahead and integrate this into your solution & I will have a look at it again or over the weekend, to isolate the power button a bit more.
dynamis_dk
Posts: 5
Joined: Wed Dec 04, 2013 7:44 pm

Re: Attiny85 Single button device - Help with coding

Post by dynamis_dk »

Ah I say the delay bit it never trigger that it maybe I was pressing buttons too fast doh!

I'm waiting on a few parts to enable me to program the Attiny and a few bits to complete my board but I'm hoping to call into a Maplin branch tomorrow so I should be able to get a working breadboard of it sorted this weekend to test everything works as expected.

Thanks again for you continued efforts.
User avatar
AnalysIR
Site Admin
Posts: 776
Joined: Sat Aug 31, 2013 3:51 pm
Location: Dublin, Ireland
Contact:

Re: Attiny85 Single button device - Help with coding

Post by AnalysIR »

Played around with it a bit more...and this version only has 2 x 2 keys that return duplicate numbers, on my MCE infrared remote control.

You will notice now that you get the toggle effect included (e.g. for the power key you will get 2 different numbers, alternating every press and for every key).

This version compiles only slightly larger than the previous one. So all you need to do is trigger your own code when you get either value for a Power press.

The main changes in the new code is that it now measures the lenght of each full pulse, whereas the previous version measured only the length of the high part of each pulse.
(Also note, IR receivers deliver an inverted signal to the Arduino).

This is indeed a cool way to detect IR signals for a small footprint device like the ATTiny family, without using a full blown library, like IRremore or IRLib. However, there is no guarantee that other remotes would activate the signal. I tested an LG remote using an NEC IR protocol and it only returns '0' every time and on a Sony remote, it returns a different set of values, which is good. To change this to work with NEC, it should only be a matter of changing the value '444' in the code to match the NEC timings.

Let me know if there are any problems or 'scope creep' :D

Code: Select all

/*
Software to demonstrate how to decode IR signals from a Microsoft style MCE Infrared Remote Control.
 This code detects the keys pressed, with a minimum of overlap between keys.
 The purpose was to have a small footprint of code less using less than 1.5k flash, to fit on to an ATTiny and to detect when the power key was pressed o nthe remote,
 without using up all of the memory on the ATTiny
 .
 Remove the all Serial statements to shrink the code to under 1.5k (UNO)
 
 Author: AnalysIR, http://www.AnalysIR.com/
 Licence: Free to use, without restriction, by people with AnalysIR (excluding demo). 
 Please credit the Author and provide a link to the website above, where feasible.
 
 This code should filter out most other common IR protocols.
 Also, works for Sony protocol and can be adjusted to work for almost any protocol, where a small footprint is required.
 It identifies the keys pressed, but not using the official decoding methods. In some cases two or 3 keys may return the same value (for dummyValueIR)
 If you need to uniquely identify every key then the code must be updated accordingly.
 */

//This is just a simple way to define what we want
#define pin2HIGH digitalRead(2)

const byte IR_Pin =2;//pin to receive demodulated IR signal

unsigned long timeA=0;

unsigned long dummyValueIR=0; //this store the 'dummy' value we calculate for each signal

byte retVal=0;
byte pulseCount=0; //counts the number of high pulses in each signal

void setup(){
  Serial.begin(115200);  //start serial connection
  //configure pin2 as an input and enable the internal pull-up resistor
  pinMode(2, INPUT_PULLUP);
  while (!pin2HIGH); //wait here until pin 2 is high = default idle state
  Serial.println("Get AnalysIR at www.AnalysIR.com");
}

void loop(){
  if (!pin2HIGH) { //we want to measure the low pulses only on the IR Receiver (IR receiver provides the actual signal inverted)
    timeA=micros(); //get the time now
    retVal=getPulseTicks(); //return the number of 444 uSecs in the pulse
    if (retVal>2 && retVal<6) dummyValueIR =dummyValueIR*2+retVal; //pretend this is a '1'
    else  dummyValueIR =dummyValueIR*2; ////pretend everything else is a '0'
    //we are finishedlooking for the Power signal when we get 34 signals
    if (pulseCount>33) delay(1000);//force timeout once we have enough pulses
  }

  if((micros()-timeA)>1000000){ //only report event 1 sec after last pulse
    if (pulseCount>0) {
      Serial.print(pulseCount);
      Serial.println(" Pulses Counted");
      Serial.print(dummyValueIR);
      Serial.println(" Timer Expired");
    }
    dummyValueIR=0;
    timeA=micros();
    pulseCount=0; //reset for next one
  }
}

byte getPulseTicks(){ //each tick is 444 uSecs, returns number of tics for full pulse
  while (!pin2HIGH && micros() <(timeA+3500) );//wait here until it goes low or times out
  if(micros() >(timeA+3500)) {
    pulseCount=255;
    return (micros()-timeA+200)/444;//error signal
  }
  while (pin2HIGH && micros() <(timeA+3500) );//wait here until it goes high or times out
  //now we have captured the time for the full pulse (or timedout)
  if(micros() >(timeA+3500)) return 2;//special for end of valid signal
  //otherwise return value for normal bit
  pulseCount +=1; //keep track of the number of pulse received
  return (micros()-timeA+200)/444;//all RC6 pulses are in multiples of 444 uSecs, the 200 is to round it up to allow for variations caused by IR Receivers
}
dynamis_dk
Posts: 5
Joined: Wed Dec 04, 2013 7:44 pm

Re: Attiny85 Single button device - Help with coding

Post by dynamis_dk »

Oh fantastic, thanks again for the quick turn around.

The bits I need to program the Attiny arrived today so I should be able to breadboard my solution and then try on the Attiny chip. Soon as I've given it a test drive I'll let you know how I get on.
Post Reply