Problem with DC motor and IR remote

Hello everyone, this is my 1st post on this forum. I am working on a small project, which require remote control of DC motor. I've used IRremote library from arduino, basic IR remote (cheapest possible with 9 numbres and UP, LEFT, DOWN, RIGHT, OK buttons) and VS1883B sensor.

Right now, i can control my motor with basic instructions: click -> forward -> click -> stop -> click -> backward -> click -> stop etc.

I want to control my motor by holding a button (motor should move when button is hold and stop when i release a button). I've read tons of similar threads, but most of them require remote which sends "repeat code" (0xFFFFFF etc), but my remote / sensor doesnt register any "reapeat code". My cheap IR remote doesnt not "spam" codes when i hold a button, it just send one, single code.

I've also tried my TV remote. This one is "spamming" codes when i hold a button.

Whats the difference between my cheap remote and TV remote? Why cheap one sends just one code and TV remote is spamming codes again and again?

Is it possible to implement something which would help my cheap remote to control motor while holding a button? Should i use interrupts and timers?

This is my current source code with basic control:

#include <IRremote.h>
int input_pin = 2;
IRrecv irrecv(input_pin);
decode_results signals;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn();

  pinMode(6, OUTPUT); //PWM
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
}

void loop() {

  if (irrecv.decode(&signals)) {
    Serial.println(signals.decode_type);
    Serial.print(F("received code = 0x"));
    Serial.println(signals.value, HEX); //hex value
    irrecv.blink13(true); //blink leds when code is received

    if (signals.value == 0x3D9AE3F7 )//go up
    { 
      analogWrite(6, 255);
      digitalWrite(7, HIGH);
      digitalWrite(8, LOW);
      delay(50);
    }

    if (signals.value == 0x1BC0157B) 
     { //go down
      analogWrite(6, 255);
      digitalWrite(7, LOW);
      digitalWrite(8, HIGH);
      delay(50);
    }

    if (signals.value == 0x488F3CBB) { //stop
      analogWrite(6, 0);
      digitalWrite(7, LOW);
      digitalWrite(8, LOW);
      delay(100);
    }
    irrecv.resume();
    delay(100);
  }
}

I think you're expecting the code to perform magic. If the remote doesn't send anything on a key release, how could there be any other way for the program to know?

In some cases, like for example the "Power" button, a TV remote only sends the code once. For buttons like Volume-Up or Volume-Down, it sends some form or repeat. On a TV remote, there is usually an LED to let you know if a button is repeating or not.

Your "cheap remote" is doing whatever it was designed to do. Unless you have a way of changing its firmware it is unlikely you will be able to get it to send a repeat indication.

You can build your own remote using an Arduino and have it send whatever you want.

aarg:
I think you're expecting the code to perform magic. If the remote doesn't send anything on a key release, how could there be any other way for the program to know?

Yeah, maybe you are right :slight_smile: What do u think, is it a problem with remote or sensor? IR LED shines when i hold a button (checked on phone camera), so maybe its something with my sensor? NVM, looks like @johnwasser explained everything.

You can build your own remote using an Arduino and have it send whatever you want.

I think its an overkill, because it would be way more complicated than the whole project :slight_smile: I am gonna use TV remote.

So, if it is impossible to implement my cheap remote, what can i do with TV remote, which sends codes when i hold a button? While loop?

[/ltr]

No not an extra while-loop.

the function loop() itself what its name says: looping

Some additional advice:

you should give all variables and all IO-oin-numbers selfexplaining names
This makes it much easier to understand the program and in most cases it eliminates the need for a comment.

best regards Stefan

hardtofindanynick:
So what can i do with TV remote, which sends codes when i hold a button? While loop?

No.

Measure the time between the button and the repeat codes. When a button arrives, start a timer. If a repeat doesn't arrive before the repeat code is expected to arrive, the button has been released.

Measure the time between repeat codes (may be different from the initial interval). Start a timer when a repeat arrives. If another repeat doesn't arrive before the repeat code is expected to arrive, the button has been released.

If a new button arrives, the previous button has been released.

Learn about state machines - most code interfacing to the outside world is much
easier to think about as a state-transition diagram.

Notice that JW didn't have to use any programming terms to explain that. It's a great habit to logically define a process completely before you start coding. With something like that in hand, the coding part is always much easier (and often better).

Thanks for your feedback guys, i really appreciate it. This is first contact with programming and i am still learning basics.

@StefanL38 i am gonna sort out everything when i finish the project, because i have to create clear documentation.

@johnwasser thank you again, i am gonna read about timers.

@MarkT i know something about state machines, but i dont think its neccessary in my project.

took me 5 minutes to find and replace

#include <IRremote.h>
int input_pin = 2;
IRrecv irrecv(input_pin);
decode_results signals;

const byte PWM_Pin = 6;
const byte Fwd_Pin = 7;
const byte Bak_Pin = 8;

#define goUp   0x3D9AE3F7
#define goDown 0x1BC0157B
#define DoStop 0x488F3CBB 

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn();

  pinMode(PWM_Pin, OUTPUT); 
  pinMode(Fwd_Pin, OUTPUT);
  pinMode(Bak_Pin, OUTPUT);
}

void loop() {

  if (irrecv.decode(&signals)) {
    Serial.println(signals.decode_type);
    Serial.print(F("received code = 0x"));
    Serial.println(signals.value, HEX); //hex value
    irrecv.blink13(true); //blink leds when code is received

    if (signals.value == goUp )
    {
      analogWrite(PWM_Pin, 255);
      digitalWrite(Fwd_Pin, HIGH);
      digitalWrite(Bak_Pin, LOW);
      delay(50);
    }

    if (signals.value == goDown)
     { //go down
      analogWrite(PWM_Pin, 255);
      digitalWrite(Fwd_Pin, LOW);
      digitalWrite(Bak_Pin, HIGH);
      delay(50);
    }

    if (signals.value == DoStop) { 
      analogWrite(PWM_Pin, 0);
      digitalWrite(Fwd_Pin, LOW);
      digitalWrite(Bak_Pin, LOW);
      delay(100);
    }
    irrecv.resume();
    delay(100);
  }
}

best regards Stefan