OpenCN detailed documentation

Actually problem was with default terminal of Kubuntu which disaplayed only 8 lines and previous lines got depleted.

I used another terminal Xterm and the cat command worked.


opencn ~ # cat micro5/micro5.hal

Micro5 HAL file

The threads period is in [us], contrary to the one defined for the

Ethercat master in its xml, where it is in [ns]

– load components –

load lcec cfg=micro5/micro5_ec_topology.xml -d
load ocno axes=zbxyc # Order of axis to handle clearing - temporary solution
load feedopt --axes=xyzbc
load plc cfg=micro5
load plc cfg=spindle
load simple_pg joint_nr=5
load mux name=position type=float vector_nr=2 vector_size=5
load kinematic type=xyzbc params=micro5/m5_kin_param.txt

– Signal creation –

Inactive of operation

net set-mode-inactive-X ocno.axisX.set-mode-inactive => lcec.0.TSDXB.set-mode-inactive-0
net set-mode-inactive-Y ocno.axisY.set-mode-inactive => lcec.0.TSDYC.set-mode-inactive-0
net set-mode-inactive-Z ocno.axisZ.set-mode-inactive => lcec.0.TSDZS.set-mode-inactive-0
net set-mode-inactive-B ocno.axisB.set-mode-inactive => lcec.0.TSDXB.set-mode-inactive-1
net set-mode-inactive-C ocno.axisC.set-mode-inactive => lcec.0.TSDYC.set-mode-inactive-1
net in-mode-inactive-X <=
net in-mode-inactive-Y <=
net in-mode-inactive-Z <=
net in-mode-inactive-B <=
net in-mode-inactive-C <=


net spindle-target-velocity =>
net spindle-current-velocity plc.spindle.current-velocity <= lcec.0.TSDZS.current-velocity-1
net spindle-set-mode-csv plc.spindle.set-mode-csv => lcec.0.TSDZS.set-mode-csv-1
net spindle-set-mode-inactive plc.spindle.set-mode-inactive => lcec.0.TSDZS.set-mode-inactive-1
net spindle-in-mode-csv <=
net spindle-in-mode-inactive <=

Spindle parameter

setp plc.spindle.acceleration 5000 # Debug mode !
#setp plc.spindle.min-velocity 8000 # TO BE SET ONECE TEST IS DONE
setp plc.spindle.max-velocity 60000

#spindle to be linked in real machine
net spindle-cmd-target-velocity plc.spindle.cmd-target-velocity <= ocno.spindle.speed
net spindle-cmd-rotate-spindle plc.spindle.cmd-rotate-spindle <= ocno.spindle.enable

Homing of operation

net set-hm-csp-X ocno.axisX.set-mode-homing => lcec.0.TSDXB.set-mode-hm-0
net set-hm-csp-Y ocno.axisY.set-mode-homing => lcec.0.TSDYC.set-mode-hm-0
net set-hm-csp-Z ocno.axisZ.set-mode-homing => lcec.0.TSDZS.set-mode-hm-0
net set-hm-csp-B ocno.axisB.set-mode-homing => lcec.0.TSDXB.set-mode-hm-1
net set-hm-csp-C ocno.axisC.set-mode-homing => lcec.0.TSDYC.set-mode-hm-1
net in-hm-csp-X <=
net in-hm-csp-Y <=
net in-hm-csp-Z <=
net in-hm-csp-B <=
net in-hm-csp-C <=

CSP of operation

net set-mode-csp-X ocno.axisX.set-mode-csp => lcec.0.TSDXB.set-mode-csp-0
net set-mode-csp-Y ocno.axisY.set-mode-csp => lcec.0.TSDYC.set-mode-csp-0
net set-mode-csp-Z ocno.axisZ.set-mode-csp => lcec.0.TSDZS.set-mode-csp-0
net set-mode-csp-B ocno.axisB.set-mode-csp => lcec.0.TSDXB.set-mode-csp-1
net set-mode-csp-C ocno.axisC.set-mode-csp => lcec.0.TSDYC.set-mode-csp-1
net in-mode-csp-X <=
net in-mode-csp-Y <=
net in-mode-csp-Z <=
net in-mode-csp-B <=
net in-mode-csp-C <=

Data Path

net data-selector mux.position.selector <= ocno.datapath-sel
net cmd-pos{XYZBC} ocno.axis{XYZBC}.target-pos => simple_pg.joint{01234}.cmd-pos
net cmd-pos{XYZBC} ocno.axis{XYZBC}.target-pos => mux.position.vector0.input{01234}
net pg-data{XYZBC} mux.position.vector1.input{01234} <= simple_pg.joint{01234}.target-position
net target-position-x mux.position.output0 =>
net target-position-y mux.position.output1 =>
net target-position-z mux.position.output2 =>
net target-position-b mux.position.output3 =>
net target-position-c mux.position.output4 =>


