I am trying to help a couple students with a project that involves controlling some DC motors with propellers attached.
Initially we were going to use this
But no luck in getting it to work.
Now, I do have a lab power supply and the effect we can get with pushbuttons would suffice. Would I be able to use a sensors instead to turn motors on an off? Putting it in another words...is there a way i can wire this up such that via software i can control if power is driven to the motors or not?
Well you'll need to elaborate on what that means.... does the code compile?- if not what are the errors?... if it does compile, what happens when it runs that shouldn't happen or doesn't happen that should?
You'll need to post your code, and also a schematic of the circuit would help.
To answer your other question...
Putting it in another words...is there a way i can wire this up such that via software i can control if power is driven to the motors or not?
.... well the answer there is a definite yes: you use the value of the sensor in you code, as input on which you base a decision which outputs the value to the motor. Let's say your sensor measures distance to an object. You could say, well, the object is >1m, I'll drive the motors full tilt. Or oops, it's between 0.5 m and 1m, so better only go half-speed. Or lastly, oh-oh, less than 0.5m better stop.
Exactly how you hook up and read a sensor, depends on the actual sensor of course, but if you get them from an "Arduino-friendly" source like Sparkfun or adafruit, they usually come with some sample Arduino code.
The sample code provided compiles fine, but not even following the datasheet wiring diagram for steppers produced any output which may or may not indicate a faulty shield
This was the code for steppers:
#include <ShiftStepper.h>
#define DATPIN 13
#define SCLPIN 12
#define LATPIN 7
#define MRPIN 8
#define INDPIN 2
// Set up the step sequence for a random motor...
static const uint8_t stepSequence[4] = {0x2, 0x4, 0x1, 0x8};
// Set up channel combinations for the motors...
static const uint8_t motChans0[__channelsPerMotor__] = {0,2,3,1};
static const uint8_t motChans1[__channelsPerMotor__] = {4,5,6,7};
static const uint8_t motChans2[__channelsPerMotor__] = {11,9,10,8};
static const uint8_t motChans3[__channelsPerMotor__] = {15,14,13,12};
// Declare some required globals
shiftChain *myChain = 0; // initializes so everyone can see it, but doesn't call the constructor
shiftStepMotor motor0(__channelsPerMotor__, stepSequence, motChans0);
shiftStepMotor motor1(__channelsPerMotor__, stepSequence, motChans1);
shiftStepMotor motor2(__channelsPerMotor__, stepSequence, motChans2);
shiftStepMotor motor3(__channelsPerMotor__, stepSequence, motChans3);
shiftDevice *motors[4] = {&motor0, &motor1, &motor2, &motor3};
shiftSixteen board0(4, motors);
shiftBoard *boards[1] = {&board0};
shiftChain storeChain(1, boards, DATPIN, SCLPIN, LATPIN, MRPIN, INDPIN);
/* ISR functions to shift it all out */
ISR (TIMER2_OVF_vect)
{
myChain->doTick();
}
void setup (void)
{
myChain = &storeChain;
Serial.begin(57600);
Serial.println("I live!");
myChain->startTimer(__preScaler32__, 0, 2);
Serial.println("Timer started");
((shiftStepMotor*)myChain->getBoard(0)->getDev(0))->doSteps(-1,1); // set motor for continuous rotation
((shiftStepMotor*)myChain->getBoard(0)->getDev(1))->doSteps(-1,-1); // set motor for continuous rotation
((shiftStepMotor*)myChain->getBoard(0)->getDev(2))->doSteps(-1,1); // set motor for continuous rotation
((shiftStepMotor*)myChain->getBoard(0)->getDev(3))->doSteps(-1,-1); // set motor for continuous rotation
}
void loop (void) {
char in = 0; // input character
static int16_t speedSetting = 1; // speed
if (Serial.available() > 0) {
in = Serial.read();
switch (in) {
case '+':
speedSetting++;
((shiftStepMotor*)myChain->getBoard(0)->getDev(0))->setSpeed(speedSetting);
((shiftStepMotor*)myChain->getBoard(0)->getDev(1))->setSpeed(-speedSetting);
((shiftStepMotor*)myChain->getBoard(0)->getDev(2))->setSpeed(speedSetting);
((shiftStepMotor*)myChain->getBoard(0)->getDev(3))->setSpeed(-speedSetting);
Serial.print("Speed setting: ");
Serial.print(speedSetting, DEC);
Serial.print(" Forward speed: ");
Serial.print(((shiftStepMotor*)myChain->getBoard(0)->getDev(0))->getSpeed(), DEC);
Serial.print(" Reverse speed: ");
Serial.println(((shiftStepMotor*)myChain->getBoard(0)->getDev(1))->getSpeed(), DEC);
break;
case '-':
speedSetting--;
((shiftStepMotor*)myChain->getBoard(0)->getDev(0))->setSpeed(speedSetting);
((shiftStepMotor*)myChain->getBoard(0)->getDev(1))->setSpeed(-speedSetting);
((shiftStepMotor*)myChain->getBoard(0)->getDev(2))->setSpeed(speedSetting);
((shiftStepMotor*)myChain->getBoard(0)->getDev(3))->setSpeed(-speedSetting);
Serial.print("Speed setting: ");
Serial.print(speedSetting, DEC);
Serial.print(" Forward speed: ");
Serial.print(((shiftStepMotor*)myChain->getBoard(0)->getDev(0))->getSpeed(), DEC);
Serial.print(" Reverse speed: ");
Serial.println(((shiftStepMotor*)myChain->getBoard(0)->getDev(1))->getSpeed(), DEC);
break;
}
}
delay(10);
}
as per controlling the dc motors via arduino i was just suggested either using a dual chip h-bridge (which I am not sure i could get one that would allow the peak to go up to 4A or close to that value) or a transistor.
I have never worked with transistors but can anyone recommend one that would work for me? I did a bit of research and came across this one http://www.fairchildsemi.com/ds/TI/TIP120.pdf
I'm a bit confused now, because in your first post you didn't mention steppers, just DC motors, but then provide code for steppers....
4A is a lot... are you sure that's what the motors draw?- Checkd the data sheet? Easy to test by putting ammeter in series with motor and measuring the current under no-load and under some load or other, like trying to stop the motor by grabbing the spindle somehow. (Normal safety measures apply....)
Others wiser than I will need to advise on what parts are needed to drive those high current motors, if that's what they are.
Edit... you only need a bridge for a dc motor if you need it bi-directional. Otherwise, a meaty enough transistor will do the trick, as shown here
And further confusion, along with the stepper thing... the shield to which you link, is capable of that current, but then it's not the one in your photo. You're not actually making it easy for us to help you.
the indicated shield should suffice: 5A at up to 30V
My motors are indeed 9-18v, 24000rpm, 4.2A draw at maximum efficiency (guess it will never go that high with just propellers)
As for the code...I definitely couldn't get the shield to work with DC's so I tested with a stepper, since the documentation and example code provided uses a stepper...hope that clarifies it
my bad...the stepper driver was just sitting on the breadboard, i used the one i provided link for....
as up now i was trying this code and wiring
(probably there is something wrong with the wiring, i was just trying to get voltage variation on the multimeter but no luck. if i set latchpin to 8, multimeter is at 0, if i use any other pin it gets the power supply voltage
/************************************************************************************************************************************
* ShiftPWM non-blocking RGB fades example, (c) Elco Jacobs, updated August 2012.
*
************************************************************************************************************************************/
// You can choose the latch pin yourself.
const int ShiftPWM_latchPin=8;
// If your LED's turn on if the pin is low, set this to true, otherwise set it to false.
const bool ShiftPWM_invertOutputs = false;
const bool ShiftPWM_balanceLoad = false;
#include <ShiftPWM.h> // include ShiftPWM.h after setting the pins!
unsigned char maxBrightness = 255;
unsigned char pwmFrequency = 75;
int numRegisters = 6;
int numOutputs = numRegisters*8;
int numRGBLeds = numRegisters*8/3;
int fadingMode = 0; //start with all LED's off.
unsigned long startTime = 0; // start time for the chosen fading mode
void setup() {
Serial.begin(9600);
// Sets the number of 8-bit registers that are used.
ShiftPWM.SetAmountOfRegisters(numRegisters);
// SetPinGrouping allows flexibility in LED setup.
// If your LED's are connected like this: RRRRGGGGBBBBRRRRGGGGBBBB, use SetPinGrouping(4).
ShiftPWM.SetPinGrouping(1); //This is the default, but I added here to demonstrate how to use the funtion
ShiftPWM.Start(pwmFrequency,maxBrightness);
printInstructions();
}
void loop()
{
if(Serial.available()){
if(Serial.peek() == 'l'){
// Print information about the interrupt frequency, duration and load on your program
ShiftPWM.PrintInterruptLoad();
Serial.flush();
}
else{
fadingMode = Serial.parseInt(); // read a number from the serial port to set the mode
Serial.print("Mode set to ");
Serial.print(fadingMode);
Serial.print(": ");
startTime = millis();
switch(fadingMode){
case 0:
Serial.println("All LED's off");
break;
case 1:
Serial.println("Fade in and out one by one");
break;
case 2:
Serial.println("Fade in and out all LED's");
break;
default:
Serial.println("Unknown mode!");
break;
}
}
}
unsigned char brightness;
switch(fadingMode){
case 0:
// Turn all LED's off.
ShiftPWM.SetAll(0);
break;
case 1:
oneByOne();
break;
case 2:
inOutAll();
break;
default:
Serial.println("Unknown Mode!");
delay(1000);
break;
}
}
void oneByOne(void){ // Fade in and fade out all outputs one at a time
unsigned char brightness;
unsigned long fadeTime = 500;
unsigned long loopTime = numOutputs*fadeTime*2;
unsigned long time = millis()-startTime;
unsigned long timer = time%loopTime;
unsigned long currentStep = timer%(fadeTime*2);
int activeLED = timer/(fadeTime*2);
if(currentStep <= fadeTime ){
brightness = currentStep*maxBrightness/fadeTime; ///fading in
}
else{
brightness = maxBrightness-(currentStep-fadeTime)*maxBrightness/fadeTime; ///fading out;
}
ShiftPWM.SetAll(0);
ShiftPWM.SetOne(activeLED, brightness);
}
void inOutTwoLeds(void){ // Fade in and out 2 outputs at a time
unsigned long fadeTime = 500;
unsigned long loopTime = numOutputs*fadeTime;
unsigned long time = millis()-startTime;
unsigned long timer = time%loopTime;
unsigned long currentStep = timer%fadeTime;
int activeLED = timer/fadeTime;
unsigned char brightness = currentStep*maxBrightness/fadeTime;
ShiftPWM.SetAll(0);
ShiftPWM.SetOne((activeLED+1)%numOutputs,brightness);
ShiftPWM.SetOne(activeLED,maxBrightness-brightness);
}
void inOutAll(void){ // Fade in all outputs
unsigned char brightness;
unsigned long fadeTime = 2000;
unsigned long time = millis()-startTime;
unsigned long currentStep = time%(fadeTime*2);
if(currentStep <= fadeTime ){
brightness = currentStep*maxBrightness/fadeTime; ///fading in
}
else{
brightness = maxBrightness-(currentStep-fadeTime)*maxBrightness/fadeTime; ///fading out;
}
ShiftPWM.SetAll(brightness);
}
void alternatingColors(void){ // Alternate LED's in 6 different colors
unsigned long holdTime = 2000;
unsigned long time = millis()-startTime;
unsigned long shift = (time/holdTime)%6;
for(int led=0; led<numRGBLeds; led++){
switch((led+shift)%6){
case 0:
ShiftPWM.SetRGB(led,255,0,0); // red
break;
case 1:
ShiftPWM.SetRGB(led,0,255,0); // green
break;
case 2:
ShiftPWM.SetRGB(led,0,0,255); // blue
break;
case 3:
ShiftPWM.SetRGB(led,255,128,0); // orange
break;
case 4:
ShiftPWM.SetRGB(led,0,255,255); // turqoise
break;
case 5:
ShiftPWM.SetRGB(led,255,0,255); // purple
break;
}
}
}
void hueShiftAll(){ // Hue shift all LED's
unsigned long cycleTime = 10000;
unsigned long time = millis()-startTime;
unsigned long hue = (360*time/cycleTime)%360;
ShiftPWM.SetAllHSV(hue, 255, 255);
}
void randomColors(){ // Update random LED to random color. Funky!
unsigned long updateDelay = 100;
static unsigned long previousUpdateTime;
if(millis()-previousUpdateTime > updateDelay){
previousUpdateTime = millis();
ShiftPWM.SetHSV(random(numRGBLeds),random(360),255,255);
}
}
void fakeVuMeter(void){ // immitate a VU meter
static int peak = 0;
static int prevPeak = 0;
static int currentLevel = 0;
static unsigned long fadeStartTime = startTime;
unsigned char brightness;
unsigned long fadeTime = (currentLevel*2);// go slower near the top
unsigned long time = millis()-fadeStartTime;
unsigned long currentStep = time%(fadeTime);
if(currentLevel==peak){
// get a new peak value
prevPeak = peak;
while(abs(peak-prevPeak)<5){
peak = random(numRGBLeds); // pick a new peak value that differs at least 5 from previous peak
}
}
if(millis()-fadeStartTime > fadeTime){
fadeStartTime = millis();
if(currentLevel<peak){ //fading in
currentLevel++;
}
else{ //fading out
currentLevel--;
}
}
// animate to new top
for(int led=0;led<numRGBLeds;led++){
if(led<currentLevel){
int hue = (numRGBLeds-1-led)*120/numRGBLeds; // From green to red
ShiftPWM.SetHSV(led,hue,255,255);
}
else if(led==currentLevel){
int hue = (numRGBLeds-1-led)*120/numRGBLeds; // From green to red
int value;
if(currentLevel<peak){ //fading in
value = time*255/fadeTime;
}
else{ //fading out
value = 255-time*255/fadeTime;
}
ShiftPWM.SetHSV(led,hue,255,value);
}
else{
ShiftPWM.SetRGB(led,0,0,0);
}
}
}
void rgbLedRainbow(unsigned long cycleTime, int rainbowWidth){
// Displays a rainbow spread over a few LED's (numRGBLeds), which shifts in hue.
// The rainbow can be wider then the real number of LED's.
unsigned long time = millis()-startTime;
unsigned long colorShift = (360*time/cycleTime)%360; // this color shift is like the hue slider in Photoshop.
for(int led=0;led<numRGBLeds;led++){ // loop over all LED's
int hue = ((led)*360/(rainbowWidth-1)+colorShift)%360; // Set hue from 0 to 360 from first to last led and shift the hue
ShiftPWM.SetHSV(led, hue, 255, 255); // write the HSV values, with saturation and value at maximum
}
}
void printInstructions(void){
Serial.println("---- ShiftPWM Non-blocking fades demo ----");
Serial.println("");
Serial.println("Type 'l' to see the load of the ShiftPWM interrupt (the % of CPU time the AVR is busy with ShiftPWM)");
Serial.println("");
Serial.println("Type any of these numbers to set the demo to this mode:");
Serial.println(" 0. All LED's off");
Serial.println(" 1. Fade in and out one by one");
Serial.println(" 2. Fade in and out all LED's");
Serial.println("");
Serial.println("Type 'm' to see this info again");
Serial.println("");
Serial.println("----");
}
That code is for fading a bunch of leds off and on, based on a keypress on the pc keyboard, as far as I can make out. And the wiring shows a stepper motor wired in far right with the dc motor lurking by the tool box....
breadboard hook-up wires won't take 4A or anything like that - often they have significant series resistance and I'd
keep them for low current use only. Also some of the croc-clip leads I've bought weren't even soldered to the clips
and had stupidly thin wires. If you want 4A to flow reliably you'll need better wiring and screw-terminals or soldered connections only.