Go Down

Topic: Project Need help Integrating two Arduino Codes (Read 996 times) previous topic - next topic

Elijah912

Hey guys,
Im building an object avoidance bot and I mounted two small speakers on it. I want it to play the Mario theme song as it navigates around. Having some trouble integrating the Mario song code to the avoidance code. Just cant get it to work properly. Can anybody help??? Ive been working on this project for a few months now. Almost done! Any help would be greatly appreciated.

Avoidance code:
Code: [Select]
 #define servoPin     12         // Servomotor on pin D12.
 #define pingpin      13         // Ping ultrasonic sensor on pin D13.
 #define redled        9         // 2 drive motors, motor driver SN754410NE
 #define whiteled      8
 
 #define leftSpeedPin   10       // Left motor speed control
 #define leftmotorpin1  5        // Left motor direction 1
 #define leftmotorpin2  6        // Left motor direction 2

 #define rightmotorpin1 3        // Right motor direction 1
 #define rightmotorpin2 4        // Right motor direction 2
 #define rightSpeedPin  11       // Right motor speed control

 #define SERVOCENTER   1500     // Tweak so sensor looks straight ahead.
 #define SERVORIGHT    550      // Servo position when looking right.
 #define SERVOLEFT     2500     // Servo position when looking left.
 int numPulses;                 // Number of pulses to servomotor.
 
void setup() {
 
 pinMode(leftmotorpin1, OUTPUT);        // Set motor pins as outputs.
 pinMode(leftmotorpin2, OUTPUT);
 pinMode(leftSpeedPin, OUTPUT);  
 pinMode(rightmotorpin1, OUTPUT);      
 pinMode(rightmotorpin2, OUTPUT);
 pinMode(rightSpeedPin, OUTPUT);
 pinMode(servoPin, OUTPUT);             // Servomotor as output.
 pinMode(redled, OUTPUT);               // leds as outputs
 pinMode(whiteled, OUTPUT);
 
 centerServo();                         // Centers Servo
 delay(2000);                           // Wait 2 seconds
 
 Serial.begin(115200);
}

void loop() {
 
 int leftDistance, rightDistance, currDist;                   // Distance readings from Ping sensor.
 int dangerlevel = 30;                                        // How far away should things be, before we react?
                                                              // int numPulses;
 
 currDist = readDistance();
 if(currDist > dangerlevel) {
   nodanger();                         // If no danger, drive ahead
 }
 else {
   whichway();                         // If obstacle ahead then decide which way is better
 }
}

 
void nodanger() {                       // Drive forward
 digitalWrite(whiteled, HIGH);
 digitalWrite(redled, LOW);
 analogWrite(leftSpeedPin, 127);       //PWM Speed Control 0 - 255
 analogWrite(rightSpeedPin, 127);
 digitalWrite(leftmotorpin1, HIGH);
 digitalWrite(leftmotorpin2, LOW);
 digitalWrite(rightmotorpin1, HIGH);
 digitalWrite(rightmotorpin2, LOW);
 return;
}  

void whichway() {
 digitalWrite(whiteled, LOW);
 digitalWrite(redled, HIGH);
 totalhalt();                                        // First stop before looking left and right

int leftDistance, rightDistance, currDist;

for (numPulses = 0; numPulses < 20; numPulses++)      // Turn servo left (look left)        
 {
   pulseOut(servoPin, SERVOLEFT);              
   delay(40);
 }
 leftDistance = readDistance();                      // Check distance
 totalhalt();                                        // totalhalt also centers the servo

  for (numPulses = 0; numPulses < 20; numPulses++)   // Turn servo right (look right)
 {
   pulseOut(servoPin, SERVORIGHT);
   delay(40);
 }

 rightDistance = readDistance();                     // Check distance
 totalhalt();                                        // totalhalt also centers the servo

 if(leftDistance > rightDistance) {                  // Choose better direction. Greater space
   body_leftturn();
 }
   else {
   body_rightturn();
 }
 return;
}  

