Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

BASIC PIC command for dual PWM motor control?

Status
Not open for further replies.

blueroomelectronics

Well-Known Member
I'm writing a module in Swordfish BASIC for the Mongoose robot kit. I've looked at the now discontinued Micro-Bot's PICBasic Pros "MotorDir" command for controlling a pair of servo motors.
Here's what I've come up with.
Code:
MotorLR(lm,rm,offset)
where:
lm = +/-1023 (sets left motor direction & 10bit PWM directly)
rm = +/-1023 (sets right motor direction & 10bit PWM directly)
offset = +/- 127 (subtracts from lm + and rm -) corrects motor difference

Also I'm trying to figure out a syntax for the wheel rotation sensors. Two integer variables +/- 32767 (approx +/-50m on the Mongoose) will be automatically updated using Swordfish's interrupt on change module.

Any suggestions?
 
When working with decoding a Vex xmitter and sending the info to a Tamiya dual gearbox motor, pwm seemed difficult to achieve. Ended up with just going on or off. The 10 bit pwm makes for a great led dimmers, but is it practical for a motor?

The offset is a good idea, because when my batteries get low its not going straight at all, although the vex xmitter can adjust for that. The Vex uses up and down buttons and a counter no doubt to achieve that.
 
nickelflippr said:
When working with decoding a Vex xmitter and sending the info to a Tamiya dual gearbox motor, pwm seemed difficult to achieve. Ended up with just going on or off. The 10 bit pwm makes for a great led dimmers, but is it practical for a motor?

The offset is a good idea, because when my batteries get low its not going straight at all, although the vex xmitter can adjust for that. The Vex uses up and down buttons and a counter no doubt to achieve that.

PWM is how you SHOULD drive a DC motor, those Vex servos require much more CPU overhead where as hardware PWM is set and go.
 
I found this easy to use. I have the C code for the moongose H-Bridge working. This is from memory. Should have just pulled up the code...

EDIT: Move could also watch the rotation sensors and adjust PWM to ensure that each wheel moves the correct percentage of the other. The offset could be learned/calculated and the user would need not bother with it.

Code:
// command to move robot
void move(
   int16 duration,       // duration of command, IIRC in 10ths of a second
   byte montion,       //  how to set the H-Bridge.
   byte powerLeft,  // % power for left motor
   byte powerRight) // % power for right motor
The first 4 bits of the motion parameter apply to the left motor h-bridge. The last 4 the right. The power settings specify the PWM setting.

Where motion can be one of a set of defines that look like
Code:
#define L_FOR = XXXX
#define R_FOR = XXXX
#define FOR = L_FOR + R_FOR

#define L_REV = XXXX
#define R_BAK = XXXX
#define REV = L_REV + R_REV

#define L_COAST = XXXX
#define R_COAST = XXXX
#define COAST = L_COAST + R_COAST

#define L_BRAKE = XXXX
#define R_BRAKE = XXXX
#define BRAKE = L_BRAKE + R_BRAKE

#define L_TURN = R_FOR + LEFT_BRAKE
#define R_TURN = L_FOR + R_BRAKE

#define L_SPIN = R_FOR + L_REV
#define R_SPIN = L_FOR + R_REV
From what I have seen 100 steps for motor speed is more the enough. Much of the time I define a FAST, MEDIUM, and SLOW and use them.
Code:
move(100,FOR,100,95)  // wide circle for 10 seconds
move(30,L_SPIN,50,50) // spin to the left for two seconds.

I am sending a PM.
 
Last edited:
I've setup the 18F2525 to run at 4MHz with a period of ~2KHz this allows the full 1024 step duty and the motors are happy with it.
This was easy in either assembler, BASIC and C just set the direction PORTB 0-3 write to a few SFRs and the motors run.

As for continous servos they use the same 1ms to 2ms to control speed and direction, 1.5 is stop (more or less :) sometimes they stutter)
 
Isn't a 2 KHz period equal to 500 usecs? How do you develop a 1 to 2 msec pulse within a 500 usec period? What am I missing?
 
Here's the main code, simple MotorLM(Left,Right) command
Code:
Device = 18F2525        // Required for Mongoose
Clock = 8               // 8MHz required clock for Mongoose.bas 0.9 beta
Config OSC = INTIO67, LVP = OFF, PBADEN = OFF
Include "Mongoose.bas"
MotorLR(65,127)
DelayMS(8000)
MotorLR(0,0)
End

Here's the module code (beta)
Code:
{
*****************************************************************************
*  Name    : MONGOOSE.BAS                                                   *
*  Author  : William Richardson                                             *
*  Notice  : Copyright (c) 2007 blueroomelectronics                         *
*          : All Rights Reserved                                            *
*  Date    : 12/23/2007                                                     *
*  Version : 0.9 beta
 Notes   
    : Routines designed for 8 MHz Clock
    : 976.5625KHz PWM Motor module                    
    : MotorLR (LeftMotor +/-127, RightMotor +/-127) 
*****************************************************************************
}
Module Mongoose
Device  = 18F2525
{
*****************************************************************************
* Name    : MotorLR (LeftMotor, RightMotor)                                 *
* Purpose : Sets PWM direction and speed for left & Right motors            *
*           Range +127 / -127 (positive forward, 0 stop, negative reverse)  *
*****************************************************************************
}
Public Sub MotorLR(LeftMotor, RightMotor As ShortInt)
LATB = 0                ' clear the direction 
If LeftMotor < 0
    Then
    LeftMotor = -LeftMotor      // abs()
    High(PORTB.3)       // Reverse LeftMotor
    Else
    High(PORTB.1)       // Forward LeftMotor 
EndIf
If RightMotor < 0
    Then
    RightMotor = -RightMotor    // abs()
    High(PORTB.2)       // Reverse RightMotor
    Else
    High(PORTB.0)       // Forward RightMotor
EndIf                          
CCPR2L =  LeftMotor     // 0 - $7F  
CCPR1L = RightMotor     // 0 - $7F

End Sub
// Initialize PWM module & I/O for 1KHz PWM operation (Private)
Inline Sub InitMongoose()  
OSCCON = $72            ' enable 8MHz clock
CMCON = 7               ' comparators off
PR2 = $7F               ' 9bit PWM mode
CCP1CON = $0C           ' CCP1 enable PWM mode
CCP2CON = $0C           ' CCP2 enable PWM mode
CCPR1L = 0              ' zero duty register Left Motor
CCPR2L = 0              ' zero duty register Right Motor
T2CON = %00000101       ' 1:4 prescaler, TMR2 on (1953.125KHz PWM)
TRISB = %11110000       ' motor direction
TRISC = %11111001       ' PWM outputs RC1, RC2
End Sub
// Initialize the Mongoose
Config OSC = INTIO67, LVP = OFF, PBADEN = OFF
InitMongoose
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top