Moving motors from a Python script

Since last time I've been pretty busy with some work related projects, so the CANopen safari has suffered a bit. Luckily I've got a little bit more time lately so I have picked up the CANopen stuff.

It's been a pretty heavy learning curve. I've spent a lot of time looking at the console and trying to understand what is going on. I received a lot of help from various people (thanks for showing me correct messages Uwe!) getting to understand the DS402 state engine. As well as (thanks Michael!) getting new programming-related knowledge.

In hindsight the combination of picking the tools (libraries) and understanding these conbines with getting to grips with the CANopen internals was pretty "heavy". For example; If you send an SDO message with the wrong amount of bytes, you get an unexpected response. So you not only have to understand using the library, but you have to understand the library correctly.

So, past days, pieces of the puzzle fall into place, and I have a nice video to show for it.

Libcanopen has python bindings (extended by Michael, thanks for making the MNT commands available in the python bindings). So with the cycanopen-402-prepare.py python script:

  • the various states of the DS402 state engine have to be processed.
  • a profile position mode is chosen
  • a target position is set

Then after the first scrip "initializing" the device,  the cycanopen-positionmove.py script toggles the bit to start the previous set-up travel order.

Now that this is in place I'll work towards gluing Machinekit and CANopen together with Python. First creating some userland components and get the motor running from a Machinekit GUI button.

Better to first understand what we need to do before writing RT components. Long live the Python glue!

Some additional links:

  • Working towards Machinekit Issue #589
  • USB to socketcan USBTin device.
  • node 2 and 3 Maxon Epos 24/1 CANopen devices.
  • node 5 Nanotec CL3-E CANopen device.
  • My fork of libcanopen and the installation instructions:
    bas@jessie:~$ sudo apt-get install python-dev cython pkg-config
    bas@jessie:~$ git clone https://github.com/luminize/libcanopen
    bas@jessie:~$ cd libcanopen
    bas@jessie:~/libcanopen$ git fetch origin
    bas@jessie:~/libcanopen$ git checkout machinekit-prep
    bas@jessie:~/libcanopen$ sh build.sh
    bas@jessie:~/libcanopen$ sudo make install
    bas@jessie:~/libcanopen$ cd cycanopen
    bas@jessie:~/libcanopen/cycanopen$ make
    bas@jessie:~/libcanopen/cycanopen$ cd ..
    bas@jessie:~/libcanopen$ sudo ldconfig
Share/Bookmark

Sniffing at CANopen

The week is at its end, and especially today was a good day for the engineer-becoming-can-abled. Yesterday evening I struggled mightily so I went to bed hoping that a good nights sleep would help... It did.

The situation so far:

  • This week I got 2 Maxon Epos 24/1 modules including motors loaned to me (Thanks!), which are both CANopen devices.
  • I have a Trinamic TMCM-303 board I bought approx 6 weeks ago
  • 2 USBtin devices
  • breadboards, wires, solder, connectors, shrink tube.
  • Macbook Pro with Parallels VM's on which I have my Debian Jessie development VM.

As with all mechanical development I started with the first step. Making sure I have a working CAN bus. That means the physical bus. Since I wanted to test if messages are sent and received via the hardware (wires) I used the 2 USBTin devices to make the bus. These have a jumper to enable the 120 Ohm endresistor, and both should provide the correct bus voltage.

USBtin-can-bus

  1. Put the 2 devices in the USB hub and tell Parallels to use the devices with the Jessie VM (as of now I'll call it the dev-VM).
  2. In the dev-VM open a terminal and do ls /dev/ttyACM*. USBtin devices will register as ttyACM{nr} so this resulted in /dev/ttyACM0 /dev/ttyACM1
  3. See below the output of the terminal and how get the can interfaces up.
    bas@mbp-jessie:~$ ls /dev/ttyA*
    /dev/ttyACM0  /dev/ttyACM1
    bas@mbp-jessie:~$ sudo bash
    [sudo] password for bas:
    root@mbp-jessie:/home/bas# slcand -f -o -c -s8 /dev/ttyACM0 can0
    root@mbp-jessie:/home/bas# slcand -f -o -c -s8 /dev/ttyACM1 can1
    root@mbp-jessie:/home/bas# ifconfig can0 up
    root@mbp-jessie:/home/bas# ifconfig can1 up
    root@mbp-jessie:/home/bas#
  4. Above sets the can interfaces to 1000kbit bus speed (-s8)
  5. Open 2 new terminals
    in the first one type candump can0 can1 and in the second one type cansend can0 001#01.04.00.00.00.00.C8.CD
  6. Output in cansend terminal:
    bas@mbp-jessie:~$ cansend can0 001#01.04.00.00.00.00.C8.CD
    Output in candump terminal:
    bas@mbp-jessie:~$ candump can0 can1
    can0 001 [8] 01 04 00 00 00 00 C8 CD
    can1 001 [8] 01 04 00 00 00 00 C8 CD
  7. We have created a Cansocket hardware bridge :) Fun, isn't it.