void totalhalt() {
 digitalWrite(whiteled, LOW);
 digitalWrite(redled, HIGH);
 digitalWrite(leftmotorpin1, LOW);
 digitalWrite(leftmotorpin2, LOW);
 digitalWrite(rightmotorpin1, LOW);
 digitalWrite(rightmotorpin2, LOW);
 digitalWrite(leftSpeedPin, LOW);
 digitalWrite(rightSpeedPin, LOW);
 centerServo();
 delay(1000);
}  



void body_leftturn() {
 digitalWrite(whiteled, LOW);
 digitalWrite(redled, HIGH);
 digitalWrite(leftmotorpin1, LOW);
 digitalWrite(leftmotorpin2, HIGH);
 digitalWrite(rightmotorpin1, HIGH);
 digitalWrite(rightmotorpin2, LOW);
 digitalWrite(leftSpeedPin, HIGH);
 digitalWrite(rightSpeedPin, HIGH);
 delay(300);
 totalhalt();
}  

void body_rightturn() {
 digitalWrite(whiteled, LOW);
 digitalWrite(redled, HIGH);
 digitalWrite(leftmotorpin1, HIGH);
 digitalWrite(leftmotorpin2, LOW);
 digitalWrite(rightmotorpin1, LOW);
 digitalWrite(rightmotorpin2, HIGH);
 digitalWrite(leftSpeedPin, HIGH);
 digitalWrite(rightSpeedPin, HIGH);
 delay(300);
 totalhalt();
}

void pulseOut(byte pinNumber, int duration)
{
 digitalWrite(servoPin, HIGH);
 delayMicroseconds(duration);
 digitalWrite(servoPin, LOW);
}

void centerServo()
{
 byte index;
 
 for (index = 0; index < 20; index++)
 {
   pulseOut(servoPin, SERVOCENTER);
   delay(20);
 }}
 
long readDistance() {

 long duration, inches, cm;

 // The Ping is triggered by a HIGH pulse of 2 or more microseconds.
 // We give a short LOW pulse beforehand to ensure a clean HIGH pulse.
 pinMode(pingpin, OUTPUT);
 digitalWrite(pingpin, LOW);
 delayMicroseconds(2);
 digitalWrite(pingpin, HIGH);
 delayMicroseconds(5);
 digitalWrite(pingpin, LOW);

 // The same pin is used to read the signal from the Ping: a HIGH
 // pulse whose duration is the time (in microseconds) from the sending
 // of the ping to the reception of its echo off of an object.
 pinMode(pingpin, INPUT);
 duration = pulseIn(pingpin, HIGH);

 // Convert the time into a distance.
 cm = microsecondsToCentimeters(duration);
 return(cm);
}

long microsecondsToCentimeters(long microseconds)
{
 // The speed of sound is 340 m/s or 29 microseconds per centimeter.
 // The ping travels out and back, so to find the distance of the
 // object we take half of the distance traveled.
 return microseconds / 29 / 2;}  


Elijah912

And here the Mario theme song code:
Code: [Select]
// A fun sketch to demonstrate the use of the Tone library.

// To mix the output of the signals to output to a small speaker (i.e. 8 Ohms or higher),
// simply use 1K Ohm resistors from each output pin and tie them together at the speaker.
// Don't forget to connect the other side of the speaker to ground!

// You can get more RTTTL (RingTone Text Transfer Language) songs from
// http://code.google.com/p/rogue-code/wiki/ToneLibraryDocumentation

#include <Tone.h>

Tone tone1;

#define OCTAVE_OFFSET 0

int notes[] = { 0,
NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4, NOTE_FS4, NOTE_G4, NOTE_GS4, NOTE_A4, NOTE_AS4, NOTE_B4,
NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5,
NOTE_C6, NOTE_CS6, NOTE_D6, NOTE_DS6, NOTE_E6, NOTE_F6, NOTE_FS6, NOTE_G6, NOTE_GS6, NOTE_A6, NOTE_AS6, NOTE_B6,
NOTE_C7, NOTE_CS7, NOTE_D7, NOTE_DS7, NOTE_E7, NOTE_F7, NOTE_FS7, NOTE_G7, NOTE_GS7, NOTE_A7, NOTE_AS7, NOTE_B7
};

