I’m at home stretch. I am doing an Alexa billy bass project.
I have everything working fine, motors I know work fine as I ran a test sketch.
Now signal flow is fine up to the speaker, it works fine , the issue is audio BACK to the motor shield. In the code , it specifies A1 I believe which I believe, is what I soldered to.
The singnal to A1, is coming from the speaker + going into the little amp. The speaker works as you can hear in the video. So I Twisted a line as instructed with that line, and T’d off to the A1 input on the shield.
There is no pickup on the motor shield analog of the audio. I “think” the code is good. I ran it, came back no errors. Maybe something I can’t see.
The solder is bang on, I believe everything is correct. If anyone can help that would be great , I’ll also include the code in a Seperate post.
The power to the shield is coming from the battery pack on the billy bass fish, I removed the little jumper which allowed the amp etc to work fine. The issue is the analog, I’m so close lol. Video is below and extra pics
/*
Make a set of motors move to sound.
Uses an Arduino Uno paired with the Adafruit Motor Shield v2.
Written with the larger Big Mouth Billy Bass (or any animatronic) in mind.
Modified by Joe Villegas on July 2018:
-Defined all motors
-Set variables (Ex: speed and sensitivity) for easier tweaking
-Added support for the third motor in some Basses (Disable/Enable third motor use)
-Included serial printouts for debugging and audio reading monitoring
August 2018:
-Added frantic mode (Maximum speed of motor movement, requires lots of power)
Original information:
Created by Donald Bell, Maker Project Lab (2016).
Based on Sound to Servo by Cenk Özdemir (2012)
and DCMotorTest by Adafruit
*/
// Libraries
#include <Wire.h>
#include <QueueArray.h>
#include <Adafruit_MotorShield.h>
#include <Adafruit_PWMServoDriver.h>
//* SETUP (!!! This is the usually the best and probably only place you need to adjust!)
boolean legacyFish = true; //For older models that incorporate three motors
//* Motor speed variables
int motorDelay = 0; //Delay between sound readings and motor movements
//* Range: 1 - 255. Lower makes most movement.
int mouthMotorSpeed = 100;
int headMotorSpeed = 100;
int tailMotorSpeed = 25;
// Funsies (ENABLE AT RISK (make sure you have power)
boolean modeFrantic = false;
int logDelay = 10;
//* SETUP finished
//Base system variables
int afmsFreq = 1600; //Default is 1600 (1.6kHz)
int audioSensitivity = 1023;
//Audio threshold variables
boolean headMovementEnabled = true; //TODO: head motor is unable to move the head itself (reglue?)
int staticThreshold = 1; //To leave out any unwanted movement due to static
int mouthAudioThreshold = 10;
int tailAudioThreshold = 25;
//* ---- This section below don't touch
//Handled all by system (Best to not touch)
// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
// Or, create it with a different I2C address (say for stacking)
// Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61);
// Select which 'port' M1, M2, M3 or M4.
Adafruit_DCMotor *mouthMotor = AFMS.getMotor(1);
Adafruit_DCMotor *headMotor = AFMS.getMotor(2);
Adafruit_DCMotor *tailMotor = AFMS.getMotor(3);
// Some other Variables we need
int SoundInPin = A1;
int LedPin = 12; //in case you want an LED to activate while mouth moves
boolean audioDetected = false;
int audioLastDetected = 0;
QueueArray<int> audioReadingQueue;
boolean bodyMoved;
int speedFrantic = 254;
int ping = 0;
//* ---- This section above don't touch ---
//The setup routine runs once when you press reset:
void setup()
{
//Pre-setup tweaks
if (modeFrantic == true)
{
motorDelay = 0;
mouthMotorSpeed = speedFrantic;
headMotorSpeed = speedFrantic;
tailMotorSpeed = speedFrantic;
Serial.println("hello");
}
Serial.begin(9600); // set up Serial library at 9600 bps
Serial.println("sup b");
AFMS.begin(afmsFreq);
if (afmsFreq == 1600)
{
Serial.println("Adafruit Motor Shield booted");
}
else
{
Serial.println("AFMS enabled with frequency of " + String(afmsFreq));
}
// Set the speed to start, from 0 (off) to 255 (max speed)
//mouth motor
mouthMotor->setSpeed(mouthMotorSpeed);
Serial.println("Mouth motor speed set to " + String(mouthMotorSpeed) + ".");
mouthMotor->run(FORWARD); // turn on motor
Serial.println("Mouth motor connected, attempted to move");
mouthMotor->run(RELEASE);
pinMode(SoundInPin, INPUT);
pinMode(LedPin, OUTPUT);
//head motor
headMotor->setSpeed(headMotorSpeed);
Serial.println("Head motor speed set to " + String(headMotorSpeed) + ".");
headMotor->run(FORWARD); // turn on motor
Serial.println("Head motor connected, attempted to move");
headMotor->run(RELEASE);
pinMode(SoundInPin, INPUT);
//tail motor
if (legacyFish == true)
{
tailMotor->setSpeed(tailMotorSpeed);
Serial.println("Tail motor speed set to " + String(tailMotorSpeed) + ".");
tailMotor->run(FORWARD); // turn on motor
Serial.println("Tail motor connected, attempted to move");
tailMotor->run(RELEASE);
}
Serial.println("Billy Bass is GO!");
}
void loop()
{
uint8_t i;
//Reading values from analog pin
int sensorValue = analogRead(SoundInPin);
sensorValue = map(sensorValue, 0, 256, 0, audioSensitivity); //Sets the range of audio readings
if (ping >= logDelay)
{
Serial.println("Audio - Input value: " + String(sensorValue));
ping = 0;
}
else
{
ping++;
}
//int LEDValue = map(sensorValue,0,512,0,255); // we Map another value of this for LED that can be a integer betwen 0..255
//int MoveDelayValue = map(sensorValue,0,255,0,sensorValue); // note normally the 512 is 1023 because of analog reading should go so far, but I changed that to get better readings.
//Passive movement (Moves the head when it detects any audio, and moves back when it becomes silent for a while)
if (headMovementEnabled)
{
//Gathering history
audioReadingQueue.enqueue(sensorValue);
//Serial.println("QUEUE SIZE: " + String(audioReadingQueue.count())); //DEBUG
if (audioReadingQueue.count() == 50)
{
if (audioReadingQueue.peek() > staticThreshold)
{
audioLastDetected = 0;
audioDetected = true;
}
else
{
audioLastDetected++;
audioDetected = false;
}
audioReadingQueue.pop();
//Serial.println("Audio - Last detected " + String(audioLastDetected) + " steps ago"); //DEBUG
}
//Moving head according to specific scenario
if (audioLastDetected < 50 && bodyMoved == false)
{
headMotor->run(FORWARD);
for (i = headMotorSpeed; i < 255; i++)
{
headMotor->setSpeed(i);
}
headMotor->setSpeed(0);
bodyMoved = true;
Serial.println("I'm ALIVEEEEE");
}
else if (audioLastDetected < 50)
{
//hold position
}
else if (bodyMoved == true)
{
headMotor->run(BACKWARD);
for (i = headMotorSpeed; i < 255; i++)
{
headMotor->setSpeed(i);
}
headMotor->setSpeed(0);
bodyMoved = false;
Serial.println("Imma be sleepin");
}
else
{
//hold position
}
}
//Active movement
if (sensorValue > mouthAudioThreshold)
{
delay(motorDelay);
// now move the motor
mouthMotor->run(FORWARD);
for (i = mouthMotorSpeed; i < 255; i++)
{
mouthMotor->setSpeed(i);
}
analogWrite(LedPin, sensorValue); //Brightens LED according to immediate audio strength
mouthMotor->run(RELEASE);
}
if (sensorValue > tailAudioThreshold)
{
delay(motorDelay);
// now move the motor
tailMotor->run(BACKWARD);
for (i = tailMotorSpeed; i < 255; i++)
{
tailMotor->setSpeed(i);
}
tailMotor->run(RELEASE);
}
// Done.
// turn off the led again.
analogWrite(LedPin, 0);
// and this repeats all the time.
}
im trying to find out how to use the serial monitor to test the audio A1 , not too sure how to proceed or find a proper code to test with, any advice would be awesome. Im trying to do my best. audio is fine up to leaving the speaker to the arduino, so the problem is the Analog input not registering imo.
Im running this is the serial monitor at moment and, i can hear music fine on the speaker, coming out of it into A1 pin, and nothing is registering into the Serial monitor
[code]
int sensorPin = A1; // select the input pin for the audio signal input
int ledPin = 13;
void setup() {
// declare the ledPin as an OUTPUT and sensorPin as input
pinMode(ledPin, OUTPUT);
pinMode(sensorPin, INPUT);
Serial.begin(9600 ); // open the serial port at 9600 bps:
}
void loop() {
int quietThreshold = 3;
int sensorValue = analogRead(sensorPin);
if(sensorValue > quietThreshold) {
digitalWrite(ledPin, HIGH);
Serial.println("Music IS playing!");
Serial.print("sensorValue: ");
Serial.println(sensorValue);
} else {
digitalWrite(ledPin, LOW);
Serial.println("Music is NOT playing.");
Serial.print("sensorValue: ");
Serial.println(sensorValue);
}
}
Here’s as good of a drawing I can do with limited skills.
Now my signal flow is fine , I get sound from the amp, to the speakers, and can see it registering In A1 via the serial monitor. The final hurdle is the reaction of the fish talking with the code. I feel like it’s something mislabelled in the code.
The motors work fine via test sketch, the power coming from the battery bank on the fish is fine, powers the shield fine, and running seperate power for the Arduino via USB cable.
As I suggested in your other thread, take a copy of your code and delete a lot of it (or at least comment it out) so you can detect sound from A1 and when you do, run one of the motors for a few seconds. At this point you could use delay to ensure you get movement for long enough to see.
That code is a bit convoluted but you can build back up to whatever complex fish actions you want once the basics are working.
i will attempt to do this, however i am not a coder. so i was hoping to try to outsource this issue by payment. Its a christmas present project and unfort with 2 toddlers and a busy business its very hard to take on something like coding. i am trying to learn basics, but very time sesitive and consuming, i wouldnt even know what to delete etc . All good i appreciate the feedback, ill keep plugging away at this
You can flag this thread for moderation and have the moderator move the post to "Gigs and Collaborations" where someone may give you a hand for a fee or not.
Here's a combination of your two programs. All it is supposed to do is detect sound and then move the head. I'm not sure if the music detection code is your latest. If it works, we can move on to more movement.
/*
Make a set of motors move to sound.
Uses an Arduino Uno paired with the Adafruit Motor Shield v2.
Written with the larger Big Mouth Billy Bass (or any animatronic) in mind.
Modified by Joe Villegas on July 2018:
-Defined all motors
-Set variables (Ex: speed and sensitivity) for easier tweaking
-Added support for the third motor in some Basses (Disable/Enable third motor use)
-Included serial printouts for debugging and audio reading monitoring
August 2018:
-Added frantic mode (Maximum speed of motor movement, requires lots of power)
Original information:
Created by Donald Bell, Maker Project Lab (2016).
Based on Sound to Servo by Cenk Özdemir (2012)
and DCMotorTest by Adafruit
*/
// Libraries
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include <Adafruit_PWMServoDriver.h>
boolean legacyFish = true; //For older models that incorporate three motors
//* Motor speed variables
int motorDelay = 0; //Delay between sound readings and motor movements
//* Range: 1 - 255. Lower makes most movement.
int mouthMotorSpeed = 100;
int headMotorSpeed = 100;
int tailMotorSpeed = 25;
//Base system variables
int afmsFreq = 1600; //Default is 1600 (1.6kHz)
int audioSensitivity = 1023;
//Audio threshold variables
boolean headMovementEnabled = true; //TODO: head motor is unable to move the head itself (reglue?)
int staticThreshold = 1; //To leave out any unwanted movement due to static
int mouthAudioThreshold = 10;
int tailAudioThreshold = 25;
//* ---- This section below don't touch
//Handled all by system (Best to not touch)
// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
// Or, create it with a different I2C address (say for stacking)
// Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61);
// Select which 'port' M1, M2, M3 or M4.
Adafruit_DCMotor *mouthMotor = AFMS.getMotor(1);
Adafruit_DCMotor *headMotor = AFMS.getMotor(2);
Adafruit_DCMotor *tailMotor = AFMS.getMotor(3);
// Some other Variables we need
int SoundInPin = A1;
//int LedPin = 12; //in case you want an LED to activate while mouth moves
int sensorPin = A1; // select the input pin for the audio signal input
int LedPin = 13;
boolean audioDetected = false;
int audioLastDetected = 0;
boolean bodyMoved;
bool modeFrantic = true;
int speedFrantic = 254;
int ping = 0;
void setup()
{
if (modeFrantic == true)
{
motorDelay = 0;
mouthMotorSpeed = speedFrantic;
headMotorSpeed = speedFrantic;
tailMotorSpeed = speedFrantic;
Serial.println("Frantic mode");
}
Serial.begin(115200);
Serial.println("sup b");
AFMS.begin(afmsFreq);
if (afmsFreq == 1600)
{
Serial.println("Adafruit Motor Shield booted");
}
else
{
Serial.println("AFMS enabled with frequency of " + String(afmsFreq));
}
// Set the speed to start, from 0 (off) to 255 (max speed)
//mouth motor
mouthMotor->setSpeed(mouthMotorSpeed);
Serial.println("Mouth motor speed set to " + String(mouthMotorSpeed) + ".");
mouthMotor->run(FORWARD); // turn on motor
Serial.println("Mouth motor connected, attempted to move");
mouthMotor->run(RELEASE);
pinMode(SoundInPin, INPUT);
pinMode(LedPin, OUTPUT);
//head motor
headMotor->setSpeed(headMotorSpeed);
Serial.println("Head motor speed set to " + String(headMotorSpeed) + ".");
headMotor->run(FORWARD); // turn on motor
Serial.println("Head motor connected, attempted to move");
headMotor->run(RELEASE);
pinMode(SoundInPin, INPUT);
//tail motor
if (legacyFish == true)
{
tailMotor->setSpeed(tailMotorSpeed);
Serial.println("Tail motor speed set to " + String(tailMotorSpeed) + ".");
tailMotor->run(FORWARD); // turn on motor
Serial.println("Tail motor connected, attempted to move");
tailMotor->run(RELEASE);
}
Serial.println("Billy Bass is GO!");
}
void loop()
{
if (MusicPlaying())
{
headMotor->run(FORWARD);
for (int i = headMotorSpeed; i < 255; i++)
{
headMotor->setSpeed(i);
}
headMotor->setSpeed(0);
bodyMoved = true;
Serial.println("I'm ALIVEEEEE");
}
}
bool MusicPlaying()
{
int quietThreshold = 3;
int sensorValue = analogRead(sensorPin);
if (sensorValue > quietThreshold)
{
digitalWrite(LedPin, HIGH);
Serial.println("Music IS playing!");
Serial.print("sensorValue: ");
Serial.println(sensorValue);
}
else
{
digitalWrite(LedPin, LOW);
Serial.println("Music is NOT playing.");
Serial.print("sensorValue: ");
Serial.println(sensorValue);
}
return sensorValue > quietThreshold;
}