Hi and thanks for the quick replies,
robtillaart:
please post the whole code as I suspect some race condition in the code.
Here. I hope it's not too much.. If you have any questions about the code please ask.
The entire code is too long so I skipped the unimportant parts.
...
const byte ENCODER_X_A = 21; //Sets timer/counter pins 21 (Timer counter 2) and 20 (Timer counter 3) as encoder A inputs for both axes
const byte ENCODER_Y_A = 20;
...
volatile long int x_position = 0; //Global, relative coordinates
volatile long int y_position = 0;
byte right = 0, up = 0;
long int setpoint[2] = {0,0};
...
int x = 0;
int y = 0;
/****************************************************************************************************************************************************************************************
* Pulsed motor control function
*****************************************************************************************************************************************************************************************/
void pulsedMotor(int delay_time, byte x_or_y, byte upright_or_downleft)
{
if (x_or_y)
{
Motor2(90, !upright_or_downleft);
delay(delay_time);
Motor2(0, !upright_or_downleft);
delay(100);
}
if (!x_or_y)
{
Motor1(90, upright_or_downleft);
delay(delay_time);
Motor1(0, upright_or_downleft);
delay(100);
}
}
/****************************************************************************************************************************************************************************************
* Gotoxy function
*****************************************************************************************************************************************************************************************/
void gotoxy(long int x_set, long int y_set)
{
int x_count = 0, y_count = 0;
byte in_position = ((x_position == x_set) && (y_position == y_set));// If already in position return
if (in_position) return;
Serial.print("ORIGIN: ");// Print point of origin onto serial monitor
displayCoordinates(x_position, y_position, x_set, y_set);
coarseGotoxy(x_set, y_set);// Go to the area arround the requested point
Serial.print("COARSE DESTINATION: ");
displayCoordinates(x_position, y_position, x_set, y_set);
x_count = fineGotoxy(x_set, 1);// Go to exact location
y_count = fineGotoxy(y_set, 0);
...
}
/****************************************************************************************************************************************************************************************
* Fine Gotoxy function
*****************************************************************************************************************************************************************************************/
int fineGotoxy(long int set, byte x_or_y)
{
int delta = 0, count = 0;
if (!x_or_y) // If we're fine tuning Y
{
while (y_position != set)
{
delta = set - y_position;
up = delta >= 0;
if (abs(delta) >= 100)
{
pulsedMotor(20, 0, delta > 0);
count++;
continue;
}
if ((abs(delta) >= 20) && (abs(delta) < 100))
{
pulsedMotor(10, 0, delta > 0);
count++;
continue;
}
if ((abs(delta) >= 5) && (abs(delta) < 20))
{
pulsedMotor(5, 0, delta > 0);
count++;
continue;
}
if (abs(delta) < 5) pulsedMotor(1, 0, delta > 0);
count++;
}
return count;
}
if (x_or_y) // If we're fine tuning X
{
while (x_position != set)
{
delta = set - x_position;
right = delta >= 0;
if (abs(delta) >= 100)
{
pulsedMotor(25, 1, delta < 0);
count++;
continue;
}
if ((abs(delta) >= 20) && (abs(delta) < 100))
{
pulsedMotor(10, 1, delta < 0);
count++;
continue;
}
if ((abs(delta) >= 5) && (abs(delta) < 20))
{
pulsedMotor(5, 1, delta < 0);
count++;
continue;
}
if (abs(delta) < 5) pulsedMotor(1, 1, delta < 0);
count++;
}
return count;
}
}
/****************************************************************************************************************************************************************************************
* Coarse Gotoxy function
*****************************************************************************************************************************************************************************************/
void coarseGotoxy(long int x_set, long int y_set)
{
right = x_position <= x_set; //Set direction
up = y_position <= y_set;
while ((up && (y_position < y_set)) || (!up && (y_position > y_set))) // Coarse positioning
{
Motor1(90, up);
}
Motor1(0, up);
while ((right && (x_position < x_set)) || (!right && (x_position > x_set)))
{
Motor2(90, !right);
}
Motor2(0, up);
delay(100);
}
/****************************************************************************************************************************************************************************************
* Initial setup
*****************************************************************************************************************************************************************************************/
void setup()
{
...
pinMode(ENCODER_X_A,INPUT); //Encoder inputs
digitalWrite(ENCODER_X_A,HIGH);
pinMode(ENCODER_Y_A,INPUT);
digitalWrite(ENCODER_Y_A,HIGH);
attachInterrupt(2, doEncoderX, RISING); //Define interrupts on counters 2,35 for x,y axes respectively upon rise in waveform
attachInterrupt(3, doEncoderY, RISING);
}
/****************************************************************************************************************************************************************************************
* Main Program
*****************************************************************************************************************************************************************************************/
void loop()
{
if (!digitalRead(PIN_BUTTON_UP)) //If UPPER button is pressed - SET COORDINATES TO ZERO and display
{
x_position = 0;
y_position = 0;
displayCoordinates(x_position, y_position, setpoint[0], setpoint[1]);
}
if (!digitalRead(PIN_BUTTON_LEFT)) //If LEFT button is pressed - SAVE AS SETPOINT and display
{
setpoint[0] = x_position;
setpoint[1] = y_position;
displayCoordinates(x_position, y_position, setpoint[0], setpoint[1]);
}
if (!digitalRead(PIN_BUTTON_RIGHT)) //If RIGHT button is pressed - GOTO SETPOINT
{
gotoxy(setpoint[0], setpoint[1]);
}
x = analogRead(PIN_ANALOG_X)/2-256; //Transform analog input of 0:1023 to range -255:255
if (x == -256) x = -255;
y = analogRead(PIN_ANALOG_Y)/2-256;
if (y == -256) y = -255;
if (abs(x) < 10 ) x = 0; //Threshholding
if (abs(y) < 10) y = 0;
right = x >= 0;
up = y >= 0;
limit_x = CheckLimitSwitches(1, x < 0); //Check if limit switches are activated
limit_y = CheckLimitSwitches(0, y > 0);
if (digitalRead(PIN_BUTTON_SELECT)) //If select button is NOT pressed - go at speed dictated by the joystick
{
if (!limit_y) Motor1(abs(y), y > 0); //Send info to motors
if (!limit_x) Motor2(abs(x), x < 0);
}
else //If select button IS pressed - go at speed 2 times slower
{
x = x/2;
y = y/2;
if (!limit_y) Motor1(abs(y), y > 0);
if (!limit_x) Motor2(abs(x), x < 0);
}
}
/****************************************************************************************************************************************************************************************
* Encoder interrupt service routines
*****************************************************************************************************************************************************************************************/
void doEncoderX(){
x_position += (right) ? +1 : -1; // and adjust counter + if going right and - if opposite
}
void doEncoderY(){
y_position += (up) ? +1 : -1; // and adjust counter + if going up and - if opposite
}