Hello, Jan,

this is my carousel HAL component version. I made it more reliable, was 
tested a lot and is working on a real machine. Sense-pocket is low when 
carousel is fixed and high between positions. Sense-index occurs between 
positions AFAIR.
Might require changes because of hard-coded sensor states it expects. I 
used it with M6 re-mapping, thus used analog-out for socket number.
Here is the code:

component mycarousel "Orient a tool drum custom component";
// partly derived from andy-pugh carousel HAL component

pin in  float pocket-number-f "The pocket to move to when the .enable 
pin goes high. Float to be compatible with motion.analog-out";
pin in  bit    enable "Set this pin high to start movement. Setting it 
low will stop movement";
pin in  bit    unhome "Unhomes the component and forces to find index 
again";
pin out bit    active "indicates that the component is active";
pin out bit    ready "This pin goes high when the drum is in-position";
pin in  bit    sense-index "Drum index position feedback pin";
pin in  bit    sense-pocket = true "Drum pocket position feedback pin";
pin out bit    motor-fwd "Indicates the motor should run forwards 
(bigger numbers)";
pin out bit    motor-rev "Indicates the motor should run reverse";
pin out bit    is-ok = true "No fault output";
pin out signed pos = 0 "This pin indicates the current position feedback";
pin out bit    homed = false "Shows that homing is complete.";

param r  signed state = 0 "Current component state";
param rw signed home-pocket = 19 "Pocket number at index.";
param rw signed pockets = 21 "Pocket count in drum";
param rw signed timeout-one = 60 "Maximum time to wait for next pocket 
in thread periods";
param rw signed timeout-all = 1600 "Maximum time to rotate to any pocket 
in thread periods";

license "GPL";
author "andy pugh, Marius Alksnys";

variable hal_bit_t old_sense = false;
variable hal_bit_t old_index = false;
variable hal_s32_t timeone = 3;
variable hal_s32_t timeall = 3;
variable hal_s32_t pocket_number = 0;

function _ fp;

option singleton yes;

;;

#include <rtapi_math.h>

#define ST_WAITING 0
#define ST_HOMING_INDEX 10
#define ST_FINISH_HOMING 20
#define ST_CHOOSE_DIR 30
#define ST_MOVING 40
#define ST_STOP_AT_POCKET 50
#define ST_DONE 60
#define ST_HALT 96
#define ST_HALTED 99

#define MSG_SOURCE "Tool carousel: "

