combining 3 codes

Hello. I am doing a robotics project in which I build a robot that uses a sensor to detect an object (in this case, trash). The robot will first move a certain distance using DC motors. As it drives toward the object, the sensor will detect the object, and the buzzer will buzz. After that, the two servo motors at the front that have two sticks that will move via the servo motors. I have the DC motor codes, the ultrasonic and buzzer codes, and the two servo codes that I'm using. I'll also be testing a PIR sensor later on once I find a code for it. My main question is, how will I combine the first three code mentioned so the robot can work altogether? I'm not really sure where to start.

the DC motors code:

/**
* Bruno Santos, 2013
* feiticeir0@whatgeek.com.pt
* Small code to test DC motors - 2x with a L298 Dual H-Bridge Motor Driver
* Free to share
**/

//Testing the DC Motors with
// L293D

//Define Pins
//Motor A
int enableA = 5;
int MotorA1 = 6;
int MotorA2 = 7;
 
//Motor B
int enableB = 8;
int MotorB1 = 9;
int MotorB2 = 10;

void setup() {
  Serial.begin (9600);
  //configure pin modes
  pinMode (enableA, OUTPUT);
  pinMode (MotorA1, OUTPUT);
  pinMode (MotorA2, OUTPUT);  
  
  pinMode (enableB, OUTPUT);
  pinMode (MotorB1, OUTPUT);
  pinMode (MotorB2, OUTPUT);   
}

void loop() {
  //enabling motor A
  Serial.println ("Enabling Motors");
  digitalWrite (enableA, HIGH);
  digitalWrite (enableB, HIGH);
  delay (1000);
  //do something

  Serial.println ("Motion Forward");
  digitalWrite (MotorA1, LOW);
  digitalWrite (MotorA2, HIGH);

  digitalWrite (MotorB1, LOW);
  digitalWrite (MotorB2, HIGH);

  //9s forward
  delay (9000);
  
  Serial.println ("Motion Backwards");
  //reverse
  digitalWrite (MotorA1,HIGH);
  digitalWrite (MotorA2,LOW);  
  
  digitalWrite (MotorB1,HIGH);
  digitalWrite (MotorB2,LOW);  

  Serial.println ("Stoping motors");
  //stop
  digitalWrite (enableA, LOW);
  digitalWrite (enableB, LOW);
  delay(9000);  
  
  //9s backwards
  delay(9000);
  
}

The ultrasonic sensor and buzzer code:

/*
	This code should work to get warning cross the buzzer when something be closer than 0.5 meter
	Circuit is ultrasonic sensor and buzzer +5v and Arduino uno is used
	a_atef45@yahoo.com
	www.zerosnones.net
	+201153300223
*/
// Define pins for ultrasonic and buzzer
int const trigPin = 12;
int const echoPin = 11;
int const buzzPin = 2;

void setup()
{
	pinMode(trigPin, OUTPUT); // trig pin will have pulses output
	pinMode(echoPin, INPUT); // echo pin should be input to get pulse width
	pinMode(buzzPin, OUTPUT); // buzz pin is output to control buzzering
}

void loop()
{
	// Duration will be the input pulse width and distance will be the distance to the obstacle in centimeters
	int duration, distance;
	// Output pulse with 1ms width on trigPin
	digitalWrite(trigPin, HIGH); 
	delay(1);
	digitalWrite(trigPin, LOW);
	// Measure the pulse input in echo pin
	duration = pulseIn(echoPin, HIGH);
	// Distance is half the duration devided by 29.1 (from datasheet)
	distance = (duration/2) / 29.1;
	// if distance less than 0.5 meter and more than 0 (0 or less means over range) 
    if (distance <= 50 && distance >= 0) {
    	// Buzz
    	digitalWrite(buzzPin, HIGH);
    } else {
    	// Don't buzz
    	digitalWrite(buzzPin, LOW);
    }
    // Waiting 60 ms won't hurt any one
    delay(60);
}

and the two servos code:

#include <Servo.h>

Servo servoLeft;          // Define left servo
Servo servoRight;         // Define right servo

void setup() { 
  servoLeft.attach(10);  // Set left servo to digital pin 10
  servoRight.attach(9);  // Set right servo to digital pin 9
} 

void loop() {            // Loop through motion tests
  forward();             // Example: move forward
  delay(2000);           // Wait 2000 milliseconds (2 seconds)
  reverse();
  delay(2000);
  stopRobot();
  delay(2000);
}

// Motion routines for forward, reverse, turns, and stop
void forward() {
  servoLeft.write(0);
  servoRight.write(180);
}

void reverse() {
  servoLeft.write(180);
  servoRight.write(0);
}

