The arduino Waveshield sketch

The Waweshield with amplificator 10W RMS

The arduino Waveshield sketch

The Arduino board with the Waveshield becomes a system that plays the files specified in the string received via I2C. Prepare a separate Arduino board with a small sketch capable of send data over the I2C bus to address 4, to which responds the system visible in the photos. Note that the waveshield is mounted above the Arduino as routinely used, but it is placed under. So most of the wires are used to connect the different pins. Under the waveshield a small base with a transistor, a resistor and a relay that used to power the amplifier at the bottom. The sketch follows turn on a pin that activates a relay for a fraction of a second, before play the wav file in according to instructions received via I2C.

 

The format of the command to be sent through the I2C system is as follows:

**xyz

that the system interpreters as a valid command (the presence of two **) and therefore plays the file xyz.wav contained on the memory card SD (example I2C command **145 plays 145.wav file)

If it receives the file number 099, then the system plays and puts it back in buffer queue so play it repeatedly until to it arrivals the file number 098. This file as well as being played eliminates all 099 occurrences in the buffer. The file 099 contains a pair of tones that repeated continuously produces the effect of alarm siren. A solution that allows to stop the siren at the end of the two tones and therefore without the effect of abrupt cessation.

The program is an implementation of a basic sketch that located on the sitehttp://www.ladyada.net/make/waveshield/use.html.

Is freely used on condition that keep the name of the author in the comments initials.

 

/***********************************/
/*  Written by Corrado Bevilacqua  */
/*                                 */
/***********************************/
//per la comunicazione sui pin 4 e 5 analogici di aruino. Wire è il nome che usa Arduino per lo standard I2C Bus
#include<Wire.h>
//funziona
19/05/2010
//domenica 16 maggio 2010 ok. Se il binary sketch supera circa 12000, 12500 byte, il wire non funziona.
//sabato 15 maggio 2010
//definizioni per il wave
// Funziona – i pin 2 3 4 5 e 10 poi 11 12 13
int numwave=0;
#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

char a9[8]=” ” ; //buffer di input per i2c
char wav0[10]; //stringa contenente il nomefile da suonare

int Vett_arrivo[90]; //vett con i valori in arrivo
// int Vett_suona[9]; //vett con i valori da suonare

int dim_vettore=89;
int e=0;

long old_millis=0;

boolean ampli_acceso = 0;

/*************************/
/*                       */
/*                       */
/*                       */
/*************************/
void sdErrorCheck(void)
{
if (!card.errorCode()) return;
putstring(“\n\rSD I/O error: “);
putstring(“, “);
while(1);
}

/*************************/
/*                       */
/*                       */
/*                       */
/*************************/
void setup() {
// byte i;
// set up serial port
Serial.begin(115200);
Serial.println(“File: PerArduinoConWaveShield_Slave_VersionFinale”);
putstring_nl(“WaveHC “);

// Set the output pins for the DAC control. This pins are defined in the library
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);

int i=0;

for (i = 0; i<=dim_vettore; i++)
{
Vett_arrivo[i] = 0;
}

// pin8 Accendo l’amplificatore
pinMode(8, OUTPUT);

// 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 “);
putstring(“, type is FAT”);

// 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!
}

//parte wire
Wire.begin(4); // join i2c bus with address #4
Wire.onReceive(receiveEvent); // register event

}