//char *song = "The Simpsons:d=4,o=5,b=160:c.6,e6,f#6,8a6,g.6,e6,c6,8a,8f#,8f#,8f#,2g,8p,8p,8f#,8f#,8f#,8g,a#.,8c6,8c6,8c6,c6";
//char *song = "Indiana:d=4,o=5,b=250:e,8p,8f,8g,8p,1c6,8p.,d,8p,8e,1f,p.,g,8p,8a,8b,8p,1f6,p,a,8p,8b,2c6,2d6,2e6,e,8p,8f,8g,8p,1c6,p,d6,8p,8e6,1f.6,g,8p,8g,e.6,8p,d6,8p,8g,e.6,8p,d6,8p,8g,f.6,8p,e6,8p,8d6,2c6";
//char *song = "TakeOnMe:d=4,o=4,b=160:8f#5,8f#5,8f#5,8d5,8p,8b,8p,8e5,8p,8e5,8p,8e5,8g#5,8g#5,8a5,8b5,8a5,8a5,8a5,8e5,8p,8d5,8p,8f#5,8p,8f#5,8p,8f#5,8e5,8e5,8f#5,8e5,8f#5,8f#5,8f#5,8d5,8p,8b,8p,8e5,8p,8e5,8p,8e5,8g#5,8g#5,8a5,8b5,8a5,8a5,8a5,8e5,8p,8d5,8p,8f#5,8p,8f#5,8p,8f#5,8e5,8e5";
//char *song = "Entertainer:d=4,o=5,b=140:8d,8d#,8e,c6,8e,c6,8e,2c.6,8c6,8d6,8d#6,8e6,8c6,8d6,e6,8b,d6,2c6,p,8d,8d#,8e,c6,8e,c6,8e,2c.6,8p,8a,8g,8f#,8a,8c6,e6,8d6,8c6,8a,2d6";
//char *song = "Muppets:d=4,o=5,b=250:c6,c6,a,b,8a,b,g,p,c6,c6,a,8b,8a,8p,g.,p,e,e,g,f,8e,f,8c6,8c,8d,e,8e,8e,8p,8e,g,2p,c6,c6,a,b,8a,b,g,p,c6,c6,a,8b,a,g.,p,e,e,g,f,8e,f,8c6,8c,8d,e,8e,d,8d,c";
//char *song = "Xfiles:d=4,o=5,b=125:e,b,a,b,d6,2b.,1p,e,b,a,b,e6,2b.,1p,g6,f#6,e6,d6,e6,2b.,1p,g6,f#6,e6,d6,f#6,2b.,1p,e,b,a,b,d6,2b.,1p,e,b,a,b,e6,2b.,1p,e6,2b.";
//char *song = "Looney:d=4,o=5,b=140:32p,c6,8f6,8e6,8d6,8c6,a.,8c6,8f6,8e6,8d6,8d#6,e.6,8e6,8e6,8c6,8d6,8c6,8e6,8c6,8d6,8a,8c6,8g,8a#,8a,8f";
//char *song = "20thCenFox:d=16,o=5,b=140:b,8p,b,b,2b,p,c6,32p,b,32p,c6,32p,b,32p,c6,32p,b,8p,b,b,b,32p,b,32p,b,32p,b,32p,b,32p,b,32p,b,32p,g#,32p,a,32p,b,8p,b,b,2b,4p,8e,8g#,8b,1c#6,8f#,8a,8c#6,1e6,8a,8c#6,8e6,1e6,8b,8g#,8a,2b";
//char *song = "Bond:d=4,o=5,b=80:32p,16c#6,32d#6,32d#6,16d#6,8d#6,16c#6,16c#6,16c#6,16c#6,32e6,32e6,16e6,8e6,16d#6,16d#6,16d#6,16c#6,32d#6,32d#6,16d#6,8d#6,16c#6,16c#6,16c#6,16c#6,32e6,32e6,16e6,8e6,16d#6,16d6,16c#6,16c#7,c.7,16g#6,16f#6,g#.6";
//char *song = "MASH:d=8,o=5,b=140:4a,4g,f#,g,p,f#,p,g,p,f#,p,2e.,p,f#,e,4f#,e,f#,p,e,p,4d.,p,f#,4e,d,e,p,d,p,e,p,d,p,2c#.,p,d,c#,4d,c#,d,p,e,p,4f#,p,a,p,4b,a,b,p,a,p,b,p,2a.,4p,a,b,a,4b,a,b,p,2a.,a,4f#,a,b,p,d6,p,4e.6,d6,b,p,a,p,2b";
//char *song = "StarWars:d=4,o=5,b=45:32p,32f#,32f#,32f#,8b.,8f#.6,32e6,32d#6,32c#6,8b.6,16f#.6,32e6,32d#6,32c#6,8b.6,16f#.6,32e6,32d#6,32e6,8c#.6,32f#,32f#,32f#,8b.,8f#.6,32e6,32d#6,32c#6,8b.6,16f#.6,32e6,32d#6,32c#6,8b.6,16f#.6,32e6,32d#6,32e6,8c#6";
//char *song = "GoodBad:d=4,o=5,b=56:32p,32a#,32d#6,32a#,32d#6,8a#.,16f#.,16g#.,d#,32a#,32d#6,32a#,32d#6,8a#.,16f#.,16g#.,c#6,32a#,32d#6,32a#,32d#6,8a#.,16f#.,32f.,32d#.,c#,32a#,32d#6,32a#,32d#6,8a#.,16g#.,d#";
//char *song = "TopGun:d=4,o=4,b=31:32p,16c#,16g#,16g#,32f#,32f,32f#,32f,16d#,16d#,32c#,32d#,16f,32d#,32f,16f#,32f,32c#,16f,d#,16c#,16g#,16g#,32f#,32f,32f#,32f,16d#,16d#,32c#,32d#,16f,32d#,32f,16f#,32f,32c#,g#";
//char *song = "A-Team:d=8,o=5,b=125:4d#6,a#,2d#6,16p,g#,4a#,4d#.,p,16g,16a#,d#6,a#,f6,2d#6,16p,c#.6,16c6,16a#,g#.,2a#";
//char *song = "Flinstones:d=4,o=5,b=40:32p,16f6,16a#,16a#6,32g6,16f6,16a#.,16f6,32d#6,32d6,32d6,32d#6,32f6,16a#,16c6,d6,16f6,16a#.,16a#6,32g6,16f6,16a#.,32f6,32f6,32d#6,32d6,32d6,32d#6,32f6,16a#,16c6,a#,16a6,16d.6,16a#6,32a6,32a6,32g6,32f#6,32a6,8g6,16g6,16c.6,32a6,32a6,32g6,32g6,32f6,32e6,32g6,8f6,16f6,16a#.,16a#6,32g6,16f6,16a#.,16f6,32d#6,32d6,32d6,32d#6,32f6,16a#,16c.6,32d6,32d#6,32f6,16a#,16c.6,32d6,32d#6,32f6,16a#6,16c7,8a#.6";
//char *song = "Jeopardy:d=4,o=6,b=125:c,f,c,f5,c,f,2c,c,f,c,f,a.,8g,8f,8e,8d,8c#,c,f,c,f5,c,f,2c,f.,8d,c,a#5,a5,g5,f5,p,d#,g#,d#,g#5,d#,g#,2d#,d#,g#,d#,g#,c.7,8a#,8g#,8g,8f,8e,d#,g#,d#,g#5,d#,g#,2d#,g#.,8f,d#,c#,c,p,a#5,p,g#.5,d#,g#";
//char *song = "Gadget:d=16,o=5,b=50:32d#,32f,32f#,32g#,a#,f#,a,f,g#,f#,32d#,32f,32f#,32g#,a#,d#6,4d6,32d#,32f,32f#,32g#,a#,f#,a,f,g#,f#,8d#";
//char *song = "Smurfs:d=32,o=5,b=200:4c#6,16p,4f#6,p,16c#6,p,8d#6,p,8b,p,4g#,16p,4c#6,p,16a#,p,8f#,p,8a#,p,4g#,4p,g#,p,a#,p,b,p,c6,p,4c#6,16p,4f#6,p,16c#6,p,8d#6,p,8b,p,4g#,16p,4c#6,p,16a#,p,8b,p,8f,p,4f#";
//char *song = "MahnaMahna:d=16,o=6,b=125:c#,c.,b5,8a#.5,8f.,4g#,a#,g.,4d#,8p,c#,c.,b5,8a#.5,8f.,g#.,8a#.,4g,8p,c#,c.,b5,8a#.5,8f.,4g#,f,g.,8d#.,f,g.,8d#.,f,8g,8d#.,f,8g,d#,8c,a#5,8d#.,8d#.,4d#,8d#.";
//char *song = "LeisureSuit:d=16,o=6,b=56:f.5,f#.5,g.5,g#5,32a#5,f5,g#.5,a#.5,32f5,g#5,32a#5,g#5,8c#.,a#5,32c#,a5,a#.5,c#.,32a5,a#5,32c#,d#,8e,c#.,f.,f.,f.,f.,f,32e,d#,8d,a#.5,e,32f,e,32f,c#,d#.,c#";
char *song = "smb:d=4,o=5,b=100:16e6,16e6,32p,8e6,16c6,8e6,8g6,8p,8g,8p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,16p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16c7,16p,16c7,16c7,p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16d#6,8p,16d6,8p,16c6";

