Archive for the 'Line-us Clone' Category

Digital vs. Analog Servos

wiggles

There is quite a bit of wiggliness on my drawing bot. While it is a bit adorable as it draws, I wanted to see if I could improve the line quality. I thought increasing the the rate at which I updated the position would make it smoother. I took it all the way up to 48Hz, but was not getting much better quality than I did at a 1/4 of that.

Analog Servos

I little research into analog servos brought some possible solution to light. Analog servos are controlled with a PWM signal.  The PWM pulse should be between 1ms and 2ms and repeat at 50Hz.

servo_timing

The basic technology inside an analog servo has been around longer than I have. The circuit converts the signal pulse into a voltage based on it’s length.  The output shaft is coupled to a potentiometer which also outputs a voltage. These two voltages are compared to produce an error voltage.  The error voltage would be positive or negative based on which direction off the output shaft potentiometer is from the input signal voltage.  This voltage is sent through an amplifier and then to the motor.  The motor turns in the proper direction until the error voltage is zero.

aservo

One problem with this method is the voltage to the motor is proportional to the error voltage.  The motor will have very little torque when the error is small, as would occur with small moves.

To keep the servo from being overly sensitive to small changes changes in the pulse length, the servos have a deadband.  Over sensitivity would cause jittering and use a lot of power. The deadband is expressed in microseconds (us). Analog servos typically have a 5us deadband. If the error is less than the deadband, the servo will not move.

If the servo pulse range is 1ms to 2ms or a 1000us range, then this causes the second problem. A  1000us range divided by the 5us deadband is 200.  This means I basically have to move more the 1/200 of the usable range to get it to move.  The full range is 180° so I have roughly 1° resolution.  That will cause lines to look very jittery.

Try this to get a feel for an analog servo.  With the servo receiving a commanded position, attempt to rotate the output.  You will notice two thing. First you will notice the strength of the servo is proportional to how far you twist it off the commanded position. The second thing to notice is noise and vibration.  That vibration is the 50Hz PWM period.

Digital Servos

Digital Servos use the same same basic input method (1ms to 2ms pulse) to preserve backward compatibility, but everything is done digitally.  Additionally, most of the servo’s parameters can be programmed. The digital circuit does not need to be limited to the 50Hz period and the control loop can be more sophisticated than simply using the error voltage.

The two immediate things I can take advantage of is lowering the deadband.  I can program it down to 1us or on some servos even lower. This give me a 5x improvement in resolution.  The other thing is the higher torque at small moves.

Try this to get the feel for a digital servo.  With the servo receiving a commanded position, attempt to rotate the output.  You will notice two thing. First you will notice the strength is very strong regardless of how far you twist it. The second thing to notice is noise and vibration.  That vibration is going to be a much higher pitch.

The results.

digital_wiggles

The results are subtle, but I think it is better.  With no changes to the firmware it got a little better.  I changed the update rate from 50Hz to 200Hz and it got a little better again.

I used Hitec HS5055MG servos.  I wanted a brand name servo, I know I could program.  Out of the box the servo only had about 90deg of rotation.  I was able to up that to about 178.  I was quite surprised I could not get 180°.  That needed to be accounted for in the kinematic or the shapes are distorted.

I think if you want the best, go for the digital, but in my opinion, the improment in quality did not justify the cost.

 

 

Yet Another Way to do the Kinematics

image1

Paul Kaplan, originator of the Easel project, came up with another way to do the kinematics for the Line-us Clone. My method used intersecting circles. His method uses the Law of Cosines.

The Law of Cosines relates the lengths of the sides of a triangle to the cosine of one of its angles.

Triangle_with_notations_2.svg

lawofcosines

 

This can be used to find the angles of the servo arms.

(Click on the images if you want a larger view)

The Goal

goal

The goal is to find the two angles, A1 and A2, of the servo arms

Known Values

  • Px is the desired X location of the pen
  • Py is the desired Y location of the pen
  • L1 is the length of the upper servo arm (50mm)
  • L2 is the length of the end of the Pen Arm (50mm)

Step 1

Find the distance “D” of the pen to hub using the Pythagorean Theroem and the angle T1 using arctangent.

Px2 + Py2 = D2

rewritten … D = Sqrt(Px2 + Py2)

step1

 

T1 can be found using the arctangent or inverse tangent formula. Note: When programming use the atan2(x,y) function to preserve the quadtrant.

T1 = atan2(Py,Px)

Step 2

step2

 

Find T2 using the Law of Cosines

L12 + D2 – L22 = 2 * L1 * D *cos(T2)

rewritten …  T2 = acos( (L12 + D2 – L22) / (2 * L1 * D))

Step 3

step3

 

Find T3 using the Law of Cosines. We want the left one of the two T3 angles, but since the linkages form a parallelogram that same angle shows occurs in several places.  We will use the right one and the dimensions associated with it.

L12 + L22 – D2 = 2 * L1 * L3 * cos(T3)

rewritten … T3 = acos( (L12 + L22 – D2) / (2 * L1 * L2))

Step 4

step4

 

Determine A1 and A2 from the angles we figured out.

A1 = T1 + T2

A2 = A1 + T3

