commander un buzzer et un servo avec un seul bouton

salut tout le monde!
je suis debutant en arduino et je souhaiterais lancer une melodie a l'aide d'un buzzer en pressant sur un bouton ,
une fois la medolie lancée, le servo doit faire un quart de tour.
a priori rien de compliqué mais quand je lance le programme , seule la melodie se met en route , le servo lui ne bouge pas , si je supprime la melodie le servo fonctionne, donc je n'arrive pas a associer les deux
merci pour vos reponses
voici le code du loop:

void loop(void)
{
b1=digitalRead(BP1);
// si appuie BP1
if (b1 == HIGH){
play_rtttl(song);
Serial.println("Done.");
while(1);
servo.write(position);
position = position + 30;
delay(10);
}
}

code en entier:

#include <Servo.h>
#define BP1 4
int position=0;
int b1=0;
Servo servo;

#define OCTAVE_OFFSET 0
#define TONE_PIN 8

#define NOTE_C4 262
#define NOTE_CS4 277
#define NOTE_D4 294
#define NOTE_DS4 311
#define NOTE_E4 330
#define NOTE_F4 349
#define NOTE_FS4 370
#define NOTE_G4 392
#define NOTE_GS4 415
#define NOTE_A4 440
#define NOTE_AS4 466
#define NOTE_B4 494
#define NOTE_C5 523
#define NOTE_CS5 554
#define NOTE_D5 587
#define NOTE_DS5 622
#define NOTE_E5 659
#define NOTE_F5 698
#define NOTE_FS5 740
#define NOTE_G5 784
#define NOTE_GS5 831
#define NOTE_A5 880
#define NOTE_AS5 932
#define NOTE_B5 988
#define NOTE_C6 1047
#define NOTE_CS6 1109
#define NOTE_D6 1175
#define NOTE_DS6 1245
#define NOTE_E6 1319
#define NOTE_F6 1397
#define NOTE_FS6 1480
#define NOTE_G6 1568
#define NOTE_GS6 1661
#define NOTE_A6 1760
#define NOTE_AS6 1865
#define NOTE_B6 1976
#define NOTE_C7 2093
#define NOTE_CS7 2217
#define NOTE_D7 2349
#define NOTE_DS7 2489
#define NOTE_E7 2637
#define NOTE_F7 2794
#define NOTE_FS7 2960
#define NOTE_G7 3136
#define NOTE_GS7 3322
#define NOTE_A7 3520
#define NOTE_AS7 3729
#define NOTE_B7 3951

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 = "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";

void setup(void)
{
// bouton 1
pinMode(BP1,INPUT_PULLUP);

//attache le servomoteur a la broche 5
servo.attach(5); //
servo.write(0);
Serial.begin(9600);
}

#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);
tone(TONE_PIN, notes[(scale - 4) * 12 + note]);
delay(duration);
noTone(TONE_PIN);
}
else
{
Serial.print("Pausing: ");
Serial.println(duration, 10);
delay(duration);
}
}
}

void loop(void)
{
b1=digitalRead(BP1);
// si appuie BP1
if (b1 == HIGH){
play_rtttl(song);
Serial.println("Done.");
while(1);
servo.write(position);
position = position + 30;
delay(10);

}

}

Pour avoir plus de réponses et pour ne pas se voir mis de côté, il ne faut pas seulement lire Faire un Nouveau Sujet ou le corriger avec les Balises, mais aussi l'appliquer.

Bon maintenant le

while(1);

est une instruction qui boucle infiniment sur elle même et tout ce qu'il y a derrière ne sera jamais exécuté

Dans ton code, le servo va tourner une fois la mélodie terminée, non pas une fois la mélodie lancée...

Dans ton code, le servo va tourner une fois la mélodie terminée, non pas une fois la mélodie lancée...

Oui, si on enlève le while(1).

Et si on inverse l'ordre mélodie et servo, le servo va tourner et la musique vont commencer quasi en même temps. Pour la machine, le servo commence à tourner puis la mélodie commence. Pour l'homme, les deux démarrent en même temps, et cela correspond au fonctionnement demandé.

deja merci a tous de vos reponse
j'ai deja essayé d'nlever le while(1) mais rien ne change
j'ai egalement mis l'action du servo en premier mais le servo ne se lance jamais meme apres la melodie
voici ce que j'ai essayé mais sans succes

void loop(void)
{
b1=digitalRead(BP1);
// si appuie BP1
if (b1 == HIGH){
servo.write(position);
position = position + 30;
delay(10);
play_rtttl(song);
}
}

Si ton bouton est bien branché en INPUT_PULLUP comme indiqué dans le setup, c'est à dire GND-BP-pin, il renvoie un LOW lorsqu'il est enfoncé.

Pour avoir plus de réponses et pour ne pas se voir mis de côté, il faut vraiment lire les instructions d'utilisation du forum.

Pour ton problème:

servo.write(position);
position = position + 30;

Au début position vaut 0 et le servo est en position 0. Quand le code du servo est exécuté, il positionne le servo sur position qui vaut encore 0, puis incrément position. Ce n'est que pour la deuxième mélodie qu'il doit avancer. Pour le faire avancer la première fois, il faut inverser ces deux lignes, Ainsi le servo sera à la nouvelle position.

Le delay ne sert à rien. Le code doit devenir:

void loop(void)
{
  b1=digitalRead(BP1);
  // si appuie BP1
  if (b1 == LOW){
    position = position + 30;
    servo.write(position);
    play_rtttl(song);
  }
}

on progresse!
j 'ai donc mis en low, mais la musique se lance toute seule sans appui de bouton, et le servo se met en route mais seulement a la fin de la musique
donc y a un progres, les deux se mettent en route,
mais je veux lancer les deux en appuyant sur le bouton uniquement , et je veux que le servo se lance en premier

Pour LOW ou HIGH, il y a une incertitude quand au câblage qui ne semple pas correspondre au code. Comment est-il branché? Avec une résistance?

Remettre HIGH, et donner le câblage.

oui j 'ai mis une resistance de 1k pour le bouton

Ceci

// bouton 1
 pinMode(BP1,INPUT_PULLUP);

implique que ton bouton est connecté d'un côté à GND et de l'autre à la pin BP1, et qu'un digitalRead(BP1) renvoie LOW si le bouton est enfoncé et HIGH sinon.
Il n'y a pas besoin de résistance, elle est déjà dans le boitier de ton arduino.

Je te conseille de ne pas mettre de résistance, de câbler ton bouton comme indiqué ci-dessus et de tester sur LOW si tu veux détecter un appui.

corrigez tous vos posts ci-dessus et rajoutez les code tags autour du code:
[code]`` [color=blue]// votre code ici[/color] ``[/code].

ça doit ressembler à cela:// votre code ici
(faites aussi ctrl-T (PC) or cmd-T (Mac) dans l'IDE avant de copier le code pour qu'il soit indenté correctement)

Merci.