Loading...
  Show Posts
Pages: [1]
1  Using Arduino / Motors, Mechanics, and Power / Re: DC Motor crashes cpu when it nears full speed. on: February 03, 2013, 09:43:22 am
Can the motor supply drive the motor at full speed (ie directly connected, no transistor) without the
voltage falling below the nominal value?  (ie is the power source up to the job?)

Have you ensured _both_ power and ground wires to the motor circuit branch off before the 7805, that the 7805
has suitable decoupling right next to it?

I ended up swapping over to a different brand of motor and I don't seem to have this issue now.
But yes, the motor positive and negative are connected to the power supply before the 7805, and at the 7805 I have a 10uf cap before and after it as per the instructions found here: http://arduino.cc/en/Main/Standalone
maybe the caps need to be larger?

I read the motor running at full speed and it was drawing around ~400MA, both the power supplies I tested could support 900MA and 1000MA
2  Using Arduino / Motors, Mechanics, and Power / Re: DC Motor crashes cpu when it nears full speed. on: January 30, 2013, 08:39:29 pm
Chances are you have a common ground wire or ground loop or similar issue. Post a photo of your setup.

I'm creating what I currently have in Fritzing. I'll post that when it's done, my breadboard is a mess of wires and you wouldn't be able to tell where anything is going.
3  Using Arduino / Motors, Mechanics, and Power / Re: DC Motor crashes cpu when it nears full speed. on: January 30, 2013, 08:38:06 pm
Typically one could start looking with an oscilloscope to see what the Vcc voltage looks like and possibly how you have the arduino and motor ground wires routed to the negative terminal of the power source, they should not share the same conductor anywhere and be connected together only at the power supply.

 It can be solved but you have to have good tools to see what you are up against and what effect any changes you make have on the situation.

Lefty

it's pretty much setup like this
http://bildr.org/blog/wp-content/uploads/2011/03/tip120-solenoid.png

my power connections for the motor are connected to the dc supply, before the 7805 regulator. Maybe I'll rip it apart and start from scratch with the uno, then move to the breadboard arduino when that's functioning, Although I've done that already a few times.
4  Using Arduino / Motors, Mechanics, and Power / DC Motor crashes cpu when it nears full speed. on: January 29, 2013, 08:50:56 pm
I've confirmed that this happens with my Arduino Mega 1280, Uno and a breadboard atmega328 running standalone. Sometimes after it crashes the cpu the only way to recover is to reflash my program. I thought it may have been my code so I setup a simple pwm output with a potentiometer program and it still crashes when the motor is approaching full rpm. Sometimes it does not crash right away, But it usually doesn't last more than 30sec at high speed.

for the motor power I've tried two power supplies, one 18v and another 14v. On my breadboard arduino this power supply is also powering the atmega328 chip with a 7805 regulator, on my mega and uno the power supply is only powering the motor, The DC motor can support up to 18v. It's just a off the shelf toy dc motor that I got from "The Source" (canadian radioshack) I'm using a TIP120 transistor to control it with a 2.2k resistor (I've tried other combinations) between the output pin of the arduino and the base of the tip120. I've put a 0.01uf cap between the power legs on the motor as well as a 1n4004 diode. I've also extended the wires and moved the motor further away from the breadboard where the arduino is and it's still locking up the atmega chip.

I believe I've tried everything except more 0.01uf caps between the power legs of the motor to the motor case to further cut down on interference so I'm currently at a loss as to why this is happening.

In my searching I can't really seem to find anyone else with this issue that couldn't solve it by doing at least one of the things I already have tried.
5  Using Arduino / Interfacing w/ Software on the Computer / Re: serial data with breadboard atmega328 and using TX/RX on uno on: January 28, 2013, 10:00:20 pm
There has to be a shared ground connection from your breadboard system to the system (your 'chipless' Uno board) that has the USB serial converter chip, otherwise the send and receive signals will not work between those two different circuits.

Lefty