void stopRobot() {
  servoLeft.write(90);
  servoRight.write(90);
}

I know this is a lot of code to go through, but any help on this would be greatly appreciated. Thank you.

Hi,

Combining Arduino Sketches
This is often difficult. Here is an approach that may help you be successful:

http://arduino-info.wikispaces.com/CombiningArduinoSketches

Write a fourth sketch containing the top layer of your completed sketch - the overall behaviour of what you want your robot to do. This sketch will reference functions that haven't been written yet - give them meaningful names: "sound_buzzer", "get_distance", "start moving forward".

You then pull the code out of the other sketches to implement those functions.

To test that top layer, you can implement the underlying functions as just prints to serial and button reads.

For instance, the top layer might be:

void loop() {
  if(i_am_moving() && need_to_stop_moving()) {
    stop_moving();
  }
  else if(!i_am_moving() && need_to_start_moving()) {
    start_moving();
  }
}

the start_moving function will eventually be replaced by something that writes to the servos, but for testing you'd just write

void start_moving() {
  Serial.println("START MOVING");
}

likewise, need_to_start_moving() will eventually read the ultrasound, but for testing you'd just attach a pushbutton to the arduino

boolean need_to_start_moving() {
  return digitalRead(5) == LOW; // for testing
}

You can then test that top layer, the overall logic, by pressing buttons and seeing that the stuff that should get printed out gets printed.

Once that does what it should, you can put in the other bits. These can be tested independently. For instance

boolean need_to_start_moving() {
#ifdef SIMULATE_PIR
  return digitalRead(5) == LOW; // for testing
#else
  // do stuff here to read the PIR and calculate
#endif
}

This allows you to sub in the test pushbutton for the real PIR code, so that you can test the servo on/off code in an isolated way.

That kind of thing.

Build the code in steps. Build it in such a way that the steps can be tested. And don't think in terms of "combining sketches". You don't buy a plane and a boat and attempt to assemble a seaplane from the parts - you design a seaplane. Of course, once you get down to individual bits (eg: the engine) it's just a matter of swapping in the parts you need, but the approach is to start with the idea of a seaplane, then drill down to the components - not the other way around.

Will it be easier if I don't combine the code with the servos in it?

Yes. Do most of the work without the actual robot connected and powered up. It's too easy to type the wrong thing and have it drive off your desk and crash to the floor.

Thank you. When I combined the code for the DC motors and the ultrasonic sensor with the buzzer, it verified, but I want to know if I'll have to remove the delays in the code. This is the code so far:

/*
UltraRobot
the wheels, ultrasonic sensor, and buzzer
*/

//Define Pins
//Motor A
int enableA = 5;
int MotorA1 = 6;
int MotorA2 = 7;
 
//Motor B
int enableB = 8;
int MotorB1 = 9;
int MotorB2 = 10;

// Define pins for ultrasonic and buzzer
int const trigPin = 12;
int const echoPin = 11;
int const buzzPin = 2; 
int duration, distance;

void setup() {
Serial.begin (9600);
//configure pin modes
pinMode (enableA, OUTPUT);
pinMode (MotorA1, OUTPUT);
pinMode (MotorA2, OUTPUT);  
  
pinMode (enableB, OUTPUT);
pinMode (MotorB1, OUTPUT);
pinMode (MotorB2, OUTPUT); 
  
pinMode(trigPin, OUTPUT); // trig pin will have pulses output
pinMode(echoPin, INPUT); // echo pin should be input to get pulse width
pinMode(buzzPin, OUTPUT); // buzz pin is output to control buzzering
}

void loop() {
  //enabling motor A
  Serial.println ("Enabling Motors");
  digitalWrite (enableA, HIGH);
  digitalWrite (enableB, HIGH);
  delay (1000);
  //do something

  Serial.println ("Motion Forward");
  digitalWrite (MotorA1, LOW);
  digitalWrite (MotorA2, HIGH);

  digitalWrite (MotorB1, LOW);
  digitalWrite (MotorB2, HIGH);

  //9s forward
  delay (9000);
  
  Serial.println ("Motion Backwards");
  //reverse
  digitalWrite (MotorA1,HIGH);
  digitalWrite (MotorA2,LOW);  
  
  digitalWrite (MotorB1,HIGH);
  digitalWrite (MotorB2,LOW);  

  Serial.println ("Stoping motors");
  //stop
  digitalWrite (enableA, LOW);
  digitalWrite (enableB, LOW);
  delay(9000);  
  
  //9s backwards
  delay(9000);
  
  // Duration will be the input pulse width and distance will be the distance to the obstacle in centimeters
	// Output pulse with 1ms width on trigPin
	digitalWrite(trigPin, HIGH); 
	delay(1);
	digitalWrite(trigPin, LOW);
	// Measure the pulse input in echo pin
	duration = pulseIn(echoPin, HIGH);
	// Distance is half the duration devided by 29.1 (from datasheet)
	distance = (duration/2) / 29.1;
	// if distance less than 0.5 meter and more than 0 (0 or less means over range) 
    if (distance <= 50 && distance >= 0) {
    	// Buzz
    	digitalWrite(buzzPin, HIGH);
    } else {
    	// Don't buzz
    	digitalWrite(buzzPin, LOW);
    }
    // Waiting 60 ms won't hurt any one
    delay(60);
}

