I'm a complete neophyte hacking my way through projects. So forgive me for not using technical language in describing my project and efforts...
I've been working on an art project robot that is responsive to sound and light (moves and draws in response to sound and light levels). It has motors (2 stepper motors) and a servo that move in a variety of ways based on the volume level coming into a mic and the light levels from a photocell
Everything has been working fine with the stepper motors and generally with the photocell readings. But when I started working with the servo and the photocell more actively I noticed what I am assuming is feedback or noise affecting my performance.
The servo starts to create noise that the mic picks up (but I don't think directly) and it can get into a feedback loop where it's own noise creates the noise that triggers it to move. Secondarily, if the photocell gets under a strong light source the mic levels also get really high and it also kicks off a lot of activity I don't want.
I'm kind of guessing both the servo and the photocell are creating noise within the electric circuit, but I have no idea really how to isolate them.
Some background on the project.
- I built the mic from this example : LM358 microphone amplifier | Low voltage. Mostly harmless...
- the servo is a Datan S1213
- the photocell and the servo are on the 3V line, the mic and the light/sound meter are on the 5v, the motors are on a motorshield (adafruit v2.0)
- I've got a 8x8 bicolor backpack to convert light and sound to a meter to give me a rough visual of the light and sound levels
I'm going to try to build a circuit diagram, but that's not something I've done before, so I thought I'd post generally first and then see if I can illustrate my layout.
Dode follows.
/*
A Sound and light controlled roboot for making drawings that respond to environment
Takes sound and light measurements over 10 cycles to set response variables
Uses sound to set direction and duration of movement
Uses light to set speed of movement and as a multiplied on duration of movement.
Uses light sensor pointed downward check if it is on canvas and corrects if not
Displays sound and light levels as two 3 pixel wide meters on 8x8 backpack
*/
#include <Wire.h>
#include <Servo.h>
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_PWMServoDriver.h"
Adafruit_BicolorMatrix matrix = Adafruit_BicolorMatrix();
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *myMotorR = AFMS.getMotor(2);
Adafruit_DCMotor *myMotorL = AFMS.getMotor(3);
int soundPin = 0;
int lightPinUp = 3;
int lightPinDown = 2;
Servo myservo;
void setup() {
myservo.attach(12);
matrix.begin(0x74);
AFMS.begin();
myMotorL->setSpeed(255);
myMotorL->run(FORWARD);
myMotorL->run(RELEASE);
myMotorR->setSpeed(255);
myMotorR->run(FORWARD);
myMotorR->run(RELEASE);
Serial.begin(9600);
}
//establish conditions, measure environment and set variables for light and sound
void loop() {
myMotorL->run(RELEASE);
myMotorR->run(RELEASE);
int mnS = 1024;
int mxS = 0;
int mxLU = 0;
int mxLD = 0;
int pos = 125;
myservo.write(pos);
for (int i = 0; i < 10; ++i) {
int sound = analogRead(soundPin);
int lightUp = analogRead(lightPinUp);
int lightDown = analogRead(lightPinDown);
mnS = min(mnS, sound);
mxS = max(mxS, sound);
mxLU = max(mxLU, lightUp);
mxLD = max(mxLD, lightDown);
}
//using this section to create a sound meter.
//two "bars" each 3 pixels wide. Green is sound, Red is light.
matrix.clear();
matrix.fillRect(0,0, (mxS-mnS)/6,3, LED_GREEN);
matrix.fillRect(0,5, map(mxLU,100,1200,0,8),3, LED_RED); //adjust number to parameterize light
matrix.writeDisplay();
int motorSpeed = map(mxLU, 100,1200 ,100, 255);
int lightDuration = map(mxLU,100,1200,5,10); // setting duration of wheel turning to respond to light levels.
Serial.print(mxLU);
Serial.print (" - ");
Serial.print (mxLD);
Serial.println();
/*
This sections is for the action routine.
two nested if statements
1) Only moves if lower photocell is above a certain level, if not backs up and turns around, intended to keep on canvas
2) only moves if sound is above a threshold
Sets motor speed according to light level on up sensor
Direction of motor is set randomly to create more dynamic action
Duration of motor turning is based on light levels and sound levels
*/
if(mxLD>50){ //sets sensitivity to being on light colored surface hard to tune based on ambiant light
if(((mxS-mnS)/6)>1){ //sets sensoitivity of sound to action
myMotorR->setSpeed(motorSpeed);
myMotorL->setSpeed(motorSpeed);
if(random(100) >50)
{
myMotorL->run(FORWARD);
}
else{
myMotorL->run(BACKWARD);
}
if(random(100) >50) {
myMotorR->run(FORWARD);
}
else{
myMotorR->run(BACKWARD);
}
pos = 125-((mxS-mnS)/3);
myservo.write(pos);
delay((mxS-mnS)*lightDuration); //using light duration as a factor in turn rotation
}
}
else{
myMotorR->setSpeed(255);
myMotorL->setSpeed(255);
myMotorR->run(BACKWARD);
myMotorL->run(BACKWARD);
delay (500); //needs to be enough to get clearance back on canvas
myMotorR->run(BACKWARD);
myMotorL->run(FORWARD);
delay (2000); // needs to be enough for 180
}
}
