IR remote/What the remote is saying/07. One button, one job
What the remote is saying · 07 of 11

One button, one job

Three buttons on the remote, one LED: one button switches it on and off, two dim it up and down. The sketch is short; the decision in it is what a held button means, because a held button arrives as a stream of repeat frames.

Three buttons, one LED

Wire the TK15 exactly as for your first key code, and an LED on a PWM pin: a TK01 XL LED, or any LED with its resistor. The LED pin is D9 on an Uno, GPIO 4 on an ESP32, GPIO 5 on an ESP32-S3 and GP15 on a Pico.

Then pick three buttons on the remote, run the key-code sketch, and put their command values into CMD_POWER, CMD_UP and CMD_DOWN. The sketch's values are placeholders.

What a held button sends

One press, held
every 110 ms
The button
Data frames
1
Repeat frames
4
Counting toggle ends
on
Held, the remote sends one data frame and then a repeat frame every 110 ms. A toggle that counts them flips 5 times and lands wherever the count leaves it. Skip repeats for anything that toggles; use them for anything that should keep going, like volume or brightness.

A tap is one data frame. A hold is one data frame and then a repeat frame every 110 ms for as long as the button is down. The repeat carries no data; IRremote fills in the command of the frame it repeats and sets IRDATA_FLAGS_IS_REPEAT.

So the sketch has to decide, per button, what a repeat means. For power it means nothing: the toggle skips repeats and changes once per press. For brightness it means "keep going": each repeat is another step.

What you should see

off 128
on  128
on  144
on  160
on  176
off 176

Power, then holding the up button for about a quarter of a second (a data frame and two repeats), then power again. The level is kept while the LED is off.

Why not match the address

The sketch compares commands only. With one remote pointed at the board that is enough, and it keeps working if a second remote of the same kind turns up with a different address. If two remotes in the room share command values, check d.address as well.

The code

One button toggles an LED, two more dim it. Put three commands your own remote sent to the key-code sketch into CMD_POWER, CMD_UP and CMD_DOWN; the values here are placeholders. The address is not checked: one remote is pointed at this.

ir_one_button_one_job.ino
/*
  IR Receiver - one button, one job                      TK15 / /p/tk15

  Wiring. Count from the square pad on the TinkerBlock board, parts
  up, header at the bottom:

    GND    -> GND
    VCC    -> 5V on an Uno; 3V3 on an ESP32, ESP32-S3 or Pico
              (SIGNAL idles at VCC, so match your board)
    NC     -> nothing   (unconnected on the board)
    SIGNAL -> D2 on an Uno, GPIO 23 on an ESP32, GPIO 9 on an
              ESP32-S3, GP16 on a Raspberry Pi Pico

  The LED: a TK01 XL LED (SIGNAL to LED_PIN, GND to GND), or any LED
  with a resistor, on D9, GPIO 4, GPIO 5 or GP15.

  Arduino IDE
    Tools > Board                 your board, e.g. Arduino Uno
    Tools > Port                  the one that appears when you plug in
    Tools > USB CDC On Boot       Enabled   (ESP32-S3 only)
    Tools > Manage Libraries      IRremote by shirriff, z3t0 and
                                  ArminJo, version 4 or later
    Serial Monitor                115200
*/

#include <IRremote.hpp>

// The pin SIGNAL is wired to.
// Uno: 2. ESP32: 23. ESP32-S3: 9. Pico: 16.
const int IR_RX_PIN = 2;
// A PWM pin for the LED. Uno: 9. ESP32: 4. ESP32-S3: 5. Pico: 15.
const int LED_PIN = 9;

// REPLACE THESE with commands your own remote sent.
const uint16_t CMD_POWER = 0x16;   // toggles: repeats ignored
const uint16_t CMD_UP = 0x17;      // dims up: every repeat counts
const uint16_t CMD_DOWN = 0x18;    // dims down: every repeat counts

bool on = false;
int level = 128;                   // 16 to 255

void show() {
  analogWrite(LED_PIN, on ? level : 0);
  Serial.print(on ? "on  " : "off ");
  Serial.println(level);
}

void setup() {
  Serial.begin(115200);
  pinMode(LED_PIN, OUTPUT);
  IrReceiver.begin(IR_RX_PIN, DISABLE_LED_FEEDBACK);
  show();
}

void loop() {
  if (!IrReceiver.decode()) return;

  IRData &d = IrReceiver.decodedIRData;
  // A repeat frame carries no data; the library fills in the
  // command of the frame it repeats.
  bool repeat = d.flags & IRDATA_FLAGS_IS_REPEAT;

  if (d.command == CMD_POWER && !repeat) {
    on = !on;                        // once per press
    show();
  } else if (d.command == CMD_UP && on) {
    level = min(level + 16, 255);    // held: keeps going
    show();
  } else if (d.command == CMD_DOWN && on) {
    level = max(level - 16, 16);
    show();
  }

  IrReceiver.resume();    // nothing else decodes until this runs
}

The power button ignores repeat frames, so holding it toggles once. The dimming buttons act on every repeat, so holding one keeps going, a step every 110 ms. On an Uno the LED pin must not be 3 or 11: receiving takes Timer2, which drives their PWM.

When it does not work

The power button flickers the LED

The toggle is acting on repeat frames. Holding the button sends one data frame and a repeat every 110 ms, and a toggle that counts them lands on or off at random. Skip anything flagged IRDATA_FLAGS_IS_REPEAT for a toggle.

Nothing happens, but the key-code sketch sees the buttons

The three commands in the sketch are still the placeholders. Replace them with the command values your own remote printed; the address does not matter here.

Dimming does nothing on an Uno

The LED is on pin 3 or 11. Receiving takes Timer2, which drives PWM on those two pins. Use pin 9, 10, 5 or 6.

The LED is on but will not dim below a glow

The sketch stops at 16 so off stays the power button's job. Change the 16 in the dim-down line to 0 if you want dimming to reach dark.

Where this goes next

One LED, one transistor, and where its current comes from.

The sender, pin by pin

Edit this page — content/books/ir-receiver/one-button-one-job.mdx

Community

Questions about this product

See what other owners have asked, and read their solutions.

This page covers several products. Choose yours to see the right discussions.

Discuss this article

Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.

Browse Modules and blocks on the forum