Pages: 1 [2] 3   Go Down
Author Topic: Tank Robot Sr. Design - PWM questions  (Read 3774 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 200
Posts: 12773
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I still cannot find documentation in the datasheet about what pins lead to these. I think this is because the datasheet is not specific to the Arduino Uno.

This should help (the labels / assignments are the same for the 328 processor)...

http://www.arduino.cc/en/Hacking/PinMapping168
Logged

Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 200
Posts: 12773
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
According to the register summary many of the bits transfer over directly by changing n=1 to n=2.

That is certainly true but timer 2 does not have a mode 14.  To get 10 KHz output it is necessary to set the prescaler and the TOP value.  That means you will have to use mode 7.  That also means that OCR2A is used to set the TOP value and you will have to give up one output (OC2A).

I think this will work...

Code:
void setup( void )
{
  // Turn off the timer while we make changes
  TCCR2B = TCCR2B & ~ ((1 << CS22) | (1 << CS21) | (1 << CS20));
 
  // Ensure the Timer 2 output pin is configured for output
  pinMode( 3, OUTPUT );
 
  // Set Compare Output Mode and part of the Waveform Generation Mode (mode 7)
  TCCR2A =
      (0 << COM2A1) | (0 << COM2A0) 
      |
      (1 << COM2B1) | (0 << COM2B0) 
      |
      (1 << WGM21) | (1 << WGM20); 

  // Set the other half of the Waveform Generation Mode (mode 7) and ensure a few things are disabled
  TCCR2B =
      (0 << FOC2A) 
      |
      (0 << FOC2B) 
      |
      (1 << WGM22)
      |
      (0 << CS22) | (0 << CS21) | (0 << CS20); 


  OCR2A = 199;

  // Start with the output turned off
  OCR2B = 0;
 
  // Start the clock
  TCCR2B =
      TCCR2B
      |
      (0 << CS22) | (1 << CS21) | (0 << CS20); 
}
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I still cannot find documentation in the datasheet about what pins lead to these. I think this is because the datasheet is not specific to the Arduino Uno.

This should help (the labels / assignments are the same for the 328 processor)...

http://www.arduino.cc/en/Hacking/PinMapping168


That is a handy reference. I was able to infer the timer1 and timer2 pins but this will be much faster in the future.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I haven't had a chance to test out that code yet. Before I can, I have a basic question about implementation.

I have a PS2 controller interface library from Bill Porter, and I am writing a motor control program to output phase-correct PWM to a motor driver. I know that I can use #include ps2x.h to include the library of commands for the controller. Where do these timer modifier codes go? In the setup section of my motor control program? Or are they 'called' in a similar way to the ps2x library? If you need me to provide what I have written, I can.

Also, do all of the libraries upload to the arduino when I upload a program? If not how are they employed?

Thank you.
Logged

Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 200
Posts: 12773
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I have a PS2 controller interface library from Bill Porter, and I am writing a motor control program to output phase-correct PWM to a motor driver.

Will that be part of the project you described above?

Quote
Where do these timer modifier codes go? In the setup section of my motor control program?

In setup.  But you will not be able to use the stuff above with the PS2 controller interface library.  There are three timers on an Arduino Uno.  Timer 0 is used by millis (and two PWM pins).  It should be left alone.

The stuff above modifies timer 1 and timer 2 to generate a 10 KHz fast PWM signal on up to three pins.  The PS2 controller interface library is also going to use a timer (either 1 or 2).  You've run out of timers.

Quote
Or are they 'called' in a similar way to the ps2x library?

Not in their current form.  The code could be turned into a library but I recommend including it directly in your Sketch at least until you've tested it.

Quote
Also, do all of the libraries upload to the arduino when I upload a program?

No.  First, there has to be a reference to the library.  That's what the "#include" lines do.  Then, your Sketch has to actually use the library.

Basically, only the stuff used in your Sketch gets uploaded.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Following all of your help, I have really begun to get a handle on the programming for this project.

I was informed that the larger motors I am using make fast PWM less important due to the inertia of the motor. Coupled with the fact that modifying the timers was impractical to use in the same project as the PS2 interface, I have abandoned the timer modification.

Here is the code I have come up for my motor control.

Note also the scale of the project was reduced to 3 motors.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
#include <PS2X_lib.h>  //for v1.6
PS2X ps2x; // create PS2 Controller Class

//Initializes some variables used
int error = 0;
byte vibrate = 0;
int RYin = 0;
int RYout = 0;
int LYin = 0;
int LYout = 0;
int timer = 1;    // Every clock cycle is ~50 milliseconds, so 100 clock cycles is 5 seconds. To set a timer vibration time, use (# of seconds x 1000/50)
int SMS = 128;    //Set Scoop Motor Speed from 0-255.

//Use this section to change which pin outputs are used.
int  pwmPinL = 3;
int signPinL = 2;
int  pwmPinR = 9;
int signPinR = 4;
int  pwmPinS = 5;
int signPinS = 8;

void setup() {
  Serial.begin(57600);
 
 //Check for error
 //Notes:
 //Clock = blue wire
 //Command = orange wire
 //Attention = yellow wire
 //Data = brown wire, has a 10k pull-up resistor connected to 3.3V VCC
 error = ps2x.config_gamepad(13,11,10,12, false, true); //setup pins and settings:  GamePad(clock, command, attention, data, Pressures?, Rumble?)
 
 if(error == 0){
   Serial.println("Found Controller, configured successful");
 }
 
  else if(error == 1)
   Serial.println("No controller found, check wiring, see readme.txt to enable debug. visit www.billporter.info for troubleshooting tips");
   
  else if(error == 2)
   Serial.println("Controller found but not accepting commands. see readme.txt to enable debug. Visit www.billporter.info for troubleshooting tips");
   
  else if(error == 3)
   Serial.println("Controller refusing to enter Pressures mode, may not support it. ");
   
//Set all pins used to output mode
  pinMode( pwmPinL , OUTPUT );
  pinMode( signPinL, OUTPUT );
  pinMode( pwmPinR , OUTPUT );
  pinMode( signPinR, OUTPUT );
  pinMode( pwmPinR , OUTPUT );
  pinMode( pwmPinS , OUTPUT );
  pinMode( signPinS, OUTPUT );
}  //End of setup

void loop() {
 
if(error == 1) //skip loop if no controller found
  return;
 
else {

  ps2x.read_gamepad(false,vibrate);         //read controller, send vibration signal to motor at vibrate (0-255)
 
  RYin = ps2x.Analog(PSS_RY);
  LYin = ps2x.Analog(PSS_LY);
//  Serial.print("Number of Cycles on Timer: ");
//  Serial.println(timer);

//------------------------------------------------------------------------------------ 
if(RYin > 128) {                         //Reads right stick vertical value and determines if value is greater than 128 (neutral) -> right stick pushed down     
     Serial.print("Right Motor Spinning Reverse, RYin=");
     Serial.print(RYin);

     RYout = ((2*(RYin))-256);           //Reads in stick position RYin, outputs linearly scaled PWM magnitude as RYout
     
     if(RYout > 255) {
         RYout = 255;
     }
     if(RYout == 0 || RYout == 1 || RYout == -1) {
         RYout = 0;
     }           
       
     Serial.print(". RYout= ");
     Serial.print(RYout);
     Serial.println(".");

     analogWrite(pwmPinR,RYout);         //Writes magnitude to pwmPinR
     digitalWrite(signPinR,LOW);         //Writes sign as LOW or reverse   
}                                        //End of if(RYin > 128)
//------------------------------------------------------------------------------------     
if(RYin < 128) {                         //Right stick pushed up
     Serial.print("Right Motor Spinning Forward, RYin=");
     Serial.print(RYin);
     
     RYout = ((-2*RYin)+255);            //Linearly scales magnitude to RYout
     
     if(RYout > 255) {
         RYout = 255;
     }
     if(RYout == 0 || RYout == 1 || RYout == -1) {
         RYout = 0;
     }           
       
     Serial.print(". RYout= ");
     Serial.print(RYout);
     Serial.println(".");
     
     analogWrite(pwmPinR,RYout);         //Writes magnitude to pwmPinR
     digitalWrite(signPinR,HIGH);        //Writes sign as HIGH or forward
}                                        //End of if(RYin < 128)
//------------------------------------------------------------------------------------
if(LYin > 128) {                         //Reads left stick vertical value and determines if value is greater than 128 (neutral) -> left stick pushed down
     Serial.print("Left Motor Spinning Reverse, LYin=");
     Serial.print(LYin);

     LYout = ((2*(LYin))-256);            //Reads in stick position LYin, outputs linearly scaled PWM magnitude as LYout
   
     if(LYout > 255) {                    //Corrects upper endpts
         LYout = 255;
       }
     if(LYout == 0 || LYout == 1 || LYout == -1) {   //Corrects lower endpt
         LYout = 0;
       }       
 
     Serial.print(", LYout = ");
     Serial.print(LYout);
     Serial.println(".");
     
     analogWrite(pwmPinL,LYout);         //Writes magnitude to pwmPinL
     digitalWrite(signPinL,LOW);         //Writes sign as LOW or reverse
}                                        //End of if(LYin > 128)
//------------------------------------------------------------------------------------
if(LYin < 128) {                         //Left stick pushed up
     Serial.print("Left Motor Spinning Forward, LYin=");
     Serial.print(LYin);
   
       LYout = ((-2*LYin)+255);          //Linearly scaled magnitude to LYout
     
       if(LYout > 255) {                 //Corrects upper endpts
         LYout = 255;
       }
       if(LYout == 0 || LYout == 1 || LYout == -1) {   //Corrects lower endpt
         LYout = 0;
       }       
 
     Serial.print(". LYout= ");
     Serial.print(LYout);
     Serial.println(".");
     
     analogWrite(pwmPinL,LYout);         //Writes magnitude to pwmPinL
     digitalWrite(signPinL,HIGH);        //Writes sign as HIGH or forward
}                                        //End of if(LYin < 128)
//------------------------------------------------------------------------------------
if(ps2x.Button(PSB_L2)) {                //Overrides timer limits for resetting scoop
     analogWrite(pwmPinS,SMS);           //Writes SMS power to pwmPinS
     digitalWrite(signPinS,HIGH);        //Spin forward -> open scoop
     Serial.println("Scoop Motor Spinning Forward");
}
//------------------------------------------------------------------------------------
if(ps2x.Button(PSB_R2)) {                //Overrides timer limits for resetting scoop
     analogWrite(pwmPinS,SMS);           //Writes SMS power to pwmPinS
     digitalWrite(signPinS,LOW);         //Spin reverse -> closes scoop
     Serial.println("Scoop Motor Spinning Reverse");

//------------------------------------------------------------------------------------

if(timer<=100 && timer>=1){              //Describes normal operation (R1 and L1 do same as R2 and L2 but change timer as well)
     vibrate = 0;
//------------------------------------------------------------------------------------     
     if(ps2x.Button(PSB_L1)) {           //Will be true as long as L1 is pressed
     analogWrite(pwmPinS,SMS);           //Writes full power to pwmPinS
     digitalWrite(signPinS,HIGH);        //Writes HIGH or forward -> opens scoop
     Serial.println("Scoop Operation Normal. Scoop Motor Spinning Forward");
     timer = timer++;
     }
//------------------------------------------------------------------------------------     
     if(ps2x.Button(PSB_R1)) {           //Will be true as long as R1 is pressed
     analogWrite(pwmPinS,SMS);           //Writes SMS power to pwmPinS
     digitalWrite(signPinS,LOW);         //Writes LOW or reverse -> closes scoop
     Serial.println("Scoop Operation Normal. Scoop Motor Spinning Reverse");
     timer = timer--;
     }
}                                        //End of if(timer<100)
if(timer>100){
     vibrate = 100;
     Serial.println("Vibration should be on. High Red Zone. ");
     if(ps2x.Button(PSB_L1)) {
     analogWrite(pwmPinS,0);             //Output a motor speed of 0. (Opeen button disabled)
     digitalWrite(signPinS,HIGH);        //Arbitrary
     Serial.println("Scoop Motor Already Fully Open");
      }
     if(ps2x.Button(PSB_R1)) {
     analogWrite(pwmPinS,SMS);           //Writes SMS power to pwmPinS
     digitalWrite(signPinS,LOW);         //Spin reverse
       timer = timer--;                  //Detracts from timer to take it out of red zone
     Serial.println("Leaving high red zone. Scoop Motor Spinning Reverse");
     }
}                                        //End of if(timer>101)

if(timer<1){
     vibrate = 100;
     Serial.println("Vibration should be on. Low Red Zone. ");
     if(ps2x.Button(PSB_L1)) {
     analogWrite(pwmPinS,SMS);           //Writes SMS power to pwmPinS
     digitalWrite(signPinS,HIGH);        //Spin forward
       timer = timer++;                  //Advances timer to take it out of red zone
     Serial.println("Leaving low red zone. Scoop Motor Spinning Forward");
      }
     if(ps2x.Button(PSB_R1)) {
     analogWrite(pwmPinS,0);             //Output a motor speed of 0. (Close button disabled)
     digitalWrite(signPinS,LOW);         //Arbitrary
     Serial.println("Scoop Motor Already Fully Closed");
     }
}                                        //End of if(timer<1)

//------------------------------------------------------------------------------------     

}                 //Corresponds to the else
 delay(50);
}                 //Corresponds to the void loop
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here is an updated schematic with only 1 motor connected for simplicity/testing purposes.

My program runs great and all components power on. Unfortunately, I cannot get the motor to turn by any means.

Is there a glaring error?


Additional information: 15A inline fuse between battery positive and MD10C. Motor runs when connected directly to battery.
« Last Edit: May 21, 2011, 07:23:44 pm by jdeck004 » Logged

New Jersey
Offline Offline
Faraday Member
**
Karma: 65
Posts: 3638
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Can you get it to work with a much simpler sketch that just turns the motor on?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
int pwmtestL = 3;
int signtestL = 2;

void setup()
{
Serial.begin(57600);
pinMode( pwmtestL , OUTPUT );
pinMode( signtestL, OUTPUT );
}
void loop()
{
analogWrite(pwmtestL,100);         //Writes magnitude to pwmPinL
digitalWrite(signtestL,LOW);         //Writes sign as LOW or reverse
}                                   

I tried to run it with this one and it also did not play out. I believe the coding is correct. I think I need a DMM to test how many amps I am pulling across certain terminals.
Logged

0
Offline Offline
Sr. Member
****
Karma: 0
Posts: 360
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What's the "MD10C" in your diagram?  If it's just a standard H-Bridge, you won't be able to run a direction and a PWM to it, unless the direction line connects to an inverter, and the PWM to 'enable'.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What's the "MD10C" in your diagram?  If it's just a standard H-Bridge, you won't be able to run a direction and a PWM to it, unless the direction line connects to an inverter, and the PWM to 'enable'.

http://www.robotshop.com/ca/cytron-single-dc-motor-controller-2.html

Quote
MD10C is compatible with 2 types of PWM operation, which are:
1. Sign-Magnitude PWM – For sign-magnitude PWM operation, 2 control signals are used
to control the speed and direction of the motor. PWM is feed to the PWM pin to control
the speed while DIR pin is used to control the direction of the motor.
2. Locked-Antiphase PWM – For locked-antiphase PWM operation, only 1 control signal is
needed to control the speed and direction of the motor. PWM pin is connected to logic
high while the DIR pin is being feed with the PWM signal. When the PWM signal has
50% duty cycle, the motor stops running. If the PWM has less than 50% duty cycle, the
motor will turn CW (or CCW depending on the connection). If the PWM signal has more
than 50% duty cycle, motor will turn CCW (or CW depending on the connection).
Logged

0
Offline Offline
Sr. Member
****
Karma: 0
Posts: 360
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hm... Have you tried skipping the Arduino and testing the motor controller directly (hook both inputs up to +5v)?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 28
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hm... Have you tried skipping the Arduino and testing the motor controller directly (hook both inputs up to +5v)?

No I have not but it sounds like a great idea. You mean PWM and DIR, right?

Could that 5V source still be the 5V pin from the Arduino? And I would continue to power the motor controller with the 9V?
Logged

0
Offline Offline
Sr. Member
****
Karma: 0
Posts: 360
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes, that's fine.  The motor power would come from the 12v battery, and logic power from the 9v (at least, from what I can tell from your diagram). 

It should send the motor into full speed in one direction.
Logged

Pages: 1 [2] 3   Go Up
Jump to: