Moderators: adafruit_support_bill, adafruit
//------------------------------------------------------------------------------
// 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
//------------------------------------------------------------------------------
// 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/*
* 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();
}*/
} Motor_1.setSpeed(leftFastSpeed);
Motor_2.setSpeed(rightFastSpeed);
Return to Arduino Shields from Adafruit
Users browsing this forum: cfoAdafruit and 3 guests