It works, Thank you!
6  Using Arduino / Interfacing w/ Software on the Computer / serial data with breadboard atmega328 and using TX/RX on uno on: January 28, 2013, 09:29:43 pm
I've setup an atmega328 on a breadboard and it's working fine. Only problem is that for power I have LM7805 that's going to be powering it. Right now I'm powering the breadboard arduino with USB power from the chipless UNO board, +5 and GND and the TX/RX to capture serial data. When I'm powering it from the 7805 do I have to just share the GND connection? I assume serial communication will need a shared gnd, or is there another way to do this? I usually would just try it, but I don't want to blow the communication chip on the uno board as it is my only one.
7  Using Arduino / Sensors / Re: using an interrupt to get rpm on: January 13, 2013, 08:32:58 pm
I redid everything and I'm now using the TimedAction library to check for the RPM every 100ms and apply the correct math to it in the TimedAction loop. As far as I can see it's working perfectly and the PID follows nearly perfect. I've even added another pulse per revolution on my wheel and it smoothed things out, I will add a few more when I get down to making the final product. I still have to add another pulse counter for the setpoint so I hope it will be able to handle two interrupts without much slowdown.
Also I did find that I was getting a lot of interference from the motor and it was causing false rpm readings.. I found that using the same GND for the power supply that's powering the motor that I was also using for the IR sensor causes this and it has to be moved to the other gnd pin.
Thank you everyone for your advice, even though I did end up using another method, But it is appreciated smiley
8  Using Arduino / Sensors / Re: using an interrupt to get rpm on: January 10, 2013, 07:31:45 am
Well you're right about it being broken smiley-wink. For starters, you're never updating Input within loop().

You shouldn't be updating your RPM measurement every 20 counts. You're trying to smooth out the readings for the current RPM but you should leave that work to the PID library. If you're having problems with your optical sensing then you need to fix that or you will never get reliable control.

I would suggest that you simplify by setting Input to the time (milliseconds) between interrupts. Also adjust the value read from analogRead(setpointPin) to units that are equivalent to the milliseconds you want per revolution. Remember that the PID library tries to match the value of Input to Setpoint and the units for each variable must be equivalent.

It would also be helpful to know what range of speeds (what RPM will be typical) you're trying to achieve.

between 0-4000rpm. Thanks, when I get time I will redo and post the new code. I was just jumbling things around for testing and it ended up like this.. lol
9  Using Arduino / Sensors / Re: using an interrupt to get rpm on: January 09, 2013, 07:56:18 pm
Thank you for taking the time to explain all of this. It's really helpful and now I understand it a bit more.

currently my motor is 1 pulse per rotation for testing, it's just a thick band of tape on the shaft and 50% of it is painted silver and the other 50% of it is black so the optical ir reflective sensor can read it I hope that the resolution is not too low. I've been playing with the PID tuning settings for a while and it seems that most of my issues are leading back to the way it's getting the rpm.


the reason I didn't post all of my code it because it's messed up and I'm embarrassed.. but here it is, it might be broken in it's current state.

Code:
/******************************************************************
 * PID Simple Example (Augmented with Processing.org Communication)
 * Version 0.3
 * by Brett Beauregard
 * License: Creative-Commons Attribution Share-Alike
 * April 2011
 ******************************************************************/

#include <PID_v1.h>

//Define Variables we'll be connecting to
double Setpoint, Input, Output;
int setpointPin=0, inputPin=1, outputPin=13;

//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint,10,40,0, DIRECT);
 
 
 volatile byte rpmcount;

 unsigned int rpm;

 unsigned long timeold;


unsigned long serialTime; //this will help us know when to talk with processing

void setup()
{
  //initialize the serial link with processing
  Serial.begin(9600);
  attachInterrupt(0, rpm_fun, RISING);
     rpmcount = 0;
   rpm = 0;
   timeold = 0;
  //initialize the variables we're linked to
  Input = (rpm);
  Setpoint = analogRead(setpointPin);

  //turn the PID on
  myPID.SetMode(AUTOMATIC);
}

void loop()
{

 

 
  //send-receive with processing if it's time
  if(millis()>serialTime)
  {
    SerialReceive();
    SerialSend();
    serialTime+=500;
  }
     if (rpmcount >= 20) {
     //Update RPM every 20 counts, increase this for better RPM resolution,
     //decrease for faster update
     rpm = 30*1000/(millis() - timeold)*rpmcount;
     timeold = millis();
     rpmcount = 0;
  //pid-related code
  Setpoint = analogRead(setpointPin);
  myPID.Compute();
  analogWrite(outputPin,Output);
 
   }
 }

 void rpm_fun()
 {
   rpmcount++;
   //Each rotation, this interrupt function is run twice
 }



/********************************************
 * Serial Communication functions / helpers
 ********************************************/


union {                // This Data structure lets
  byte asBytes[24];    // us take the byte array
  float asFloat[6];    // sent from processing and
}                      // easily convert it to a
foo;                   // float array



// getting float values from processing into the arduino
// was no small task.  the way this program does it is
// as follows:
//  * a float takes up 4 bytes.  in processing, convert
//    the array of floats we want to send, into an array
//    of bytes.
//  * send the bytes to the arduino
//  * use a data structure known as a union to convert
//    the array of bytes back into an array of floats

