- Thu Jun 01, 2017 3:18 pm
#195038
Firstly, I wanted to comment that I'm loving this board!
I bought it to play some tricks with talking automats, using the Arduino to control it.
It took me a while to figure out how to do what I need, but I ended up finding a way.
I'm making a little choir in three voices, with eighteen dolls that are controlled by servo motors. The sound part of this coral is made with the Tsunami. And the control of the engines with the Adafruit PWM Servo Motor Drive.
I'm having some difficulty understanding the correct use of the tsunami.update () and tsunami.isTrackPlaying (int trk) functions. It seems that some kind of delay is needed after invoking them, but I can not understand exactly how long it lasts.
I'm having a problem with my code and I get the impression that it's something related to communicating with the Tsunami.
The program should work like this: when something is in front of an ultrasonic sensor, the Tsunami plays five mono tracks simultaneously. The Arduino must detect that one of these bands is playing and when this happens, it must position the servo motors according to the signals that enter its analog inputs.
I connected three mono Tsunami outputs to the three analog inputs of the Arduino (using circuits to set the voltage offset). The other two outputs are connected to a speaker.
The three mono outputs connected on the Arduino are control voices, one for each voice of the chorus (bass, mid and treble). The other two are the mixed voices and go to the sound output.
I'm using a while (!tsunami.isTrackPlaying (1) {to put all the code of what needs to be done when I have no music playing.) And another while (tsunami.isTrackPlaying (1) {to do what it takes when Some music is playing.
The problem is that my program is not detecting this correctly.
There are five tracks on the SD card, all mono, all named correctly. The ini file is also correct.
The program operated using only three servo motors (one for each voice). But when I increased the servos and created the routine that divides the voices into groups of six, the whole thing got complicated.
How do I use these two functions?
:pray:
Here is the code...
I bought it to play some tricks with talking automats, using the Arduino to control it.
It took me a while to figure out how to do what I need, but I ended up finding a way.
I'm making a little choir in three voices, with eighteen dolls that are controlled by servo motors. The sound part of this coral is made with the Tsunami. And the control of the engines with the Adafruit PWM Servo Motor Drive.
I'm having some difficulty understanding the correct use of the tsunami.update () and tsunami.isTrackPlaying (int trk) functions. It seems that some kind of delay is needed after invoking them, but I can not understand exactly how long it lasts.
I'm having a problem with my code and I get the impression that it's something related to communicating with the Tsunami.
The program should work like this: when something is in front of an ultrasonic sensor, the Tsunami plays five mono tracks simultaneously. The Arduino must detect that one of these bands is playing and when this happens, it must position the servo motors according to the signals that enter its analog inputs.
I connected three mono Tsunami outputs to the three analog inputs of the Arduino (using circuits to set the voltage offset). The other two outputs are connected to a speaker.
The three mono outputs connected on the Arduino are control voices, one for each voice of the chorus (bass, mid and treble). The other two are the mixed voices and go to the sound output.
I'm using a while (!tsunami.isTrackPlaying (1) {to put all the code of what needs to be done when I have no music playing.) And another while (tsunami.isTrackPlaying (1) {to do what it takes when Some music is playing.
The problem is that my program is not detecting this correctly.
There are five tracks on the SD card, all mono, all named correctly. The ini file is also correct.
The program operated using only three servo motors (one for each voice). But when I increased the servos and created the routine that divides the voices into groups of six, the whole thing got complicated.
How do I use these two functions?
:pray:
Here is the code...
Code: Select all
/*When something is in front of Ultrasound Sensor, play 5 tracks poly at TSUNAMI SUPER WAV TRIGGER
if there is any audio playing at TSUNAMI, move 18 Servo Motors that is attached to a FROG DOLL mouth
And make the FROGS sing.
*/
#include <Wire.h> // I2C to Adafruit 16 Channel PWM Servo Driver
#include <Adafruit_PWMServoDriver.h> // Adafruit 16 Channel PWM Servo Driver
#include <Tsunami.h> // Tsunami Super Wav Trigger
#include <Ultrasonic.h> // Ultrasound Sensor HC-SR04
/* Relay Board */
#define ABAJUR1 8 // Lights
#define ABAJUR2 9 // Lights
/* Tsunami Super Wav Trigger */
Tsunami tsunami; // Create tsunami object
int gRateOffset = 0; // Offset Rate Tsunami
int gNumTracks; // Number of SD Card Tracks
char gTsunamiVersion[VERSION_STRING_LEN]; // Tsunami Version String
/* Sensor Ultrasonico HC-SR04 */
#define SENSORMIN 10 // Minimum distance to Trigger
#define SENSORMAX 50 // Maximum distance to Trigger
#define TRIGGER_PIN 6
#define ECHO_PIN 7
Ultrasonic ultrasonic(TRIGGER_PIN, ECHO_PIN); // Create Ultrasonic Object
/* Servo Parameters */
#define VOICECONTROL 2 // Number of control voices (index 0)
#define SERVONUM 17 // Number of SERVO MOTORS
#define VOZAGUDAMIN 264 // Mouth CLOSED for Small FROG
#define VOZAGUDAMAX 380 // Mouth OPENED for Small FROG
#define VOZMEDIAMIN 264 // Mouth CLOSED for Medium FROG
#define VOZMEDIAMAX 410 // Mouth OPENED for Medium FROG
#define VOZGRAVEMIN 264 // Mouth CLOSED for Big FROG
#define VOZGRAVEMAX 371 // Mouth OPENED for Big FROG
/* Trying to find mid position - just for testing
int VOZAGUDAMED = ((VOZAGUDAMAX - VOZAGUDAMIN) / 2) + VOZAGUDAMIN;
int VOZMEDIAMED = ((VOZMEDIAMAX - VOZMEDIAMIN) / 2) + VOZMEDIAMIN;
int VOZGRAVEMED = ((VOZGRAVEMAX - VOZGRAVEMIN) / 2) + VOZGRAVEMIN;
*/
int servomin;
int actmax;
int actmin;
int Audio[] = {1, 2, 3, 4, 5}; // Array with audio track number
int Servos[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}; // Array with servo number
/*Arrays for Motor Position and Amplitude of Audio Signal*/
int Posicao[VOICECONTROL];
int Amplitude[VOICECONTROL];
Adafruit_PWMServoDriver sapo = Adafruit_PWMServoDriver(); // Create an PWM Servo object called "sapo" (frog)
/* Preparing Arduino Audio Readings */
int Offset = 520; // Voltage offset for audio - measured in tests
int AudioMax = 690; // Audio Peak
void setup() {
Serial.println ("Started");
Serial.begin (9600);
sapo.begin(); // Start Adafruit PWM Servo Driver
sapo.setPWMFreq(60); // Servos at 60hz
yield ();
/* Init Tsunami Super Wav Trigger */
delay(1000); // Start TSUNAMI
tsunami.start();
delay(10);
tsunami.stopAllTracks(); // Stop all tracks
tsunami.samplerateOffset(0, 0); // Reset Sample Rate Offset
tsunami.setReporting(true); // Track Report Enabled
Serial.println ("Tsunami inicializada");
delay(1000); // Wait for Tsunami Report
/* Testing Arduino and Tsunami communication */
if (tsunami.getVersion(gTsunamiVersion, VERSION_STRING_LEN)) {
Serial.println ("Estabelecendo comunicação com a Tsunami");
Serial.print(gTsunamiVersion);
Serial.println("\n");
gNumTracks = tsunami.getNumTracks();
Serial.print("Numero de pistas = ");
Serial.println(gNumTracks);
Serial.println ("*************************************");
}
/* Preparing the Relay Board */
pinMode(ABAJUR1, OUTPUT);
pinMode(ABAJUR2, OUTPUT);
digitalWrite(ABAJUR1, LOW);
digitalWrite(ABAJUR2, LOW);
Serial.println ("Relay Board Preparada");
Serial.println ("*************************************");
Serial.println ("Setup das placas OK");
Serial.println ("*************************************");
} /* SETUP FINISHED */
/* Setting Servos at Miliseconds */
void setServoPulse(uint8_t n, double pulse) {
double pulselength;
pulselength = 1000000; // 1,000,000 us por segundo
pulselength /= 60; // 60 Hz
Serial.print(pulselength);
Serial.println(" us por periodo");
pulselength /= 4096; // 12 bits de resolution
Serial.print(pulselength);
Serial.println(" us por bit");
pulse *= 1000;
pulse /= pulselength;
Serial.println(pulse);
sapo.setPWM(n, 0, pulse);
}
void loop() {
tsunami.update(); // Update Tsunami Status
/* Preparo o Sensor Ultrasonico */
float cmMsec;
long microsec = ultrasonic.timing();
cmMsec = ultrasonic.convert(microsec, Ultrasonic::CM); // Read Ultrasound Sensor
while (!tsunami.isTrackPlaying(1)) {
// When Tsunami is not playing Track 1
digitalWrite(ABAJUR1, LOW); // Keep Lights Off
digitalWrite(ABAJUR2, LOW);
for (int fecha = 0; fecha <= SERVONUM; fecha++) { // Keep Frogs with closed Mouth.
sapo.setPWM (Servos[fecha], 0, VOZAGUDAMIN);
}
if ((cmMsec >= SENSORMIN) && (cmMsec <= SENSORMAX)) { // Test if there is an object in front of sensor
for (int a = 0; a < gNumTracks; a++) {
tsunami.trackLoad(Audio[a], a, true); // Load Audio Track
Serial.print ("Faixa ");
Serial.print (Audio [a]);
Serial.println (" Carregada...");
}
tsunami.resumeAllInSync(); // Play All Tracks
tsunami.update();
Serial.print ("Objeto detectado a "); // Just for show Object Distance
Serial.print (cmMsec);
Serial.println (" Cm");
}
}
/* But, if Tsunami is playing... Lights ON, read ANALOG INPUT and Position SERVOS based on sound input - LipSync!!! */
while (tsunami.isTrackPlaying(1)) {
digitalWrite(ABAJUR1, HIGH); // Lights ON
digitalWrite(ABAJUR2, HIGH);
for (int i = 0; i <= VOICECONTROL; i++) { // Starting loop that control motors based on Analog Read
Amplitude[i] = analogRead (i);
if (Amplitude[i] >= Offset) {
if (i == 0) {
actmin = 0;
actmax = 6;
servomin = VOZAGUDAMIN;
Posicao[i] = map (Amplitude[i], Offset, AudioMax, VOZAGUDAMIN, VOZAGUDAMAX); // Position SERVOS 0 to 5
} else if (i == 1) {
actmin = 6;
actmax = 12;
servomin = VOZMEDIAMIN;
Posicao[i] = map (Amplitude[i], Offset, AudioMax, VOZMEDIAMIN, VOZMEDIAMAX); // Position SERVOS 6 to 11
} else if (i == 2) {
actmin = 12;
actmax = 18;
servomin = VOZGRAVEMIN;
Posicao[i] = map (Amplitude[i], Offset, AudioMax, VOZGRAVEMIN, VOZGRAVEMAX); // Position SERVOS 12 to 17
}
for (int s = servomin; s < Posicao[i]; s++) { // Move SERVOS
for (int act = actmin; act < actmax; act++) {
sapo.setPWM (Servos[act], 0, s);
}
}
}
}
tsunami.update();
delay(50); //
}
}