Change a pin in the WaveHC library
Moderators: adafruit_support_bill, adafruit

Change a pin in the WaveHC library

by Vincent14 on Wed Jan 23, 2013 11:54 am

Hello (I am french)

Because of a conflict with an other shield (the Rotoshield from SnootLab), I need to move at least one pin in the WaveShield library.

I've read this thread on this forum talking about my problem, but I don't want to make a hardware manipulation because of my level.

I need to move pin 3 or 5 in WaveHC to be able to use Snootor Library without any problem (pins not removables), could you help me please ?

[Edit] : This problem require a small soldering modification explained at the end of this topic. Good luck.
Last edited by Vincent14 on Sat Feb 02, 2013 9:20 am, edited 1 time in total.
Vincent14
 
Posts: 17
Joined: Sun Jan 20, 2013 2:49 pm

Re: Change a pin in the WaveHC library

by adafruit_support_bill on Wed Jan 23, 2013 12:12 pm

These pins are used for the DAC. They are defined in WavePinDefs.h. Note that there are 3 #defines for each pin: Data Direction, port number and bit number. You must change all three.

Code: Select all | TOGGLE FULL SIZE
//------------------------------------------------------------------------------
// DAC pin definitions

// LDAC may be connected to ground to save a pin
/** Set USE_MCP_DAC_LDAC to 0 if LDAC is grounded. */
#define USE_MCP_DAC_LDAC 1

// use arduino pins 2, 3, 4, 5 for DAC

// pin 2 is DAC chip select

/** Data direction register for DAC chip select. */
#define MCP_DAC_CS_DDR  PIN2_DDRREG
/** Port register for DAC chip select. */
#define MCP_DAC_CS_PORT PIN2_PORTREG
/** Port bit number for DAC chip select. */
#define MCP_DAC_CS_BIT  PIN2_BITNUM

// pin 3 is DAC serial clock
/** Data direction register for DAC clock. */
#define MCP_DAC_SCK_DDR  PIN3_DDRREG
/** Port register for DAC clock. */
#define MCP_DAC_SCK_PORT PIN3_PORTREG
/** Port bit number for DAC clock. */
#define MCP_DAC_SCK_BIT  PIN3_BITNUM

// pin 4 is DAC serial data in

/** Data direction register for DAC serial in. */
#define MCP_DAC_SDI_DDR  PIN4_DDRREG
/** Port register for DAC clock. */
#define MCP_DAC_SDI_PORT PIN4_PORTREG
/** Port bit number for DAC clock. */
#define MCP_DAC_SDI_BIT  PIN4_BITNUM

// pin 5 is LDAC if used
#if USE_MCP_DAC_LDAC
/** Data direction register for Latch DAC Input. */
#define MCP_DAC_LDAC_DDR  PIN5_DDRREG
/** Port register for Latch DAC Input. */
#define MCP_DAC_LDAC_PORT PIN5_PORTREG
/** Port bit number for Latch DAC Input. */
#define MCP_DAC_LDAC_BIT  PIN5_BITNUM
#endif // USE_MCP_DAC_LDAC
User avatar
adafruit_support_bill
 
Posts: 31071
Joined: Sat Feb 07, 2009 10:11 am

Re: Change a pin in the WaveHC library

by Vincent14 on Wed Jan 23, 2013 2:35 pm

Here are my modifications :

Code: Select all | TOGGLE FULL SIZE
//------------------------------------------------------------------------------
// DAC pin definitions

// LDAC may be connected to ground to save a pin
/** Set USE_MCP_DAC_LDAC to 0 if LDAC is grounded. */
#define USE_MCP_DAC_LDAC 1

// use arduino pins 2, 3, 4, 5 for DAC

// pin 2 is DAC chip select

/** Data direction register for DAC chip select. */
#define MCP_DAC_CS_DDR  PIN2_DDRREG
/** Port register for DAC chip select. */
#define MCP_DAC_CS_PORT PIN2_PORTREG
/** Port bit number for DAC chip select. */
#define MCP_DAC_CS_BIT  PIN2_BITNUM

// pin 7 is DAC serial clock
/** Data direction register for DAC clock. */
#define MCP_DAC_SCK_DDR  PIN7_DDRREG
/** Port register for DAC clock. */
#define MCP_DAC_SCK_PORT PIN7_PORTREG
/** Port bit number for DAC clock. */
#define MCP_DAC_SCK_BIT  PIN7_BITNUM

// pin 4 is DAC serial data in

