Прошу помощи со скетчем

nail2007
Offline
Зарегистрирован: 08.12.2017

Здравствуйте! 

Пытаюсь запрограммировать работу вибромоторов в зависимости от нажатия двух кнопок.

Первая кнопка - просто дребезжат, не останавливаясь. Вторая кнопка - вибрация плавно доходит до максимума, а потом затухает. 

У меня, к сожалению, почему то не получается сделать зацикленный второй режим. Вибрация доходит до максимума и дальше на этом же максимуме дребезжит. 

Ниже прикреплю код. Помогите, пожалуйста, найти ошибку! Или , что вероятнее всего, я что-то не догоняю в работе с кнопками, может подскажете. Взял пример из библиотеки 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);
}

 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Начать тут нужно с другого: определиться как предполагается вписать этот фрагмент в остальной код. Например, то что Вы написали сейчас в click2() заблокирует процесс. Невозможно будет ни работать с MPU-шкой, ни прервать вибрацию.

nail2007
Offline
Зарегистрирован: 08.12.2017

Нет, МПУшку я на другую ардуинку цепляю. Решил разделить две функции, чтобы было меньше волокиты. Все равно портативного прибора тут не получишь. 

Я думал, что сделал так:

1 клик на первую кнопку включает первый режим работы. двойное нажатие на первую кнопку выключает первый режим.

1 клик на вторую кнопку включает второй режим, двойное - выключает его.

Я пытался настроить с одной кнопкой, но там проблем было больше. Здесь все работает, но описанная выше проблема только присутствует.

nail2007
Offline
Зарегистрирован: 08.12.2017

может и дилдо

в любом случае без второго режима работы даже дилдо получится плохим. 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Ну, т.е. вибрация не будет поставлена в прямую зависимость от частоты тремора? Т.е. управление всегда ручное будет?

nail2007
Offline
Зарегистрирован: 08.12.2017

Да, совершенно верно! Я решил, что в первой версии исследований будет именно так. Я буду в ручную менять параметры вибрации. Если я сейчас буду все объединять, то я половину лета проведу с железками. А такой карт бланш на время у меня , к сожалению, нет. Поэтому к объединению двух функций вернусь осенью, там вроде нас пошлюс к студентам технарям, которые будут с нами работать. А пока хочу собрать данных на пациентах

Позже закажу драйвера на моторчики, там вроде как можно различные виды импульсов на моторы посылать. 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

nail2007 пишет:
А пока хочу собрать данных на пациентах

Ну, вот я накидал на коленке. В парадигме 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;
  }
}

 

nail2007
Offline
Зарегистрирован: 08.12.2017

Здравствуйте! Прошу прощения, что пропал на эти дни. 

Кинул Ваш код в Ардуино ИДЕ, вставил свои данные в инт и войд сэтап 

Но при компиляции выдает ошибку "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;
  }
}

 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Сорри, это я накопипастил, конечно, в ночи. 

Должно быть:

#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

И, естественно, с первоначального скетча все эти OneButton, attachClick() надо перетащить. 

nail2007
Offline
Зарегистрирован: 08.12.2017

ну, теперь похоже пошло мое непонимание программирования. 

перетащил,что сказали и ошибки выдает, подсвечивая войд сетап. типа в аттачах я написал то, чего нет в коде, как я понял

#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;
  }
}

 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Всё правильно компилятор говорит.

Вы посылаете attachClick() за йодом (функция click1), а на складе только зелёнка - buttonMode01Click. Говорите attachDoubleClick() накладывать гипс (doubleclick1), а его нет в наличии.

Я попытался написать так, чтобы Вы смогли проследить логику действий, руководствуясь именами функций и переменных. Но в компилятор исходник не засовывал. Сейчас вот ещё вижу, что написал ещё changeMotorsSpeed(), а вызываю changeMotorSpeed(). Так что придётся посидеть ещё Вам над исходником.

 

nail2007
Offline
Зарегистрирован: 08.12.2017

с йодом и зеленкой понял, вроде поправил. теперь ругается на   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;
  }
}

 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Та же самая история: объявили OneButton button1(..), зааттачили button1.attachClick(), т.е. и tick() надо вызывать у button1. Или имя объекту везде поменять на buttonMode01.

nail2007
Offline
Зарегистрирован: 08.12.2017

Дайте ж я Вас расцелую!!! Работает) Единственное что, на двойной клик вторая кнопка не реагирует. Если с кодом все ок, то ладно. буду останавливать первой кнопкой

#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;
  }
}

 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

А... ну я-то с чего-то решил, что надо делать так: первое нажатие на кнопку запускает соотв. режим, второе (либо первое на другую кнопку) - останавливает. Поэтому даблклики не включал в свою версию. 

nail2007
Offline
Зарегистрирован: 08.12.2017

все, понял теперь! значит пока буду делать так)) ничего страшного) Огромное спасибо Вам!