/*************************/
/*                       */
/*                       */
/*                       */
/*************************/
void loop()
{

display(10);

int k;
int i;
k=0;
//se ci sono dati allora ricevili
if (Wire.available() != 0)
{
//prendo tutta la stringa ricevuta e la metto in appo
while (Wire.available() != 0)
{
//Serial.print(“?”);
if (k<8)
{
a9[k]= Wire.receive();

Serial.print(a9[k]);

k=k+1;
}
}
//se ha due * allora lo prendo come file da suonare
if (a9[0]==’*’ && a9[1]==’*’ )
{
//ha due * per cui è un suono. Allora accendo subito l’amplificatore
//cerco la posizionedove scrivere nel vettore di arrivo

int appo=0;
appo=trovaaritroso();

Vett_arrivo[appo] = a9[2]*100 + a9[3]*10 + a9[4];

}
}

display(30);

Compatta();

display(50);
//prendi il file da suonare e rimpiazzalo con -1
i = -1;
int esci=0;
while (i < dim_vettore and esci == 0)
{
i = i + 1;
if (Vett_arrivo[i] > 0) //prendo il caso 0 e -1
{
esci = 1;
}
}

if (wave.isplaying == false)
{

if (Vett_arrivo[i] != 0) //prendo il caso 0 e -1
{

old_millis=millis(); //Memorizzo quando ho acceso l’amplificatore perspegenerlo dopo

int centinaia=0;
int decine=0;
int unita=0;
centinaia=(Vett_arrivo[i]-(Vett_arrivo[i] % 100))/100;
decine=(Vett_arrivo[i] % 100 – Vett_arrivo[i] % 10)/10;
unita= Vett_arrivo[i] % 10;

sprintf(wav0,”%d%d%d.wav”,centinaia,decine,unita);

//se devo suonare un wav ritardo di un seconso per aspettare che l’amplificatore si sia acceso bene. Però se è già acceso allora non ritardo.
if (ampli_acceso==0)
{
digitalWrite(8, 1); //accendi amplificatore
ampli_acceso = 1;

Serial.println(“ritardo”);
delay(1000);
}

Serial.println(wav0);
playfile(wav0);

}

if (Vett_arrivo[i] == 99)
{

int aa =0;
aa = trovaaritroso();
Vett_arrivo[aa] = 99;
//un giro per cancellare i 99
int trovato = 0;
for (aa = dim_vettore; aa>=1 ;aa–) //deve essere 1
{
if (Vett_arrivo[aa] == 99)
{
if (trovato == 1)
{
Vett_arrivo[aa] = -1;
}
else
{trovato = 1;}
}
}

}

int j =0;
if (Vett_arrivo[i] == 98)
{
for (j = 0; j<= dim_vettore; j++)
{
if (Vett_arrivo[j] == 99)
{
Vett_arrivo[j] = -1;
}
}
}

if (Vett_arrivo[i] != 0)
{Vett_arrivo[i] = -1;}

}
else
{
//Serial.println(“”);
//Serial.println(“Suona Suona”);
}
display(90);

//*************************************************************
e=e+1;

if (e<79)
{Serial.print(“.”);}
else
{Serial.println(“.”); e=0;}

if (wave.isplaying == false)
{
if (millis() – old_millis >5000) //se sono passati 5 secondi dall’accensione dell’amplificatore senza suoni allora spegnilo
{
digitalWrite(8, 0); //spegni amplificatore
ampli_acceso=0;
}
}
else
{
//se suona aggiorno oldmillis per garantire che si spenga dopo 5 sec dall’ultimo file suonato
old_millis=millis();
}

delay(20);

}

/*************************/
/*                       */
/*                       */
/*                       */
/*************************/
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();

}

//****************************************************************************************
// function that executes whenever data is received from master
// this function is registered as an event, see setup()

/*************************/
/*                       */
/*                       */
/*                       */
/*************************/
void Compatta ()
{
int i=0;
//sostituisce i meno due con 0
for (i = 0; i<=dim_vettore ; i++)
{
if (Vett_arrivo[i] <= -1)
{Vett_arrivo[i] = 0;}
}

//Ultimo pezzo 22-Nov-2010
//elimina i valori del vettore che sono vicini e doppioni
for (i = dim_vettore -1; i>=0 ; i–)
{
if (Vett_arrivo[i] == Vett_arrivo[i+1]) //se il l’elemeno i è uguale all’elemento i+1 allora metti in i+1 il valore zero
{Vett_arrivo[i+1] = 0;}
}

int esci=0;
int j=0;
while (esci == 0)
{
esci = 1;

for (j = 0; j<= dim_vettore – 1; j++)
{
if (Vett_arrivo[j] <= 0 and Vett_arrivo[j + 1] !=0) //’comprende 0 e anche il -1
{
Vett_arrivo[j] = Vett_arrivo[j + 1];
Vett_arrivo[j + 1] = 0;
esci = 0;
}
}
}
}

/*************************/
/*                       */
/*                       */
/*                       */
/*************************/
void display(int indicatore)
{
if (1==0) //lo faccio uscire subito e quindi non visualizza messaggi
{
int i=0;
// Serial.println(“”);
for (i = 0; i <= dim_vettore; i++)
{
if (Vett_arrivo[i] != 0 )
{
i=99;

}
}

i=99;
if (i>50)
{
Serial.print(“Rif.=”);
Serial.print(indicatore);

Serial.print(” Vett_arrivo=> “);
for (i = 0; i < dim_vettore; i++)
{
Serial.print(” “);Serial.print(i);Serial.print(“=”);Serial.print(Vett_arrivo[i]);
delay(5);
}
Serial.print(” “);Serial.print(dim_vettore);Serial.print(“=”);Serial.println(Vett_arrivo[dim_vettore]);

}

}
}

/*************************/
/*                       */
/*    Trova a Ritroso    */
/*          OK           */
/*************************/
int trovaaritroso()
{
//trovo la posizione del primo valore diverso da zero a partire dal fondo del vettore
int i =0 ;
int esci=0;
i = dim_vettore;
esci = 0;

while (i >= 0 and i <= dim_vettore and esci == 0)
{
if (Vett_arrivo[i] == 0 )
{
esci = 0;
}
else
{
esci = 1;
}
i = i – 1;
}

if (esci == 0)
{i = 0;}
if (esci == 1)
{i = i + 1 + 1; } //più 2 per trovare il primo libero
if (i >= dim_vettore)
{i = dim_vettore;} //se il vettore è pieno sovrascrivi sempre l’ultimo elemento
int g;
g=i;
return g;

}

void receiveEvent(int howMany)
{
}