void setup(void)
{
  Serial.begin(9600);
  tone1.begin(2);
}

#define isdigit(n) (n >= '0' && n <= '9')

void play_rtttl(char *p)
{
  // Absolutely no error checking in here

  byte default_dur = 4;
  byte default_oct = 6;
  int bpm = 63;
  int num;
  long wholenote;
  long duration;
  byte note;
  byte scale;

  // format: d=N,o=N,b=NNN:
  // find the start (skip name, etc)

  while(*p != ':') p++;    // ignore name
  p++;                     // skip ':'

  // get default duration
  if(*p == 'd')
  {
    p++; p++;              // skip "d="
    num = 0;
    while(isdigit(*p))
    {
      num = (num * 10) + (*p++ - '0');
    }
    if(num > 0) default_dur = num;
    p++;                   // skip comma
  }

  Serial.print("ddur: "); Serial.println(default_dur, 10);

  // get default octave
  if(*p == 'o')
  {
    p++; p++;              // skip "o="
    num = *p++ - '0';
    if(num >= 3 && num <=7) default_oct = num;
    p++;                   // skip comma
  }

  Serial.print("doct: "); Serial.println(default_oct, 10);

  // get BPM
  if(*p == 'b')
  {
    p++; p++;              // skip "b="
    num = 0;
    while(isdigit(*p))
    {
      num = (num * 10) + (*p++ - '0');
    }
    bpm = num;
    p++;                   // skip colon
  }

  Serial.print("bpm: "); Serial.println(bpm, 10);

  // BPM usually expresses the number of quarter notes per minute
  wholenote = (60 * 1000L / bpm) * 4;  // this is the time for whole note (in milliseconds)

  Serial.print("wn: "); Serial.println(wholenote, 10);


  // now begin note loop
  while(*p)
  {
    // first, get note duration, if available
    num = 0;
    while(isdigit(*p))
    {
      num = (num * 10) + (*p++ - '0');
    }
   
    if(num) duration = wholenote / num;
    else duration = wholenote / default_dur;  // we will need to check if we are a dotted note after

    // now get the note
    note = 0;

    switch(*p)
    {
      case 'c':
        note = 1;
        break;
      case 'd':
        note = 3;
        break;
      case 'e':
        note = 5;
        break;
      case 'f':
        note = 6;
        break;
      case 'g':
        note = 8;
        break;
      case 'a':
        note = 10;
        break;
      case 'b':
        note = 12;
        break;
      case 'p':
      default:
        note = 0;
    }
    p++;

    // now, get optional '#' sharp
    if(*p == '#')
    {
      note++;
      p++;
    }

    // now, get optional '.' dotted note
    if(*p == '.')
    {
      duration += duration/2;
      p++;
    }
 
    // now, get scale
    if(isdigit(*p))
    {
      scale = *p - '0';
      p++;
    }
    else
    {
      scale = default_oct;
    }

    scale += OCTAVE_OFFSET;

    if(*p == ',')
      p++;       // skip comma for next note (or we may be at the end)

    // now play the note

    if(note)
    {
      Serial.print("Playing: ");
      Serial.print(scale, 10); Serial.print(' ');
      Serial.print(note, 10); Serial.print(" (");
      Serial.print(notes[(scale - 4) * 12 + note], 10);
      Serial.print(") ");
      Serial.println(duration, 10);
      tone1.play(notes[(scale - 4) * 12 + note]);
      delay(duration);
      tone1.stop();
    }
    else
    {
      Serial.print("Pausing: ");
      Serial.println(duration, 10);
      delay(duration);
    }
  }
}