net start-hm-X ocno.homing.axisX.start =>
net start-hm-Y ocno.homing.axisY.start =>
net start-hm-Z ocno.homing.axisZ.start =>
net start-hm-B ocno.homing.axisB.start =>
net start-hm-C ocno.homing.axisC.start =>
net stop-hm-X ocno.homing.axisX.stop =>
net stop-hm-Y ocno.homing.axisY.stop =>
net stop-hm-Z ocno.homing.axisZ.stop =>
net stop-hm-B ocno.homing.axisB.stop =>
net stop-hm-C ocno.homing.axisC.stop =>
net homed-X ocno.homing.axisX.homed <= lcec.0.TSDXB.homed-0
net homed-Y ocno.homing.axisY.homed <= lcec.0.TSDYC.homed-0
net homed-Z ocno.homing.axisZ.homed <= lcec.0.TSDZS.homed-0
net homed-B ocno.homing.axisB.homed <= lcec.0.TSDXB.homed-1
net homed-C ocno.homing.axisC.homed <= lcec.0.TSDYC.homed-1


net jog-enable ocno.jog.enable => simple_pg.enable
#net pg-target-pos{XYZBC} ocno.axis{XYZBC}.target-pos => simple_pg.joint{01234}.cmd-pos
net current-pos-X lcec.0.TSDXB.current-position-0 => simple_pg.joint0.current-position
net current-pos-Y lcec.0.TSDYC.current-position-0 => simple_pg.joint1.current-position
net current-pos-Z lcec.0.TSDZS.current-position-0 => simple_pg.joint2.current-position
net current-pos-B lcec.0.TSDXB.current-position-1 => simple_pg.joint3.current-position
net current-pos-C lcec.0.TSDYC.current-position-1 => simple_pg.joint4.current-position
net jog-running-{XYZBC} ocno.jog.axis{XYZBC}.is_running <= simple_pg.joint{01234}.is_running

OCNO - current position

net current-pos-{XYZBC} ocno.axis{XYZBC}.current-joint-pos

OCNO machining

net spindle-current-velocity ocno.spindle.current-speed lcec.0.TSDZS.current-velocity-1


net in-fault-X
net in-fault-Y
net in-fault-Z
net in-fault-B
net in-fault-C

ocno - fault reset

net fault-reset-X ocno.axisX.fault-reset => lcec.0.TSDXB.fault-reset-0
net fault-reset-Y ocno.axisY.fault-reset => lcec.0.TSDYC.fault-reset-0
net fault-reset-Z ocno.axisZ.fault-reset => lcec.0.TSDZS.fault-reset-0
net fault-reset-B ocno.axisB.fault-reset => lcec.0.TSDXB.fault-reset-1
net fault-reset-C ocno.axisC.fault-reset => lcec.0.TSDYC.fault-reset-1


net quick-stop-X ocno.axisX.quick-stop => lcec.0.TSDXB.quick-stop-0
net quick-stop-Y ocno.axisY.quick-stop => lcec.0.TSDYC.quick-stop-0
net quick-stop-Z ocno.axisZ.quick-stop => lcec.0.TSDZS.quick-stop-0
net quick-stop-B ocno.axisB.quick-stop => lcec.0.TSDXB.quick-stop-1
net quick-stop-C ocno.axisC.quick-stop => lcec.0.TSDYC.quick-stop-1

Simple PG

always in ‘absolute’ position - relative position handled by ‘ocno’)

setp simple_pg.joint0.relative-pos 0
setp simple_pg.joint1.relative-pos 0
setp simple_pg.joint2.relative-pos 0
setp simple_pg.joint3.relative-pos 0
setp simple_pg.joint4.relative-pos 0

PLC safety and functionality of M5

net in-fault-X plc.micro5.is_x_in_fault <=
net in-fault-Y plc.micro5.is_y_in_fault <=
net in-fault-Z plc.micro5.is_z_in_fault <=
net in-fault-S plc.micro5.is_spindle_in_fault <=
net in-fault-B plc.micro5.is_b_in_fault <=
net in-fault-C plc.micro5.is_c_in_fault <=
net m5-EStop plc.micro5.is_EStop_pushed <= lcec.0.EL1809.din-4-not
net m5-release-break-z plc.micro5.release_break_z => lcec.0.CTEU.out0.bit-0
net is-enabled-2 plc.micro5.is_z_enabled <= lcec.0.TSDZS.enabled-0
net is-enabled-3 plc.micro5.is_spindle_enabled <= lcec.0.TSDZS.enabled-1
net is-enabled-4 plc.micro5.is_b_enabled <= lcec.0.TSDXB.enabled-1
net is-enabled-5 plc.micro5.is_c_enabled <= lcec.0.TSDYC.enabled-1
net m5-sealing plc.micro5.b_c_s_axis_sealing => lcec.0.CTEU.out0.bit-1
net m5-spindle_cooling plc.micro5.spindle_cooling => lcec.0.CTEU.out0.bit-6

