Hi everyone,
I'm trying to control a microscope stage with a home-built controller.
I'm using the Arduino Mega 2560 with a DFRobot 1A motor shield and a Sparkfun joystick kit.
The stage motors each have an encoder with 1000 pulses per revolution and a 1mm/rev gear factor.
When using the following code (I'm attaching only the relevant parts), I get very funny readouts:
/*
This program uses the following hardware:
1. Arduino mega2560
2. DFRobot 1A motor shield
3. Sparkfun joystick shield kit
...
It also supplies 5V to the encoders of the motors and reads data from the motors' limit
switches and encoder using interrupts - currently configured to count only full steps
as opposed to half-steps. This saves two timer\counter sockets (in order to count
half-steps as well one has to move encoder B outputs to timer\counter sockets and duplicate
interrupt function). The counting is done using interrupt socket #2 and #3, only available on
Arduino Mega.
Furthermore it prints out data on the serial monitor.
...
Motor 2 is defined as the x axis and Motor 1 is defined as the y axis
*/
const byte ENCODER_POWER_X = 23; //Sets pins 23 and 22 (arbitrary) as the 5V power sources for the x and y axis encoder respectively
const byte ENCODER_POWER_Y = 22;
const byte ENCODER_A_X = 21; //Sets timer/counter pins 21 (Timer counter 2) and 20 (Timer counter 3) as encoder A inputs for both axes
const byte ENCODER_A_Y = 20;
const byte ENCODER_B_X = 28; //Sets pins 28 and 29 as encoder B inputs for both axes
const byte ENCODER_B_Y = 29;
volatile unsigned int x_position = 0; //Global coordinates, remembering last position
unsigned int last_x_position = 1;
volatile unsigned int y_position = 0;
unsigned int last_y_position = 1;
boolean x_A_set = false; //Used for encoder reading mechanism
boolean x_B_set = false;
boolean y_A_set = false;
boolean y_B_set = false;
//Auxilary function for displaying coordinates on serial monitor
void displayCoordinates(int x_position, int y_position)
{
Serial.print("(x,y) in pulses:(");
Serial.print(x_position, DEC);
Serial.print(",");
Serial.print(y_position, DEC);
Serial.print(")");
Serial.print("(x,y) in mm:("); //For 1000 pulses per revolution and 1 mm per revolution
Serial.print(x_position/1000, DEC);
Serial.print(",");
Serial.print(y_position/1000, DEC);
Serial.print(")");
Serial.println();
}
//Initial setup
void setup()
{
Serial.begin(9600); //Activate serial monitor
pinMode(ENCODER_A_X,INPUT); //Encoder inputs
digitalWrite(ENCODER_A_X,HIGH);
pinMode(ENCODER_A_Y,INPUT);
digitalWrite(ENCODER_A_Y,HIGH);
pinMode(ENCODER_B_X,INPUT);
digitalWrite(ENCODER_B_X,HIGH);
pinMode(ENCODER_B_Y,INPUT);
digitalWrite(ENCODER_B_Y,HIGH);
pinMode(ENCODER_POWER_X, OUTPUT); //Set encoder power source pins to output and produce 5V
digitalWrite(ENCODER_POWER_X, HIGH);
pinMode(ENCODER_POWER_Y, OUTPUT);
digitalWrite(ENCODER_POWER_Y, HIGH);
attachInterrupt(2,doEncoderX,CHANGE); //Define interrupts on counters 2,3 for x,y axes respectively upon change in waveform
attachInterrupt(3,doEncoderY,CHANGE);
}
//Main Program
void loop()
{
if (!digitalRead(PIN_BUTTON_UP)) //If upper button is pressed - set coordinates to zero
{
x_position = 0;
y_position = 0;
}
if ((last_x_position != x_position) || (last_y_position != y_position)) //If there has been motion display new coordinates
{
displayCoordinates(x_position,y_position);
last_x_position = x_position;
last_y_position = y_position;
}
}
//The interrupt functions, first for x axis A wave changing state and then the same for y
void doEncoderX()
{
x_A_set = digitalRead(ENCODER_A_X) == HIGH; // Test transition
x_B_set = digitalRead(ENCODER_B_X);
x_position += (x_A_set != x_B_set) ? -1 : +1; // and adjust counter - if A leads B and + if opposite
}
void doEncoderY()
{
y_A_set = digitalRead(ENCODER_A_Y) == HIGH; // Test transition
y_B_set = digitalRead(ENCODER_B_Y);
y_position += (y_A_set != y_B_set) ? -1 : +1; // and adjust counter - if A leads B and + if opposite
}
What I get is that the (x,y) count displayed is very low, the x axis count doesn't change at all and the y count goes up regardless of the actual direction of motion.
I'd appreciate any useful ideas.. I'm new to all of this..
Thanks,
Gadi.