void loop(void)
{
  play_rtttl(song);
  Serial.println("Done.");
  while(1);
}


Korman

Ok, first the good news: You need to change on your hardware setup one thing to be able to integrate the two programs. At the moment you use pin 10 and pin 11 with analogWrite(). This is a little unfortunate, as pin 10 is linked to Timer1 and pin 11 to timer 2. Timer 2 is used by the Tone library so you create a conflict. If you need 2 pins for analogWrite(), you should make sure to use the pins connected to the same timers so you keep as many timers as possible available for other uses. I would suggest to use pins 5 and 6 for left and right motor speed, those are linked to timer 0 and work safely together with the timer interrupt.

Now the less so good news: You need to rewrite both programs so that the don't use the delay() function and do any waiting inside the loop() function by checking the elapses time for various timers. The tutorial to look at is "Blink without Delay". You can leave any delay() call in setup, nobody cares about those. You also need to get rid of loops inside your functions which takes a lot of time and do this piecewise from loop(). A prime suspect for those are the functions driving your servo. You probably can leave in the calls to delayMicroseconds and pulseIn, the pulseOut for the servo is probably a bad idea, but you need to check that. If the song has unwanted pauses between notes, that's the place to check.

Once you have rewritten both programs this way, the rest will be easy. Merge both files, merge the setup() and loop() functions, check if you don't have conflicting variables and defines and you're done.

Korman

Elijah912

Thanks alot.. Ive decided that the song was too much to incorporate, now Im fine with incorporating a single beep sound when it detects an object. any idea on how i can do this?? thanks again

Elijah912

here a good beep code that i wud like to incorporate:
Code: [Select]
#include <Tone.h>
Tone tone1;

void setup()
{
  tone1.begin(2);//Playback on Pin 11, change to whatever you may need
  tone1.play(660,200);
}

void loop()
{


}

Korman

Just add the line
Code: [Select]
tone1.play(660,200);
whenever you feel a beep is in order. If you cleaned up the part with the motors speed control pins, it will work.

Korman

Elijah912

I have a question. my code works fine most of the time but sometimes the bot stops and acts like theres an object within its "dangerzone" and looks for a better path when there is no object there... is this from the ping returning false values sometimes?? any ideas why??

bilbo

Can we get any more details about your robot? While it is most likely a software issue, To be sure about a problem, more info is needed.
Alice asked the Chesire Cat, who was sitting in a tree, "What road do I take?"
The cat asked, "Where do you want to go?"
"I don't know," Ali

bill2009

asked and answered here http://arduino.cc/forum/index.php/topic,58378.0.html

Go Up