net set-mode-inactive-3 plc.micro5.spindle_set_mode_inactive => lcec.0.TSDZS.set-mode-inactive-1

net set-mode-csv-3 plc.micro5.spindle_set_mode_csv => lcec.0.TSDZS.set-mode-csv-1

net m5-pull-0 plc.micro5.spindle_pulling_pin0 <= lcec.0.EL1809.din-11
net m5-pull-1 plc.micro5.spindle_pulling_pin1 <= lcec.0.EL1809.din-12
net m5-free-tool plc.micro5.free_milling_tool => lcec.0.CTEU.out0.bit-4
net m5-cone-clean plc.micro5.cone_cleaning => lcec.0.CTEU.out0.bit-5
net m5-free-pal plc.micro5.free_palette => lcec.0.CTEU.out0.bit-2
net m5-blow-pal plc.micro5.blowing_palette => lcec.0.CTEU.out0.bit-3
net spindle-can-turn plc.micro5.spindle_can_turn => ocno.spindle.can-turn
net spindle-temperature plc.micro5.spindle_temperature <= lcec.0.EL3202.chan1.temperature
net m5-is-milling plc.micro5.is_milling <= ocno.machining.running


net machining-finished feedopt.finished => ocno.machining.finished
net machining-underrun feedopt.sample.underrun => ocno.machining.underrun
net machining-ready feedopt.ready => ocno.machining.operation-ready
net machining-read-one-samples <= ocno.machining.get-one-sample
net machining-read-samples <=
net machining-cmd-pos-{XYZBC} feedopt.axis{XYZBC}.sample => ocno.machining.axis{XYZBC}.cmd-pos
net feedopt-spindle-target-speed feedopt.spindle-target-speed =>
net feedopt-resampling-pause feedopt.resampling.pause => ocno.machining.resampling-pause

#to be linked
#net m5-cmd-free-tool plc.micro5.cmd_free_tool <=
#net m5-cmd_free_pal plc.micro5.cmd_free_palette <=
#net m5-cmd-enable-spindle plc.micro5.cmd_enable_spindle <=
#net m5-stop-operation plc.micro5.stop_operation =>

– Parameters config --#

lcec - modulo mode

setp lcec.0.TSDYC.modulo-1 360

– Micro5 specific behavior –

Machine position limits

setp ocno.axisX.limit-min -39
setp ocno.axisX.limit-max 39
setp ocno.axisY.limit-min -28
setp ocno.axisY.limit-max 28
setp ocno.axisZ.limit-min -50
setp ocno.axisZ.limit-max 0
setp ocno.axisB.limit-min -102 # 10 recommended from manufaccturer / (24 degree mesured143degree mesured in full range, we still use manufacturer spec
setp ocno.axisB.limit-max 15
setp ocno.axisC.limit-min 0
setp ocno.axisC.limit-max 0

– Export functions –

addf ocno.func lcec_thread.0
addf feedopt.update lcec_thread.0
addf plc.micro5 lcec_thread.0
addf plc.spindle lcec_thread.0
addf simple_pg.func lcec_thread.0
addf mux.position_func lcec_thread.0

– Debug mode –

in debug mode set some default values !

setp lcec.0.EL1809.debug_din-11 1
setp lcec.0.EL1809.debug_din-12 1

– Sampler –

load sampler depth=1000 cfg=fffffffffffffffub

net target-position-x
net target-position-y
net target-position-z
net target-position-b
net target-position-c
net current-pos-X
net current-pos-Y
net current-pos-Z
net current-pos-B
net current-pos-C

#sampler logging of error position
net pos-error-0 lcec.0.TSDXB.position-error-0 =>
net pos-error-1 lcec.0.TSDYC.position-error-0 =>
net pos-error-2 lcec.0.TSDZS.position-error-0 =>
net pos-error-3 lcec.0.TSDXB.position-error-1 =>
net pos-error-4 lcec.0.TSDYC.position-error-1 =>

net data-selector
net machining-finished

addf sampler.0 lcec_thread.0

– Start operations –


Hi Nadim,

Thanks for sharing the file. Unfortunately (if I can say) it seems correct. I’ve no idea why you had an error at the boot. I’ve to debug (I will try to do it asap).

Anyway, you still can play with OpenCN without it.

Regarding the terminal display issue, the cmd resize usually restore the print area.


1 Like

No Problem @jmi , Thanks
You can debug as per your time.