//  the bytes coming from the arduino follow the following
//  format:
//  0: 0=Manual, 1=Auto, else = ? error ?
//  1: 0=Direct, 1=Reverse, else = ? error ?
//  2-5: float setpoint
//  6-9: float input
//  10-13: float output 
//  14-17: float P_Param
//  18-21: float I_Param
//  22-245: float D_Param
void SerialReceive()
{

  // read the bytes sent from Processing
  int index=0;
  byte Auto_Man = -1;
  byte Direct_Reverse = -1;
  while(Serial.available()&&index<26)
  {
    if(index==0) Auto_Man = Serial.read();
    else if(index==1) Direct_Reverse = Serial.read();
    else foo.asBytes[index-2] = Serial.read();
    index++;
  }
 
  // if the information we got was in the correct format,
  // read it into the system
  if(index==26  && (Auto_Man==0 || Auto_Man==1)&& (Direct_Reverse==0 || Direct_Reverse==1))
  {
    Setpoint=double(foo.asFloat[0]);
    //Input=double(foo.asFloat[1]);       // * the user has the ability to send the
                                          //   value of "Input"  in most cases (as
                                          //   in this one) this is not needed.
    if(Auto_Man==0)                       // * only change the output if we are in
    {                                     //   manual mode.  otherwise we'll get an
      Output=double(foo.asFloat[2]);      //   output blip, then the controller will
    }                                     //   overwrite.
   
    double p, i, d;                       // * read in and set the controller tunings
    p = double(foo.asFloat[3]);           //
    i = double(foo.asFloat[4]);           //
    d = double(foo.asFloat[5]);           //
    myPID.SetTunings(p, i, d);            //
   
    if(Auto_Man==0) myPID.SetMode(MANUAL);// * set the controller mode
    else myPID.SetMode(AUTOMATIC);             //
   
    if(Direct_Reverse==0) myPID.SetControllerDirection(DIRECT);// * set the controller Direction
    else myPID.SetControllerDirection(REVERSE);          //
  }
  Serial.flush();                         // * clear any random data from the serial buffer
}

// unlike our tiny microprocessor, the processing ap
// has no problem converting strings into floats, so
// we can just send strings.  much easier than getting
// floats from processing to here no?
void SerialSend()
{
  Serial.print("PID ");
  Serial.print(Setpoint);   
  Serial.print(" ");
  Serial.print(Input);   
  Serial.print(" ");
  Serial.print(Output);   
  Serial.print(" ");
  Serial.print(myPID.GetKp());   
  Serial.print(" ");
  Serial.print(myPID.GetKi());   
  Serial.print(" ");
  Serial.print(myPID.GetKd());   
  Serial.print(" ");
  if(myPID.GetMode()==AUTOMATIC) Serial.print("Automatic");
  else Serial.print("Manual"); 
  Serial.print(" ");
  if(myPID.GetDirection()==DIRECT) Serial.println("Direct");
  else Serial.println("Reverse");
}
10  Using Arduino / Sensors / using an interrupt to get rpm on: January 08, 2013, 11:21:01 pm
I've seem to have run into a wall when trying to get the RPM of a DC Motor to use for PID Control.
I've butchered my own code so I'm going to start fresh with examples of just the rpm code so it's easier to understand.

when using this code to get the rpm, Because of the 1 second delay the PID code is only getting a rpm update every second which is making my motor pulse up and down and it never finds the setpoint, I change this to a very low number and it doesn't matter, the delay just gets shorter but it doesn't help. If I remove the delay, then the rpm doesn't update at all. I assume it should, just with no delay? but I guess not.


Code:
void loop()
 {
   //Update RPM every second
   delay(1000);
   //Don't process interrupts during calculations
   detachInterrupt(0);
   rpm = 30*1000/(millis() - timeold)*rpmcount;
   timeold = millis();
   rpmcount = 0;
   attachInterrupt(0, rpm_fun, FALLING);
  }


This code which is basically the same as above but instead of a delay it has a if statement. It updates the RPM every 20 pulses and does not go back to 0 if the rpm input stops, which is a issue. Because if the PID overshoots and the motor turns off, the rpm will never come back down and it will never start again.

