hello all,
we trying to build an arduino robot ...
by using the following components:
1x Pololu Dual MC33887 motor controller
2x GHM-16 gearhead motors
2x QME-01 encoders (attached to the motors)
1x ps2 mouse
1x Arduino Duemilanove
specs
http://www.looksgood.de/_tmp/ghm16.pdf
http://www.looksgood.de/_tmp/encodeur-quadrature-qme-01-lynxmotion-assembly-guide.pdf
http://www.looksgood.de/_tmp/schaltplan2009.10.14.pdf
actually we are quite happy that we reached already the step, that we have everything up and running:
we get precise encoder values, we are able to control the motors with PWM via the pololu controller and with the help of the ps2 library the mouse is also working as an input sensor.
but so far we couldn't solve one strange problem:
if we drive the motors above certain PWM values the whole arduino freezes
for instances:
// causes freeze
out_motorPWM[0] = 255;
out_motorPWM[1] = 255;
// working
out_motorPWM[0] = 127;
out_motorPWM[1] = 127;
please note also, without reading the mouse values in the main loop, we have no problems to drive the motors with any PWM value without any freeze.
so it seems to us that we have some strange interaction with the motors and the ps2 mouse lib.
any hint is very welcome. see below code and wiring.
thanks
benedikt
#include <ps2.h>
// Ps2mouse lib -> http://www.arduino.cc/playground/ComponentLib/Ps2mouse
// ---- pins ----
#define pinM1_DirectionA 4
#define pinM1_DirectionB 5
#define pinM1_PWM 10
#define pinM2_DirectionA 13
#define pinM2_DirectionB 7
#define pinM2_PWM 11
#define pinE1_A 2
#define pinE1_B 8
#define pinE2_A 3
#define pinE2_B 6
#define pinP_data 9
#define pinP_clock 12
PS2 mouse(pinP_clock, pinP_data);
// ---- vars ----
int out_motorPWM[2] = {
0,0};
// encoder 1
volatile int in_steps1 = 0;
int in_E1_prev = LOW;
int in_E1_curr = LOW;
// encoder 2
volatile int in_steps2 = 0;
int in_E2_prev = LOW;
int in_E2_curr = LOW;
// mouse
char mstat = '0';
char mx = '0';
char my = '0';
void setup() {
// motor controller
pinMode(pinM1_DirectionA, OUTPUT);
pinMode(pinM1_DirectionB, OUTPUT);
pinMode(pinM1_PWM, OUTPUT);
pinMode(pinM2_DirectionA, OUTPUT);
pinMode(pinM2_DirectionB, OUTPUT);
pinMode(pinM2_PWM, OUTPUT);
// encoders
pinMode (pinE1_A,INPUT);
pinMode (pinE1_B,INPUT);
pinMode (pinE2_A,INPUT);
pinMode (pinE2_B,INPUT);
attachInterrupt(0, doEncoder1, CHANGE);
attachInterrupt(1, doEncoder2, CHANGE);
Serial.begin(19200);
Serial.println("hello");
mouse_init();
// wait for the mouse to be ready
delay(2000);
}
void loop() {
// ---- read data from computer host ----
if (Serial.available() > 0) {
int incomingByte = Serial.read();
// turn on both motors
if (incomingByte == 'h') {
// cause arduino to freeze
out_motorPWM[0] = 255;
out_motorPWM[1] = 255;
// works
//out_motorPWM[0] = 127;
//out_motorPWM[1] = 127;
}
// turn off both motors
if (incomingByte == 'l') {
out_motorPWM[0] = 0;
out_motorPWM[1] = 0;
}
}
// ---- set PWM + direction motor controller ----
drive("motor1");
drive("motor2");
analogWrite(pinM1_PWM, abs(out_motorPWM[0]));
analogWrite(pinM2_PWM, abs(out_motorPWM[1]));
// ---- read mouse data ----
mouse.write(0xeb); // give me data!
mouse.read(); // ignore ack
mstat = mouse.read();
mx = mouse.read();
my = mouse.read();
// ---- send data to host ----
Serial.print(in_steps1);
Serial.print(';');
Serial.print(in_steps2);
Serial.print(';');
Serial.print(mx, DEC);
Serial.print(';');
Serial.print(my, DEC);
Serial.println();
// reset variables after sending data, we just wanna have the delta
in_steps1 = 0;
in_steps2 = 0;
}
// ---- turn motros on + set direction ----
void drive(char m[]) {
if (m=="motor1" && out_motorPWM[0]>=0) { // forward
digitalWrite(pinM1_DirectionA, HIGH);
digitalWrite(pinM1_DirectionB, LOW);
}
else if (m=="motor1" && out_motorPWM[0]<0) { // backward
digitalWrite(pinM1_DirectionA, LOW);
digitalWrite(pinM1_DirectionB, HIGH);
}
else if (m=="motor2" && out_motorPWM[1]>=0) { // forward
digitalWrite(pinM2_DirectionA, HIGH);
digitalWrite(pinM2_DirectionB, LOW);
}
else if (m=="motor2" && out_motorPWM[1]<0) { // backward
digitalWrite(pinM2_DirectionA, LOW);
digitalWrite(pinM2_DirectionB, HIGH);
}
}
// ---- encoder interrupts event ----
void doEncoder1() {
// left motor, cw = forward
if ((digitalRead(pinE1_A) == HIGH)) {
if (digitalRead(pinE1_B) == LOW) {
in_steps1++;
}
else {
in_steps1--;
}
}
else {
if (digitalRead(pinE1_B) == LOW) {
in_steps1--;
}
else {
in_steps1++;
}
}
}
void doEncoder2() {
// right motor, cw = backward
if (digitalRead(pinE2_A) == HIGH) {
if (digitalRead(pinE2_B) == LOW) {
in_steps2--;
}
else {
in_steps2++;
}
}
else {
if (digitalRead(pinE2_B) == LOW) {
in_steps2++;
}
else {
in_steps2--;
}
}
}
// ---- mouse ----
void mouse_init()
{
mouse.write(0xff); // reset
mouse.read(); // ack byte
mouse.read(); // blank */
mouse.read(); // blank */
mouse.write(0xf0); // remote mode
mouse.read(); // ack
delayMicroseconds(100);
}