In the meantime I will try below tasks:

  • I will redo the whole procedure on Ubuntu version because thats what i use for other work also. I will redo and then study and try the document in detail. I will also check if this same problem occurs again.
  • I will also try to build and run on raspberrypi4 target
  • I will comeback with the results

Can you create a seperate branch from where I can checkout and try my handson and update things?

My gitlab userid is :15429624
I am new to gitlab but i can follow along its documentation.

Hi Nadim,

I will add you as developer in the OpenCN repo. Regarding the branches and issue, we already have the issue #113. This issue, and its related branch, was created to follow documentation update which was not related to new features/dev.

  • The branch has to be aligned with the current master

You can use this issue/branch if it is ok for you

Have a nice day

I need you gitlab username. I cannot add you using the userid

My username is nadim4114

Done - you should receive an invitation

1 Like

Thanks for adding me.
I received an invitation.

I am using below branch to checkout a copy. Is this correct if you can confirm.

nadim@nadim-pc:~/opencn$ git checkout origin/113-documentation-update
M agency/usr/matlab
HEAD is now at dc31915f1e [doc] deployment: add info to install on PC internal disk

Yes, it is the correct branch. But I has to be aligned with the current state of master branch.


  1. I will follow this procedure everytime for documentation update. 13. Development flow — OpenCN 2021.2.0 documentation

  2. Just a quick silly question.
    The script mentioned in below userguide creates document from the updated files present in /home/nadim/opencn/doc/src ?
    8. User guide — OpenCN 2021.2.0 documentation

  3. I have made my first commit and push to gitlab repository for testing purpose. Pls confirm if change is reflected and everything is okay?

Hi Nadim,

  1. Yes this doc seems correct.
  2. This script will generate the documentation in html (or pdf) or the src folder. All is performed locally.
  3. I’ll look at the push in detail lately (no time right now), but you did not follow the doc at 1 (see below).

Doc update flow
Here is a summary of the process to update the documentation.

N.B: This flow is valid only for activities on the doc only - no code source update !
N.B2: In case of the integration of a new feature, a new branch/issue has to be created and the doc has to be integrated in this branch as well.

First the 113 branch has to be align with the master branch. It is important ! It will avoid many conflict during the merge / alignment.

" First the 113 branch has to be align with the master branch."

To align 113 branch to master, do you mean to create a merge request of branch 113?

Since my background is new to these kind of development tools, I am asking a lot of questions. Sorry for that.

No, it consists in rebasing the 113 branch on top of master branch.

$ git fetch --all
$ git checkout 113-documentation-update
$ git rebase origin/master

// Update the documentation and push the modification

$ git push --force

This is what is used as per the document.

Any thing to add or modify in these steps, please suggest.

Or if the step is okay then i go ahead and build and run openCN and start learning and documenting.

Yes it is correct !

it is what you have done ? sorry, It means I’ve looked at the commit to quickly !

Have a nice day

1 Like

No issues @jmi,

I am taking diligent steps just to make sure I do not mess up with the system.
I will now follow the same steps to update the document. I will not hesitate to ask you guys again. :innocent:


Thanks for your help and don’t hesitate to ask questions !


I am trying hal commands in qemu. I have taken up this topic to try things and see where document can be corrected
some commands seem to return nothing or maybe I am doing wrong.

I tried below commands from the sample commands given in userguide.

opencn ~ # ./halcmd load loopback cfg=fsub
hal_systemv: waiting for child ./loopback
hal_connect returned with ret = 0
hal_systemv: OK, we can go ahead…

opencn ~ # ./halcmd load threads name1=loopback_thread period1=20000
hal_systemv: waiting for child ./threads
OpenCN: Threads component starting…
threads_connect returned with ret = 0
hal_systemv: OK, we can go ahead…

opencn ~ # ./halcmd addf loopback.0 loopback_thread
opencn ~ # ./halcmd show pin
opencn ~ # ./halcmd show pin loopback
opencn ~ # ./halcmd setp loopback.0.f_in.0 12.3
opencn ~ # ./halcmd show pin loopback
opencn ~ # ./halcmd start
opencn ~ # ./halcmd show pin
opencn ~ # ./halcmd show comp
opencn ~ # ./halcmd show sig
opencn ~ # ./halcmd show param
opencn ~ # ./halcmd show thread
opencn ~ # ./halcmd show

Can anyone suggest whether I am doing something wrong or the commands dont work in qemu?

Hi Nadim,

No idea right now on what is going on. halcmd is working - we are using it most of the time…

Can you try halcmd getp loopback.0.f_in.0 command ?


I followed the procedure shown in user guide.

Only changes are

I am running x86-qemu
I have commented below lines as suggested by you

  • Comment all lines in agency/rootfs/board/common/rootfs_overlay/root/

Other all things i have followed same.