Doe anyone know how to count button presses if you are using an infrared controller?

Hi, I am sort of a beginner in terms of Arduino but I have been working on a project that involves an up and down button selector to change between the speeds of a robot. The up arrow button acts as a speed up button and the down arrow acts as a slow down button. I have looked Arduino's website in hopes that State of Change would be the answer. However that involves a pull up or pull down resistor which isn't relevant to an infrared controller from what I thought. I may be wrong.

I have spent a long time searching Google and YouTube for an answer but to no avail. I honestly have little to no idea how I could do this with an IR controller and I could really do with some help. Please take it easy on me I am a beginner to most of Arduino and I could do with some direction for this programming.

Show us your code. In code tags.

Wading a counter should be simple,maybe a little more background on what and why you want to count a particular state.

So, basically I am using an Arduino Nano and an L298 motor driver to make a line follower using basic code. To make it more interesting though and make it a little bit more controllable by using an IR controller and receiver to change it's speed when it is line following on a track. I made four different speed settings for the motors by doing this:

//Speed settings for line follower
int speeds[] = {90, 130, 170, 220};

I also got the Hexadecimal codes for my IR controller by making a simple circuit.
Here is the code I did in the end for the IR control:

//IR CONTROLLER SETUP//
const int RECV_PIN = 9;
IRrecv irrecv(RECV_PIN);
decode_results results;
const int US = 0xFF629D;  // UP SPEED      
int SHState = 0;
const int DS = 0xFFA857;  //DOWN SPEED
int SLState = 0
const int LL = 0xFF22DD;  //LEFT LANE
int LLState = 0
const int RL = 0xFFC23D;  //RIGHT LANE
int RLState = 0
const int STOP = 0xFF02FD;
int RESULTS;

Overall I just want to use two buttons on the IR controller to change up and down between the speeds I have set for the line follower. Here is my code overall I hope you can make sense of it:

#include <IRremote.h>
#include <IRremoteInt.h>

//Define the sensor
#define RS 12
#define LS 13
#define MS 14

//Define the left motor
#define LM1 5
#define LM2 7
#define enL 6

//Define the right motor
#define RM1 10
#define RM2 15
#define enR 8

//IR CONTROLLER SETUP//
const int RECV_PIN = 9;
IRrecv irrecv(RECV_PIN);
decode_results results;
const int US = 0xFF629D;  // UP SPEED      
int SHState = 0;
const int DS = 0xFFA857;  //DOWN SPEED
int SLState = 0
const int LL = 0xFF22DD;  //LEFT LANE
int LLState = 0
const int RL = 0xFFC23D;  //RIGHT LANE
int RLState = 0
const int STOP = 0xFF02FD;
int RESULTS;

//Speed settings for line follower
int speeds[] = {90, 130, 170, 220};

void setup()
{
  Serial.begin(9600);
  IR.enableIRIn();
  pinMode(RS, INPUT);
  pinMode(LS, INPUT);
  pinMode(MS, INPUT);
  
  pinMode(LM1, OUTPUT);
  pinMode(LM2, OUTPUT);
  pinMode(RM1, OUTPUT);
  pinMode(RM2, OUTPUT);
  
  pinMode(enL, OUTPUT);
  pinMode(enR, OUTPUT);

  digitalWrite(enL, HIGH); 
  digitalWrite(enR, HIGH); 

  delay(500);
}

void loop()
{
  if(irrecv.decode(&results))
{
        RESULTS = results.value;
        if(RESULTS == US)
        {
              irrecv.resume();
              

        }
}          
}

//Defining the lineFollow command.
void lineFollow(){
 if((digitalRead(RS)==LOW)&&(digitalRead(LS)==LOW)&&(digitalRead(MS)==HIGH))
  {
    MoveForward();
  }
 if((digitalRead(RS)==HIGH)&&(digitalRead(LS)==HIGH)&&(digitalRead(MS)==HIGH))
  {
    Stop();
  }  
 if((digitalRead(RS)==LOW)&&(digitalRead(LS)==HIGH))
  {
    TurnLeft();
  }
 if((digitalRead(RS)==HIGH)&&(digitalRead(LS)==LOW))
  {
    TurnRight();
  }
 }
  
//Define conditions to move forward
void MoveForward()
{
  digitalWrite(LM1, HIGH);
  digitalWrite(LM2, LOW);
  digitalWrite(RM1, LOW);
  digitalWrite(RM2, HIGH);
  
  analogWrite(enL, speeds[]);
  analogWrite(enR, speeds[]);
  
  delay(20);
}

//Define conditions to stop
void Stop()
{
  digitalWrite(LM1, LOW);
  digitalWrite(LM2, LOW);
  digitalWrite(RM1, LOW);
  digitalWrite(RM2, LOW);
  
  analogWrite(enL, 0);
  analogWrite(enR, 0);
  
  delay(20);
}