Next BIG lesson is to explore STATE MACHINES.

The linear way you've programmed your example will inevitably end in tears.
delay() is bad as we all know, but to make your robot aware & responsive in real-time, you MUST do away with them.

In this case your millis() timing should be performed at a very high level - so the low-level functions can operate 'almost transparently' and the functions just appear to happen by themselves.

(I have a project that does a 'lot' 24x7 - and uses more than 30 concurrent millis() timers so that different parts of the system just do what they have to do - when they have to do it.)

e.g. Simple example - your states could be

STOPPED
FORWARD
BACKWARD
TURN_LEFT
TURN_RIGHT
DO_BUZZER
STICKS_MID
STICKS_LEFT
STICKS_RIGHT
Many of these can equate to functions() within your code.

Your state machine can perform one function and depending on the sensors, jump between each and other states as each sensor/operating mode is triggered. Often states are stepped through sequentially for simplicity, but there is no hard rule - and for example in collision situations, you may need to jump from turning to STOP immediately.

An extension of this is if you need to buzz, or move the sticks while moving...
You may need to implement TWO (or more) state variables - so the sticks can be triggered WHILE the chassis is moving.
Similarly, you may choose to put combined sensor states into yet another state - to identify when it is clear to activate the sticks, or turn (i.e. when there is nothing off to the side of the chassis.

MorganS:
Yes. Do most of the work without the actual robot connected and powered up. It's too easy to type the wrong thing and have it drive off your desk and crash to the floor.

I sit my robots up on some blocks and let it spin its wheels. weeeeeeeeeee...
Tom..... :slight_smile:

@Tom...
Did you really mean ‘Wheee’?
The other one is corrosive!

If I included the two servos (that move the sticks to collect the trash), would "turn right" and "turn left" be considered good state functions for the servos?

Only OP can tell.
It depends on the mechanism and purpose of your robot.

The way I read the original post, the sticks operate independently of the transport chassis ...

ok then, I'll use two codes for the robot then. Would replacing the Serial.printIn with "FORWARD" work?

OP, I think you're oversimplifying this.

Your device is a 'system' that involves a platform, sensors (IR, switches etc), and actuators (motors, sticks etc).
These are implemented by hardware, and coordinated with software.

As many have said elsewhere in these forums, don't try to do everything at once.

  • Develop your hardware/chassis (no software yet).
  • Planning the power supply becomes important about now
  • Start thinking about 'functions'
  • Develop your sensors (only software to determine they work - put them into functions)
  • Develop your motion platform (only software to determine they work - put them into functions)

Then. develop your operating strategy (no sensors or chassis yet!). just Serial.print()s and blinking LEDs
Slowly start to pull them together by combining the sensor & motion functions into a container program.

There is a lot more to this - and it can be extended infinitely, but to perform the very simplest actions - the above is a good starting point.

lastchancename:

  • Develop your hardware/chassis (no software yet).
  • Planning the power supply becomes important about now
  • Start thinking about 'functions'
  • Develop your sensors (only software to determine they work - put them into functions)
  • Develop your motion platform (only software to determine they work - put them into functions)

Then. develop your operating strategy (no sensors or chassis yet!). just Serial.print()s and blinking LEDs
Slowly start to pull them together by combining the sensor & motion functions into a container program.

Okay, I'll work on the project in steps. Thank you.

  1. the chassis is developed and connected and works on its own.
  2. I asked about how I would power the DC motors and servo motors in another forum, and the person said I should use 4x D cells to power them.
  3. I guess possible functions would be "forward" and "backward"
  4. One of the sensors I'm using, ultrasonic, works
  5. Would do you mean by "motion platform"?
  1. So no STOP then? No turns planned in the future?

  2. The thing which moves. That's the motion platform. It doesn't move just to demonstrate moving - it should do something. So the motion is just a platform to build the 'something' upon.

MorganS:
3. So no STOP then? No turns planned in the future?

I meant those as just examples. I'll still have more functions.

For sketches made out of a number of interdependent things, I like to use classes and objects. It allows you to build and test small things that work. I have a webpage where I run through an example of how I like to do this.