FUNCTION(_) {
     if (unhome) homed = false;
     if (sense_pocket && !old_sense) { // Pocket sensor signal just rised!
         timeone = timeout_one;
         if (homed) {
             if (motor_fwd) {
                 pos += 1;
                 if (pos > pockets) pos -= pockets;
             }
             if (motor_rev) {
                 pos -= 1;
                 if (pos < 1) pos += pockets;
             }
             if (!motor_fwd && !motor_rev) {
                 homed = false;
                 state = ST_WAITING;
                 rtapi_print_msg(RTAPI_MSG_ERR, MSG_SOURCE "got socket 
sensor signal, while no command to turn. Will re-home.");
             }
         }
     }
     old_sense = sense_pocket;

     if (sense_index && !old_index) { // Index sensor signal just rised!
         if (homed) {
             if ((motor_fwd && (pos != home_pocket)) || (motor_rev && 
(pos != home_pocket + 1))) {
                 state = ST_HALT;
                 rtapi_print_msg(RTAPI_MSG_ERR, MSG_SOURCE "home sensor 
signal at wrong time (very big risk to brake equipment), component will 
halt!!!");
             }
         }
     }
     old_index = sense_index;

     if (is_ok) {
         if (sense_pocket && sense_index) {
             state = ST_HALT;
             rtapi_print_msg(RTAPI_MSG_ERR, MSG_SOURCE "both sensors 
active (very big risk to brake equipment), component will halt!!!");
         }
         if (active) { // Checking for timeouts
             if (timeone-- < 0) {
                 motor_fwd = false;
                 motor_rev = false;
                 active = false;
                 is_ok = false;
                 state = ST_DONE;
                 rtapi_print_msg(RTAPI_MSG_ERR, MSG_SOURCE "time-out 
waiting for one position!");
             }
             if (timeall-- < 0) {
                 is_ok = false;
                 state = ST_STOP_AT_POCKET;
                 rtapi_print_msg(RTAPI_MSG_ERR, MSG_SOURCE "requested 
position time-out!");
             }
         }
     }

     switch (state) {
     case ST_WAITING: // waiting at start
         if (! enable) return;
         timeall = timeout_all;
         if (! sense_pocket) {
             homed = false;
             rtapi_print_msg(RTAPI_MSG_ERR, MSG_SOURCE "carousel was not 
fixed before rotating. Will re-home.");
         }
         active = true;
         pocket_number = round(pocket_number_f);
         if (!homed) {
             motor_fwd = false;
             motor_rev = true;
             timeone = timeout_one;
             state = ST_HOMING_INDEX;
             break;
         }
         state = ST_CHOOSE_DIR;
         ready = false;
     case ST_CHOOSE_DIR: // choose direction
         if (pocket_number < 1 || pocket_number > pockets) {
             motor_fwd = false;
             motor_rev = false;
             active = false;
             is_ok = false;
             state = ST_DONE;
             rtapi_print_msg(RTAPI_MSG_ERR, MSG_SOURCE "there is no such 
socket!");
             return;
         }
         if (pos < pocket_number) motor_fwd = !(pocket_number - pos > 
(pockets / 2));
         else motor_fwd = (pos - pocket_number > (pockets / 2));
         motor_rev = !motor_fwd;
         timeone = timeout_one;
         state = ST_MOVING;
     case ST_MOVING: // moving
         if (enable && !unhome) {
             if (pos == pocket_number) {
                 motor_fwd = false;
                 motor_rev = false;
                 active = false;
                 ready = true;
                 state = ST_DONE;
             }
         }
         else {
             timeone = timeout_one;
             state = ST_STOP_AT_POCKET;
         }
         break;

     case ST_STOP_AT_POCKET: // waiting for sense_pocket or another enable
         if (enable || sense_pocket) {
             motor_fwd = false;
             motor_rev = false;
             active = enable;
             state = ST_WAITING;
         }
         break;
     case ST_DONE: //waiting for enable to go false
         if (!enable) {
             ready = false;
             is_ok = true;
             state = ST_WAITING;
         }
         break;
     case ST_HOMING_INDEX: // waiting for index
         if  (sense_index) { // index found
             state = ST_FINISH_HOMING;
         }
         break;
     case ST_FINISH_HOMING: // waiting for pulse
         if  (sense_pocket) {
             pos = home_pocket;
             homed = true;
             active = false;
             state = ST_WAITING;
         }
         break;
     case ST_HALT:
         motor_fwd = false;
         motor_rev = false;
         active = false;
         ready = false;
         is_ok = false;
         homed = false;
         state = ST_HALTED;
         break;
     case ST_HALTED:
         break;
     default:
         state = ST_HALT;
         rtapi_print_msg(RTAPI_MSG_ERR, MSG_SOURCE "unknown state, 
component will halt!!!");
     }
}



11/04/2016 03:23 AM, Jan Bos rašė:
> Hello everybody,
>
> I am working on an ATC for my mill and intend to use the carousel
> component. My ATC has only one sensor that detects the pockets, it is a
> Geneva style ATC and the sensor is on the drive wheel and senses each
> rotation i.e. each step the wheel makes. There is no sensor to tell the
> system which pocket is facing the spindle. If the wheel rotates the sensor
> pulses for each pocket only.
>
> Question now is how do I tell LinuxCNC which pocket is facing the spindle
> and how to home this thing?
>
> Do I need to add a 'home' sensor or a 'pocket 1' sensor?
>
> I am not quite clear on how this is supposed to work, could anybody shine
> some light on how the Carousel component works with sensor inputs like this?
>
> Thanks,
>
> JB


------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today. http://sdm.link/xeonphi
_______________________________________________
Emc-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/emc-users

Reply via email to