Hi everybody,
I'm trying to modify a little example found on the web made for arduino UNO driving a motor with a pololu motor carrier BUT...
I'm not able to understand how can I make things work for my arduino mega2560, I mean, the last three #define are correct, but I can't understand PORTx and DDRx ones. In comments there's my solution. Is this the way?
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
/* Right motor */
#define rightPort PORTC //PORTA on mega
#define rightPortDirection DDRC //DDRA on mega
#define rightPwmPortDirection DDRB //DDRL on mega
#define rightA PINC4 // PC4 - pin A4 (1INA on the motor driver) // D22 on mega PA0
#define rightB PINC5 // PC5 - pin A5 (1INB on the motor driver) // D23 on mega PA1
#define rightPWM PINB2 // PB2 - pin 10 - (1PWM on the motor driver) // D44 on mega PL5
and in setup():
// /* Setup motor pins to output */
sbi(rightPwmPortDirection,rightPWM);
sbi(rightPortDirection,rightA);
sbi(rightPortDirection,rightB);
The digitalRead(), digitalWrite() and pinMode() functions may be too slow in some cases and in those cases the solution is to do direct port manipulation.
In your example, the right motor controller is wired:
1INA -> UNO A0 (PORTC bit 4) or MEGA Pin 22 (PORTA bit 0)
1INB -> UNO A1 (PORTC bit 5) or MEGA Pin 23 (PORTA bit 1)
1PWM -> UNO Pin 10 (PORTB bit 2) or MEGA Pin 44 (PORTL bit 5)
You just have to switch the values from the UNO values to the MEGA values.
/* Left motor */
#define leftPort PORTA
#define leftPortDirection DDRA
#define leftPwmPortDirection DDRL
#define leftA PINA2 // PA2- pin 24 ON MEGA (2INA on the Pololu motor driver)
#define leftB PINA3 // PA3- pin25 ON MEGA (2INB on the Pololu motor driver)
#define leftPWM PINL4 // PL4- pin 45 ON MEGA (2PWM on the Pololu motor driver)
/* Right motor */
#define rightPort PORTA
#define rightPortDirection DDRA
#define rightPwmPortDirection DDRL
#define rightA PINA0 // PA0 - pin 22 (1INA on the Pololu motor driver)
#define rightB PINA1 // PA1 - pin 23 (1INB on the Pololu motor driver)
#define rightPWM PINL5 // PL5 - pin 44 (1PWM on the Pololu motor driver)
/* Setup motor pins to output */
sbi(leftPwmPortDirection,leftPWM);
sbi(leftPortDirection,leftA);
sbi(leftPortDirection,leftB);
sbi(rightPwmPortDirection,rightPWM);
sbi(rightPortDirection,rightA);
sbi(rightPortDirection,rightB);
Can leftPort and rightPort be PORTA both ?
YES, because we are just accessing a register, I think.
The important thing is not to use a pin two times, but can I use a PORTA for both my two motors?
I'm driving crazy... everything was OK till I've read about port manipulation... but now motors don't work.. this is port test code... really don't know...
/* These are used to read and write to the port registers - see http://www.arduino.cc/en/Reference/PortManipulation
I do this to save processing power - see this page for more information: http://www.billporter.info/ready-set-oscillate-the-fastest-way-to-change-arduino-pins/ */
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
/* Left motor */
#define leftPort PORTA
#define leftPortDirection DDRA
#define leftPwmPortDirection DDRL
#define leftA PINA2 // PA2 - pin 24 (2INA on the Pololu motor driver)
#define leftB PINA3 // PA3 - pin 25 (2INB on the Pololu motor driver)
#define leftPWM PINL4 // PL4 - pin 45 (2PWM on the Pololu motor driver)
/* Right motor */
#define rightPort PORTA
#define rightPortDirection DDRA
#define rightPwmPortDirection DDRL
#define rightA PINA0 // PA0 - pin 22 (1INA on the Pololu motor driver)
#define rightB PINA1 // PA1 - pin 23 (1INB on the Pololu motor driver)
#define rightPWM PINL5 // PL5 - pin 44 (1PWM on the Pololu motor driver)
void setup() {
/* Setup motor pins to output */
sbi(leftPwmPortDirection,leftPWM);
sbi(leftPortDirection,leftA);
sbi(leftPortDirection,leftB);
sbi(rightPwmPortDirection,rightPWM);
sbi(rightPortDirection,rightA);
sbi(rightPortDirection,rightB);
TCCR5A = B00101001; // Phase and frequency correct PWM change at OCR5A
TCCR5B = B10001; // System clock
OCR5A = 800; // 16MHz/10kHz/2=800 prescaler a 1 (0-799)
OCR5B = 0; // motori fermi
OCR5C = 0;
}
void loop() {
setPWM(leftPWM,600);
setPWM(rightPWM,600);
}
void setPWM(uint8_t pin, int dutyCycle) { // dutyCycle is a value between 0-ICR
if(pin == leftPWM) {
OCR5BH = (dutyCycle >> 8);
OCR5BL = (dutyCycle & 0xFF);
} else if (pin == rightPWM) {
OCR5CH = (dutyCycle >> 8);
OCR5CL = (dutyCycle & 0xFF);
}
}
[/]