So for this project I'm making a small unit with an IR sensor (digital output) and two end stops. It runs a motor through an L293D chip. The idea is that when the sensor detects something within its FOV it reads LOW and causes a motor to turn in a random direction, making the unit move left or right at random. However if the unit reaches its extreme left it triggers the endstop and the direction is no longer random but to the right and vice versa for the right trigger.
I thought I had the code pretty close however testing has shown otherwise, any help would be greatly appreciated!
Also as a side note I'm thinking of getting it to play a simplified tune through a buzzer only when it senses something. there's some projects I can take inspiration from for the actual code however what's the feasibility of running those two functions (motion and sound) at the same time and how would I go about doing so? I understand I'll probably need to use a clock update system.
Any help would be greatly appreciated, I've been in a rut for weeks! Thanks!
/*************** INTERACTIVE WINDOW DISPLAY ***************/
// The circuit is placed within a mirror in a shop window //
// It uses an Arduino Uno, L293D motor controller, //
// 2 microswitches, low V DC bidirectional motor and an //
// IR distance sensor with digital output //
// //
// This program will check the IR sensor and if it //
// receives a HIGH return it checks both the end switches //
// (NO) before deciding how to move. //
// Controller pins: Enable, L1, L2 //
// Enable is power override, L1&2 choose direction //
/************************************************************/
/******************** GLOBAL CONTROLS ***********************/
// Pin declarations
int leftTrigger = 7;
int rightTrigger = 5;
int IR = 6;
int enable = 11;
int leftSpin = 10;
int rightSpin = 9;
// Control declarations
int IRval; //Value from IR sensor
int lVal; //Value from Left trigger
int rVal; //Value from Right trigger
boolean drctn; //Left or right (chip control)
int velocity = 255; //Motor speed control
int off = 0; //Easy-read off
boolean left = true; //(chip control)
boolean right = false; //(chip control)
int rnd; //Holds random value
/********************* CIRCUIT SETUP ************************/
void setup() {
// Declaring pin uses
pinMode(leftTrigger,INPUT);
pinMode(rightTrigger, INPUT);
pinMode(IR, INPUT);
pinMode(leftSpin, OUTPUT);
pinMode(rightSpin, OUTPUT);
pinMode(enable, OUTPUT);
}
void loop(){
/*********************** RANDOMISER ************************/
// Uses a larger range for better randomisation.
rnd = random(0, 1000);
drctn = right; //default case
if (rnd <= 500){drctn = left;} //option 2
/********************** MAIN CODE **************************/
//First we read the IR state
while (digitalRead(IR) == LOW){
if (digitalRead(leftTrigger) == HIGH){setMotor(velocity, right);}
if (digitalRead(rightTrigger) == HIGH){setMotor(velocity, left);}
else{setMotor(velocity, drctn);}
}
setMotor(off,left);
}
/**************** motor control function ******************/
void setMotor(int power, boolean direct){
analogWrite(enable, power);
digitalWrite(leftSpin, direct);
digitalWrite(rightSpin, !direct);
}
while (digitalRead(IR) == LOW) {
if (digitalRead(leftTrigger) == HIGH) {
setMotor(velocity, right);
}
if (digitalRead(rightTrigger) == HIGH) {
setMotor(velocity, left);
}
else {
setMotor(velocity, drctn);
}
}
setMotor(off, left);
If the random direction was 'left' and you hit the left endstop the direction will change to 'right' ONLY UNTIL YOUARE NO LONGER HITTING THE LEFT ENDSTOP. As soon as you move right far enough to clear the left endstop the direction will switch back to 'left' and you will hit the left endstop almost immediately.
You want to keep going right after you hit the left endstop, until either you hit the right endstop or the object goes out of range.
while (digitalRead(IR) == LOW) {
if (digitalRead(leftTrigger) == HIGH) {
drctn = right;
}
if (digitalRead(rightTrigger) == HIGH) {
drctn = left;
}
setMotor(velocity, drctn);
}
setMotor(off, left);
Hi John , I see what you mean, thanks for pointing it out! I've made that change and have a better understanding of what's actually happening now! I'm having a large amount of bias in the randomisation process, do you have any suggestions on how to improve that?
Thanks for the help 
Try putting a switch in place of the IR sensor for testing. Then you can see what direction is chosen each time you change the input from HIGH to LOW. Keep a count of each direction to see how biased it is.
I've replaced the motor with two LEDs in opposite directions for testing, seems occasionally I'm getting current from both directions.
SJMaybury:
I've replaced the motor with two LEDs in opposite directions for testing, seems occasionally I'm getting current from both directions.
You can't be getting current simultaneously from both directions so I suspect it is rapidly switching back and forth. Post your new sketch and maybe someone can spot why that might be happening. My first guess would be that both endstops are active at the same time.
Are you sure you have a pull-up or pull-down on every input pin? Floating (unconnected inputs can cause some wild behavior. Since you are not using the internal pull-ups (INPUT_PULLUP) you have to add an external resistor to each input pin.
I've upgraded every input to a pulp and heres the code:
/*************** INTERACTIVE WINDOW DISPLAY ***************/
/* The circuit is placed within a mirror in a shop window
It uses an Arduino Uno, L293D motor controller,
2 microswitches, low V DC bidirectional motor and an
IR distance sensor with digital output
This program will check the IR sensor and if it
receives a LOW return it checks both the end switches
(NO) before deciding how to move.
Controller pins: Enable, L1, L2
Enable is power override, L1&2 choose direction */
/************************************************************/
/******************** GLOBAL CONTROLS ***********************/
// Pin declarations
int leftTrigger = 7;
int rightTrigger = 5;
int IR = 6;
int enable = 11;
int leftSpin = 10;
int rightSpin = 9;
// Control declarations
int IRval; //Value from IR sensor
int lVal; //Value from Left trigger
int rVal; //Value from Right trigger
boolean drctn; //Left or right (chip control)
int velocity = 255; //Motor speed control
int off = 0; //Easy-read off
boolean left = true; //(chip control)
boolean right = false; //(chip control)
int rnd; //Holds random value
/********************* CIRCUIT SETUP ************************/
void setup() {
// Declaring pin uses
pinMode(leftTrigger,INPUT_PULLUP);
pinMode(rightTrigger, INPUT_PULLUP);
pinMode(IR, INPUT_PULLUP);
pinMode(leftSpin, OUTPUT);
pinMode(rightSpin, OUTPUT);
pinMode(enable, OUTPUT);
}
void loop(){
/*********************** RANDOMISER ************************/
// Uses a larger range for better randomisation.
rnd = random(0, 1000);
drctn = right; //default case
if (rnd <= 500){drctn = left;} //option 2
/********************** MAIN CODE **************************/
//First we read the IR state
while (digitalRead(IR) == LOW){
if (digitalRead(leftTrigger) == HIGH){drctn = right;}//{setMotor(velocity, right);}
if (digitalRead(rightTrigger) == HIGH){drctn = left;}//{setMotor(velocity, left);}
setMotor(velocity, drctn); //Credit: JW
}
setMotor(off,left);
}
/**************** motor control function ******************/
void setMotor(int power, boolean direct){
analogWrite(enable, power);
digitalWrite(leftSpin, direct);
digitalWrite(rightSpin, !direct);
}
/*********************** Credit **************************/
/* Credit is due to:
* -johnwasser on the Arduino forums for advice
*/
I'm noticing that theres an ~100% bias to the right on the randomiser (I've run 50 tests with no change) and when the IR is triggered heading right the right endstop causes movement to the left FOR THE DURATION of press now.
Hi!
With the help of my dad (who's a spectacular engineer) I've managed to get it working!!!!!!!!!!!
/*************** INTERACTIVE WINDOW DISPLAY ***************/
/* The circuit is placed within a mirror in a shop window
It uses an Arduino Uno, L293D motor controller,
2 microswitches, low V DC bidirectional motor and an
IR distance sensor with digital output
This program will check the IR sensor and if it
receives a LOW return it checks both the end switches
(NO) before deciding how to move.
Controller pins: Enable, L1, L2
Enable is power override, L1&2 choose direction */
/************************************************************/
/******************** GLOBAL CONTROLS ***********************/
// Pin declarations
int leftTrigger = 7;
int rightTrigger = 5;
int IR = 6;
int enable = 11;
int leftSpin = 10;
int rightSpin = 9;
// Control declarations
int IRval; //Value from IR sensor
int lVal; //Value from Left trigger
int rVal; //Value from Right trigger
boolean drctn; //Left or right (chip control)
int velocity = 255; //Motor speed control
int off = 0; //Easy-read off
boolean left = true; //(chip control)
boolean right = false; //(chip control)
int rnd; //Holds random value
/********************* CIRCUIT SETUP ************************/
void setup() {
// Declaring pin uses
pinMode(leftTrigger,INPUT_PULLUP);
pinMode(rightTrigger, INPUT_PULLUP);
pinMode(IR, INPUT_PULLUP);
pinMode(leftSpin, OUTPUT);
pinMode(rightSpin, OUTPUT);
pinMode(enable, OUTPUT);
}
void loop(){
/*********************** RANDOMISER ************************/
// Uses a larger range for better randomisation.
rnd = random(0, 1000);
drctn = right; //default case
if (rnd <= 500){drctn = left;} //option 2
/********************** MAIN CODE **************************/
//First we read the IR state
while (digitalRead(IR) == LOW){
if (digitalRead(leftTrigger) == HIGH){drctn = right;}//{setMotor(velocity, right);}
if (digitalRead(rightTrigger) == HIGH){drctn = left;}//{setMotor(velocity, left);}
setMotor(velocity, drctn); //Credit: JW
}
setMotor(off,left);
}
/**************** motor control function ******************/
void setMotor(int power, boolean direct){
analogWrite(enable, power);
digitalWrite(leftSpin, direct);
digitalWrite(rightSpin, !direct);
}
/*********************** Credit **************************/
/* Credit is due to:
* -johnwasser on the Arduino forums for advice
*/
There was something odd going on with the switches so with some tinkering and the debugs to guide it's now working!!
Thanks for all the help! 