Code:
void loop()
 {
//Update RPM every 20 counts
if (rpm >= 20) {
   //Don't process interrupts during calculations
   detachInterrupt(0);
     rpm = 30*1000/(millis() - timeold)*rpmcount;
     timeold = millis();
     rpmcount = 0;
attachInterrupt(0, rpm_fun, FALLING);
}

I can't figure this out. I basically need the rpm to always be updated with no delay (so the first block of code is out) but the second block of code won't go back to 0 if the input stops, it just stays at the last rpm it was at.
I might be going at this the wrong way, I don't know. Someone please put me in the right direction. If it helps I'm using the PID library and the processing front end to monitor what's going on with this.
11  Using Arduino / Motors, Mechanics, and Power / Simple Motor Speed Control - Help Please! on: November 02, 2011, 10:21:33 pm
What I am looking to do is control the speed of a 12vDC Motor in one direction, but I need stable and repeatable RPM Results. I have no problem getting it to work with just PWM but I realize that I will need to put a rotary encoder on the motor and somehow control it by monitoring that value and adjusting the PWM output if the motor ever see's load.

to start out with I just want to get to the point where I can just manually put a rpm value into a variable, or change that value through a potentiometer and have the motor go to the correct rpm that the value is asking for and attempt to hold it if I put load on the motor. I can work out from there. I'm not using a motor shield, or H-Bridge.. just a TIP120 transistor, like I said, only one direction, speed up and down.
in the end the input will be coming from a hall sensor from another piece of equipment and the DC motor rpm will change depending on the shaft rotation from that device.

I have looked at the PID Library, and I'm sure this can be done without it, but I can't seem to find any examples without a tonne of extra's in the code that I tend to get lost in, and I honestly can't find anyone who is just doing simple one direction control.
12  Forum 2005-2010 (read only) / Syntax & Programs / Re: LED Bar using PWM outputs for fading each LED on: December 20, 2010, 05:45:11 pm
well I can't believe it was something that simple.. ok I'm getting somewhere now.
thank you!
13  Forum 2005-2010 (read only) / Syntax & Programs / LED Bar using PWM outputs for fading each LED on: December 20, 2010, 12:08:30 am
Hi everyone.. I am a new arduino user.. I have a Mega board and I've been messing with it for a few weeks.
I have 10 LED's setup and functioning using the PWM outputs. With the push of a button I want to start off with pin1 and fade it in over 200ms and keep it on then move to pin2 and repeat, so over the course of 2 seconds I illuminate the strip.

I have this operating fine when just turning on the LED's using     digitalWrite(pin, HIGH);  but when it comes to using a pwm output with 255 steps it wants to cycle through only one step at a time before moving to the second led.

I have tried everything I can think of. I could see this working if you could somehow use multiple loops that exit and go to the next when the 255 value is achieved, but I'm sure that's impossible. and not to mention that the led would probably turn off when you exit that loop.

here is the last code I was working on and I keep changing it constantly so this is probably not what everyone expects to see (I removed the button part for testing so ignore that)
with this code it's not even fading, just turning on the LED's it was fading at one point smiley-sad

Code:
const int buttonPin = 12;  
int value = 0;                    
int ledPin1 =  2;
int ledPin2 =  3;
int ledPin3 =  4;
int ledPin4 =  5;
int ledPin5 =  6;
int ledPin6 =  7;
int ledPin7 =  8;
int ledPin8 =  9;
int ledPin9 =  10;
int ledPin10 =  11;
int buttonState = 0;

void setup()   {                
  // initialize the digital pin as an output:
  pinMode(buttonPin, INPUT);  
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);
  pinMode(ledPin4, OUTPUT);
  pinMode(ledPin5, OUTPUT);
  pinMode(ledPin6, OUTPUT);
  pinMode(ledPin7, OUTPUT);
  pinMode(ledPin8, OUTPUT);
  pinMode(ledPin9, OUTPUT);
  pinMode(ledPin10, OUTPUT);  
}

// Program

void loop()                    
{
  buttonState = digitalRead(buttonPin);
  // LED STRIP ON
  {
 for(value = 0 ; value <= 255; value+=5)
   analogWrite(ledPin1, value);  
   delay(100);    
 }
  {
 for(value = 0 ; value <= 255; value+=5)
   analogWrite(ledPin2, value);    
   delay(100);                    
 }  
  {
 for(value = 0 ; value <= 255; value+=5)
   analogWrite(ledPin3, value);      
   delay(100);              
 }  
  {
 for(value = 0 ; value <= 255; value+=5)
   analogWrite(ledPin4, value);    
   delay(100);                      
  }
    {
 for(value = 0 ; value <= 255; value+=5)
   analogWrite(ledPin5, value);    
   delay(100);                      
  }
    {
 for(value = 0 ; value <= 255; value+=5)
   analogWrite(ledPin6, value);    
   delay(100);                      
  }
    {
 for(value = 0 ; value <= 255; value+=5)
   analogWrite(ledPin7, value);    
   delay(100);                      
  }
    {
 for(value = 0 ; value <= 255; value+=5)
   analogWrite(ledPin8, value);    
   delay(100);                      
  }
    {
 for(value = 0 ; value <= 255; value+=5)
   analogWrite(ledPin9, value);    
   delay(100);                      
  }
    {
 for(value = 0 ; value <= 255; value+=5)
   analogWrite(ledPin10, value);    
   delay(100);                      
  }
}
Pages: [1]