Официальный сайт компании Arduino по адресу arduino.cc
Общение через Монитор Порта с Ардуино
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Пнд, 01/04/2019 - 19:48
Здравствуйте друзья.Пробую написать скетч,хочу управлять шаговиком через монитор порта.
Если с библиотекой и работой с ней уже разобрался то с монитором порта всё туго...А дело в том что хочу сделать такое себе меню с несколькими вариантами работы.Но ничего не получается.Помогите понять что сделал не так?
КОД:
#include <Arduino.h> //Параметры двигателя #define MOTOR_STEPS 200 #define RPM 120 #define DIR 8 #define STEP 9 //Инициализация параметров драйвера #include "DRV8825.h" #define MODE0 10 #define MODE1 11 #define MODE2 12 DRV8825 stepper(MOTOR_STEPS, DIR, STEP, MODE0, MODE1, MODE2); //Переменные int Mode = 0; int Impulses = 0; int Speed = 0; int Angle1 = 0; int Angle2 = 0; void setup() { Serial.begin(115200); stepper.begin(RPM); stepper.enable(); Serial.println("Выберите режим 1-4:"); doMode(); } void loop() { doMode(); } void doMode(){ if (Serial.available() > 0) { //если есть доступные данные Mode = Serial.parseInt(); // считываем байт Serial.print("Выбран режим: "); // отсылаем то, что получили Serial.println(Mode);} else if (Mode > 4){ Mode = 0; Serial.println("Выбран несуществующий режим!"); } switch (Mode){ //Логика режима 1: case 1: Serial.println("Количество шагов и направлеие(для влево введите количество шагов со знаком -(минус): "); if (Serial.available()) { //если есть доступные данные Impulses = Serial.parseInt(); Serial.print("Количество шагов и направлеие:"); Serial.println(Impulses); if (Serial.available()) { //если есть доступные данные Serial.print("Установите скорость: "); Speed = Serial.parseInt(); Serial.print("Cкорость:"); Serial.println(Speed);}} break; //Логика режима 2: case 2: Serial.println("Установите скорость: "); if (Serial.available() > 0) { //если есть доступные данные Speed = Serial.parseInt(); Serial.print("Cкорость:"); Serial.println(Speed);} stepper.setMicrostep(4); // Set microstep mode to 1:1 stepper.rotate(Impulses); break;
Вся проблема в том что после выбора например 1 режима начинается цикличная прокрутка фразы "Количество шагов и направлеие(для влево введите количество шагов со знаком -(минус): " и всё,не реагирует больше.
А какая работа ожидалось?
Нужно чтобы после выбора режима 1:
Напечатало "Количество шагов и направлеие(для влево введите количество шагов со знаком -(минус):
затем я ввел значение допустим 300
Напечатало "Установите скорость: "
ввел значение допустим 100,отправил
и шаговик повернулся на заданые параметры.
после чего вышел и ждёт какой режим выберут.
Второй по аналогии.
А автор кода чо говорит?
Так я сам его писал.
Где вы в свиче выпрыгиваете из case 1 или крутите мотор?
Дописал
А "после чего вышел" где? Mode не меняется и на следующем лупе опять попадаете в case 1.
По ходу туплю но не мойму как сдклать событие после которого он выйдет.Сейчас получается что если выбрать режим пишет"Ввести количество импульсов" но если ввести то он опять выбирает Mode.
Ваша проблема в том, что вы не понимаете, что такое асинхронность и неблокирующая работа. Пример простой: вы напечатали в Serial приглашение, и ТУТ ЖЕ проверяете, что там в приёмном буфере. Очевидно, что в этот момент там может быть - ничего.
Смотрите, какая история: давайте представим, что у нас есть флажки, скажем, 3 штуки разных цветов - как светофор. И, понимая, какой флажок сейчас поднят - мы знаем, что должны делать. Я вам сейчас ниже напишу логику в псевдокоде, чтобы было понятно, как это работает, а вы попытаетесь разобраться, ок?
Это простой конечный автомат, писанный буквально в лоб. В тот или иной момент - выполняется одна ветка кода, при этом состояние системы (например, введённый режим работы) - известны в переменных. Достаточно чуть-чуть дописать - и будет прошивка, выполняющая то, что вам нужно.
А как сделали событие по которому входит?
Вся проблема в том что после выбора например 1 режима начинается цикличная прокрутка фразы "Количество шагов и направлеие(для влево введите количество шагов со знаком -(минус): " и всё,не реагирует больше.
Код неполный, потому если не поможет, то публикуйте полный, так программы не смотрят.
На первый взгляд, вы не доедаете Serial (если конечно, они не решены в полном коде). Кроме того, у Вас странная логика.
Вот давайте смотреть.
Про недоедание. После функций типа parseInt во входном буфере остаются символы перевода каретки и возврата строки. Их надо вычитать.
И про логику. См. Ваши строки 49-50 (и много пободных). Вот Вы напечатали текст, проверили есть ли там чего в буфере (а там нет, т.к. юзер ещё не успел ничего ввести) и летите дальше ... ещё раз печатать текст и снова проверять.
Вот так она у Вас и работает.
Наверное в этом месте нужно было не проверять и бежать сломя голову, а ждать пока юзер введёт. Или уж если не ждать, а заниматься своими делами, то не печатать приглашение каждый раз, а просто периодически посматривать "не ввёл ли".
Разберитесь с сериалом БЕЗ МОТОРОВ НА КРОХОТНОМ ПРИМЕРЕ - НЕ ВАЛИТЕ ВСЁ КУЧУ!
Вот смотрите.
Попробуйте убрать доедание и посмотреть, что будет. Попробуйте вместо ожидания вставить Вашу проверку и опять же посмотрите.
И всегда так поступайте - отлаживайтесь по отдельности, не валите всё в кучу. Ешьте слона по частям.
Пока что это весь код который смог написать,я учусь и паралельно делаю что-то полезное для себя.Вот столкнулся с этим и застрял.
Спасибо вам,попробую разобраться.
Добрый вечер. Читать данные из порта в loop() это плохая идея. Вот как я в своем первом аппаратном решении реализовывал нечто подобное:
Куда запоминать место нахождения в меню или лучше просто одному символу алфавита задать одно действие без перевода в число - решать Вам.
Читать данные из порта в loop() это плохая идея.
Да ну? А не подскажешь ли, откуда вызывается serialEvent, внутри которой ты пишешь свой код? Даю наколку: она вызывается прямо ну вот совсем рядышком с вызовом loop, и, ВНЕЗАПНО, перед её вызовом проверяется, есть ли что-то в приемном буфере соответствующего UART. Т.е. код, написанный внутри serialEvent, АНАЛОГИЧЕН коду ниже, размещённому в loop:
Прежде чем выносить сомнительные утверждения - очень советую ознакомиться с исходниками Wiring, тем более, что они совершенно открыты и есть у каждого, у кого установлена Arduino IDE ;)
Всем спасибо,вчера разобрался,я пихал всё и сразу а нужно было по степенно,теперь ясно)
Особенно наглядно это демонстрирует логика написаная DIYMan за что ему ОГРОМНАЯ благодарность!