# Modify repetier firmware for SCARA

First of all i want to thanks for the great job on repetier firmware and host. I love it much more than marlin.

I'm using repetier firmware for my delta printer, and now i'm trying build my own design scara arm 3d printer. So i'm trying to modify repetier firmware.

Hopefully it's okay and i get some guidance.

What i've done is add new drive system called scara.

Then i add some new functions for converting.

First function is scara inverse kinematics, this is to convert cartesian coordinate to scara.

Second function is scara forward kinematics, this is to convert scara coordinate to cartesian.

Third function is dummy convert cartesian to delta. This is because i include scara drive to non linear, and i see there are some functions use the function.

The main idea is cartesian use x & y axis linearly, i use x & y axis circulary. While z axis is the same as cartesian.

So cartesian step per unit is step per mm, scara step per unit is step per degree.

The main different converting cartesian to scara compare to convert to delta is which one to convert first.

i see that repetier firmware convert mm to steps then convert to delta towers in steps.

While scara have to convert coordinate in mm to coordinate in degree first then convert in steps.

That's why i try to convert all the command in cartesian to scara in units then convert to steps.

My questions are

1. What functions that i have to modify.

I add conversion scara-cartesian in motion.cpp, I found ispositionallowed(), updatederivedparameter(), moveto(), movetoreal(), setdestinationstepsfromgcode() in printer.cpp that i've modify, do i miss something?.

2. I'm confused with moveto() and moveto() function.

A. I read the code and the comments but i dont really understand what is the different. Can you please explain what is the meaning of untransformed move, transformed cartesian coordinate, absolute cartesian space, mapping real(model) space to printer space.?

B. In moveto() function. If i'm not mistaken, It's written if value is not ignored, then destinationsteps = (value + offset) * steppermm.

What happen if it's ignored, what is the value of destinationsteps?

I mean if moveto(5, ignore, ignore, ignore)

I believe the x value is 5, what is the value of y?

Because when convert cartesian to scara it need both x & y coordinate to get how much steps x & y motors should go.

3. Questions about homing.

A. My scara have 2 parameters, armlength & forearmlength. X motor to move arm, y motor to move forearm.

The ideal home coordinate is x motor at 0 degree and y motor at 180 degree. But it is not the fact. Let say x motor at 5, y motor at 175. What is this suppose to call? X offset & y offset or must be something else?

B. I set my print bed at the left side of the center axis (x motor). Because of x & y motor home coordinate is not ideal, it's forming a distance. I call it scara minimum radius, the maximum radius is armlength + forearmlength. In between min & max radius is my print bed area. Let say min radius is 50mm, max radius is 250mm and i want to put my print bed at leftside. So my printbed center is at (-150,0) cartesian position from x motor axis.

Which one suppose to be the (0,0)? The x motor axis, nozzle position when touch endstop, center of printbed, or somewhere else?

I am thinking it suppose to be the x motor axis, but i'm thinking how to use repetier host & cura about the printer shape.

That's all for now, hopefully it's too many questions & i hope you can kindly guide me.

Best regards

Kusuma

## Comments

uint8_t transformCartesianStepsToDeltaSteps(

int32_tcartesianPosSteps[],int32_tcorePosSteps[])and you are done. First you should understand how to handle steps right. User enters real coordinates (currentPosition). If you check for example moveTo Real the main logic is then

transformToPrinter(x + Printer::offsetX, y + Printer::offsetY, z + Printer::offsetZ, x, y, z);

// There was conflicting use of IGNOR_COORDINATE

destinationSteps[X_AXIS] = static_cast<

int32_t>(floor(x * axisStepsPerMM[X_AXIS] + 0.5f));destinationSteps[Y_AXIS] = static_cast<

int32_t>(floor(y * axisStepsPerMM[Y_AXIS] + 0.5f));destinationSteps[Z_AXIS] = static_cast<

int32_t>(floor(z * axisStepsPerMM[Z_AXIS] + 0.5f));You see it gets transformed (meaning rotation of bed) and then converted to steps. So currentPositionSteps and destinationSteps are in cartesian printer format with steps per mm resolution. Your problem is X and Y which has nothing to do with rotation. So select for x and y a virtual resolution. So say you take 1000 for both. Using axisStepsPerMM you can convert this back into floats if needed or you keep computing with integers if that is faster. Next you implement

uint8_t transformCartesianStepsToDeltaSteps(

int32_tcartesianPosSteps[],int32_tdeltaPosSteps[])input is cartesianPosSteps = destination coordinates in steps as described

output deltaPosSteps = real motor position, so z stays the same and x and y are A/B rotations. You need to introduce a new parameter for your real motor resolution to do the conversion.

Last you need to write your own homing routine (see printer.cpp how we already have 3 implementations for different drive systems). There are lots of delta parameter in eeprom you can misuse for your system, e.g. setDeltaTowerXOffsetSteps for homing offsets. Please update eeprom input/output so it shows user correct names for scara then.