/** Data direction register for DAC serial in. */
#define MCP_DAC_SDI_DDR  PIN4_DDRREG
/** Port register for DAC clock. */
#define MCP_DAC_SDI_PORT PIN4_PORTREG
/** Port bit number for DAC clock. */
#define MCP_DAC_SDI_BIT  PIN4_BITNUM

// pin 8 is LDAC if used
#if USE_MCP_DAC_LDAC
/** Data direction register for Latch DAC Input. */
#define MCP_DAC_LDAC_DDR  PIN8_DDRREG
/** Port register for Latch DAC Input. */
#define MCP_DAC_LDAC_PORT PIN8_PORTREG
/** Port bit number for Latch DAC Input. */
#define MCP_DAC_LDAC_BIT  PIN8_BITNUM
#endif // USE_MCP_DAC_LDAC

#endif // WavePinDefs_h



I always have the conflict :cry: My other shield use the pins D5 and D6. So, as you can see in WaveHC D5 has been moved to D8 (normaly not used, see the extremities of the schema http://snootlab.com/attachment.php?id_attachment=33 ).

Here is my sketch :

Code: Select all | TOGGLE FULL SIZE
/*
 * Importation des bibliothèques
 */
#include <Wire.h>      //Permet à Arduino et Rotoshield de communiquer
#include <snootor.h>   //Permet de manipuler le Rotoshield
#include <WaveHC.h>      //Permet de manipuler le Wave Shield
#include <WaveUtil.h>   //Permet de manipuler le Wave Shield

/*
 * Déclarations des variables
 *
 * Les déclarations sont faites en dehors de setup() et loop(),
 * afin de pouvoir être utilisées à la fois dans les deux fonctions.
 * Il faut être dans setup() ou loop() pour appeler du code (obligation)
 */
 
//Définition du mode par défaut. 0 pour Stationnaire / 1 pour Sentinelle
bool mode = 0;

//Choisi quel dossier de la racine utiliser pour les effets sonores
#define sound_effects portal2_turret_floor

//Pins utilités par les capteurs
#define IRSensorRightPin 14
#define IRSensorLeftPin 15

//Instanciation de deux objets moteurs
SnootorDC Motor_1;
SnootorDC Motor_2;

//Définition des vitesses indépendantes des moteurs pour le parallélisme
#define leftFastSpeed 255
#define rightFastSpeed 253
#define leftSlowSpeed 155
#define rightSlowSpeed 153

//Définition d'une variable mémorisant le sens des virages
int turnDirection = 0;   //0 : réinitialisé / 1 : Gauche / 2 : Droite

//Déclaration de deux variables de temps
unsigned long timeA;
unsigned long timeB;

//Instanciation des objets nécessaires au Wave Shield
SdReader card;   //Contient l'information de la carte SD
FatVolume vol;   //Contient l'information de la partition sur la carte
FatReader root;   //Contient l'information du dossier root du volume
WaveHC wave;   //Seul objet WaveHC car il ne joue qu'un son à la fois

//Déclaration de variables utiles pour naviguer sur la carte SD
uint8_t dirLevel;   //Niveau d'indentation des noms de fichiers/dossiers
dir_t dirBuf;      //Tampon pour les lectures de dossier

//Déclaration de la variable qui contient le fichier wav à jouer
FatReader file;

//Défini une macro pour insérer des messages d'erreur dans la mémoire flash
#define error(msg) error_P(PSTR(msg))


/*
 * Définition des fonctions basiques
 *
 * Les fonctions facilitent la lecture du code, elles regroupent
 * des instructions répétitives sous un nom explicite.
 */

void moveForward()
{
   Motor_1.run(FORWARD);
   Motor_2.run(FORWARD);
   
   delay(500);
}

void turnLeftForward()
{
   Motor_1.run(RELEASE);
   Motor_2.run(FORWARD);
   
   delay(500);
}

void turnRightForward()
{
   Motor_1.run(FORWARD);
   Motor_2.run(RELEASE);
   
   delay(500);
}

void moveBackward()
{
   Motor_1.run(BACKWARD);
   Motor_2.run(BACKWARD);
   
   delay(500);
}

void turnLeftBackward()
{
   Motor_1.run(RELEASE);
   Motor_2.run(BACKWARD);
   
   delay(500);
}


void turnRightBackward()
{
   Motor_1.run(BACKWARD);
   Motor_2.run(RELEASE);
   
   delay(500);
}

void releaseMotors()
{
   Motor_1.run(RELEASE);
   Motor_2.run(RELEASE);
}


/*
 * Définition de fonctions plus complexes
 *
 * Il s'agit de fonctions qui sont presque des programmes à part entière
 * et qui auraient pu être placées dans loop(). Leur lecture peut être
 * difficile mais elles améliorent encore la compréhension de loop().
 */

void stationaryMode()
{
   //Si les deux capteurs sont activés pendant 5s: Mode Sentinelle
   if(digitalRead(IRSensorLeftPin) == LOW && digitalRead(IRSensorRightPin) == LOW)
   {
      timeA = millis();
      timeB = millis();
      
      while(digitalRead(IRSensorLeftPin) == LOW && (timeB-timeA) < 5050)
      {
         timeB = millis();
      }
      
      if((timeB-timeA) > 5000)
      {
         //Initialise la vitesse par défaut utilisée par les moteurs
         Motor_1.setSpeed(leftFastSpeed);
         Motor_2.setSpeed(rightFastSpeed);
         
         //éventuellement émettre un son
         //avancer pendant 1s pour laisser à l'utilisateur le temps de retirer sa main
         
         Serial.println("Switching to sentinelMode()");
         mode = 1;
         
         return;
      }
   }
}

void sentinelMode()
{
   //Donne des détails sur le statut courant des moteurs
   //quand MOTOR_DEBUG est défini dans snootor_common.h
   SC.dump();
   
   
   //Si seul le capteur gauche est déclenché
   if(digitalRead(IRSensorLeftPin) == LOW)
   {
      Serial.println("Turn right forward");
      while(digitalRead(IRSensorLeftPin) == LOW || digitalRead(IRSensorRightPin) == LOW)
      {
         turnRightForward();
      }
   }
   
   //Si seul le capteur droit est déclenché
   else if(digitalRead(IRSensorRightPin) == LOW)
   {
      Serial.println("Turn left forward");
      while(digitalRead(IRSensorLeftPin) == LOW || digitalRead(IRSensorRightPin) == LOW)
      {
         turnLeftForward();
      }
   }
   
   //Si aucun capteur n'est activé, les deux moteurs s'activent
   else if(digitalRead(IRSensorLeftPin) == HIGH && digitalRead(IRSensorRightPin) == HIGH)
   {
      Serial.println("Move forward");
      while(digitalRead(IRSensorLeftPin) == HIGH && digitalRead(IRSensorRightPin) == HIGH)
      {
         moveForward();
      }
   }
   
   
   //On réinitialise les moteurs avant le prochain cycle
   releaseMotors();
}


/*
 * Définition des fonctions relatives au WaveShield
 */

//Affiche un message d'erreur et arrête le programme
void error_P(const char *str) {
  PgmPrint("Error: ");
  SerialPrint_P(str);
  sdErrorCheck();
  while(1);
}

//Affiche un message d'erreur et arrête le programme en cas d'erreur I/O
void sdErrorCheck(void) {
  if (!card.errorCode()) return;
  PgmPrint("\r\nSD I/O error: ");
  Serial.print(card.errorCode(), HEX);
  PgmPrint(", ");
  Serial.println(card.errorData(), HEX);
  while(1);
}

//Lit un fichier au hasard dans un dossier donné
void playOneRandomFileFromDirectory(char folderGiven[])
{
   FatReader folder;   //Dossier de lecture, sera réinitialisé à chaque appel
   
   if (!folder.open(root, folderGiven))
   {
      error("folder.open failed");
   }
   
   if (!file.open(folder, "R2_D.wav"))
   {
      error("file.open failed");
   }
   
   if (!wave.create(file))
   {
      error("file is not a valid wav");
   }
   
   wave.play();
}


/*
 * setup(): Fonction appelée automatiquement au début du programme
 *
 * Tout est initialisé ici car elle n'est appelé qu'une seule fois.
 */
void setup()
{
   //Initialisation d'une liaison série pour avoir un retour en console
   //Baudrate 9600: identique à la valeur initialisée par la connexion
   Serial.begin(9600);
   
   Serial.println("Program started");
   
   //Initialisation des pins des capteurs en mode "écoute"
   pinMode(IRSensorLeftPin,INPUT);
   pinMode(IRSensorRightPin,INPUT);
   
   //Initialisation d'une communication I²C/TWI avec le Rotoshield
   Wire.begin();
   
   //Instanciation des moteurs sur leur bornier correspondant
   Motor_1.init(3);   //Gauche
   Motor_2.init(4);   //Droite
   
   Serial.print("Ready in ");
   Serial.print(millis());
   Serial.println("ms");
   
   
   //Initialise la carte SD et affiche une erreur si cela se passe mal
   if (!card.init()) {         //lit avec 8Mhz spi (défaut, plus rapide)
   //if (!card.init(true)) {   //lit avec 4Mhz spi si 8Mhz ne marche pas
      error("Card init. failed");
   }

   //Active l'optimisation en lecture (désactiver en cas de timeout/pb)
   card.partialBlockRead(true);

   //Recherche une partition FAT
   uint8_t part;
   for (part = 0; part < 5; part++) {   //Il y a jusqu'à 5 slots à lire
   if (vol.init(card, part))
     break;                     //Si une partition a été trouvée
   }
   if (part == 5) {
      error("No valid FAT partition");//Sinon cela affiche une erreur
   }

   //Imprime dans la console ce qui a été trouvé
   putstring("Using partition ");
   Serial.print(part, DEC);
   putstring(", type is FAT");
   Serial.println(vol.fatType(), DEC);   //FAT16 ou FAT32

   //Essaye d'ouvrir le dossier root
   if (!root.openRoot(vol)) {
      error("Can't open root dir");   //Quelque chose s'est mal passé
   }

   //Si tout s'est correctement déroulé
   putstring_nl("Files found (* = fragmented):");

   //Affiche le contenu de tous les dossiers de la carte SD
   //root.ls(LS_R | LS_FLAG_FRAGMENTED);
   
   //Premier test audio
   //root.rewind();
   //playAllInLoop(root);
   //playOneRandomFileFromDirectory();
   
   
   //Défini le Mode qui va être utilisé
   /*while(digitalRead(IRSensorLeftPin) == HIGH || digitalRead(IRSensorRightPin) == HIGH)
   {
      
      //Capteur droit activé le premier 5s : mode Stationnaire
      if(digitalRead(IRSensorRightPin) == LOW)
      {
         timeA = millis();
         timeB = millis();
         
         while(digitalRead(IRSensorRightPin) == LOW && (timeB-timeA) < 5050)
         {
            timeB = millis();
         }
         
         if((timeB-timeA) > 5000)
         {
            //Initialise la vitesse par défaut utilisée par les moteurs
            Motor_1.setSpeed(leftSlowSpeed);
            Motor_2.setSpeed(rightSlowSpeed);
            
            Serial.println("Switching to stationaryMode()");
            mode = 0;
            
            break;
         }
      }
      //Capteur gauche activé le premier 5s: mode Sentinelle
      if(digitalRead(IRSensorLeftPin) == LOW)
      {
         timeA = millis();
         timeB = millis();
         
         while(digitalRead(IRSensorLeftPin) == LOW && (timeB-timeA) < 5050)
         {
            timeB = millis();
         }
         
         if((timeB-timeA) > 5000)
         {
            //Initialise la vitesse par défaut utilisée par les moteurs
            Motor_1.setSpeed(leftFastSpeed);
            Motor_2.setSpeed(rightFastSpeed);
            
            //éventuellement émettre un son
            //avancer pendant 1s pour laisser à l'utilisateur le temps de retirer sa main
            
            Serial.println("Switching to sentinelMode()");
            mode = 1;
            
            break;
         }
      }
   }*/
   
   Motor_1.setSpeed(leftFastSpeed);
   Motor_2.setSpeed(rightFastSpeed);
}


/*
 * loop(): Fonction appelée après setup(), en boucle, à l'infini
 */
void loop()
{
   char folderGiven[ ] = "STARWA~1";
   if(!wave.isplaying)
   {
      playOneRandomFileFromDirectory(folderGiven);
      Serial.println("Play");
   }
   
   
   //sentinelMode();
   
   /*
   //Mode Stationnaire actif
   if(mode == 0)
   {
      stationaryMode();
   }
   //Mode Sentinelle actif
   if(mode == 1)
   {
      sentinelMode();
   }*/
}


If you put it in your text editor, you can see :
- declaration line 28
- initialization line 272 (place on the physical terminal)
- call line 377

And if I comment the line 377, the sound is played. If not, it won't work. I'm so sad, I thought that solved the double usage of this pin let work the Wave Shield correctly, because it work perfectly with the other motor (declarared line 29, initialized line 273 and called line 378).
Last edited by Vincent14 on Thu Jan 24, 2013 5:15 am, edited 1 time in total.
Vincent14
 
Posts: 17
Joined: Sun Jan 20, 2013 2:49 pm

Re: Change a pin in the WaveHC library

by adafruit_support_bill on Wed Jan 23, 2013 2:50 pm

Do you have any free analog pins? These can be used as digital pins also.
User avatar
adafruit_support_bill
 
Posts: 31071
Joined: Sat Feb 07, 2009 10:11 am

Re: Change a pin in the WaveHC library

by Vincent14 on Wed Jan 23, 2013 4:06 pm

Yes, I have 3 analog pins free, but the digital pins I used was free just before.

This is my actual map :
D0 : free
D1 : free
D2 : Wave Shield movable
D3 : Rotoshield Motor 1 not removable (Wave Shield moved to D7)
D4 : Wave Shield movable
D5 : Rotoshield Motor 3 not removable (Wave Shield moved to D8)
D6 : Rotoshield Motor 4 not removable
D7 : [Wave Shield D3 now here]
D8 : [Wave Shield D5 now here]
D9 : free
D10: Wave Shield movable
D11: Wave Shield not removable (Rotoshield Motor 2 unusable)
D12: Wave Shield not removable
D13: Wave Shield not removable

A0 : IR sensor
A1 : IR sensor
A2 : free
A3 : free
A4 : Rotoshield
A5 : Rotoshield
Vincent14
 
Posts: 17
Joined: Sun Jan 20, 2013 2:49 pm

Re: Change a pin in the WaveHC library

by adafruit_support_bill on Wed Jan 23, 2013 5:05 pm

It looks like the rotoshield is using PWM pins for motor speed control. Any way to change motor 2 to pin 9?
User avatar
adafruit_support_bill
 
Posts: 31071
Joined: Sat Feb 07, 2009 10:11 am

Re: Change a pin in the WaveHC library

by Vincent14 on Wed Jan 23, 2013 6:13 pm

I don't use the Motor 1 & 2, only Motor 3 & Motor 4. Is it important ?

If it is, I don't think motor 2 could be changed, because of hardware wiring.
Vincent14
 
Posts: 17
Joined: Sun Jan 20, 2013 2:49 pm

Re: Change a pin in the WaveHC library

by adafruit_support_bill on Wed Jan 23, 2013 6:39 pm

In the code you posted, you said these lines were the problem:
Code: Select all | TOGGLE FULL SIZE
       Motor_1.setSpeed(leftFastSpeed);
       Motor_2.setSpeed(rightFastSpeed);
User avatar
adafruit_support_bill
 
Posts: 31071
Joined: Sat Feb 07, 2009 10:11 am

Re: Change a pin in the WaveHC library

by Vincent14 on Thu Jan 24, 2013 5:02 am

Oh, yes sorry, just read line 272 in my code, I've initialized the object Motor_1 to the place of M3 and the Motor_2 object at the place of M4 on the Rotoshield.

Mh, I don't understand, this morning even if I comment the two call of the objects line 377 - 378, the WaveShield doesn't play anything.
Vincent14
 
Posts: 17
Joined: Sun Jan 20, 2013 2:49 pm

Re: Change a pin in the WaveHC library

by adafruit_support_bill on Thu Jan 24, 2013 8:08 am

Do you see any errors in the serial monitor?
User avatar
adafruit_support_bill
 
Posts: 31071
Joined: Sat Feb 07, 2009 10:11 am

Re: Change a pin in the WaveHC library

by Vincent14 on Thu Jan 24, 2013 8:18 am

No, the Serial.println done in the loop() works fine.
Vincent14
 
Posts: 17
Joined: Sun Jan 20, 2013 2:49 pm

Re: Change a pin in the WaveHC library

by adafruit_support_bill on Thu Jan 24, 2013 8:20 am

But what does it print?
User avatar
adafruit_support_bill
 
Posts: 31071
Joined: Sat Feb 07, 2009 10:11 am

Re: Change a pin in the WaveHC library

by Vincent14 on Thu Jan 24, 2013 10:37 am

It print "Play" each 2 seconds approximatly.
Vincent14
 
Posts: 17
Joined: Sun Jan 20, 2013 2:49 pm

Re: Change a pin in the WaveHC library

by adafruit_support_bill on Thu Jan 24, 2013 11:12 am

So it is opening the files on the SD card OK. Does it work if you plug in only the wave shield?
User avatar
adafruit_support_bill
 
Posts: 31071
Joined: Sat Feb 07, 2009 10:11 am

Re: Change a pin in the WaveHC library

by xl97 on Wed Jan 30, 2013 3:08 pm

(sorry noob interjecting here) :)


I thought you could NOT use PWM when using the WaveShield/WaveHC? as it uses the same timers to play the audio or something to that effect?

possible problem? (remember reading comments about having to use different libs that utilize the same timers...and use PWM..etc)
xl97
 
Posts: 144
Joined: Mon Jul 27, 2009 12:51 pm