I have created an NXT printer before using .pbm files, where the file is read on the nxt and then printed out.

http://en.wikipedia.org/wiki/Netpbm_formatHowever, now I am trying to instead print pixels, print strokes.

I have created a C++ that parses the pbm file into commands for the nxt in the format

D (lower pen)

U (lift pen)

5 9

5 10

5 11 (coordinates)

I did try to do this in RobotC and it did work, but as I increased the resolution, the array became too large to fit in the NXT's flash memory so I resorted to doing it on the pc.

However, the issue now is for the arm to move to a specific coordinate.

Always, I come back to this issue and sometimes it gets better, sometimes, worse.

Here is the code for the function of moving it to a coordinate. It seems fine to me, yet the movements are always innacurate by up to 1cm (note that my gearing for the two joints are 56:1, 120:1).

/* Functions for a SCARA robot

Some of these variables may seem useless (for example a1 and a2) as I have used them in the past but then realised I didn't need them

but may need them in the future.

*/

const int speed = 50; //speed

const float mm = 1; //mm per pixel

const float arm1 = 15.2*7.95*mm, //Length of arm1 in m

arm2 = 14*7.95*mm, //Length of arm2 in mm

arm1R = 56, //Gear ratios

arm2R = -120;

int asign1,asign2;

float s1,s2; //speed of motors

float t; //time to move to coordinate(in some form of measurement that I don't know)

long a1,a2; //the amount still needed to move to the angle

long target1,target2; //targets for the motor to move to

long encoderBBegin = (arm1R*90), //The start numbers of the motor encoders (90 and 180 degrees so the arm forms a straight line)

encoderCBegin = (arm2R*180);

void moveToAngle(float angle1, float angle2){ //function to move the arm to a certain position (using two angles)

target1 = ceil(angle1 * arm1R - encoderBBegin);

a1 = target1;

target2 = ceil(angle2 * arm2R - encoderCBegin);

a2 = target2;

// find t (time in s)

asign1=1;

asign2=1;

if(a1<0){

a1*=-1;

asign1 = -1;

}

if(a2<0){

a2*=-1;

asign2 = -1;

}

if(a1>a2){

t=a1/speed;

}

else{

t=a2/speed;

}

if(t<0){

t *= -1;

}

// find speeds

s1 = ceil(asign1*a1/t);

s2 = ceil(asign2*a2/t);

nxtDisplayTextLine(3,"%f - %d",angle1,target1);

nxtDisplayTextLine(4,"%f - %d",angle2,target2);

if(target1==0 && target2==0){

return;

}

else if(target1==0){

nMotorEncoderTarget[motorC] = target2; // set the target for Motor Encoder of Motor C

motor[motorC] = s2;

while(nMotorRunState[motorC] != runStateIdle){}

motor[motorC] = 0; // motor B is stopped at a power level of 0

}

else if(target2==0){

nMotorEncoderTarget[motorB] = target1; // set the target for Motor Encoder of Motor C

motor[motorB] = s1;

while(nMotorRunState[motorB] != runStateIdle){}

motor[motorB] = 0; // motor B is stopped at a power level of 0

}

else{

nMotorEncoderTarget[motorB] = target1; // set the target for Motor Encoder of Motor B

nMotorEncoderTarget[motorC] = target2; // set the target for Motor Encoder of Motor C

motor[motorB] = s1;

motor[motorC] = s2;

while(nMotorRunState[motorB] != runStateIdle || nMotorRunState[motorC] != runStateIdle){}

motor[motorB] = 0; // motor B is stopped at a power level of 0

motor[motorC] = 0; // motor C is stopped at a power level of 0

}

encoderBBegin = (arm1R*90) + nMotorEncoder[motorB];

encoderCBegin = (arm2R*180) + nMotorEncoder[motorC];

}

void ikinematics(int xx,int yy,float arm1,float arm2){ //function to calculate the angles required

float B = sqrt(pow(xx,2)+pow(yy,2));

float t = atan2(yy,xx);

float theta = (t-acos((pow(arm1,2)+pow(B,2)-pow(arm2,2))/(2*arm1*B)))*180/PI;

float alpha = (acos((pow(arm1,2)-pow(B,2)+pow(arm2,2))/(2*arm1*arm2)))*180/PI;

//move motor B and C to position

alpha=360-alpha;

nxtDisplayTextLine(6,"Target: %d x %d",xx,yy);

moveToAngle(theta,alpha);

}