rage писал(а): ↑08 дек 2021, 15:32
Кмпонент для упрвления револьверкой:
Алгоритм такой:
- Разблокируем инструмент, ждем проверяем концевик разблокировки. Если концевик не отработал - ошибка
- Поворачиваем инструмент на нужный, ждем. Проверяем по концевикам текущую позицию, если не совпадет с заданной - ошибка
- Блокируем инструмент, ждем. Проверяем концевик блокировки, если не заблокировано - ошибка
- все ок, сообщаем о успешной смене инструмента
Настройка в hal:
(для просмотра содержимого нажмите на ссылку)
Код: Выделить всё
loadrt message names=zb,rev-0,rev-1,rev-2,rev-3 messages="Наезд на ЗБ!,Ошибка разблокировки инструмента,Ошибка позиции инструмента,Таймаут вращения инструмента,Ошибка блокировки инструмента"
loadrt mux8
loadrt revolt
addf mux8.0 servo-thread
addf conv-float-s32.0 servo-thread
addf revolt.0 servo-thread
addf zb servo-thread
addf rev-0 servo-thread
addf rev-1 servo-thread
addf rev-2 servo-thread
addf rev-3 servo-thread
# Револьверка
net rev-en <= hm2_7i96.0.gpio.000.in_not
net rev-b1 <= hm2_7i96.0.gpio.001.in
net rev-b2 <= hm2_7i96.0.gpio.002.in
net rev-b3 <= hm2_7i96.0.gpio.003.in
net rev-b1 => mux8.0.sel0
net rev-b2 => mux8.0.sel1
net rev-b3 => mux8.0.sel2
setp mux8.0.in0 6
setp mux8.0.in1 8
setp mux8.0.in2 2
setp mux8.0.in3 5
setp mux8.0.in4 4
setp mux8.0.in5 3
setp mux8.0.in6 1
setp mux8.0.in7 7
setp hm2_7i96.0.stepgen.02.dirsetup 2000
setp hm2_7i96.0.stepgen.02.dirhold 2000
setp hm2_7i96.0.stepgen.02.steplen 2000
setp hm2_7i96.0.stepgen.02.stepspace 2000
setp hm2_7i96.0.stepgen.02.position-scale 400
setp hm2_7i96.0.stepgen.02.step_type 0
setp hm2_7i96.0.stepgen.02.control-type 0
setp hm2_7i96.0.stepgen.02.maxaccel 30
setp hm2_7i96.0.stepgen.02.maxvel 20
net tool-number-current-f <= mux8.0.out => conv-float-s32.0.in
net tool-number-current <= conv-float-s32.0.out => revolt.0.current-tool
net machine-is-enabled => revolt.0.enable
net tool-position-fb hm2_7i96.0.stepgen.02.position-fb => revolt.0.motor-position
net tool-position revolt.0.motor-position-cmd => hm2_7i96.0.stepgen.02.position-cmd
net tool-change-in-work <= revolt.0.in-work => not.2.in
net tool-change-in-work => hm2_7i96.0.ssr.00.out-00
net tool-change-in-work-not not.2.out => hm2_7i96.0.gpio.024.out
net rev-en revolt.0.tool-unlocked
net rev-error0 revolt.0.error-0 => rev-0.trigger
net rev-error1 revolt.0.error-1 => rev-1.trigger
net rev-error2 revolt.0.error-2 => rev-2.trigger
net rev-error3 revolt.0.error-3 => rev-3.trigger
Код компонента:
(для просмотра содержимого нажмите на ссылку)
Код: Выделить всё
component revolt "Revolver tool changer";
pin in bit enable = 0 "Enable component when machine is on";
pin out bit in_work = 0 "Identifier that tool in change process";
pin in bit tool_change = 0 "Tool change request";
pin out bit tool_changed = 0 "Tool changed";
pin in signed current_tool "Current tool";
pin in signed next_tool = 0 "Tool to change for";
pin in float motor_position "Motor feedback position";
pin out float motor_position_cmd "Motor position comand";
pin in bit tool_unlocked = 0 "Tool unlocked";
pin out bit error = 0 "Tool chnage error";
pin out bit error_not = 1 "Tool chnage not error";
pin out bit error_0 "Error tool not unlocked";
pin out bit error_1 "Error tool position";
pin out bit error_2 "Error tool rotate timeout";
pin out bit error_3 "Error tool lock";
pin in bit reset = 0 "Reset state";
param rw float position_cmd = 1.0 "Steps for change position for 1 tool";
param rw float unlock_delay = 0.5 "Time for tool unlock delay";
param rw float move_timeout = 10.0 "Timeout for motor move";
param rw signed pockets = 8 "Pockets number in revolver";
variable double timer;
function _ fp;
license "GPL";
;;
#include <stdlib.h>
#define STATE_NONE 0
#define STATE_CHECK_TOOL 1
#define STATE_TOOL_UNLOCK 2
#define STATE_TOOL_UNLOCKED 3
#define STATE_ROTATE_TOOL 4
#define STATE_ROTATE_TOOL_WAIT 5
#define STATE_TOOL_LOCK 6
int state = 0;
FUNCTION(_){
int HALF_POCKETS = pockets / 2;
if(error) {
timer += fperiod;
if(timer >= 1.0) {
error = 0;
error_not = 1;
error_0 = 0;
error_1 = 0;
error_2 = 0;
error_3 = 0;
state = STATE_NONE;
tool_changed = 0;
in_work = 0;
timer = 0;
}
return;
}
if(!enable) {
return;
}
.
if(reset) {
error = 0;
error_not = 1;
error_0 = 0;
error_1 = 0;
error_2 = 0;
error_3 = 0;
state = STATE_NONE;
tool_changed = 0;
in_work = 0;
}
if(!tool_change || error) {
return;
}
if(state == STATE_NONE && (next_tool > pockets || next_tool < 1 || next_tool == current_tool)) {
in_work = 0;
tool_changed = 1;
return;
}
if(state == STATE_NONE) {
state = STATE_CHECK_TOOL;
}
if(state == STATE_CHECK_TOOL) {
state = STATE_TOOL_UNLOCK;
timer = 0.0;
tool_changed = 0;
in_work = 1;
}
if(state == STATE_TOOL_UNLOCK) {
if(unlock_delay > 0 && timer < unlock_delay) {
timer += fperiod;
return;
}
if(tool_unlocked) {
state = STATE_TOOL_UNLOCKED;
}
else {
in_work = 0;
error = 1;
error_not = 0;
error_0 = 1;
state = STATE_NONE;
timer = 0;
return;
}
}
if(state == STATE_TOOL_UNLOCKED) {
state = STATE_ROTATE_TOOL;
int pos = next_tool - current_tool;
int mpos = abs(pos);
if(mpos > HALF_POCKETS) {
int p = pockets - mpos;
pos = pos > 0 ? -p : p;
}
timer = 0;
motor_position_cmd = motor_position + pos * position_cmd;
}
if(state == STATE_ROTATE_TOOL || state == STATE_ROTATE_TOOL_WAIT) {
timer += fperiod;
if(abs(motor_position - motor_position_cmd) <= 0.0000001) {
if(state == STATE_ROTATE_TOOL) {
state = STATE_ROTATE_TOOL_WAIT;
timer = 0;
return;
}
if(timer < 0.5) {
return;
}
if(current_tool != next_tool) {
timer = 0;
in_work = 0;
tool_changed = 0;
error = 1;
error_not = 0;
error_1 = 1;
state = STATE_NONE;
timer = 0;
return;
}
timer = 0;
state = STATE_TOOL_LOCK;
in_work = 0;
}
else if(timer >= move_timeout) {
in_work = 0;
tool_changed = 0;
error = 1;
error_not = 0;
error_2 = 0;
state = STATE_NONE;
timer = 0;
return;
}
}
if(state == STATE_TOOL_LOCK) {
if(unlock_delay > 0 && timer < unlock_delay) {
timer += fperiod;
return;
}
timer = 0;
if(!tool_unlocked) {
state = STATE_NONE;
tool_changed = 1;
}
else {
state = STATE_NONE;
tool_changed = 0;
error = 1;
error_not = 0;
error_3 = 1;
timer = 0;
}
}
}
Компилирование: halcompile --install revolt.comp
Компиляция проходит с ошибкой:
(для просмотра содержимого нажмите на ссылку)
Traceback (most recent call last):
File "/usr/bin/halcompile", line 1553, in <module>
main()
File "/usr/bin/halcompile", line 1523, in main
process(f, mode, outfile)
File "/usr/bin/halcompile", line 1363, in process
a, b = parse(filename)
^^^^^^^^^^^^^^^
File "/usr/bin/halcompile", line 441, in parse
a, b = f.split("\n;;\n", 1)
^^^^
ValueError: not enough values to unpack (expected 2, got 1)
В программировании мало что смыслю.
Занимаюсь в основном электрикой\электроникой.
Совместно с токарем перебрали китайскую револьверную головку HAK31 на 8 инструментов.
Предназначена в основном для токарного с ЧПУ.
Выбросили червяк, блокировка муфты Хирта осуществляется пружинами, разблокировка муфты - пневмоцилиндром.
Контроль состояния муфты заблокирована\разблокирована осуществляется 2-мя датчиками Холла.
Револьвер вращается в обе стороны серводвигателем по Step/Dir.
Датчик выбора инструмента на основе 8 датчиков Холла + диск с магнитом.
Собрал на дискретной логике аппаратный перекодировщик десятичного кода в двоичный Грея.
Итого на выходе револьверки:
1. 8-ми разрядный десятичный код (8pins);
2. 3-х разрядный двоичный код (3pins);
3. Муфта заблокирована (1pin);
4. Муфта разблокирована (1pin).
Итого на входе револьверки:
1. Dir (1pin);
2. Step (1pin);
3. Включение пневмоцилиндра (для разблокировки муфты) (1pin).
Сделана полная гальваническая развязка по питанию и опторазвязка входов\выходов.
Механика, пневматика и электроника отлажены.
Последовательностью G-кодов проводили тесты:
- пневмоцилиндр сжимает пружины и тем самым разблокирует муфту Хирта,
- датчик
"разблокирована" срабатывает,
- револьвер вращается в обе стороны серводвигателем до нужной позиции, останавливается в позициях для зацепления муфты,
- пневмоцилиндр отпускает пружины и они разжимаясь тем самым блокируют муфту Хирта,
- датчик
"заблокирована" срабатывает.
Задача: - чтобы управление револьвером и контроль выбора инструмента осуществлялись от LinuxCNC.