Conclusion

I think I will switch the code to use this method. I think I can optimize it better in C code. The speed of the code is important.  The faster it runs, the most times per second we can run it.  The more often we run it, the smoother it will run.

 

Line-us Clone Controlled by Easel and Grbl

Last week I made a Line-us drawing robot clone.  Unfortunately I had no good way to make it draw easily.  I thought I would give the CNC toolpath a shot.  My goal is to have a super portable thing to generate conversation at meetups. If I used Easel it would allow anyone with a web connection to easily make something.

2dbenchy

Grbl

Grbl Logo 250px

The most compact machine controller is Grbl and I have a lot of experience with it.  Grbl is designed to send step and direction signals to stepper motors.  The draw ‘bot uses hobby servos.  The nice thing about hobby servos is they don’t need to be homed.  They have feedback to tell them where they are. They also don’t care about speed, acceleration or steps/mm.  They just go wherever you tell them as fast as they can go. It occurred to me, the easiest way to hack this into Grbl was to not modify the Grbl code at all.  I would let Grbl think it is using stepper motors.  I would just add some extra code that runs on regular interval to tell the hobby servos where the stepper motors are in 3D space and they would be told to go there.  I played around with some intervals and 8 times per second (8Hz) seemed to work pretty well.  The ‘bot uses machine coordinates. The work coordinates are offset to the left because the ‘bot cannot draw at 0,0.  The pen would crash into the frame.

PSoC

I recently port Grbl to PSoC. I used (3) 16bit PWM components to control the hobby servos.  See this blog post on how I did that.  I then attached a 8Hz clock signal to an interrupt.  The interrupt sets a flag when it is time to update the servos.  When the main code sees this flag it does the calculations and and sets the PWM values.  Keeping the code out of the interrupts gets Grbl happier.

servospwms

Easel

Easel is already setup to use Grbl.  You can either import gcode or create a design right in Easel.  I started out with importing gcode because the Benchy design was not in a format I could import. I created a template that shows the allowable work area. This will allow anyone to quickly create a drawing.

easel_template

2D Benchy

I wanted to have a little fun with the first print.  “Hello World” was not good enough.  3D printers use benchmark prints, so I thought I would do a 2D version of the classic 3DBenchy.  To get a 2D drawing of 3DBenchy, I traced over an image with the line tool in CorelDRAW.  I then exported a DXF of that.

trace

Hobby/RC Servo Control in PSoC

psoc_setup

 

The PSoC family is my go to line of processors for prototyping.  It is like having a breadboard full of digital and analog circuits that you can wire up on the fly. I have been doing some stuff with hobby servos lately so I needed to figure out how to do it on the PSoC.

Hobby Servos

Wikipedia

From Wikipedia

servo_timing

Image from Adafruit

 

Hobby servos set their rotation based on the length or a repeating pulse. The pulse should be 1ms to 2ms long and repeat every 20ms.  One end of the rotation is at 1ms and the other is at 2ms.

The PSoC PWM  Component

PWM_Comp

The PWM component is perfect for this job.  The PWM component can be setup to have a period and an on time.  The period should be 20ms and the on time would be between 1ms and 2ms.  The component uses a clock and two counter values.  The component will count on every clock pulse.  It resets the counters after the period count has been reached and the CMP value determines how long the pulse is logic high.

The PWM output goes to the servo control line.  Here is the configuration dialog box for the PWM component. The graph at the top is a good reference for what the output will look like.

pwm_setup

The goal is to have a pretty decent resolution to set the 1ms to 2ms pulse.  I chose a 2MHz clock.  I picked the fastest clock that would still fit within the 16bit (65535) limit of the control.  PSoC clocks are derived from system clocks, so you need to pick values easily divided down from them.  The IDE helps with creation of these clocks.  At 2Mhz the period (repeat rate) should be set to 40,000.  The equation is the clock * period(in second) = period counts (2,000,000 counts/sec * 0.02 secs = 40,000 counts).

The CMP Value is how many counts the high pulse should last.  The equation is the same. For 1ms the count would be (2,000,000 cnts/sec * 0.001secs =  2,000 counts) and for 2ms the counts would be 4,000.  The range is 2,000 to 4,000 (2,000 count resolution).  This is better than most hobby servos can do.

The Code

The IDE will generate a bunch of functions, a custom API, for each component used when the application is built. There are two PWM Component functions we need to use for this application .

  • PWM_Servo_Start() This will initialize the component and get it running. This is called once at the beginning of the program.
  • PWM_Servo_WriteCompare(val) This sets the CMP Value that will be used to set the pulse length.

I also wrote a function the can set the value by degrees.

void setServo(float degrees)
{
unsigned int val;
// convert degrees to compare value
// 2000 to 4000 = 0 to 180
// value is
val = (degrees / 180.0 * 2000.0) + 2000;

PWM_Servo_WriteCompare(val);
}

The Results

Here is a screen shot of my logic analyzer. The output was set for 1/2 rotation. The pulse is 1.51ms and the period is 20.14ms.  That is close enough for me.  It is likely the clock speed is different between the PSoC and  and the analyzer.

capture1

 

