Прошу помощи со скетчем
- Войдите на сайт для отправки комментариев
Ср, 29/05/2019 - 21:09
Здравствуйте!
Пытаюсь запрограммировать работу вибромоторов в зависимости от нажатия двух кнопок.
Первая кнопка - просто дребезжат, не останавливаясь. Вторая кнопка - вибрация плавно доходит до максимума, а потом затухает.
У меня, к сожалению, почему то не получается сделать зацикленный второй режим. Вибрация доходит до максимума и дальше на этом же максимуме дребезжит.
Ниже прикреплю код. Помогите, пожалуйста, найти ошибку! Или , что вероятнее всего, я что-то не догоняю в работе с кнопками, может подскажете. Взял пример из библиотеки OneButton
#include "OneButton.h"
OneButton button1(A1, true);
OneButton button2(A2, true);
int motPin1 = 5;
int motPin2 = 6;
int motPin3 = 9;
int motPin4 = 10;
void setup() {
pinMode(motPin1, OUTPUT);
pinMode(motPin2, OUTPUT);
pinMode(motPin3, OUTPUT);
pinMode(motPin4, OUTPUT);
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
Serial.println("Starting TwoButtons...");
// link the button 1 functions.
button1.attachClick(click1);
button1.attachDoubleClick(doubleclick1);
// link the button 2 functions.
button2.attachClick(click2);
button2.attachDoubleClick(doubleclick2);
}
void loop() {
// keep watching the push buttons:
button1.tick();
button2.tick();
delay(10);
}
void click1() {
Serial.println("Button 1 click.");
analogWrite(motPin1, 255);
analogWrite(motPin2, 255);
analogWrite(motPin3, 255);
analogWrite(motPin4, 255);
} // click1
// This function will be called when the button1 was pressed 2 times in a short timeframe.
void doubleclick1() {
Serial.println("Button 1 doubleclick.");
analogWrite(motPin1, 0);
analogWrite(motPin2, 0);
analogWrite(motPin3, 0);
analogWrite(motPin4, 0);
} // doubleclick1
void click2() {
Serial.println("Button 2 click.");
for (int i=0; i <= 255; i++){
analogWrite(motPin1, i);
analogWrite(motPin2, i);
analogWrite(motPin3, i);
analogWrite(motPin4, i);
delay(10);
}
}
void doubleclick2() {
Serial.println("Button 2 doubleclick.");
analogWrite(motPin1, 0);
analogWrite(motPin2, 0);
analogWrite(motPin3, 0);
analogWrite(motPin4, 0);
}
Начать тут нужно с другого: определиться как предполагается вписать этот фрагмент в остальной код. Например, то что Вы написали сейчас в click2() заблокирует процесс. Невозможно будет ни работать с MPU-шкой, ни прервать вибрацию.
Нет, МПУшку я на другую ардуинку цепляю. Решил разделить две функции, чтобы было меньше волокиты. Все равно портативного прибора тут не получишь.
Я думал, что сделал так:
1 клик на первую кнопку включает первый режим работы. двойное нажатие на первую кнопку выключает первый режим.
1 клик на вторую кнопку включает второй режим, двойное - выключает его.
Я пытался настроить с одной кнопкой, но там проблем было больше. Здесь все работает, но описанная выше проблема только присутствует.
может и дилдо
в любом случае без второго режима работы даже дилдо получится плохим.
Ну, т.е. вибрация не будет поставлена в прямую зависимость от частоты тремора? Т.е. управление всегда ручное будет?
Да, совершенно верно! Я решил, что в первой версии исследований будет именно так. Я буду в ручную менять параметры вибрации. Если я сейчас буду все объединять, то я половину лета проведу с железками. А такой карт бланш на время у меня , к сожалению, нет. Поэтому к объединению двух функций вернусь осенью, там вроде нас пошлюс к студентам технарям, которые будут с нами работать. А пока хочу собрать данных на пациентах
Позже закажу драйвера на моторчики, там вроде как можно различные виды импульсов на моторы посылать.
Ну, вот я накидал на коленке. В парадигме OneButton мне неудобно (я её первый раз вижу), так что можно было и покрасивее, конечно. Не компилировал, на железе не проверял, просто проиллюстрировал способ управления.
#define IDLE 0 case START_MODE_01 11 case RUN_MODE_01: 12 case STOP_MODE_01 13 case START_MODE_02 21 case RUN_MODE_02 22 case STOP_MODE_02 23 int16_t vibroMode, motorSpeed, motorStep; uint32_t lastMotorSpeedChangeTime; const uint32_t motorSpeedChangeInterval = 10; void buttonMode02Click() { // Stop mode #2 if it active or start it otherwise vibroMode = (vibroMode == START_MODE_02) ? IDLE : START_MODE_02; } void buttonMode01Click() { // Stop mode #1 if it active or start it otherwise vibroMode = (vibroMode == START_MODE_01) ? IDLE : START_MODE_01; } void changeMotorsSpeed(uint8_t _motorSpeed) { analogWrite(motPin1, _motorSpeed); analogWrite(motPin2, _motorSpeed); analogWrite(motPin3, _motorSpeed); analogWrite(motPin4, _motorSpeed); } void stopMotors() { digitalWrite(motPin1, LOW); digitalWrite(motPin2, LOW); digitalWrite(motPin3, LOW); digitalWrite(motPin4, LOW); } void setup() { .... } void loop() { // keep watching the push buttons: buttonMode01.tick(); buttonMode02.tick(); switch (vibroMode) { case START_MODE_02: { motorSpeed = lastMotorSpeedChangeTime = 0x00; motorStep = +1; vibroMode = RUN_MODE_02; break; } case RUN_MODE_02: { // just do nothing if no time for change motor speed if (millis() - lastMotorSpeedChangeTime < motorSpeedChangeInterval) { break; } lastMotorSpeedChangeTime = millis(); motorSpeed += motorStep; // make motors step's flip-flop on speed limits if (0x00 >= motorSpeed || 0xFF <= motorSpeed) { motorStep = -motorStep; } changeMotorSpeed(motorSpeed); break; } case STOP_MODE_02: { // stop motors here stopMotors(); vibroMode = IDLE; break; } case START_MODE_01: { motorSpeed = 128; // start motors here changeMotorSpeed(motorSpeed); vibroMode = RUN_MODE_01; break; } case STOP_MODE_01: { // stop motors here stopMotors(); vibroMode = IDLE; break; } case RUN_MODE_01: case IDLE: default: break; } }Здравствуйте! Прошу прощения, что пропал на эти дни.
Кинул Ваш код в Ардуино ИДЕ, вставил свои данные в инт и войд сэтап
Но при компиляции выдает ошибку "exit status 1 expected unqualified-id before 'case'", при этом выделяется первая строчка case START_MODE_01 11
#define IDLE 0 case START_MODE_01 11 case RUN_MODE_01 12 case STOP_MODE_01 13 case START_MODE_02 21 case RUN_MODE_02 22 case STOP_MODE_02 23 int16_t vibroMode, motorSpeed, motorStep; uint32_t lastMotorSpeedChangeTime; int motPin1 = 5; int motPin2 = 6; int motPin3 = 9; int motPin4 = 10; const uint32_t motorSpeedChangeInterval = 10; void buttonMode02Click() { // Stop mode #2 if it active or start it otherwise vibroMode = (vibroMode == START_MODE_02) ? IDLE : START_MODE_02; } void buttonMode01Click() { // Stop mode #1 if it active or start it otherwise vibroMode = (vibroMode == START_MODE_01) ? IDLE : START_MODE_01; } void changeMotorsSpeed(uint8_t _motorSpeed) { analogWrite(motPin1, _motorSpeed); analogWrite(motPin2, _motorSpeed); analogWrite(motPin3, _motorSpeed); analogWrite(motPin4, _motorSpeed); } void stopMotors() { digitalWrite(motPin1, LOW); digitalWrite(motPin2, LOW); digitalWrite(motPin3, LOW); digitalWrite(motPin4, LOW); } void setup() { Serial.begin(9600); pinMode(button1B, INPUT_PULLUP); pinMode(motPin1, OUTPUT);// установка порта на выход pinMode(motPin2, OUTPUT); pinMode(motPin3, OUTPUT); pinMode(motPin4, OUTPUT); } void loop() { // keep watching the push buttons: buttonMode01.tick(); buttonMode02.tick(); switch (vibroMode) { case START_MODE_02: { motorSpeed = lastMotorSpeedChangeTime = 0x00; motorStep = +1; vibroMode = RUN_MODE_02; break; } case RUN_MODE_02: { // just do nothing if no time for change motor speed if (millis() - lastMotorSpeedChangeTime < motorSpeedChangeInterval) { break; } lastMotorSpeedChangeTime = millis(); motorSpeed += motorStep; // make motors step's flip-flop on speed limits if (0x00 >= motorSpeed || 0xFF <= motorSpeed) { motorStep = -motorStep; } changeMotorSpeed(motorSpeed); break; } case STOP_MODE_02: { // stop motors here stopMotors(); vibroMode = IDLE; break; } case START_MODE_01: { motorSpeed = 128; // start motors here changeMotorSpeed(motorSpeed); vibroMode = RUN_MODE_01; break; } case STOP_MODE_01: { // stop motors here stopMotors(); vibroMode = IDLE; break; } case RUN_MODE_01: case IDLE: default: break; } }Сорри, это я накопипастил, конечно, в ночи.
Должно быть:
И, естественно, с первоначального скетча все эти OneButton, attachClick() надо перетащить.
ну, теперь похоже пошло мое непонимание программирования.
перетащил,что сказали и ошибки выдает, подсвечивая войд сетап. типа в аттачах я написал то, чего нет в коде, как я понял
#define IDLE 0 #define START_MODE_01 11 #define RUN_MODE_01 12 #define STOP_MODE_01 13 #define START_MODE_02 21 #define RUN_MODE_02 22 #define STOP_MODE_02 23 #include "OneButton.h" OneButton button1(A1, true); OneButton button2(A2, true); int16_t vibroMode, motorSpeed, motorStep; uint32_t lastMotorSpeedChangeTime; int motPin1 = 5; int motPin2 = 6; int motPin3 = 9; int motPin4 = 10; const uint32_t motorSpeedChangeInterval = 10; void buttonMode02Click() { // Stop mode #2 if it active or start it otherwise vibroMode = (vibroMode == START_MODE_02) ? IDLE : START_MODE_02; } void buttonMode01Click() { // Stop mode #1 if it active or start it otherwise vibroMode = (vibroMode == START_MODE_01) ? IDLE : START_MODE_01; } void changeMotorsSpeed(uint8_t _motorSpeed) { analogWrite(motPin1, _motorSpeed); analogWrite(motPin2, _motorSpeed); analogWrite(motPin3, _motorSpeed); analogWrite(motPin4, _motorSpeed); } void stopMotors() { digitalWrite(motPin1, LOW); digitalWrite(motPin2, LOW); digitalWrite(motPin3, LOW); digitalWrite(motPin4, LOW); } void setup() { Serial.begin(9600); pinMode(motPin1, OUTPUT);// установка порта на выход pinMode(motPin2, OUTPUT); pinMode(motPin3, OUTPUT); pinMode(motPin4, OUTPUT); while (!Serial) { ; // wait for serial port to connect. Needed for Leonardo only } Serial.println("Starting TwoButtons..."); // link the button 1 functions. button1.attachClick(click1); button1.attachDoubleClick(doubleclick1); // link the button 2 functions. button2.attachClick(click2); button2.attachDoubleClick(doubleclick2); } void loop() { // keep watching the push buttons: buttonMode01.tick(); buttonMode02.tick(); switch (vibroMode) { case START_MODE_02: { motorSpeed = lastMotorSpeedChangeTime = 0x00; motorStep = +1; vibroMode = RUN_MODE_02; break; } case RUN_MODE_02: { // just do nothing if no time for change motor speed if (millis() - lastMotorSpeedChangeTime < motorSpeedChangeInterval) { break; } lastMotorSpeedChangeTime = millis(); motorSpeed += motorStep; // make motors step's flip-flop on speed limits if (0x00 >= motorSpeed || 0xFF <= motorSpeed) { motorStep = -motorStep; } changeMotorSpeed(motorSpeed); break; } case STOP_MODE_02: { // stop motors here stopMotors(); vibroMode = IDLE; break; } case START_MODE_01: { motorSpeed = 128; // start motors here changeMotorSpeed(motorSpeed); vibroMode = RUN_MODE_01; break; } case STOP_MODE_01: { // stop motors here stopMotors(); vibroMode = IDLE; break; } case RUN_MODE_01: case IDLE: default: break; } }Всё правильно компилятор говорит.
Вы посылаете attachClick() за йодом (функция click1), а на складе только зелёнка - buttonMode01Click. Говорите attachDoubleClick() накладывать гипс (doubleclick1), а его нет в наличии.
Я попытался написать так, чтобы Вы смогли проследить логику действий, руководствуясь именами функций и переменных. Но в компилятор исходник не засовывал. Сейчас вот ещё вижу, что написал ещё changeMotorsSpeed(), а вызываю changeMotorSpeed(). Так что придётся посидеть ещё Вам над исходником.
с йодом и зеленкой понял, вроде поправил. теперь ругается на buttonMode01.tick(); buttonMode02.tick();
Эти две команды из моего исходника перекинуть?
#define IDLE 0 #define START_MODE_01 11 #define RUN_MODE_01 12 #define STOP_MODE_01 13 #define START_MODE_02 21 #define RUN_MODE_02 22 #define STOP_MODE_02 23 #include "OneButton.h" OneButton button1(A1, true); OneButton button2(A2, true); int16_t vibroMode, motorSpeed, motorStep; uint32_t lastMotorSpeedChangeTime; int motPin1 = 5; int motPin2 = 6; int motPin3 = 9; int motPin4 = 10; const uint32_t motorSpeedChangeInterval = 10; void buttonMode02Click() { // Stop mode #2 if it active or start it otherwise vibroMode = (vibroMode == START_MODE_02) ? IDLE : START_MODE_02; } void buttonMode01Click() { // Stop mode #1 if it active or start it otherwise vibroMode = (vibroMode == START_MODE_01) ? IDLE : START_MODE_01; } void changeMotorSpeed(uint8_t _motorSpeed) { analogWrite(motPin1, _motorSpeed); analogWrite(motPin2, _motorSpeed); analogWrite(motPin3, _motorSpeed); analogWrite(motPin4, _motorSpeed); } void stopMotors() { digitalWrite(motPin1, LOW); digitalWrite(motPin2, LOW); digitalWrite(motPin3, LOW); digitalWrite(motPin4, LOW); } void setup() { Serial.begin(9600); pinMode(motPin1, OUTPUT);// установка порта на выход pinMode(motPin2, OUTPUT); pinMode(motPin3, OUTPUT); pinMode(motPin4, OUTPUT); while (!Serial) { ; // wait for serial port to connect. Needed for Leonardo only } Serial.println("Starting TwoButtons..."); // link the button 1 functions. button1.attachClick(buttonMode01Click); button1.attachDoubleClick(stopMotors); // link the button 2 functions. button2.attachClick(buttonMode02Click); button2.attachDoubleClick(stopMotors); } void loop() { // keep watching the push buttons: buttonMode01.tick(); buttonMode02.tick(); switch (vibroMode) { case START_MODE_02: { motorSpeed = lastMotorSpeedChangeTime = 0x00; motorStep = +1; vibroMode = RUN_MODE_02; break; } case RUN_MODE_02: { // just do nothing if no time for change motor speed if (millis() - lastMotorSpeedChangeTime < motorSpeedChangeInterval) { break; } lastMotorSpeedChangeTime = millis(); motorSpeed += motorStep; // make motors step's flip-flop on speed limits if (0x00 >= motorSpeed || 0xFF <= motorSpeed) { motorStep = -motorStep; } changeMotorSpeed(motorSpeed); break; } case STOP_MODE_02: { // stop motors here stopMotors(); vibroMode = IDLE; break; } case START_MODE_01: { motorSpeed = 128; // start motors here changeMotorSpeed(motorSpeed); vibroMode = RUN_MODE_01; break; } case STOP_MODE_01: { // stop motors here stopMotors(); vibroMode = IDLE; break; } case RUN_MODE_01: case IDLE: default: break; } }Та же самая история: объявили OneButton button1(..), зааттачили button1.attachClick(), т.е. и tick() надо вызывать у button1. Или имя объекту везде поменять на buttonMode01.
Дайте ж я Вас расцелую!!! Работает) Единственное что, на двойной клик вторая кнопка не реагирует. Если с кодом все ок, то ладно. буду останавливать первой кнопкой
#define IDLE 0 #define START_MODE_01 11 #define RUN_MODE_01 12 #define STOP_MODE_01 13 #define START_MODE_02 21 #define RUN_MODE_02 22 #define STOP_MODE_02 23 #include "OneButton.h" OneButton buttonMode01(A1, true); OneButton buttonMode02(A2, true); int16_t vibroMode, motorSpeed, motorStep; uint32_t lastMotorSpeedChangeTime; int motPin1 = 5; int motPin2 = 6; int motPin3 = 9; int motPin4 = 10; const uint32_t motorSpeedChangeInterval = 10; void buttonMode02Click() { // Stop mode #2 if it active or start it otherwise vibroMode = (vibroMode == START_MODE_02) ? IDLE : START_MODE_02; } void buttonMode01Click() { // Stop mode #1 if it active or start it otherwise vibroMode = (vibroMode == START_MODE_01) ? IDLE : START_MODE_01; } void changeMotorSpeed(uint8_t _motorSpeed) { analogWrite(motPin1, _motorSpeed); analogWrite(motPin2, _motorSpeed); analogWrite(motPin3, _motorSpeed); analogWrite(motPin4, _motorSpeed); } void stopMotors() { digitalWrite(motPin1, LOW); digitalWrite(motPin2, LOW); digitalWrite(motPin3, LOW); digitalWrite(motPin4, LOW); } void setup() { Serial.begin(9600); pinMode(motPin1, OUTPUT);// установка порта на выход pinMode(motPin2, OUTPUT); pinMode(motPin3, OUTPUT); pinMode(motPin4, OUTPUT); while (!Serial) { ; // wait for serial port to connect. Needed for Leonardo only } Serial.println("Starting TwoButtons..."); // link the button 1 functions. buttonMode01.attachClick(buttonMode01Click); buttonMode01.attachDoubleClick(stopMotors); // link the button 2 functions. buttonMode02.attachClick(buttonMode02Click); buttonMode02.attachDoubleClick(stopMotors); } void loop() { // keep watching the push buttons: buttonMode01.tick(); buttonMode02.tick(); switch (vibroMode) { case START_MODE_02: { motorSpeed = lastMotorSpeedChangeTime = 0x00; motorStep = +1; vibroMode = RUN_MODE_02; break; } case RUN_MODE_02: { // just do nothing if no time for change motor speed if (millis() - lastMotorSpeedChangeTime < motorSpeedChangeInterval) { break; } lastMotorSpeedChangeTime = millis(); motorSpeed += motorStep; // make motors step's flip-flop on speed limits if (0x00 >= motorSpeed || 0xFF <= motorSpeed) { motorStep = -motorStep; } changeMotorSpeed(motorSpeed); break; } case STOP_MODE_02: { // stop motors here stopMotors(); vibroMode = IDLE; break; } case START_MODE_01: { motorSpeed = 128; // start motors here changeMotorSpeed(motorSpeed); vibroMode = RUN_MODE_01; break; } case STOP_MODE_01: { // stop motors here stopMotors(); vibroMode = IDLE; break; } case RUN_MODE_01: case IDLE: default: break; } }А... ну я-то с чего-то решил, что надо делать так: первое нажатие на кнопку запускает соотв. режим, второе (либо первое на другую кнопку) - останавливает. Поэтому даблклики не включал в свою версию.
все, понял теперь! значит пока буду делать так)) ничего страшного) Огромное спасибо Вам!