I wired the Trinamic TMCM-303 board (from now on just 303-board) with it's CAN pins to a position on the breadboard between the 2 USBtin devices. In the middle of the bus. And I sent it some CAN data that I gained from the RS232 connection from the Trinamic IDE.

I saw the motor move, played around a little, but this board is not CANopen, so spending more time won't get me to CANopen. Therefor I removed the 303-board and connected the loan-maxon-epos-device to the bus (picture below).

maxon-epos-canopen

I powered up the device and in the can dump terminal I can see:
bas@mbp-jessie:~$ candump can0 can1
can0  702   [1]  00
can1  702   [1]  00

HOORAY! the maxon device booted itself and made itself known to the world (the "2" in 702 is the node number... which is "2" for this device. My first CANopen message.
I found a nice handout here.

Enter CanFestival. This is an open source CANopen master/slave stack written in C (we'll eventually need C to write code for the HAL of Machinekit). There are other stacks like CANopenNode which runs on embedded platforms. But I have to start somewhere.

  1. Cloned from my repo which is a for of Michael's repo, which comes from the SVN source.
  2. cd ~/Canfestival-3
  3. ./configure --can=socket --enable-lss --enable-lss-fs
  4. make
  5. sudo make install
    I had to use sudo for rights issues, i got the following error during install:
    mkdir -p /usr/local/include/canfestival
    mkdir: cannot create directory ‘/usr/local/include/canfestival’: Permission denied
  6. cd ~/Canfestival-3/examples/CANOpenShell
  7. make
  8. show me where the driver for Socketcan is, but more important how it's named:
    bas@mbp-jessie:~$ sudo find / -name libcanfestival*
    /home/bas/Canfestival-3/src/libcanfestival.a
    /home/bas/Canfestival-3/drivers/can_socket/libcanfestival_can_socket.so
    /home/bas/Canfestival-3/drivers/unix/libcanfestival_unix.a
    /usr/local/lib/libcanfestival_can_socket.so
    /usr/local/lib/libcanfestival_unix.a
    /usr/local/lib/libcanfestival.a
  9. I need that because on page 21 and 22 of this document is an example how to open CANopenShell. So now we use libcanfestival_can_socket.so to start CANopenShell like this (one line):
    bas@mbp-jessie:~/Canfestival-3/examples/CANOpenShell$ ./CANOpenShell load#libcanfestival_can_socket.so,can0,1M,0,1
    which then tells us:
    Node_initialisation
    Node_preOperational
  10. And look at candump terminal:
    bas@mbp-jessie:~$ candump can0
    can0  702   [1]  00
    can0  700   [1]  00

    this shows that we booted the master!
  11. The next thing to do is to type "help" when inside the CANopenShell, here's the output:.
    MANDATORY COMMAND (must be the first command):
    load#CanLibraryPath,channel,baudrate,nodeid,type (0:slave, 1:master)NETWORK: (if nodeid=0x00 : broadcast)
    ssta#nodeid : Start a node
    ssto#nodeid : Stop a node
    srst#nodeid : Reset a node
    scan : Reset all nodes and print message when bootup
    wait#seconds : Sleep for n secondsSDO: (size in bytes)
    info#nodeid
    rsdo#nodeid,index,subindex : read sdo
    ex : rsdo#42,1018,01
    wsdo#nodeid,index,subindex,size,data : write sdo
    ex : wsdo#42,6200,01,01,FFNote: All numbers are hex
    help : Display this menu
    quit : Quit application
  12. ok, type "scan" and behold in the CANopenShell:
    Wait for Slave nodes bootup...Slave 2 boot up
    I saw the LED on the device change to red and start blinking again. The candump terminal now looks like this:
    bas@mbp-jessie:~$ candump can0
    can0  702   [1]  00
    can0  700   [1]  00
    can0  000   [2]  81 00
    can0  702   [1]  00

I had Wireshark sniffing at can0 so these packets also made it to Wireshark.

wireshark-capturing-CAN-packets

At this time I gave myself a slap on the shoulder, got a victory beer, and slapped my other shoulder for good measure.

I'm now at the beginning of the beginning.

Hope you enjoyed it!
Don't be afraid to leave a reply.
Cheers

HAL driver for CANopen stack for Machinekit

This is the first post in a series about the development of a HAL driver for CANopen for Machinekit.

I've been talking/skyping/mailing with Michael for quite some time now about CAN. And in the meantime a lot of interesting folks have expressed interest in using CAN devices (and other industrial busses) with Machinekit. So for Machinekit to get some more "industrial" traction this would be a very welcome addition.

The nice thing is that the BeagleBone Black already has a CAN interface, so it's (almost) ready to talk to CAN devices if you look at the hardware side. I say almost because you need to hook up a line driver chip to the pins.

This will be a series of posts which mark my progress on the learning curve. I'm a mechanical engineer interested in automation, open source and Machinekit. I'm not a hacker-god breathing code, so this project will come in bits and pieces. Between projects i'll probably do a lot of brushing up on C, a lot of reading regarding CAN and absorbing knowledge regarding Linux, debugging and probably more.

Recently I wrote a delayline component (which can delay an arbitrary samples of an arbitrary type for an arbitrary time) in C, and that was the first "real" thing I wrote in C other than some "hello world" tutorial stuff. More info if you're interested in the issue, the PR and the manpage. Writing that was a lot of fun, really bumped my experience and it was a really satisfying experience. I intend to keep that vibe with the HAL driver for the CANopen stack.

One thing I'll really try to do is to keep the docs up to date with the progress. Then I can give people a "prrroper bollocking" (I learned that one in Scotland) when they don't document stuff :-) .

First results are the links to developing for CAN and setting up for SocketCAN ... Note that these are working documents.

Interested in following? then have a look at Issue #589 which will serve as a collecting bin.

Feel free to leave a reply!

3DConnexion mouse as Machinekit input

Last week Michael and I went to the Hannover Fair, and we came round the 3DConnexion stand. I use a Spacepilot when doing Solidworks modelling, but since Michael didn't know these devises we had a good and proper look. What we saw was a "rugged" mouse that was in the user console of a small KUKA robot.

Further talking led to Michael giving in and buying a mouse which in turn resulted in the use of a 3DConnexion mouse as input for Machinekit.

see this thread on the Machinekit google group

Here is a video with stickers on motors driven by the Mouse:

Monster Modelling Clay 3D printed attachments

Having fun with Simon and Lucas...

I'm planning to make spikes (red ones) and other attachments. But now (because I have 2 boys modelling monsters with at least 4 eyeballs and 10 teeth per monster) I'm in desperate need of extra extra extra eyeballs and teeth.

clay-monster

Here you can find the tooth and eyeball stl files.

Agree to the terms, download them and scale them according to your monster dimensions and make the best monster you can think off.

Velocity extruding revisited

After finding some time (actually it was so simple that I'm still asking myself why I didn't make time sooner) I finally got to changing the velocity extrusion logic.

My previous posts about velocity extruding and wire-laying were about how I changed the extrusion position (the E0-axis in reprap or A-axis in Machinekit) being calculated by the slicer to a situation where the extruder velocity is a result of the actual nozzle velocity. The big advantage is that tweaking the flow of plastic can be done real-time by adjusting the flow parameters. Because of the pressure in the nozzle due to the filament speed, and as a resulting compression force of the filament (and other causes) the flow of thru the nozzle will have a hysteresis.

  • You can notice this when you accelerate to a high speed with a high velocity, the nozzle will have to build up pressure. There will be stringy parts of the path that is being printed. So until a new equilibrium is formed, the flow will lag.
  • Then decelerating the pressure is too much, with respect to the lower velocity, and thus there will be an abundance of plastic. Resulting in wider paths and blobs when standing still.

Some of you will say: "But I can't see those stringy lines in my printer!" That's because I think that the pressure will in some cases be always too big so you don't notice. What you probably would notice though is that if you print only lines at various speeds the lines will not always be equally thick at the acceleration and deceleration positions.

This movie shows that with the lines I print the thickness is equal, at various speeds.

For the velocity extruding my workflow is as follows:

  • Slice with Slic3r with ALL line widths the same width and ALL line heights (layer heights) the same height. (I'm in the process of overcoming this obstacle, but that task is not finished yet).
  • Run a script to change the Slic3r generated code to suitable g-code. This link still links to the configuration files (including script) I used with my BBB rev B and BeBoPr-Bridge. I'll do a separate post regarding the script at a later date.
  • Have Machinekit installed with a suitable configuration for the velocity extrusion.
  • Print the product.

So how does the new velocity extruding work? This week I thought: "Let's make a nice graph with Graphviz visualising the way the calculations are done...". So I started to type, and after 3 lines of adding nodes and edges in Atom with .dot syntax and graphviz preview package installed I was thinking this would be a loooooot of work. And I had already done it in my .hal file.

I searched and ultimately found this post from Jeff Epler which explains how to generate a .dot file from a running hal instance (or hal configuration file). Such a shame I didn't search for this before because it would have made the work a lot easier.

Resulting in this file. I've exported it to a .pdf document so you'll be able to zoom in and explore. I've highlighted some nodes and below I'll explain what is done at that point.

lineardeltajointscartesian.0

because I have the linear delta kinematics, the velocity of the axes are measured as joint velocities. Not x, y and z in cartesian space, but the speeds of the tower carriages. This needed to be converted to cartesian because that's not standard in LinuxCNC yet. I shamelessly took the part of the kinematics file that handles the part of calculating x, y and z from the carriage positions and from this I made a hal-component.

hypot.1

This component takes the square root of the total of the squared velocities... meaning

The nozzle speed gets multiplied with the cross section area of the line, and further on divided by the cross section area of the filament to get to the extrude rate of the extruder.

oneshot.0
mux4.0
trigger
trigger-time

these four take care of the retraction and pre-charge. These happen when the extruder velocity is coupled with the nozzle velocity and the time is set at greater than zero.

lincurve.1

The magic happens here! This lincurve takes the speed as an input, and gives a offset value as an output. This curve now consists of 5 values. Anything in-between will get interpolated.

extruder-pos-compensated

The final result is the position the extruder should have when it is compensated for the hysteresis of the filament. The derivative is taken from the (changing in time) position, resulting in a speed, which is being fed into (end of our journey):

hal_pru_generic_stepgen_03

which is input for the step generator for the extruder motor.

There's probably more that I forgot to mention, so if you've got questions or remarks leave a comment and I'll try to answer. Or else leave a message at the Machinekit group which I closely follow.

I'll publish the config files after I have cleaned up the unused artefacts of the previous velocity extruding. Here are the config files.

As an added bonus, for reading this far, here's a movie of the printer printing this part (for you who have a 3D printer and kids a must-have). I'm pretty happy with the result. There's room for improvement. Especially my mechanical setup. Due to the acceleration my hot-end overshoots. As a result the corner of the overhang at approx 4 minutes into the movie is a not as should be. Furthermore, at the end of the movie when I turn the connector around you'll notice little blobs.

I think that this is due to the way the extruder starts and ends. When starting the line, the nozzle will extrude and start to move. When that happens, the plastic is flowing in every direction without a preference. So an equal amount going to the side as, as to as the front and back. When the nozzle has speed, the plastic will become a straight line. Don't know how to solve that one yet. :) Probably when I improve the script for transforming the generated g-code. Then I'll be able to use different extrusion widths again.

 

Old-school hard-core making

Are you ready for some old-school hard-core making?
Take a good look at what you're wearing, nearly everything is knitted!

After seeing this post on my favourite site I decided I wanted to do this.
Have a look at the AYAB site, and think about what you'd want to make If you got one :)

I think with all modern dat techniques and electronics, one thing that is still very old-school is knitting. My mother spins, weaves and knits, and when you think of it, it's not all that different from 3D printing. It's funny that everybody seems to have forgotten this (who of you men have actually knitted? I know I haven't.)

The mechanics of this 30 year old machine are just from engineering perspective magnificent. Cams pushing needles out, depending on the needle position.... Adjustable tension.... Adjustable size of the stitch (stroke of the needles).... Timing of the needles.... If you like mechanics you'll appreciate a knitting machine.

I searched on marktplaats.nl and found a Brother KH-910 knitting machine (actually 2 of which the second one for spare parts), and a lot of extra's. Including a KR-850 ribber bed, KRC-830 Colour changer and a box full of yarn.

In the process of buying the second hand machine (nearly 30 years old !) I ordered the AYAB shield and an Arduino Uno.

It took a sunday afternoon to get my first knittings from the machine, and while waiting for the electronics to be delivered I started getting familiar with knitting.

In a matter of one morning (of which most of my time consisted of getting the needed python libraries installed on my Mac) I got something in 2 colors out of the machine. Some tweaking of the hall end-sensors which detect the end position of the carriage and everything worked.

Result:
IMG_1280

This evening I added the ribber bed. Paving the way for double colour jacquard knitting...

IMG_1277I need to delve in the actual control and electronics about why this works (I first neeeeded to knit something). Because there are only 16 solenoids who drive 200 needles. But forget about that for now, I'll open the spare machine at a later time.

I know the needles are sensed by the electronics (like an encoder, sensing left/right motion) and it seems there is a 3rd sensor sensing banks of 16 needles. Just have to investigate.

Maybe in the future I'll add a motor and make it entirely automatic. Maybe some future Machinekit project. Then I'll name it MachinekNit. :)

 

Setting up your linear delta printer for Machinekit

This post is not a tutorial on MachineKit/LinuxCNC. There is actually a lot of information about that on linuxcnc.org

Take some time to read about LinuxCNC and what it actually does. At the very least know that of the HAL manual and the Integrators Manual. No need to ask questions if you haven't looked up these, and at the very least read the Contents to know where to look.

When you have set up all the connections (physically wired the sensors, heater, endstop, motors, power etc.) from your printer to hardware side you're ready to do the configuration of your machine, meaning the HAL wiring in the .hal file and setting your machine properties in the .ini file

What's HAL??? The HAL is the Hardware Abstract Layer, and is in fact a way of connecting the software to the correct physical pins. This is done by "virtual" wires. Like in the real world, when you make an electronically cabinet for a machine, the wires get numbered and have a name. Same goes for the HAL. There are wires connecting software pins to hardware pins (and the hardware pins differ per electronics).

What is hard to understand at first is the way it is written. Take this for example:

net emcmot.01.enable axis.1.amp-enable-out => [PRUCONF](DRIVER).stepgen.01.enable
  

When in doubt forget <= or => and remember:

net signal source target1 target2

what above means is that axis.1.amp-enable-out is the source, [PRUCONF](DRIVER).stepgen.01.enable is (one of) the target(s), and emcmot.01.enable is the name of the signal.

You can make it a little more readable by first naming the signal and it's source and on other lines specifying the targets where the signal connects to. Again, <= and => are just for readability. Result:

net emcmot.01.enable <= axis.1.amp-enable-out
net emcmot.01.enable => [PRUCONF](DRIVER).stepgen.01.enable
  
Enough of that, just put these memories in your /swap or save them to ~/knowledge
go ahead to the next page to start writing your actual values in your .ini file.

Additive Wire-Laying

After making my machine suited for the "Velocity Extruding" I wanted to go one step further in using Additive Manufacturing. I recently tested printing over a copper wire, and since I've had this idea for a long time I needed to get it out of my head.

The basic idea is that there should be a slew-ring rotating in the direction of the movement. This rotation will put a wire always right in front of the nozzle, just before being covered with plastic. Then you'd be able to manufacture PCB's in an additive way. You lay the wire (or equivalent) where you need one. strange shaped coils? RFID/NFC antennae?

IMG_0516

I have bought a BeBoPr-Bridge a while ago, and when I met Bas Laarhoven (another Bas) the maker of the BeBoPr, he pointed me to the already available expansion for a fifth axis. The BeBoPr can be expanded with the "PEPPER" which are in fact 5 stepper drivers on one board, current adjustable via software, and also decay mode depending on the activity. That means when the machine is idle, the current in the motor is lowered so the friggin noise is less. One problem, I didn't have one at the moment.

First thought was that I could access the pins for the PEPPER and add an external stepper driver. There was one problem, and that was that the already mounted stepper drivers needed to have the "enabled" pin removed, since those signals were used for the STP and DIR pf the fifth motor. (I actually got this info from Bas-L. Below is the quick version, in real life it took a little more time).

See picture below, I bent one pin of a 8 way header, and routed the enable pin from the stepper driver to my breadboard to enable later on:

IMG_0460

The addition of this header in between elevates the stepper driver so that there now is room at the J5 connector to connect wires.

IMG_0458

Below is the end result. Wires from the enable pins on the stepper drivers, as well as the ENABLE pin, B_DIR pin and B_STP pin (J5.15, J5.4 and J5.5) going out at the right of the picture.

IMG_0514Now the 5th stepper driver is wired, I needed 12V, 5V and GND and looked at the bottom side of the board. It's all there.

IMG_0462

Last but certainly not least, the wired breadboard.

IMG_0512

This was the electronically hardware part, The mechanical hardware part was also quickly finished, at least with the normal engineering iterations. Last point on the list was getting the slew ring to rotate in the direction of the movement.

For this the direction of travel is needed. Since I have a linear delta machine, I cannot take the positions of the towers (joints) since they are not the actual x, y and z (cartesian) coordinates.

Turned out that the HAL pins I needed from Machinekit/linuxCNC did not exist, at least the reading of x, y and z position is in a branch that has yet to be merged, and I decided not to wait for that. So I took the calculation of the x-y-z position from the kinematics file and put it in a component I can then use in my HAL file. Not the most refined way, but speed is paramount.

This component produces x-y-z coordinates, That position gets a derivative (speed) and is fed into a component that calculates the angle of movement with respect to the positive x-axis. That in turn is used for generating a position command for the slew drive.

See it in action?

As you can see, there needs to be more functionality, cutting of the wire, connecting the wire to components, homing, fine-tuning etc. But that are just "details" and with time and engineering those issues can be solved.

I hope it's some use to you. Don't hold me accountable for the machine you make. Before you can easily make things with this there needs to be some new kind of software, but that's not something on my list for the near future, because that will take up too much of my time for now.

Special thanks to Bas-L, Machinekit user list and EMC user list.

I release this idea under the CERN OHL 1.2 licence. I need to clean up the code and the 3D models, but once done I'll do a pull request for Machinekit, and put the CAD models somewhere for download. I'll update this post when I do.

If you have applications or ideas you can use with this or other technology, publish them and generate prior art. Keep that technology free to use and share so the bad companies can't patent all the logical and sensible things and prevent you using it, now or in the future.

Example applications:

  • Coils
  • Antenna's
  • PCB's
  • Flexible PCB's (FPC's)
  • embed tubes and other filament types into plastic or other materials, like starch, organic printable stuff etc. etc.
  • Use dissolvable PVA as an intermediate to bring wire/chips into tissue
  • Please elaborate in the comments.

 

Machinekit and Additive PCB Manufacturing

Last week I wrote a post about how I use Machinekit with velocity extrusion and its pressure adjustment to make parts without the blobs (or at least less blobs).

Another thing that's easy to do with this configuration is the making of G-code programs from scratch. And really, just like Scratch, put the pen down, put the pen up type of programming.

See the picture below how easy it is to experiment and verify ideas. I've tensioned 2 wires (0.10 and 0.15 mm) of enamelled copper over a mirror and covered them with PLA.

Covering of enamelled copper wire

It's a wish of me to have a device that can print PCB's, but not wit conductive materials, but with good old copper. Like the traces on a real PCB. But instead of making this by removing (etching) all the copper and making a lot of unfriendly waste we could make a device which puts the wire just in front of the nozzle.

You can then also have multi-multi-layer PCB's... How's that? There's no software for this yet, but that should not stop us now. :)

I'm working to finish my device for keeping the wire just in front of the nozzle, rotating in the direction of movement as the nozzle progresses. Also I need to add some functionality to LinuxCNC (calculating the angle of the slew drive from the nozzle movement vector). That will take some days and I'll show you how it works when it's finished.

Here is the movie of the actual covering of the 2 wires.
update: see this post how you can lay down wire in a pattern