You might need to make some assumptions how bed coordinate is orientated relative to arm. If we assume arm is to right a natural coordinate system would have xmin/ymin on the left front. Or you take bed center as origin, both would work.

Below some doc I wrote for orientation. I hope this covers your first questions. Ask again if you need more help.

I will avoid using pow ect. But scara arm units conversion to steps options are only degree and rad. To convert angle to linear as far as i know only use sin cos tan asin acos atan functions. I have no idea how to replace those functions.

From your explanation, i think i can't use moveto() function. Even if i have to use them, the x and y in moveto() must not treated for cartesian coordinate. I mean i have to use them for scara coordinate directly. so for instance moveto(5, ignore) means x motor rotate 5 unit, y motor doesnt move.

Is this right?

Sorry... you are right for the map. I mean ^y, >x. And all x coordinates are negative.

And you are right that it will be not intuitive.

For the bed, actually the maximum usage is not square nor cicle. It's half circle, but it seems there is no such bed shape provided in repetier host, so the option is only square or circle. Which one you suggest will be better? Square or circle?

Please correct me, if the origin is bed center. Bed center is (0,0) and O1 let say (30,0).

If i insist O1 is (0,0) then bed center is (-30,0) and this is not intuitive for user.

To make bed is origin, simply use offset... x offset?

I confuse x offset should be 30 or -30 in this case ???

I dont know what will happen to atan(y/x) if y or x is ignored

So... you are suggesting to use O1 to be origin(0,0), but to make comfortable for users, make a dummy origin that intuitive, then all dummy coordinate transformed/corrected relative to O1?

Isn't it the same as offset?

Why not just use x offset then in user languages call it correction?

For homing i'm not worry too much it's less difficult then delta, and not so much different with cartesian. I don't need to do anything for z. Just transform xy linear to scara.

The only problem that don't know what to do is i want it home z first, then y, then x.

Autobed leveling is important to me. That is one of the thing i love about repetier firmware.

I design this scara bot for open bed, which means users can modify bed according to their applications.

They may directly print on a floor, a glass, a plate, a wood, a metal or anything. I don't give any boundary to limit the bed, it even possible to print if you put the machine on a table then print on floor. And it even possible to modify to print to wall. So autoleveling is a must everytime user changing bed.

Autolevel is something that i worry too. Is it use moveto function? If you say moveto must be cartesian, then i can't use it. I guess i must make changes to all commands that use moveto().

Btw, this is just an information that i hope useful for you. I use repetier firmware for my delta printer.

I learned about delta for months to get a proper way to calibrate. I search anywhere to get it but havent found any calibration procedure that satisfy me. So i make my own calibrating steps and succesfully get accurate result. Including how to find accurate diagonal & radius for each tower.

For calibrating delta accurately, calculating steps from a point at any towers to it's endstop is crusial. We can't get accurate diagonal & radius without this.

I know there is a command in repetier firmware gcode to do this, i was use it and found that it is not correct for some points (especially if we move extruder near z tower, we'll get strange behaviour).

Try to check distance in steps for coordinate (0,90), (0,85), (10, 80), (-10,80). It happens to my printers that one of the value doesnt change for all that points.

I found it because transformcartesiantodelta() and step limits in the calculation. So i make another gcode, another function and another integers without transformation and limits to fix it and get accurate result.

I hope you add a gcode to calculate steps to endstop without transformcartesiantodelta and limits in the next version.

I modified distortion:: in printer.cpp

It map distortion in steps, I add elif drive_system == scara that map distortions in mm, but when store to eeprom i transform it to scara coordinate.

When call from eeprom, i transform it again to cartesian in mm.

I haven't change anything in bedleveling.cpp, but I've checked and found moveto() used many times.

What if i add elif drive_system scara in moveto(... if x ignored, x =lastcmdpos x axis ?

Is this solving my problem or it will causing other problems?

/** Uncomment, to see detailed data for every move. Only for debugging purposes! */

//#define DEBUG_QUEUE_MOVE

/** write infos about path planner changes */

//#define DEBUG_PLANNER

to debug moves. DEBUG_QUEUE_MOVE gives lot of infos if echo is enabled (debug option). So if you see results here you know the move was accepted and what steps in virtual resolution it wanted. If you don't see it the move got prevent from boundary check or some other check. For homing we set homing flag to disable these checks.

I still don't understand what is the meaning of

P->

D->

Cur->

Can you please explain to me?

I think they are struc???

It's working now but still not prefect

https://www.youtube.com/watch?v=V-ltmE66adw

https://www.youtube.com/watch?v=QEI8J-BrP04

Do you use marlin?

I will release my version firmware, beside the kinematics, i also modify user interface and semi auto calibration tools. so please be patient. It's not ready now.