xenon-alien писал(а): ↑
Замечательно!
Интересно будет узнать.
На "рабочей" плате уже просто входов не осталось, так что по любому нужно будет использовать Р1.
Человек написал, что в ближайшие дни постарается сделать.
Отлично, так как использование аппаратной поддержки энкодера лучше, чем вариант который нашел.
Метод подключения индексной метки который нашел, достаточно прост, мы просто заводим сигнал OCZ (Сигнал энкодера Z (открытый коллектор)) в Mesa. А дальше используем tristate_bit (можно использовать модуль encoder, но мне нужна только индексная метка) для установки значения joint.0.index-enable и настройки поиска 0-ля описанный в документации к LinuxCnc -
https://linuxcnc.org/docs/html/config/ini-homing.html.
Вдержки из hal
Код: Выделить всё
loadrt tristate_bit count=3
addf tristate-bit.0 servo-thread
addf tristate-bit.1 servo-thread
addf tristate-bit.2 servo-thread
Для каждой из осей
Код: Выделить всё
net set.index-x.in tristate-bit.0.in hm2_7i96.0.gpio.001.in
net set.index-x.out tristate-bit.0.out joint.0.index-enable
net set.index-x.enb tristate-bit.0.enable joint.0.homing
И настройка ini для каждой из осей
Код: Выделить всё
HOME = 0.0
HOME_SEQUENCE = 2
HOME_OFFSET = 0
HOME_SEARCH_VEL = 5
HOME_LATCH_VEL = -0.5
HOME_USE_INDEX = YES
Так как у меня нет сигнала OCZ (Сигнал энкодера Z (открытый коллектор)), из-за того что не правильно выбрал сервопривод, нужно было выбирать модель Delta B3 L, а у меня Delta B3 M, пришлось подключаться к OZ.
Сигнал в OZ в логическом анализаторе, куча шумов.
- Сигнал в OZ в логическом анализаторе
Что касается второго выхода /OZ, шумов при тестировании не обнаружено (не продолжительное тестирование, на большее не хватило времени). Тут может быть как с сусликом, мы его не видим, но он есть. Поэтому принял решение, проверять сигналы OZ и /OZ в ардуине, а если оба сигнала корректны, подавать сигнал на реле, которое включает один в входов Mesa.
Код для Arduino Nano, так же подойдет и для Arduino Uno (для просмотра содержимого нажмите на ссылку)
Код: Выделить всё
//https://upload.wikimedia.org/wikipedia/commons/e/e4/Arduino-nano-pinout.png
//https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf
//https://adior.ru/index.php/robototekhnika/249-pcint-arduino
//https://bellsoft.ru/arduino/pcint-arduino/
//https://chipenable.ru/index.php/item/4
#ifndef MC_CRITICAL_SECTION_START
#define MC_CRITICAL_SECTION_START uint8_t _sreg = SREG; cli();
#endif
#ifndef MC_CRITICAL_SECTION_END
#define MC_CRITICAL_SECTION_END SREG = _sreg;
#endif
#define PIN_X_OZ 2
#define PIN_X_NOZ 8
#define PIN_X_OUT 14
#define PIN_Y_OZ 3
#define PIN_Y_NOZ 9
#define PIN_Y_OUT 15
#define PIN_Z_OZ 4
#define PIN_Z_NOZ 10
#define PIN_Z_OUT 16
// /OZ
#define PIN_PORTE_MASK_B B00000111
// OZ Output
#define PIN_PORTE_MASK_C B00000111
// OZ
#define PIN_PORTE_MASK_D B00011100
void setup()
{
Serial.begin(115200);
pinMode(PIN_X_OZ, INPUT_PULLUP);
pinMode(PIN_X_NOZ, INPUT_PULLUP);
pinMode(PIN_X_OUT, OUTPUT);
pinMode(PIN_Y_OZ, INPUT_PULLUP);
pinMode(PIN_Y_NOZ, INPUT_PULLUP);
pinMode(PIN_Y_OUT, OUTPUT);
pinMode(PIN_Z_OZ, INPUT_PULLUP);
pinMode(PIN_Z_NOZ, INPUT_PULLUP);
pinMode(PIN_Z_OUT, OUTPUT);
pinMode(A3, OUTPUT);
MC_CRITICAL_SECTION_START
// PCICR (Pin Change Interrupt Enable) - регистр разрешающий прерывания по изменению состояния группы выводов.
// PCIEn - биты которые разрешают прерывания по изменению состояния группы выводов. Когда бит PCIEn и бит I регистра SREG установлены в 1 - прерывания по изменению состояния на группе выводов PCIEn разрешены.
// Очищаем регистр разрещающий прерывания по изменению состояния группы выводов.
PCICR |= (0 << PCIE0);
// PCMSKn (Pin Change Mask Register) - регистр включающий выводы конкретной группы портов на прерываний по изменению состояния.
PCMSK0 |= (0 << PCINT7) | (0 << PCINT6) | (0 << PCINT5) | (0 << PCINT4) | (0 << PCINT3) | (1 << PCINT2) | (1 << PCINT1) | (1 << PCINT0);
// PCIFR (Pin Change Interrupt Flag Register) - регистр флагов прерываний по изменению состояния группы выводов. Указывает от какой группы поступило прерывание.
// Очищаем регистр флагов прерываний по изменению состояния группы выводов.
PCIFR = (1 << PCIF0);
// PCICR (Pin Change Interrupt Enable) - регистр разрешающий прерывания по изменению состояния группы выводов.
// PCIEn - биты которые разрешают прерывания по изменению состояния группы выводов. Когда бит PCIEn и бит I регистра SREG установлены в 1 - прерывания по изменению состояния на группе выводов PCIEn разрешены.
PCICR |= (1 << PCIE0);
MC_CRITICAL_SECTION_END
}
void loop()
{
// Чтение OZ и /OZ
//Serial.print("Mask B - ");
//Serial.print(PIN_PORTE_MASK_B, 2);
//Serial.print(" Pin B - ");
//Serial.print(pinB, 2);
//Serial.print(" After Mask - ");
//Serial.print((PIN_PORTE_MASK_B & pinB), 2);
//Serial.print(" Check Other Pin - ");
//Serial.print(((PIN_PORTE_MASK_B & pinB) ^ (pinC >> 2)), 2);
//Serial.print(" Finish To write to PIND - ");
//Serial.println((((PIN_PORTE_MASK_B & pinB) ^ (pinC >> 2))) & (pinC >> 2), 2);
//Serial.println((PIN_PORTE_MASK_B & pinB), 2);
//Mask B - 111 Pin B - 101 After Mask - 101
//Serial.println((PIN_PORTE_MASK_B | pinB), 2);
//Mask B - 111 Pin B - 101 After Mask - 111
//Serial.println((PIN_PORTE_MASK_B ^ pinB), 2);
//Mask B - 111 Pin B - 101 After Mask - 10
//Serial.println(((PIN_PORTE_MASK_B & pinB) ^ pinC), 2);
//Mask B - 111 Pin B - 101 After Mask - 101 Check Other Pin - 110
//Serial.println((((PIN_PORTE_MASK_B & pinB) ^ pinC)) & pinC, 2);
//Mask B - 111 Pin B - 101 After Mask - 101 Check Other Pin - 110 Finish To write to PIND - 10
// Запись Z_OUT
//Serial.print(" Pin C - ");
//Serial.println(PINC, 2);
}
/// <summary>
/// Прерывание по изменению состояния группы выводов 0.
/// </summary>
ISR(PCINT0_vect)
{
// Проверяем состояние пина PB0 (8) и PD2 (2).
if ((PINB & (1 << PB0)) && !(PIND & (1 << PD2)))
{
// Состояние вывода изменилось с низкого уровня на низкий.
PORTC &= ~(1 << PC0);
}
else
{
// Состояние вывода изменилось с высокого уровня на высокий.
PORTC |= 1 << PC0;
}
// Проверяем состояние пина PB1 (9) и PD3 (3).
if ((PINB & (1 << PB1)) && !(PIND & (1 << PD3)))
{
// Состояние вывода изменилось с низкого уровня на низкий.
PORTC &= ~(1 << PC1);
}
else
{
// Состояние вывода изменилось с высокого уровня на высокий.
PORTC |= 1 << PC1;
}
// Проверяем состояние пина PB2 (10) и PD4 (4).
if ((PINB & (1 << PB2)) && !(PIND & (1 << PD4)))
{
// Состояние вывода изменилось с низкого уровня на низкий.
PORTC &= ~(1 << PC2);
}
else
{
// Состояние вывода изменилось с высокого уровня на высокий.
PORTC |= 1 << PC2;
}
}
Реле было выбрано как временное решение, мне нужно было подавать сигнал 24В на вход Mesa, в дальнейшем думали поставить транзистор, но и реле отлично работает.
Если у сервопривода есть сигнал OCZ (Сигнал энкодера Z (открытый коллектор)), а еще лучше /OCZ, можно попробовать сразу отправлять сигнал /OCZ в Mesa, без ардуино. Если есть наводки и шум, то придется либо использовать ардуино, либо заводить оба сигнала и проверять их средствами LinuxCnc.
Еще пару слов про поиск нуля по индексной метке (возможно и по индуктивному датчику).
Если используется компенсация люфтов (BACKLASH), то LinuxCnc работает в 2-х вариантах.
1. Перед отправкой на 0, мы шли в противоположную сторону от нуля. В таком случае мы точно не попадем в ту же координату (проверял оптическими линейками и индикатором часового типа). Не знаю с чем это связано, просто констатирую факт.
2. Перед отправкой на 0, мы шли в сторону нуля. В таком случае мы всегда попадаем в ту же координату (проверял оптическими линейками и индикатором часового типа).
Если убрать компенсацию люфтов (BACKLASH), то мы всегда попадаем в ту же координату.
В архиве все файлы конфигурации 7I96_GMOC.rar, так же исправлены пару ошибок probe-screen связанных с нововведениями в LinuxCnc 2.8.
Буду пытаться вызвать hal команду из G-кода. Чтобы решить вопрос по поиску 0-ля с компенсацией люфта, вначале отправить ось в сторону нуля, а потом отправить на 0. И буду разбираться с датчиком инструмента и краеискателем.