//Define Turn Left
void TurnLeftA()
{
  digitalWrite(LM1, HIGH);
  digitalWrite(LM2, LOW);
  digitalWrite(RM1, LOW);
  digitalWrite(RM2, LOW);
  
  analogWrite(enL, speeds[]);
  analogWrite(enR, 0);
  
  delay(20);
}

//Define Turn Right
void TurnRightA()
{
  digitalWrite(LM1, LOW);
  digitalWrite(LM2, LOW);
  digitalWrite(RM1, LOW);
  digitalWrite(RM2, HIGH);
  
  analogWrite(enL, 0);
  analogWrite(enR, speeds[]);
  
  delay(20);
}

Which buttons do you want to count?
Do you want separate counters and range for each button, and what do you want to do with the count values once you have them ?

Oh, I am definitely adding more code in their, yah. So it's the up arrow and down arrow on this controller:

These are the values for the up triangle button and the bottom triangle button on the D pad of this controller:

const int US = 0xFF629D;  // UP SPEED      
int SHState = 0;
const int DS = 0xFFA857;  //DOWN SPEED
int SLState = 0

Obviously there is 4 speed options which I want to go up and down with these buttons which are set with this code;

int speeds[] = {0,90, 130, 170, 220};
analogWrite(motorpin, speeds[])

// if count is equal to 2 for instance the speed is 90

analogWrite(motorpin, speeds[2])

analogWrite(motorpin, 90)

// so depending on the count the speed changes

The two buttons should almost work like a shifter on a car, the up triangle button is like up gear and the down triangle button is like down gear. However, I do not have an idea of how to do this in code so that it will work. Would be grateful for any help.

no need for pull-up resistors when using IR codes

  • you passing the address to the speeds array, not a specific speed because there is no index specified. you should do something like
  analogWrite (enR, speeds [spdIdx]);

  • shouldn't you check for other codes after recognizing a result and resume() for all codes?
int speeds[] = {90, 130, 170, 220};
const int SpdMax = sizeof(speeds) / sizeof(int);
int spdIdx;

void loop() {
  if(irrecv.decode(&results))  {
    int code = results.value;
    switch (code)  {
    case US:
        if (SpdMax > spdIdx)
            spdIdx++;
        break;

    case DS:
        if (0 < spdIdx)
            spdIdx--;
        break;

    case LL:
        TurnLeftA ();
        break;

    case RL:
        TurnRightA ();
        break;

    case STOP:
        Stop ();
        break;
    }

    irrecv.resume();
  }
}

common practice is tp only Capitalize Constants

Thank you so much! You have no idea how helpful that was I have been watching videos and reading stuff for a good while to try and figure this out but being new to a lot of Arduino I didn't really know what I was looking for, I am very grateful for your help. Will try this now and see how I get on...

If say for instance after turning left when the button is pressed and the robot is in on a different line and you want it to begin line following again now that it has change line would this be the correct way of doing it:

case LL:
        TurnLeft ();
        delay(750);
        lineFollow();
        break;

Everything worked well when testing the type of code you said @gcjr was really helpful. However in the void setup it is giving me a error for this code:

void setup()
{
  Serial.begin(9600);
  IR.enableIRIn();
  pinMode(RS, INPUT);
  pinMode(LS, INPUT);
  pinMode(MS, INPUT);
  
  pinMode(LM1, OUTPUT);
  pinMode(LM2, OUTPUT);
  pinMode(RM1, OUTPUT);
  pinMode(RM2, OUTPUT);
  
  pinMode(enL, OUTPUT);
  pinMode(enR, OUTPUT);

  digitalWrite(enL, HIGH); 
  digitalWrite(enR, HIGH); 

  delay(500);
}

It says that 'IR was not declared in this scope' wasn't getting this error before.

i don't see it defined in your original post.
should it be irrecv?

Yah double checked and actually it should I have my older version of code open as well as the newer version I just did and I think It was just a slight difference in definitions in the code. In old code it was just 'IR' in new code it was 'irrecv'. Thanks again.

#include <IRremote.h>
#include <IRremoteInt.h>

//Define the sensor
#define RS 12
#define LS 13
#define MS 14

//Define the left motor
#define LM1 5
#define LM2 7
#define enL 6

//Define the right motor
#define RM1 10
#define RM2 15
#define enR 8

//IR CONTROLLER SETUP//
const int RECV_PIN = 9;
IRrecv irrecv(RECV_PIN);
decode_results results;
const int US = 0xFF629D;  // UP SPEED      
int SHState = 0;
const int DS = 0xFFA857;  //DOWN SPEED
int SLState = 0;
const int LL = 0xFF22DD;  //LEFT LANE
int LLState = 0;
const int RL = 0xFFC23D;  //RIGHT LANE
int RLState = 0;
const int STOP = 0xFF02FD;
int STOPState = 0;



//Speed settings for line follower
int speeds[] = {0, 90, 130, 170, 220};
const int SpdMax = sizeof(speeds) / sizeof(int);
int spdIndex;