Typically you will have to tune the to the actual servos used.  Just tweak the endpoint values until you get the rotation you want.

A Line-us Clone

image1

I have been going to the monthly Amp Hour, Hardware Happy Hour meetup.  A lot of people bring something to show.  My projects are too big.  Also, you need to bring your own power.  The meetup standard seems to be running off a USB cord. I was brainstorming ideas, when I saw the Line-us project on Kickstarter. It looked like the perfect size and power. I also love the challenge of non linear kinematics.

8d65c4576042e58c834aa36d1098ceb6_original

I decided to make a clone of it.  I started by importing one if their drawings into CorelDRAW and scaling it up to 1:1.  I then added some measurements.  I rounded them up to 80mm for the pen arm and 30mm and 50mm for the linkages.

measurements

I looked into hobby servos and found that the “mini” size looked about right.  I ordered 4 of them from Amazon.  I made sure to get metal output shafts because I thought I might have to press them into the 3D printed arms.

mini_servo

 

Design

I created a basic design in PTC CREO.  I added a lot of construction sketches for the linkages to help me with the kinematics later.  I downloaded a model of the servo from GrabCAD  to use while I waited the delivery.

design2

I used 3mm bearings for all the joints.  These are pressed into the linkages.  This would allow me to firmly tighten the joints and not have to worry about slop in the joints.

Assembly

When the servos arrived, there were slight differences in from the model.  The mounting holes we much smaller at about 2mm.  I had to reprint with some changes.

My concept was to press the arms onto the servo shafts.  This sort of worked, but after a few crashes, they loosened up.  I ended up using a drop of thick super glue to secure them.  They were able to stall the motor without slipping.  It is important to mount the arms at the precise angle.  I made an Arduino sketch to hold the servo in the precise position while attaching the arms at the angle I wanted.  Each servo has a 180° travel.  The upper arm travels from 135° to negative 45°.  The lower arm travels from 45° to 225°.

Kinematics

In order make the pen go where you want it to go, you have to figure out what angle to set the arms. This is not a simple linear equation. You have to solve a multi-step geometry problem for each new location. I’ll walk you through the basic process. I placed the axis of the two servos at XY 0,0 to simplify things. You know the desired Pen Tip location, so start working back towards the cranks.

  • Step1: Find the Pen A point. You know the lengths of the linkages between the 0,0 point and the pen tip. They are both 50mm. Each arm end has a set of points where it can exist that scribes a circle. If the desired pen point is within reach of the machine, the circles (green ones) will cross at two points. The solution is a well documented process. I used the C code from this page. So far, I found that using the location, of the two, with a higher Y value is the one to use.
  • Step 2: Find the Pen B point. Pen B is easy to find because you now know the slope of the Pen Arm. Multiply the X distance from the pen tip to the Pen A point by the ratio of the length of the pen arm (80mm) over the length of the arm from Pen Tip to Pen A (50mm) and add it to the pen tip. Do the same for the Y axis.
  • Step 3: Now that you know the Pen B location, you can do the intersecting circles (red ones) trick again. This time I used the left most point of the two.
  • Step 4: Find the angles. Use the X and Y distances of the crank tips and the atan function to get the angles. ( angle = atan(deltaY / deltaX) )

Another problem with non linear machines is that moving between two points will not be a straight line. The points will typically be connected with a slightly curved line. You need to constantly recalculate points along the way to keep it straight. If you break a line into smaller segments, the connecting curves also get smaller to the point where they are not notices.

 

 

kin2

Electronics.

Everything I chose was for prototyping ease and probably not the final solution. I used an Arduino UNO as the controller. I used a PCA9685 based servo motor controller for the servo. The Arduino could probably handle it on its own, but the wiring is so clean and simple with this. I used a breadboard power supply to power the servos. It had a handy switch to kill the power to the servos without killing the Arduino.

pca9685-16-channel-12-bit-pwm-servo-driver_1

PowerMBV21

 

The Results

Here is a video of the machine running. The rectangle is hard coded via some for loops recalculating at 1mm increments. The results are shaky, but consistent with the Line-us results. The machine is quite rigid. Most of the shakiness comes from the servo motion. I also do not have the machine held down. If I get some magnets like Line-us, it might help.

image2

Open Source (sorry)

I don’t think it is fair to the Line-us folks to release any files at this time. I think there are plenty of resources in this blog post if you want to clone it yourself. So far I only have about 5-6 hours into the project, so it is pretty a pretty easy project.

The real Line-us looks very polished and they are selling it at a good price. I am sure a lot of the work they did was on the UI, which I did not replicate at all.

Next Steps

I need a way to stream drawing data to the machine. I would like to use g-code. It also needs a UI and I thought Easel might be best. For the gcode I might try hacking Grbl. I would just add a timer that reads the current location at about 5hz, send it through the math and set the servos. Any value above Z 0 would be pen up.

For Easel, I could create a template that shows the usable work area. You would then just click Carve.

 

Firmware

Here is the firmware I used.  It is a quick and dirty port of my PSoC port of Grbl. I cannot give support for this. Only experienced PSoC programmers will be able to install and use this.

Grbl Line-us PSoC Firmware