Faire jouer une mélodie tout en faisant varier une sortie en PWM

Bonjour,

Je suis nouveau venu, donc je me présente : je fais du circuit bending (modification de jouets et de machines hardware sonores), et me suis mis à pratiquer Arduino depuis peu. J'ai un but précis à l'origine, mais ne me cantonne pas à celui-ci non plus.
Voici le but d'origine : réussir à controler les jouets par l'Arduino, pour pouvoir synchroniser des jouets et machines sonores ensemble.
Pour le moment j'arrive à déclencher les sons des jouets, donc à les séquencer (j'ai encore du boulot de défrichage là dessus, mais les résultats sont bien là).
Pour tester sur plusieurs jouets différents en même temps, j'ai écrit ce script :

int sensorPin = 0;
int bending1 = 7;
int bending2 = 8;
int bending3 = 12;
int bending4 = 13;
int delay1 = 20;

void setup()
{
  pinMode(bending1, OUTPUT);
  pinMode(bending2, OUTPUT);
  pinMode(bending3, OUTPUT);
  pinMode(bending4, OUTPUT);
}


void loop()
{
  int sensorValue;

  sensorValue = analogRead(sensorPin);
  
  digitalWrite(bending1, HIGH);
  delay(delay1);
  digitalWrite(bending1, LOW);
  
  delay(sensorValue*3);
  
  digitalWrite(bending2, HIGH);
  delay(delay1);
  digitalWrite(bending2, LOW);

  delay(sensorValue*2);
  
  digitalWrite(bending1, HIGH);
  delay(delay1);
  digitalWrite(bending1, LOW);
  
  delay(sensorValue*3);
  
  digitalWrite(bending2, HIGH);
  delay(delay1);
  digitalWrite(bending2, LOW);

  delay(sensorValue*2);
  
  digitalWrite(bending1, HIGH);
  delay(delay1);
  digitalWrite(bending1, LOW);
  
  delay(sensorValue*2);
  
  digitalWrite(bending3, HIGH);
  delay(delay1);
  digitalWrite(bending3, LOW);
  
  delay(sensorValue);
  
  digitalWrite(bending1, HIGH);
  delay(delay1);
  digitalWrite(bending1, LOW);
  
  delay(sensorValue*2);
  
  digitalWrite(bending4, HIGH);
  delay(delay1);
  digitalWrite(bending4, LOW);
  
  delay(sensorValue*4);
}

Ca fonctionne (un vrai sequenceur sera fait quand les tests seront concluants).

Par contre, j'essaie de rajouter une fonction "pitch". Sur un jouet, j'ai rajouté un pitch (qui n'est autre qu'un potentiomètre). Je voudrais controler ce pitch par l'Arduino, indépendamment de la "mélodie". J'ai donc déjà un potar de pitch, mais je voudrais en faire un controlé par l'Arduino : avoir un potar en entrée analogique et renvoyer la valeur sur le jouet par le biais d'un vactrum (LED en PWM+photoresistance sur le pitch du jouet). Ceci me permettra d'enregistrer une variation afin de la restituer à la demande (séquencée par exemple).
Le problème est que j'atteins mes limites en programmation : je n'arrive pas à faire une "boucle dans la boucle".

Pour résumer : j'ai une série de contacts que je déclenche dans le temps, avec des delais entre chaque déclenchement, mais il me faut dans le même temps controler en temps réel (donc pas en fonction des delais) une variation car elle est succeptible de changer tout le temps.

en gros :

int potarPitch = 1;   //le potar en entrée analo de l'Arduino
int pitchVal = 127;   //je fixe le pitch de base à moitié, c'est arbitraire
int vactrum = 11;     //le vactrum est branché sur la sortie PWM 11

  pitchVal = analogRead(potarPitch);
  manualTunePitch();    //fonction en dessous
  analogWrite(vactrum, pitchVal);
void manualTunePitch()
{
  pitchVal = map(pitchVal, 0, 1023, 0, 255);
  pitchVal = constrain(pitchVal, 0, 255);
}

Mon souci est que je ne sais pas comment faire pour que cette partie "temps réel" ne soit pas affectée par la partie "sequenceur", donc dépendant du temps. J'imagine que c'est simple pour un confirmé, mais j'ai essayé avec des do...while, etc., et je n'y arrive pas :confused:

Merci d'avance :slight_smile:

Je pense qu'il faut que tu regardes du côté des interruptions qui sont le début du multi-tâche. :wink:

EDIT : corrigé plus bas par Skywodd, le fameux BlinkWithoutDelay parait suffisant.
Docteur, j'ai un problème, je vois des interruptions partout...

Hmmm, le "schema" de code inspire confiance :

void loop()
{
  noInterrupts();
  // critical, time-sensitive code here
  interrupts();
  // other code here
}

Par contre, cette phrase me fait trembler : "Some functions will not work while interrupts are disabled, and incoming communication may be ignored."

Je teste ça ce soir ou demain, je vous tiens au courant de toute façon, merci pour ta réponse.

Bonjour,

Ici c'est simple de faire du pseudo temps réel : n'utilise tout simplement pas delay() :wink:
Exemple : http://arduino.cc/en/Tutorial/BlinkWithoutDelay

Les interruptions dans le cas présent ne sont pas la solution (à mes yeux).

une petite machine à états, peut-être ?

Merci pour vos réponses. Effectivement, le lien de skywodd semble convenir tout à fait à ce que je veux tester pour l'instant.
Là où ça va se compliquer, c'est que je vais avoir beaucoup d'entrées/sorties à gérer, donc un bon mal de crane à organiser les dépendances ^^'
Mon graal serait au final d'avoir la partie séquenceur dans pure data. Etant donné que je vais avoir besoin de beaucoup d'E/S, je pensais utiliser un Arduino Mega. Pensez-vous qu'il serait possible, et intéressant, d'utiliser deux Arduino Uno en même temps, un pour les séquences dans le temps, un autre pour tout ce qui demande du temps réel? Est-ce possible?