Infrared control while also doing other stuff


#1

I have the Starter Robot kit (with electronics) and have built the tank as a christmas gift for my nephew. I have programmed it to be a wallTracer^TM (using an extra ultrasound sensor) and that works fine. I have also tested the infrared controller, which also works fine. Howerver, I would like to see if I could join the two code bases so as to be able to shift seamlessly between infrared control and autonomous walltracing. I have made it work such taht I can shift from infrared control to autonomous control by clicking the “9” numeric button on the remote control. However, I can’t make it switch back again. I think th button push sensing part gets disrupted by the long tim,e spent running the wall tracing code. I haven’t found any example IR code that uses interrupts. Interrupts are the only way I can see this problem being solved. How do I use interrupts to detect button pushes?

My current code can be seen here;
https://dl.dropboxusercontent.com/u/2070405/infraultra.ino


#2

hi,loldrup.there is my code for double mode.you can update the latest makeblock’s library( https://github.com/Makeblock-official/Makeblock-Library) on Github first.

/*************************************************************************
* File Name          : Makeblock IR_ULTRASONIC_Controller.ino
* Author             : Jasen
* Updated            : Jasen
* Version            : V1.0.0
* Date               : 11/6/2013
* Description        : Demo code for Makeblock Starter Robot kit,two motors
                       connect on the M1 and M2 port of baseshield, The IR receiver module
                       connect on port 6.
                       The four black button on the IR controller is used to control the direction 
                       of robot, the number button on the IR controller is for changing the speed of the robot.
                       button 1 is for setting the speed to the slowest,button 9 is for setting the speed to fastest.
* License            : CC-BY-SA 3.0
* Copyright (C) 2013 Maker Works Technology Co., Ltd. All right reserved.
* http://www.makeblock.cc/
**************************************************************************/
#include "Makeblock.h"
#include < Arduino.h>
#include < SoftwareSerial.h>
#include < Wire.h>

MeDCMotor MotorL(M1);  
MeDCMotor MotorR(M2);
MeInfraredReceiver infraredReceiverDecode(PORT_6);
MeUltrasonicSensor UltrasonicSensor(PORT_3);
int moveSpeed = 190;
boolean rightflag, autoflag = false;
int distance = 0;
int minSpeed = 55;
int factor = 23;
int randnum = 0;

void setup()
{
    infraredReceiverDecode.begin();
     randomSeed(analogRead(0));
     Serial.begin(9600);
     Serial.println("start");
}

void loop()
{
  
 if(infraredReceiverDecode.buttonState() == 1)
    {
      int ir = infraredReceiverDecode.read();
        switch(ir)
        {
          case IR_BUTTON_PLUS: 
               Forward();
               break;
          case IR_BUTTON_MINUS:
               Backward();
               break;
          case IR_BUTTON_NEXT:
               TurnRight();
               break;
          case IR_BUTTON_PREVIOUS:
               TurnLeft();
               break;
          case IR_BUTTON_9:
               ChangeSpeed(factor*9+minSpeed);
               break;
          case IR_BUTTON_8:
               ChangeSpeed(factor*8+minSpeed);
               break;
          case IR_BUTTON_7:
               ChangeSpeed(factor*7+minSpeed);
               break;
          case IR_BUTTON_6:
               ChangeSpeed(factor*6+minSpeed);
               break;
          case IR_BUTTON_5:
               ChangeSpeed(factor*5+minSpeed);
               break;
          case IR_BUTTON_4:
               ChangeSpeed(factor*4+minSpeed);
               break;
         case IR_BUTTON_3:
               ChangeSpeed(factor*3+minSpeed);
               break;
         case IR_BUTTON_2:
               ChangeSpeed(factor*2+minSpeed);
               break;
         case IR_BUTTON_1:
               ChangeSpeed(factor*1+minSpeed);
               break;
          case IR_BUTTON_MENU:
               AutoMode();
               break;
           default:
       //    Stop();
           break;
        }
    }
    else
    {
      Stop();
    }
}

  

void Forward()
{
  MotorL.run(moveSpeed);
  MotorR.run(moveSpeed);
}
void Backward()
{
  MotorL.run(-moveSpeed);
  MotorR.run(-moveSpeed);
}
void TurnLeft()
{
  MotorL.run(-moveSpeed);
  MotorR.run(moveSpeed);
}
void TurnRight()
{
  MotorL.run(moveSpeed);
  MotorR.run(-moveSpeed);
}
void Stop()
{
  MotorL.run(0);
  MotorR.run(0);
}
void ChangeSpeed(int spd)
{
  moveSpeed = spd;
}
void AutoMode()
{
  
  while(infraredReceiverDecode.read()!=IR_BUTTON_MENU)
    {
       distance = UltrasonicSensor.distanceCm();
  if(distance>2&&distance<40)
  {
    randnum=random(300);
    if(randnum > 150 && !rightflag)
    {
     // leftflag=true;
      TurnLeft();   
    }
    else
    {
      rightflag=true;
      TurnRight();  
    }
  }
  else
  {
      //leftflag=false;
      rightflag=false;
      Forward();
  }
  delay(150);
    }
}

#3

Thank you! I made it work. the menu button brings it to autonomous mode and the return button brings it back (I didn’t get it to work using the menu button for both going forth and back. Doesn’t matter)

My new code is:

#include <Makeblock.h>
#include <Arduino.h>
#include <SoftwareSerial.h>
#include <Wire.h>

MeDCMotor MotorL(M1);
MeDCMotor MotorR(M2);
MeUltrasonicSensor us_front(PORT_3);
MeUltrasonicSensor us_right(PORT_4);
MeInfraredReceiver infraredReceiverDecode(PORT_6);
int moveSpeed = 100;
int turnSpeed = 200;
int minSpeed = 55;
int factor = 23;

int frontDist = 0;
int rightDist = 0;
int randnum = 0;
boolean converge = false;
boolean diverge  = false;
boolean avoidCollision  = false;
int prevRightDist = 20;
int prevFrontDist = 20;
boolean wallTrace = false;


void setup()
{
    randomSeed(analogRead(0));
    infraredReceiverDecode.begin();
    Serial.begin(9600);
}

void loop()
{ 
  if(infraredReceiverDecode.buttonState() == 1)
  {
    switch(infraredReceiverDecode.read())
    {
      case IR_BUTTON_PLUS:
        Forward();
        break;
      case IR_BUTTON_MINUS:
        Backward();
        break;
      case IR_BUTTON_NEXT:
        TurnRight();
        break;
      case IR_BUTTON_PREVIOUS:
        TurnLeft();
        break;
      case IR_BUTTON_9:
        ChangeSpeed(factor*9+minSpeed);
        break;
      case IR_BUTTON_8:
        ChangeSpeed(factor*8+minSpeed);
        break;
      case IR_BUTTON_7:
        ChangeSpeed(factor*7+minSpeed);
        break;
      case IR_BUTTON_6:
        ChangeSpeed(factor*6+minSpeed);
        break;
      case IR_BUTTON_5:
        ChangeSpeed(factor*5+minSpeed);
        break;
      case IR_BUTTON_4:
        ChangeSpeed(factor*4+minSpeed);
        break;
      case IR_BUTTON_3:
        ChangeSpeed(factor*3+minSpeed);
        break;
      case IR_BUTTON_2:
        ChangeSpeed(factor*2+minSpeed);
        break;
      case IR_BUTTON_1:
        ChangeSpeed(factor*1+minSpeed);
        break;
      case IR_BUTTON_MENU:
        wallTrace = true;
        break;
      default:
        //Stop();
        break;
    }
  } else if (!wallTrace)
  {
    Stop();
  }

  if (wallTrace && infraredReceiverDecode.read()!=IR_BUTTON_RETURN) 
  {
    WallTrace();
  } else { wallTrace = false; }
}

void WallTrace()
{
  frontDist = us_front.distanceCm();
  rightDist = us_right.distanceCm();

  if (converge) {
    Forward();
    delay(100);

    if (prevRightDist <= rightDist) {
      TurnRight();
      delay(35);
    }
    
    if (rightDist < 25  || frontDist < 25) {
      converge = false;
    }
  }

  if (diverge) {
    Forward();
    delay(100);
    
    if (prevRightDist >= rightDist) {
      TurnLeft();
      delay(35);
    }

    if (rightDist > 20  || frontDist < 25) {
      diverge = false;
    }
  }

  if (avoidCollision) {
    TurnLeft();
    delay(160);
    avoidCollision = false;
  }

  if (!converge && !diverge && !avoidCollision) {
    if (frontDist > 25) {
      Forward();
    }

    if (frontDist < 25) {
      avoidCollision = true;      
    }

    if (rightDist > 25 && frontDist > 25) {
      converge = true;
    }

    if (rightDist < 20 && frontDist > 25) {
      diverge = true;
    }
  }

  prevRightDist = rightDist;
  prevFrontDist = frontDist;  
}

void Forward()
{
  MotorL.run(-moveSpeed);
  MotorR.run(-moveSpeed);
}
void Backward()
{
  MotorL.run(moveSpeed);
  MotorR.run(moveSpeed);
}
void TurnLeft()
{
  MotorL.run(-turnSpeed);
  MotorR.run(turnSpeed);
}
void TurnRight()
{
  MotorL.run(turnSpeed);
  MotorR.run(-turnSpeed);
}
void Stop()
{
  MotorL.run(0);
  MotorR.run(0);
}
void ChangeSpeed(int spd)
{
  moveSpeed = spd;
}

#4

I just got started with my kit. This is going to be a big help. I will report back. Thanks,


#5

The code works great for the IR control but when I shift back to UltraSonic Sensor mode the robot goes a little wild, in reverse only. I also think I have a damaged or malfunctioning Sensor. I need to check that out,

Dave


#6