Сам проект корректно сделан ?
Вид для печати
Сам проект корректно сделан ?
Завтра напишу что получилось.
С моим дубовым ФБ опроса энкоднра ситуация такая. ШД нормально управляются, а при медленном вращении вала энкодера считываемое значения (position) принимает попеременно два состояния - 0 и 1. Фазы А и В энкодера подключены к 1 и 2 быстрым дискретным входам ПЛК.
Код ФБ опроса энкодера прилагаю.
Владимир Ситников
Начал испытания в железе на столе. Обнаружил проблему с обменом.
Когда обращаюсь так:
имею пустые данные, т. е. обмена нет. Как со входными, так и с выходными данными.Код:Enc:=ENCODER_AND_COUNTER_Pru0MemoryTransfer.PRU_ENCOER_COUNTER_Enc_Position;(*Показания энекодера*)
Когда обращаюсь так:
То проблем нет, всё работает нормально.Код:ENCODER_AND_COUNTER_Pru0MemoryTransfer(
PRU_ENCOER_COUNTER_DO3:=FDO3 , (*Прямое управление выходом FDO3*)
PRU_ENCOER_COUNTER_DO4:=FDO4 , (*Прямое управление выходом FDO4*)
PRU_ENCOER_COUNTER_count_Enable:=RunTransport ,(*Запуск транспорта*)
PRU_ENCOER_COUNTER_count_Lenght:= Lenght ,(*Пройденный путь*)
running=> ,
writeFails=> ,
readFails=> ,
PRU_ENCOER_COUNTER_Enc_Position=>Enc ,(*Показания энкодера*)
PRU_ENCOER_COUNTER_Enc_ZeroDetect=>ZeroDetect ,(*Обнаружение машинного нуля*)
PRU_ENCOER_COUNTER_count_Path=>Path );(*Пройденный путь транспорта*)
В обоих случаях компиляция происходит без ошибок и предупреждений.
Вполне допускаю, что напутал с синтаксисом в первом случае.
Так работает
PRU_ENCOER_COUNTER_Enc_Position=>Enc ,(*Показания энкодера*)
а так не работает
Enc:=ENCODER_AND_COUNTER_Pru0MemoryTransfer.PRU_EN COER_COUNTER_Enc_Position;(*Показания энкодера*)
Получается в первом случае обмена с PRU0 нет поэтому состояние position и не меняется.
Владимир, а у меня та же самая история ?
Так не работает.
SteppersConfig_Pru0MemoryTransfer(
STEPPER2_Enc_PRU0_dir := TRUE,
STEPPER2_Enc_PRU0_stepper_accel_ramp := 2000,
STEPPER2_Enc_PRU0_stepper_decel_ramp := 2000,
STEPPER2_Enc_PRU0_stepper_max_speed := 20000,
STEPPER2_Enc_PRU0_stepper_min_speed := 0,
STEPPER2_Enc_PRU0_stepper_quantity := 16#FFFFFFFF,
STEPPER2_Enc_PRU0_stepper_enable := TRUE
);
ENC := SteppersConfig_Pru0MemoryTransfer.STEPPER2_Enc_PRU 0_encoder_position;
Если сделать так, то энкодер будет опрашиваться ?
SteppersConfig_Pru0MemoryTransfer(
STEPPER2_Enc_PRU0_dir := TRUE,
STEPPER2_Enc_PRU0_stepper_accel_ramp := 2000,
STEPPER2_Enc_PRU0_stepper_decel_ramp := 2000,
STEPPER2_Enc_PRU0_stepper_max_speed := 20000,
STEPPER2_Enc_PRU0_stepper_min_speed := 0,
STEPPER2_Enc_PRU0_stepper_quantity := 16#FFFFFFFF,
STEPPER2_Enc_PRU0_encoder_position => ENC,
STEPPER2_Enc_PRU0_stepper_enable := TRUE
);
А разве у Sulfur не та же самая проблема была что и у меня ?
Ведь PRU-программа работает автономно, ее не обязательно постоянно вызывать.
Если так обратиться, то можно получить текущее значение Position
Enc:=ENCODER_AND_COUNTER_Pru0MemoryTransfer.PRU_EN COER_COUNTER_Enc_Position;
Почему же это не работает ?
Ещё раз: вызов ENCODER_AND_COUNTER_Pru0MemoryTransfer() осуществляет обмен данными.
Если не вызывать, то никаого обмена не будет, и никакие переменные обновляться не будут.
Если просто читать ENCODER_AND_COUNTER_Pru0MemoryTransfer.PRU_ENCOER_ COUNTER_Enc_Position и ничего больше не делать, то значение будет одним и тем же.
Тем не менее, в сообщении 485 код похож на правильный:
Т.е. сначала Pru0MemoryTransfer, затем чтение STEPPER2_Enc_PRU0_encoder_position. Выглядит верно.Код:SteppersConfig_Pru0MemoryTransfer(
STEPPER2_Enc_PRU0_dir := TRUE,
STEPPER2_Enc_PRU0_stepper_accel_ramp := 2000,
STEPPER2_Enc_PRU0_stepper_decel_ramp := 2000,
STEPPER2_Enc_PRU0_stepper_max_speed := 20000,
STEPPER2_Enc_PRU0_stepper_min_speed := 0,
STEPPER2_Enc_PRU0_stepper_quantity := 16#FFFFFFFF,
STEPPER2_Enc_PRU0_stepper_enable := TRUE
);
SteppersConfig_Pru1MemoryTransfer(
STEPPER1_PRU1_dir := TRUE,
STEPPER1_PRU1_stepper_accel_ramp := 10,
STEPPER1_PRU1_stepper_decel_ramp := 10,
STEPPER1_PRU1_stepper_max_speed := 300,
STEPPER1_PRU1_stepper_min_speed := 0,
STEPPER1_PRU1_stepper_quantity := 100000,
STEPPER1_PRU1_stepper_enable := TRUE
);
ENC := SteppersConfig_Pru0MemoryTransfer.STEPPER2_Enc_PRU0_encoder_position;
Насколько я понял, нужно в начале цикла ПЛЦ_ПРГ сделать вызов ПРУ-ПОУ (ENCODER_AND_COUNTER_Pru0MemoryTransfer в моем случае) с пустыми параметрами, и после этого должно заработать непосредственное обращение к любой переменной ПРУ-ПОУ?
В принципе, то, как сейчас работает устраивает. Однако для большей понятности программы (в первую очередь для себя, ибо "с памятью моей что-то стало") хотелось бы иметь возможность обращаться к нужным переменным обмена из любого места ПЛЦ-ПРГ.
Вариант 1
SteppersConfig_Pru0MemoryTransfer(
STEPPER2_Enc_PRU0_dir := TRUE,
STEPPER2_Enc_PRU0_stepper_accel_ramp := 2000,
STEPPER2_Enc_PRU0_stepper_decel_ramp := 2000,
STEPPER2_Enc_PRU0_stepper_max_speed := 20000,
STEPPER2_Enc_PRU0_stepper_min_speed := 0,
STEPPER2_Enc_PRU0_stepper_quantity := 16#FFFFFFFF,
STEPPER2_Enc_PRU0_encoder_position => ENC,
STEPPER2_Enc_PRU0_stepper_enable := TRUE
);
Вариант 2
SteppersConfig_Pru0MemoryTransfer(
STEPPER2_Enc_PRU0_dir := TRUE,
STEPPER2_Enc_PRU0_stepper_accel_ramp := 2000,
STEPPER2_Enc_PRU0_stepper_decel_ramp := 2000,
STEPPER2_Enc_PRU0_stepper_max_speed := 20000,
STEPPER2_Enc_PRU0_stepper_min_speed := 0,
STEPPER2_Enc_PRU0_stepper_quantity := 16#FFFFFFFF,
STEPPER2_Enc_PRU0_stepper_enable := TRUE
);
ENC := SteppersConfig_Pru0MemoryTransfer.STEPPER2_Enc_PRU 0_encoder_position;
Оба варианта кода правильные ?
Да, можно так.
Как вариант, можно добавить в начало и в конец вызовы MemoryTransfer без параметров (как бы для чтения и для записи).
А между делом (в любом месте программы обращаться к ENCODER_AND_COUNTER_Pru0MemoryTransfer.PRU_ENCOER_ COUNTER_Enc_Position и подобным)
Так устраивает? Или я чего-то не понял?
Да, оба варианта правильные, как я и говорил в 509
Sulfur, выложи, пожалуйста, свой работающий проект, сделанный в Hardella. Может я что-то не так сделал в своем проекте.
Спасибо, буду смотреть.
Не пойму как вHardella в коде вставить это - @Export(position) Всю клавиатуру истыкал.
Обсуждали же.
подвести на переменную и нажать alt+enter.
или подвести на переменную и нажать мышкой на появившуюся лампочку
или посмотреть документацию: https://hardella.com/docs/pru/data-e...а-данных-в-pru
Реакцию на @ сделаю.
Sulfur, у вас энкодер какой тип выхода имеет, n-p-n ОК или PUSH-PULL ?
Точное название вашего энкодера привести можете ?
.
В моем проекте используются два энкодера. Один полноценный ABZ, модель Autonics E80H30-360-6-L-24. Другой тоже полноценный, но используется только одна фаза. Модель Baumer EIL580P-T, 500имп\об, выход HTL/push-pull.
Оба энкодера подключены напрямую ко входам FDI1..FDI4 ПЛК.
У меня проект, с двумя ШД и одним энкодером, сделанный в Hardella заработал. Выяснилось, что брендовый энкодер вышел из строя, заменили на китайский (стоит в 3,5 раза дешевле ;)) и все закрутилось.
Хвала Владимиру Ситникову.
Skype сообщает, что у Владимира сегодня День рождения. Мои искренние поздравления по этому случаю.
Всего наилучшего, успехов в делах, с ДР
ПЛК питается от +24, от этого же напряжения запитаны оба энкодера, выходы подключены непосредственно ко входам ПЛК. Подключены только прямые выходы (+А,+В,+Z). Инверсные выходы не используются.
По поводу Аутониксов. Применяем довольно большие Е80Н, у них отмечалась проблема - разрушение шлейфа между верхней и нижней платой, т. к. он довольно жесткий. Меняли на штучные провода во фторопластовой изоляции.
Какие состояния может принимать выходной параметр state ?
Имеется в виду это - SteppersConfig_Pru0MemoryTransfer.STEPPER_PRU0_ste pper_state
Меня, в частности, интересует как узнать, что ШД отработал задание.
Ну enum же. Можно взять и посмотреть. Какие-то проблемы с этим? Посмотреть можно как в Hardella, так и в КДС.
Либо в документации:
https://hardella.com/docs/pru/examples/step-motor/
Цитата:
Ответ на этот вопрос даёт выходной параметр state...
Владимир, так правильно будет определить что ШД отработал задание ?
IF SteppersConfig_Pru1MemoryTransfer.STEPPER1_PRU1_st epper_state = STOP_STEPPER_RUN_STATE THEN STEPPER1_PRU1_stepper_enable := FALSE; END_IF