void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn();
  pinMode(RS, INPUT);
  pinMode(LS, INPUT);
  pinMode(MS, INPUT);
  
  pinMode(LM1, OUTPUT);
  pinMode(LM2, OUTPUT);
  pinMode(RM1, OUTPUT);
  pinMode(RM2, OUTPUT);
  
  pinMode(enL, OUTPUT);
  pinMode(enR, OUTPUT);

  digitalWrite(enL, HIGH); 
  digitalWrite(enR, HIGH); 

  delay(500);
}

void loop() {
  if(irrecv.decode(&results))  {
    int code = results.value;
    switch (code)  {
    case US:
        if (SpdMax > spdIndex)
            spdIndex++;
        break;

    case DS:
        if (0 < spdIndex)
            spdIndex--;
        break;

    case LL:
        TurnLeft ();
        delay(750);
        lineFollow();
        break;

    case RL:
        TurnRight ();
        delay(750);
        lineFollow();
        break;

    case STOP:
        Stop ();
        break;
    }

    irrecv.resume();
  }
}

//Defining the lineFollow command.
void lineFollow(){
 if((digitalRead(RS)==LOW)&&(digitalRead(LS)==LOW)&&(digitalRead(MS)==HIGH))
  {
    MoveForward();
  }
 if((digitalRead(RS)==HIGH)&&(digitalRead(LS)==HIGH)&&(digitalRead(MS)==HIGH))
  {
    Stop();
  }  
 if((digitalRead(RS)==LOW)&&(digitalRead(LS)==HIGH))
  {
    TurnLeft();
  }
 if((digitalRead(RS)==HIGH)&&(digitalRead(LS)==LOW))
  {
    TurnRight();
  }
 }
  
//Define conditions to move forward
void MoveForward()
{
  digitalWrite(LM1, HIGH);
  digitalWrite(LM2, LOW);
  digitalWrite(RM1, LOW);
  digitalWrite(RM2, HIGH);
  
  analogWrite(enL, speeds[spdIndex]);
  analogWrite(enR, speeds[spdIndex]);
  
  delay(20);
}

//Define conditions to stop
void Stop()
{
  digitalWrite(LM1, LOW);
  digitalWrite(LM2, LOW);
  digitalWrite(RM1, LOW);
  digitalWrite(RM2, LOW);
  
  analogWrite(enL, 0);
  analogWrite(enR, 0);
  
  delay(20);
}

//Define Turn Left
void TurnLeft()
{
  digitalWrite(LM1, HIGH);
  digitalWrite(LM2, LOW);
  digitalWrite(RM1, LOW);
  digitalWrite(RM2, LOW);
  
  analogWrite(enL, speeds[spdIndex]);
  analogWrite(enR, 0);
  
  delay(20);
}

//Define Turn Right
void TurnRight()
{
  digitalWrite(LM1, LOW);
  digitalWrite(LM2, LOW);
  digitalWrite(RM1, LOW);
  digitalWrite(RM2, HIGH);
  
  analogWrite(enL, 0);
  analogWrite(enR, speeds[spdIndex]);
  
  delay(20);
}

Does anyone have any idea of why this isn't working for some reason, I made the circuit for the car thought I might have some faulty connections which i am trying to fix but it doesn't want to work. I am using an L298n motor driver with the Arduino Nano from Elegoo for this line follower. I am using 3 photo resistor for the sensors which I am re-wiring at the moment.

I also got this during the verification of the code but am confused:

C:\Users\user\OneDrive\Technology\Technology Project\Alpha_Velocita_Mk2_Line_Following\Alpha_Velocita_Mk2_Line_Following.ino:23:16: warning: overflow in implicit constant conversion [-Woverflow]
C:\Users\user\OneDrive\Technology\Technology Project\Alpha_Velocita_Mk2_Line_Following\Alpha_Velocita_Mk2_Line_Following.ino:25:16: warning: overflow in implicit constant conversion [-Woverflow]
C:\Users\user\OneDrive\Technology\Technology Project\Alpha_Velocita_Mk2_Line_Following\Alpha_Velocita_Mk2_Line_Following.ino:27:16: warning: overflow in implicit constant conversion [-Woverflow]
C:\Users\user\OneDrive\Technology\Technology Project\Alpha_Velocita_Mk2_Line_Following\Alpha_Velocita_Mk2_Line_Following.ino:29:16: warning: overflow in implicit constant conversion [-Woverflow]
C:\Users\user\OneDrive\Technology\Technology Leaving Cert Project\Alpha_Velocita_Mk2_Line_Following\Alpha_Velocita_Mk2_Line_Following.ino:31:18: warning: overflow in implicit constant conversion [-Woverflow]
Sketch uses 8368 bytes (27%) of program storage space. Maximum is 30720 bytes.
Global variables use 422 bytes (20%) of dynamic memory, leaving 1626 bytes for local variables. Maximum is 2048 bytes.

what does it do?
what doesn't it do that it's expected to do?

I wrote before about what the line follower is supposed to do.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.