Управление текущей скоростью шагового двигателя через COM-порт
- Войдите на сайт для отправки комментариев
Как написать программу (на Delphi) и скетч для задания произвольной скорости вращения шагового двигателя в любой момент времени из программы на Delphi через COM-порт на одноплатном компьютере ODYSSEY - X86J4105800? Задача заключается в том, чтобы в произвольный момент времени из программы на Delphi посылать в COM-порт один байт, задающий скорость вращения ШД, скетч должен читать этот байт и менять в соответствии с его значением текущую скорость вращения ШД. Должно быть примерно следующее:
#include <Arduino.h>
#include "BasicStepperDriver.h"
// Motor steps per revolution. Most steppers are 200 steps or 1.8 degrees/step
#define MOTOR_STEPS 3600
#define RPM 200
// Since microstepping is set externally, make sure this matches the selected mode
// If it doesn't, the motor will move at a different RPM than chosen
// 1=full step, 2=half step etc.
#define MICROSTEPS 1
// All the wires needed for full functionality
#define DIR 6
#define STEP 5
BasicStepperDriver stepper(MOTOR_STEPS, DIR, STEP);
int incomingByte = 0;
// the setup function runs once when you press reset or power the board
void setup() {
Serial.begin(250000);
// initialize digital pin LED_BUILTIN as an output.
stepper.begin(RPM, MICROSTEPS);
}
// the loop function runs over and over again forever
void loop() {
if (Serial.available() > 0) { //если есть доступные данные
// считываем байт
incomingByte = Serial.read();
stepper.Speed(incomingByte);
}
stepper.rotate(360);
// delay(2000);
}
Тут возникает одна проблема последовательного чтения байтов из COM-порта в скетче. Что происходит с текущим значением в COM-порте при срабатывании команды Serial.read()? Оно сохраняется в COM-порте? Вторая проблема: как в скетче менять текущую скорость вращения ШД?
такие вещи делают хотя бы через простейший протокол обмена
... из программы на Delphi через COM-порт на одноплатном компьютере ODYSSEY - X86J4105800
...
Что происходит с текущим значением в COM-порте при срабатывании команды Serial.read()?
...
Вторая проблема: как в скетче менять текущую скорость вращения ШД?
1. Хотел поёрничать, но кто-то повадился все мои шутки удалять... Серьёзно спрошу: что за страсть, и уже не у тебя первого, к мертвым языкам? Палеопрограммирование? Почему Дельфи и почему такая странная и жутко дорогая железка? Это не вопросы по сути, просто очень любопытно!
2. Ну а сам-то как думаешь? Если это вопрос хоть как-то осмыслен, то unread() в Ардуино не предусмотрен.
3. При помощи функции из библиотеки, у тебя ж уже написано.
такие вещи делают хотя бы через простейший протокол обмена
Спасибо за компетентное мнение, буду знать примерно в какую сторону копать.
1. Хотел поёрничать, но кто-то повадился все мои шутки удалять... Серьёзно спрошу: что за страсть, и уже не у тебя первого, к мертвым языкам? Палеопрограммирование? Почему Дельфи
У меня сейчас на руках жутко legacy проект на Delphi в полмиллиона строк кода, над которым работали несколько программистов в течение нескольких десятилетий. Его очень проблемно перекодировать на другой язык.[/quote]
У меня сейчас на руках жутко legacy проект на Delphi в полмиллиона строк кода, над которым работали несколько программистов в течение нескольких десятилетий. Его очень проблемно перекодировать на другой язык.
и оно аж несколько десятилетий назад уже управляло моторами по последовательному порту?
У меня сейчас на руках жутко legacy проект на Delphi в полмиллиона строк кода, над которым работали несколько программистов в течение нескольких десятилетий. Его очень проблемно перекодировать на другой язык.
и оно аж несколько десятилетий назад уже управляло моторами по последовательному порту?
я не знаю что там у TC, но по протоколу YAESU GS-232 двигатели управляются не одно десятилетие )))
И оно аж несколько десятилетий назад уже управляло моторами по последовательному порту?
Нет, не по COM-порту. Была специальная PCI-плата для этого, которая вставлялась в системник. Этот проект был разработан для больших системных блоков.
Сейчас есть задача сделать управление нашими железками (не только шаговыми двигателями) через одноплатный компьютер. Пока остановились на посылке байтов (2 бита - номер одного из трех двигателей, 1 бит - направление движения, 5 битов - скорость вращения ШД) через COM порт на скетч Arduino.
Я наваял следующий скетч:
#include <Arduino.h> #include "BasicStepperDriver.h" // Motor steps per revolution. Most steppers are 200 steps or 1.8 degrees/step #define MOTOR_STEPS 3600 #define RPM 200 // Since microstepping is set externally, make sure this matches the selected mode // If it doesn't, the motor will move at a different RPM than chosen // 1=full step, 2=half step etc. #define MICROSTEPS 1 // All the wires needed for full functionality #define DIR 6 #define STEP 5 BasicStepperDriver stepper(MOTOR_STEPS, DIR, STEP); int incomingByte = 0; // the setup function runs once when you press reset or power the board void setup() { Serial.begin(250000); // initialize digital pin LED_BUILTIN as an output. stepper.begin(RPM, MICROSTEPS); } // the loop function runs over and over again forever void loop() { if (Serial.available() > 0) { //если есть доступные данные // считываем байт incomingByte = Serial.read(); if (incomingByte > 1) { stepper.rotate(1020); delay(2000); } else if (incomingByte > 0) { stepper.rotate(-1020); delay(2000); } } } void yield(){ uint16_t ADC0 = digitalRead(adc_pin0); Serial.write(ADC0); return; }Подаю на COM-порт байт "2" - ШД вращается. Посылаю на COM-порт байт "1" - ШД вращается в ту же сторону. Не понятно, почему вращается только в одну сторону.
И оно аж несколько десятилетий назад уже управляло моторами по последовательному порту?
Нет, не по COM-порту. Была специальная PCI-плата для этого, которая вставлялась в системник. Этот проект был разработан для больших системных блоков.
Сейчас есть задача сделать управление нашими железками (не только шаговыми двигателями) через одноплатный компьютер. Пока остановились на посылке байтов (2 бита - номер одного из трех двигателей, 1 бит - направление движения, 5 битов - скорость вращения ШД) через COM порт на скетч Arduino.
Я буду очень не оригинален, но реально советую нанять грамотного консультанта. Можно - даже не меня! ;)) Я не могу подобрать слов для комментирования прочитанного.
Не зная таймингов оборудования, требований к скорости реакции, требований по надежности - я никаких рекомендаций не стану писать. Если это реальное научное или промышленное решение, которому "десятки лет", то просто анализ задачи и рекомендации по способам решения - это нормальный консалтинг. Без накладных накруток на фирму я, как фрилансер, оцениваю примерно в 25-30 т.р.
Базовые варианты - поставьте на компьютер модуль CAN или RS485, а модуль управления периферией - на соответствующем интерфейсе ...ну пусть на Ардуине, меня она особо не коробит, при правильном использовании. Такой вариант будет хоть немного похож на профессиональное решение.
Я не могу подобрать слов для комментирования прочитанного.
ты не одинок )))
Подаю на COM-порт байт "2" - ШД вращается. Посылаю на COM-порт байт "1" - ШД вращается в ту же сторону. Не понятно, почему вращается только в одну сторону.
Так и должно быть.
int val; int LED = 13; void setup() { Serial.begin(9600); pinMode(LED, OUTPUT); digitalWrite(LED, HIGH); } void loop() { if (Serial.available()) { val = Serial.read(); // При символе "1" включаем светодиод if (val == '1') { digitalWrite(LED, HIGH); } // При символе "0" выключаем светодиод if ( val == '0') { digitalWrite(LED, LOW); } } }Видите 1 и 2 это не числа, а символы.
Для начала подключить дуину к ком порту и посмотреть - а чего шлёт нам ком порт. И от этого плясать.
ТС пишет про байты с ком порта, а использует параметр ИНТ в скетче. Моя твоя непонимай.
#include <Arduino.h> #include "BasicStepperDriver.h" // Motor steps per revolution. Most steppers are 200 steps or 1.8 degrees/step #define MOTOR_STEPS 3600 byte RPM = 60; // Since microstepping is set externally, make sure this matches the selected mode // If it doesn't, the motor will move at a different RPM than chosen // 1=full step, 2=half step etc. #define MICROSTEPS 1 // All the wires needed for full functionality #define DIR 6 #define STEP 5 BasicStepperDriver stepper(MOTOR_STEPS, DIR, STEP); uint8_t incomingByte = 0; // the setup function runs once when you press reset or power the board void setup() { Serial.begin(250000); } // the loop function runs over and over again forever void loop() { if (Serial.available() < 1) return; // Если есть доступные данные, считываем байт incomingByte = Serial.read(); // Чтение байта из программы - ШД поворачивается с постоянной скоростью RPM = incomingByte; stepper.begin(RPM, MICROSTEPS); // Здесь крутится с постоянной скоростью stepper.rotate(100); delay(1); }#include <Arduino.h> #include "BasicStepperDriver.h" // Motor steps per revolution. Most steppers are 200 steps or 1.8 degrees/step #define MOTOR_STEPS 3600 byte RPM = 60; byte Angle = 10; // Since microstepping is set externally, make sure this matches the selected mode // If it doesn't, the motor will move at a different RPM than chosen // 1=full step, 2=half step etc. #define MICROSTEPS 1 // All the wires needed for full functionality #define DIR 6 #define STEP 5 BasicStepperDriver stepper(MOTOR_STEPS, DIR, STEP); uint8_t incomingByte = 0; // the setup function runs once when you press reset or power the board void setup() { Serial.begin(250000); } // the loop function runs over and over again forever void loop() { if (Serial.available() < 1) return; // Если есть доступные данные, считываем байт incomingByte = Serial.read(); // Чтение байта из программы - не работает. В смысле, ничего не крутится. stepper.begin(RPM, MICROSTEPS); switch( incomingByte ) { case 0: stepper.disable(); break; case 1: stepper.rotate(2000); break; case 2: stepper.rotate(-2000); break; case 3: RPM += 20; break; case 4: RPM -= 20; break; case 5: stepper.move(-MOTOR_STEPS*MICROSTEPS); break; case 6: stepper.move( MOTOR_STEPS*MICROSTEPS); break; case 7: stepper.enable(); break; default: break; } delay(1); }#include <Arduino.h> #include "BasicStepperDriver.h" // Motor steps per revolution. Most steppers are 200 steps or 1.8 degrees/step #define MOTOR_STEPS 3600 byte RPM = 60; byte Angle = 10; // Since microstepping is set externally, make sure this matches the selected mode // If it doesn't, the motor will move at a different RPM than chosen // 1=full step, 2=half step etc. #define MICROSTEPS 1 // All the wires needed for full functionality #define DIR 6 #define STEP 5 BasicStepperDriver stepper(MOTOR_STEPS, DIR, STEP); uint8_t incomingByte = 0; // the setup function runs once when you press reset or power the board void setup() { Serial.begin(250000); } // the loop function runs over and over again forever void loop() { if (Serial.available() < 1) return; // Если есть доступные данные, считываем байт incomingByte = Serial.read()-48; // Чтение байта из монитора - все работает, движок крутится Serial.read(); Serial.println(incomingByte); stepper.begin(RPM, MICROSTEPS); switch( incomingByte ) { case 0: stepper.disable(); break; case 1: stepper.rotate(2000); break; case 2: stepper.rotate(-2000); break; case 3: RPM += 20; break; case 4: RPM -= 20; break; case 5: stepper.move(-MOTOR_STEPS*MICROSTEPS); break; case 6: stepper.move( MOTOR_STEPS*MICROSTEPS); break; case 7: stepper.enable(); break; default: break; } delay(1); }В чем дело? И как можно увидеть в скетче число, которое получает Ардуино из COM-порта?
Дело в том, что взялись не за своё. С наскоку тут ничего не выйдет, начинать надобно с более простых задач.
Но, может, и случайно получится... Если руки никому этим мотором не оторвет.
В нашей программе на Delphi есть специальная кнопочка, при нажатии на которую вызывается процедура с аргументами SendToCOMPort(ComPort, Speed), где Speed - это скорость вращения, которая задается в специальном поле на нашей формочке,
а при отжатии кнопки вызывается SendToCOMPort(ComPort, 0).
в цифре 48 )))
Большое спасибо за подсказку про передачу символов, а не чисел в COM-порт. Сделал - все заработало. (Чувствую себя идиотом, что сам не допер до этого.)
Сейчас мучаю скетч NonBlocking.ino. У нас стоит задача запустить вращение мотора из Delphi и во время его вращения управлять его скоростью тоже из Delphi. Из библиотеки StepperDriver попробовал загрузить для пробы скетч NonBlocking.ino - ШД не крутится. Что не так?
/* * Example using non-blocking mode to move until a switch is triggered. * * Copyright (C)2015-2017 Laurentiu Badea * * This file may be redistributed under the terms of the MIT license. * A copy of this license has been included with this distribution in the file LICENSE. */ #include <Arduino.h> // this pin should connect to Ground when want to stop the motor #define STOPPER_PIN 4 // Motor steps per revolution. Most steppers are 200 steps or 1.8 degrees/step #define MOTOR_STEPS 200 #define RPM 120 // Microstepping mode. If you hardwired it to save pins, set to the same value here. #define MICROSTEPS 16 #define DIR 8 #define STEP 9 #define SLEEP 13 // optional (just delete SLEEP from everywhere if not used) /* * Choose one of the sections below that match your board */ #include "DRV8834.h" #define M0 10 #define M1 11 DRV8834 stepper(MOTOR_STEPS, DIR, STEP, SLEEP, M0, M1); // #include "A4988.h" // #define MS1 10 // #define MS2 11 // #define MS3 12 // A4988 stepper(MOTOR_STEPS, DIR, STEP, SLEEP, MS1, MS2, MS3); // #include "DRV8825.h" // #define MODE0 10 // #define MODE1 11 // #define MODE2 12 // DRV8825 stepper(MOTOR_STEPS, DIR, STEP, SLEEP, MODE0, MODE1, MODE2); // #include "DRV8880.h" // #define M0 10 // #define M1 11 // #define TRQ0 6 // #define TRQ1 7 // DRV8880 stepper(MOTORS_STEPS, DIR, STEP, SLEEP, M0, M1, TRQ0, TRQ1); // #include "BasicStepperDriver.h" // generic // BasicStepperDriver stepper(DIR, STEP); void setup() { Serial.begin(115200); // Configure stopper pin to read HIGH unless grounded pinMode(STOPPER_PIN, INPUT_PULLUP); stepper.begin(RPM, MICROSTEPS); // if using enable/disable on ENABLE pin (active LOW) instead of SLEEP uncomment next line // stepper.setEnableActiveState(LOW); stepper.enable(); // set current level (for DRV8880 only). Valid percent values are 25, 50, 75 or 100. // stepper.setCurrent(100); Serial.println("START"); // set the motor to move continuously for a reasonable time to hit the stopper // let's say 100 complete revolutions (arbitrary number) // stepper.startMove(100 * MOTOR_STEPS * MICROSTEPS); // in microsteps stepper.startRotate(100 * 360); // or in degrees } void loop() { // first, check if stopper was hit if (digitalRead(STOPPER_PIN) == LOW){ Serial.println("STOPPER REACHED"); /* * Choosing stop() vs startBrake(): * * constant speed mode, they are the same (stop immediately) * linear (accelerated) mode with brake, the motor will go past the stopper a bit */ // stepper.stop(); // Закомментировал временно // stepper.startBrake(); } // motor control loop - send pulse and return how long to wait until next pulse unsigned wait_time_micros = stepper.nextAction(); // 0 wait time indicates the motor has stopped if (wait_time_micros <= 0) { stepper.disable(); // comment out to keep motor powered delay(3600000); } // (optional) execute other code if we have enough time if (wait_time_micros > 100){ // other code here } }нет ребята всё не так, всё не так ребята )))
Задержка на 1 час это круто!
На Arduino.cc мне посоветовали использовать библиотеку MobaTools, которая может уменьшать и увеличивать скорость вращения шаговика во время его работы. На Github'е указано, что она поддерживает следующие процессоры:
- AVR ATmega
- AVR ATtiny, if it has the 16-bit timer 1 and a SPI or USI hardware
- STM32F103x processors ( the core of Roger Clark must be used )
- ESP32 ( minimum core version is 1.0.6 )
- ESP8266 ( with some restrictions, Stepper via SPI does not work )
Мы работаем на одноплатном компьютере "ODYSSEY - X86J4105800" с "Arduino Coprocessor ATSAMD21 Core ARM Cortex-M0+". Он подходит для Mobatools? И еще глупый вопрос: как можно скачать и установить Mobatools с Github? Можно скачать соответствующие cpp-файлы и откомпилировать их у себя?
На Arduino.cc мне посоветовали
Подгоняешь DetSimen плату (если согласится) тогда у тебя будет хотя бы призрачная возможность реализовать свои хотелки
Нет.
Нет.
Дима, ты чё такой категоричный, хотя бы глянули, что за зверь )))
Попытался установить эту библиотеку (Mobatools) и скомпилировать скетч - выдает ошибку:
Используем библиотеку MobaTools-master версии 2.4.3 из папки: C:\Users\ODYSSEY\Documents\Arduino\libraries\MobaTools-master exit status 1 Ошибка компиляции для платы Seeeduino Zero.
Походу, с этой платой Mobatools не работает.
Попытался установить эту библиотеку (Mobatools) и скомпилировать скетч - выдает ошибку:
Используем библиотеку MobaTools-master версии 2.4.3 из папки: C:\Users\ODYSSEY\Documents\Arduino\libraries\MobaTools-master exit status 1 Ошибка компиляции для платы Seeeduino Zero.
Походу, с этой платой Mobatools не работает.
а с чего ей работать?
берешь даташит и дописываешь библиотеку