Writing a needet HAL Component
im looking for an Timer. Something like sending a siggen signal to an encoder.
Just more simple in a single threat.
Im curious how hard it is to write (im no coder at all)
Example:
loadrt u32runner [count=N|names=name1[,name2...]]
runner.N.run bit in => run
runner.N.from u32 in => Number to start =>(just nice to have)
runner.N.to u32 in => Number to count to =>(if there is no "from" this can also be "THE" number)
runner.N.speed s32 in => count speed =>(must have - can also be an u32 if in ms)
runner.N.cycle bit in => repeat yes/no =>(must have)
runner.N.rev bit in => count backwards =>(just nice to have)
runner.N.warp bit in => one way or up and down =>(one way is need, up and down is nice to have)
runner.N.out u32 out => output =>(need of course)
For the first test its for the Owl in my panel. Its an 3D rendered objekt framed in single jpegs to an image_u32.
Also im open vor every other idea!
Greetings
Emanresu
Attachments:
Please Log in or Create an account to join the conversation.
If you have no coding experience at all, it will be a bit challenging, but possible.
There is probably a component available to base it from.
Chris M
Please Log in or Create an account to join the conversation.
There are probably typos
We set up some static variables that will persist between servo thread loops
We do a firstpass to check the cycle is a positive value. This might need revising if you change this value in real time (eg move it into the run loop
then an outer loop so it only runs if run is true
So then we need to skip cycle periods so we go into a do.. while loop. (It is very rare for me to actually use a do loop)
once we have counted the required number of cycles, we reset this_cycle to 0 to start again next time.
we determine which direction we need to be stepping from to the destination to
There are more efficient ways to write this but that would defeat the purpose if you are trying to learn.
eg the if statement to change step value could be written
step = (step > 0 ? -1 : 1)
but I will leave that as an exercise for the student to research and learn about C's ternary operator
Please Log in or Create an account to join the conversation.
Well, the component "time" would be nice, if it just hat 0,1 seconds.
Example Code:
pyVCP
<vbox>
<checkbutton> <font>("Arial",12)</font> <halpin>"run"</halpin> </checkbutton>
<image_u32 halpin='selectimage' images='1 2 3 ... 27 28 29 30'/>
<image name='1' file='./My-Panel/EuleAnim/0001.png'/>
...
<image name='1' file='./My-Panel/EuleAnim/0030.png'/>
</vbox>
HAL
loadrt runner count=1
addf runner servo-thread
setp runner.0.to 30
setp runner.0.speed 100
setp runner.0.cycle 1 #(1=cycle 2=count only once)
net start => runner.0.run
net start <= pyvcp.run
net number => pyvcp.selectimage
net number <= runner.0.out
Rodw thx vor the example! Cant wait to look into it!
Maybe some more need something like that and we crate a new component for new releases
As i sayd above, i have no idea if it need to be complex. The timer.comp is verry close to what i need.
Please Log in or Create an account to join the conversation.
i used Notepad++ to konvert from CL + LF to LF only.
This is what i get in LinuxCNC:
voxters@Vox-CNC:~/Arbeitsfläche$ halcompile --install runner.comp
make KBUILD_EXTRA_SYMBOLS=/usr/realtime-3.4-9-rtai-686-pae/modules/linuxcnc/Module.symvers -C /usr/src/linux-headers-3.4-9-rtai-686-pae SUBDIRS=`pwd` CC=gcc V=0 modules
make[1]: Entering directory `/usr/src/linux-headers-3.4-9-rtai-686-pae'
CC [M] /tmp/tmpTmai2A/runner.o
runner.comp: In function '_':
runner.comp:41:2: error: initializer element is not constant
runner.comp:47:10: error: lvalue required as left operand of assignment
runner.comp:53:16: error: expected ')' before ';' token
runner.comp:54:3: error: expected ';' before '}' token
runner.comp:54:3: error: expected 'while' before '}' token
runner.comp:56:5: warning: suggest explicit braces to avoid ambiguous 'else' [-Wparentheses]
runner.comp: At top level:
runner.comp:83:1: error: expected identifier or '(' before '}' token
make[4]: *** [/tmp/tmpTmai2A/runner.o] Fehler 1
make[3]: *** [_module_/tmp/tmpTmai2A] Fehler 2
make[2]: *** [sub-make] Fehler 2
make[1]: *** [all] Fehler 2
make[1]: Leaving directory `/usr/src/linux-headers-3.4-9-rtai-686-pae'
make: *** [modules] Fehler 2
If i look into the code, my head seems to be in *.xml mode. I totally understand not a single line.
Google leads me to forums to find help...
Help like "This is so common, just google it" and im in a loop xD
Please Log in or Create an account to join the conversation.
It does not like the way I say
static int counter = from
becasue from is a variable
Line 52 where I say do, I used a bracket, not a {
Line 56, I forgot a { on the if statement
So other than simple syntax errors
the only one to worry about is the initialisation of counter
so change it to
static int counter = 0;
static int is_warping = 0;
if(counter == 0)
counter = from;
Please Log in or Create an account to join the conversation.
Ok, i havent testet it yet. But its compiled and shows up in HAL.
for
runner.comp:47:10: error: lvalue required as left operand of assignment
i changed cycle = 1; to cycle == 1;
then i got this:
runner.comp:47:10: warning: value computed is not used [-Wunused-value]
Important?
Also i wasnt sure about
if(counter == 0)
counter = from;
so i did this;
old:
else{
if(counter == from){
is_warping = 0;
if(step > 0)
step = -1;
else
step = 0;
new:
else{
if(counter == 0){
counter = from;
is_warping = 0;
if(step > 0)
step = -1;
else
step = 0;
Was that right?
UPDATE
Doesnt work, but seems verry verry close! Error seems to be in line 47
component runner "LinuxCNC runner";
description
"""
Example:
loadrt u32runner [count=N|names=name1[,name2...]]
runner.N.run bit in => run
runner.N.from u32 in => Number to start =>(just nice to have)
runner.N.to u32 in => Number to count to =>(if there is no "from" this can also be "THE" number)
runner.N.speed s32 in => count speed =>(must have - can also be an u32 if in ms)
runner.N.cycle bit in => repeat yes/no =>(must have)
runner.N.rev bit in => count backwards =>(just nice to have)
runner.N.warp bit in => one way or up and down =>(one way is need, up and down is nice to have)
runner.N.out u32 out => output =>(need of course)
""";
author "Rod Webster";
// Example Calibration Data: 0v = 122.9 kHz, 10v = 925.7 Khz should be entered as 122900 and 925700
pin in bit run "count if true";
pin in signed from "number to count from";
pin in signed to "number to count to";
pin in signed speed = 1 "number of cycles between counts (default = 1 = one servo thread cycle)";
pin in bit cycle = 1 "if true, start again or stop";
pin in bit warp "if true, count up and then back down";
pin out unsigned out "the number to output";
function _;
license "GPL";
;;
#include <rtapi_math.h>
FUNCTION(_) {
static int first_pass = 1;
static int this_cycle = 0;
static int step = 1;
static int counter = 0;
static int is_warping = 0;
if(first_pass){
//set up
if(cycle < 1){
cycle == 1;
first_pass = 0;
}
}
if(run){
do{
this_cycle++;
}while(this_cycle < cycle);
this_cycle = 0;
if(!is_warping){
if(from > to) // Set the direction to count
step = -1;
else
step = 1;
counter += step;
if(step == from){ // we go to the destination
counter = from; // stop counting
if(warp){
is_warping = 1;
if(step > 0)
step = -1;
else
step = 0;
}
}
}
else{
if(counter == 0){
counter = from;
is_warping = 0;
if(step > 0)
step = -1;
else
step = 0;
}
}
}
}
Attachments:
Please Log in or Create an account to join the conversation.
This bit should only run once and solves the static variable initialisation
if(first_pass){
//set up
counter = from;
first_pass = 0;
}
This bit is just to protect from a 0 or negative value for cycle
if(cycle < 1){
cycle = 1;
}
This bit sets the direction to count
if(from > to) // Set the direction to count
step = -1;
else
step = 1;
So if warping, you want to count backwards to the start again so we need to set a flag and invert step direction
if(warp){
is_warping = 1;
if(step > 0)
step = -1;
else
step = 0;
}
So if we are counting back to to and we get there, we need to invert the step direction and say we are going in the normal direction
else{
counter += step;
if(counter == to){
is_warping = 0;
if(step > 0)
step = -1;
else
step = 0;
}
The only thing I will say is the test to get to from and to are not very robust becasue if something goes wrong, it will keep counting forever. it is probably safer to use <= and >= in the if statements which is more defensive.
Attachments:
Please Log in or Create an account to join the conversation.
counter = to; // stop counting
This probably should be:
counter = to-1; // stop counting
Please Log in or Create an account to join the conversation.
i have to change:
if(cycle < 1){
cycle = 1;
to
if(cycle < 1){
cycle == 1;
or i get the Error:
51:9: error: lvalue required as left operand of assignment
after changing it, it says:
value computed is not used
in 56:3: it says:
error expected ´;´ before ´this_cycle´
i changed it to:
;this_cycle = 0;
But its the only ; "infront" of something in the code ?!
Last thing is 85:1:
error: expected identifier or ´(´before ´}´ token
error is gone if i delete the last }
This is exciting
Time after time with a lot of Google some little parts give me an Idea, what they are doing.
Please Log in or Create an account to join the conversation.