Pages: [1]   Go Down
Author Topic: Barrière Infrarouge + Waveshield  (Read 703 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonjour à tous.

J'ai monté un waveshield sur ma carte arduino.
La carte SD du waveshield contient 5 fichiers wave.
A côté, j'ai un petit circuit relié sur le waveshield intégrant une barrière infrarouge.
L'idée est que lorsqu'une personne coupe le faisceau infrarouge, un son est joué aléatoirement.

Au préalable j'ai testé cela sans la barrière infrarouge avec un simple boutton à partir du code suivant :

Code:
#include <FatReader.h>
#include <SdReader.h>
#include <avr/pgmspace.h>
#include "WaveUtil.h"
#include "WaveHC.h"


SdReader card;    // This object holds the information for the card
FatVolume vol;    // This holds the information for the partition on the card
FatReader root;   // This holds the information for the filesystem on the card
FatReader f;      // This holds the information for the file we're play

WaveHC wave;      // This is the only wave (audio) object, since we will only play one at a time

#define DEBOUNCE 100  // button debouncer

// this handy function will return the number of bytes currently free in RAM, great for debugging!   
int freeRam(void)
{
  extern int  __bss_end;
  extern int  *__brkval;
  int free_memory;
  if((int)__brkval == 0) {
    free_memory = ((int)&free_memory) - ((int)&__bss_end);
  }
  else {
    free_memory = ((int)&free_memory) - ((int)__brkval);
  }
  return free_memory;
}

void sdErrorCheck(void)
{
  if (!card.errorCode()) return;
  putstring("\n\rSD I/O error: ");
  Serial.print(card.errorCode(), HEX);
  putstring(", ");
  Serial.println(card.errorData(), HEX);
  while(1);
}

void setup() {
  // set up serial port
  Serial.begin(9600);
  putstring_nl("WaveHC with 6 buttons");
 
   putstring("Free RAM: ");       // This can help with debugging, running out of RAM is bad
  Serial.println(freeRam());      // if this is under 150 bytes it may spell trouble!
 
  // Set the output pins for the DAC control. This pins are defined in the library
  pinMode(2, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
 
  // pin13 LED
  pinMode(13, OUTPUT);
 
  // enable pull-up resistors on switch pins (analog inputs)
  digitalWrite(14, HIGH);
  digitalWrite(15, HIGH);
  digitalWrite(16, HIGH);
  digitalWrite(17, HIGH);
  digitalWrite(18, HIGH);
  digitalWrite(19, HIGH);
 
  //  if (!card.init(true)) { //play with 4 MHz spi if 8MHz isn't working for you
  if (!card.init()) {         //play with 8 MHz spi (default faster!) 
    putstring_nl("Card init. failed!");  // Something went wrong, lets print out why
    sdErrorCheck();
    while(1);                            // then 'halt' - do nothing!
  }
 
  // enable optimize read - some cards may timeout. Disable if you're having problems
  card.partialBlockRead(true);
 
// Now we will look for a FAT partition!
  uint8_t part;
  for (part = 0; part < 5; part++) {     // we have up to 5 slots to look in
    if (vol.init(card, part))
      break;                             // we found one, lets bail
  }
  if (part == 5) {                       // if we ended up not finding one  :(
    putstring_nl("No valid FAT partition!");
    sdErrorCheck();      // Something went wrong, lets print out why
    while(1);                            // then 'halt' - do nothing!
  }
 
  // Lets tell the user about what we found
  putstring("Using partition ");
  Serial.print(part, DEC);
  putstring(", type is FAT");
  Serial.println(vol.fatType(),DEC);     // FAT16 or FAT32?
 
  // Try to open the root directory
  if (!root.openRoot(vol)) {
    putstring_nl("Can't open root dir!"); // Something went wrong,
    while(1);                             // then 'halt' - do nothing!
  }
 
  // Whew! We got past the tough parts.
  putstring_nl("Ready!");
}

void loop() {
  //putstring(".");            // uncomment this to see if the loop isnt running
  switch (check_switches()) {
        case 1:
    {
   int Song = random(0, 4);  // choose a random song
   switch (Song)
   {
      case 0: playcomplete("1.WAV"); break;
      case 1: playcomplete("2.WAV"); break;
      case 2: playcomplete("3.WAV"); break;
      case 3: playcomplete("4.WAV"); break;
      case 4: playcomplete("5.WAV"); break;
   }
}
      break;
    case 2:
      playcomplete("2.WAV");
      break;
    case 3:
      playcomplete("3.WAV");
      break;
    case 4:
      playcomplete("4.WAV");
      break;
    case 5:
      playcomplete("5.WAV");
      break;
    case 6:
      playcomplete("6.WAV");
  }
}

byte check_switches()
{
  static byte previous[6];
  static long time[6];
  byte reading;
  byte pressed;
  byte index;
  pressed = 0;

  for (byte index = 0; index < 6; ++index) {
    reading = digitalRead(14 + index);
    if (reading == LOW && previous[index] == HIGH && millis() - time[index] > DEBOUNCE)
    {
      // switch pressed
      time[index] = millis();
      pressed = index + 1;
      break;
    }
    previous[index] = reading;
  }
  // return switch number (1 - 6)
  return (pressed);
}


// Plays a full file from beginning to end with no pause.
void playcomplete(char *name) {
  // call our helper to find and play this name
  playfile(name);
  while (wave.isplaying) {
  // do nothing while its playing
  }
  // now its done playing
}

void playfile(char *name) {
  // see if the wave object is currently doing something
  if (wave.isplaying) {// already playing something, so stop it!
    wave.stop(); // stop it
  }
  // look in the root directory and open the file
  if (!f.open(root, name)) {
    putstring("Couldn't open file "); Serial.print(name); return;
  }
  // OK read the file and turn it into a wave object
  if (!wave.create(f)) {
    putstring_nl("Not a valid WAV"); return;
  }
 
  // ok time to play! start playback
  wave.play();
}

Ok problème, lorsque j'appuye sur le bouton, un son est joué.

Puis j'ai récupéré un code afin de tester ma barrière IR sur ma carte,
voici le code récupéré à cette addresse http://www.arcfn.com/2010/03/detecting-ir-beam-break-with-arduino-ir.html

Code:
#include <IRremote.h>

#define PIN_IR 3
#define PIN_DETECT 7
#define PIN_STATUS 13

IRsend irsend;
void setup()
{
  pinMode(PIN_DETECT, INPUT);
  pinMode(PIN_STATUS, OUTPUT);
  irsend.enableIROut(38);
  irsend.mark(0);
}

void loop() {
  digitalWrite(PIN_STATUS, !digitalRead(PIN_DETECT));
}

Lorsque le faisceau est coupé, la LED 13 s'allume.
Voilà maintenant j'aimerai l'intégrer au premier programme.
Du coup je voudrai que lorsque le faisceau se coupe, le waveshield joue un son aléatoirement.
Comme je débute, je n'ai aucune idée de comment modifier le programme.

Quelqu'un aurait-il une idée ?  smiley

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Du coup pour fusionner le programme de la barrière IR,
j'importe la librairie dans le premier programme + les define

Code:
#include <FatReader.h>
#include <SdReader.h>
#include <avr/pgmspace.h>
#include "WaveUtil.h"
#include "WaveHC.h"
#include <IRremote.h>


SdReader card;    // This object holds the information for the card
FatVolume vol;    // This holds the information for the partition on the card
FatReader root;   // This holds the information for the filesystem on the card
FatReader f;      // This holds the information for the file we're play

WaveHC wave;      // This is the only wave (audio) object, since we will only play one at a time

#define DEBOUNCE 100  // button debouncer
#define PIN_IR 3
#define PIN_DETECT 7
#define PIN_STATUS 13

IRsend irsend;
// this handy functi

Ensuite dans le void setup je rajoute les fonction pinMode du PIN_DETECT et PIN_STATUS ainsi que irsend...
Code:
  pinMode(2, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(PIN_DETECT, INPUT);
  pinMode(PIN_STATUS, OUTPUT);
  irsend.enableIROut(38);
  irsend.mark(0);
 

Dans la partie void_loop pour le moment je n'ai rien changé j'ai ça :
Code:
void loop() {
  //putstring(".");            // uncomment this to see if the loop isnt running
  switch (check_switches()) {
        case 1:
    {
   int Song = random(0, 4);  // choose a random song
   switch (Song)
   {
      case 0: playcomplete("1.WAV"); break;
      case 1: playcomplete("2.WAV"); break;
      case 2: playcomplete("3.WAV"); break;
      case 3: playcomplete("4.WAV"); break;
      case 4: playcomplete("5.WAV"); break;
   }
}
      break;
    case 2:
      playcomplete("2.WAV");
      break;
    case 3:
      playcomplete("3.WAV");
      break;
    case 4:
      playcomplete("4.WAV");
      break;
    case 5:
      playcomplete("5.WAV");
      break;
    case 6:
      playcomplete("6.WAV");
  }
}

byte check_switches()
{
  static byte previous[6];
  static long time[6];
  byte reading;
  byte pressed;
  byte index;
  pressed = 0;

  for (byte index = 0; index < 6; ++index) {
    reading = digitalRead(14 + index);
    if (reading == LOW && previous[index] == HIGH && millis() - time[index] > DEBOUNCE)
    {
      // switch pressed
      time[index] = millis();
      pressed = index + 1;
      break;
    }
    previous[index] = reading;
  }
  // return switch number (1 - 6)
  return (pressed);
}

J'imagine que je peut virer la partie byte check_switches() car cette variable ne m'est plus utile. il me reste donc
Code:
void loop() {
  //putstring(".");            // uncomment this to see if the loop isnt running
  switch (check_switches()) {
        case 1:
    {
   int Song = random(0, 4);  // choose a random song
   switch (Song)
   {
      case 0: playcomplete("1.WAV"); break;
      case 1: playcomplete("2.WAV"); break;
      case 2: playcomplete("3.WAV"); break;
      case 3: playcomplete("4.WAV"); break;
      case 4: playcomplete("5.WAV"); break;
   }
}

j'aimerai remplacer le switch (check_switches()) par la condition suivante : si le PIN_DETECT ne détecte rien, alors il joue un son aléatoire…
es-ce que quelqu'un aurait une idée ?
Logged

Offline Offline
Faraday Member
**
Karma: 19
Posts: 4175
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Du coup pour fusionner le programme de la barrière IR,
j'importe la librairie dans le premier programme + les define

Code:
#include <FatReader.h>
#include <SdReader.h>
#include <avr/pgmspace.h>
#include "WaveUtil.h"
#include "WaveHC.h"
#include <IRremote.h>


SdReader card;    // This object holds the information for the card
FatVolume vol;    // This holds the information for the partition on the card
FatReader root;   // This holds the information for the filesystem on the card
FatReader f;      // This holds the information for the file we're play

WaveHC wave;      // This is the only wave (audio) object, since we will only play one at a time
---

j'aimerai remplacer le switch (check_switches()) par la condition suivante : si le PIN_DETECT ne détecte rien, alors il joue un son aléatoire…
es-ce que quelqu'un aurait une idée ?


utiliser la fonction random avec comme facteur le nombre (x) de morceaux dispos ?

randNumber = random(1, x);

par curiosité bien placée et pour "coller" sur ce sujet
http://arduino.cc/forum/index.php/topic,86084.msg666173.html#msg666173

l'occupation de l'arduino est de quel ordre avec ton code  ?
« Last Edit: January 25, 2012, 08:46:18 am by Artouste » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 17
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OK désolé pour le temps de réponse.
J'utilise ce code à l'interieur d'une maquette d'architecture à échelle 1.

Dans la partie "case" j'ai remplacé la fonction playcomplete par la fonction playfile :

Code:
void loop() {
   int Song = random(0, 9);  // choose a random song
   int Coupure = digitalRead(PIN_DETECT);
   
   if (Coupure == LOW) {
   switch (Song)
   {
      case 0: playfile("1.WAV") ; break;
      case 1: playfile("2.WAV") ; break;
      case 2: playfile("3.WAV") ; break;
      case 3: playfile("4.WAV") ; break;
     case 4: playfile("5.WAV"); break;
     case 5: playfile("6.WAV"); break;
     case 6: playfile("7.WAV"); break;
     case 7: playfile("8.WAV"); break;
   }
}
}


Du coup lorsque la personne traverse le faisceau, le son s'enclenche. Cependant il est joué pendant la durée totale de la coupure du faisceau, soit quelque dixième de son (la personne passe, elle ne reste pas dans le champ du faisceau). Dans mon cas j'aimerai que le son joué dure au moins 10 secondes. j'ai donc pensé à procéder de cette manière :

Code:
case 0: playfile("1.WAV") ; delay(10000); break;

pour chacun des case... Le problème c'est que ça ne marche pas  :smiley-yell : le wave shield joue tout les sons 10 secondes, en les enchainant, et en plus sans être déclenché par le faisceau. (les sons se lancent dès que j'upload le code)

Je joint le code de la fonction playfile, si quelqu'un a une idée pour m'aider à m'avancer, ce serait chouette

Code:
void playfile(char *name) {
 
  // see if the wave object is currently doing something
  if (wave.isplaying) { // already playing something, so stop it!
   wave.stop();// stop it
  }
  // look in the root directory and open the file
  if (!f.open(root, name)) {
    putstring("Couldn't open file "); Serial.print(name); return;
  }
  // OK read the file and turn it into a wave object
  if (!wave.create(f)) {
    putstring_nl("Not a valid WAV"); return;
  }
 
  // ok time to play! start playback
   wave.play();
}
Logged

France
Offline Offline
Faraday Member
**
Karma: 52
Posts: 5341
Arduino Hacker
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Sa fait quoi si tu utilise une fonction dans ce genre ?

Code:
void loop() {
  byte song = random(0, 9);  // choose a random song
  byte coupure = digitalRead(PIN_DETECT);
   
  if (coupure == LOW) {
    switch (song)
    {
      case 0:
        playfile("1.WAV");
        break;
      case 1:
        playfile("2.WAV");
        break;
      case 2:
        playfile("3.WAV");
        break;
      case 3:
        playfile("4.WAV");
        break;
      case 4:
        playfile("5.WAV");
        break;
      case 5:
        playfile("6.WAV");
        break;
      case 6:
        playfile("7.WAV");
        break;
      case 7:
        playfile("8.WAV");
        break;
    }
    delay(1000);
  }
}

Avec un :
Code:
pinMode(PIN_DETECT, INPUT);
digitalWrite(PIN_DETECT, HIGH);
pour activer les résistances de tirage dans setup().
Logged

Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

Pages: [1]   Go Up
Jump to: