Помогите с кодом "Механический таймер с блютуз"

c5oloj
Offline
Зарегистрирован: 14.10.2014

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

Делаю механический таймер с блютузом, имеется следующее:

1. "барабанный счетный механизм" с шаговым 2х фазным 4х проводным двигателем. подключил на прямую к пинам "8, 9, 10, 11"

2. Arduino UNO

3. Bluetooth модуль "HC-05" подключена к питанию "3,3V, Земле, пинам 6, 7"

4. Кнопка подключена к пину "12 и земле"

Хотел что бы при нажатии на кнопку двигатель делал один шаг вперед. А по блютузу можно было делать шаги в перед и назад, быстро крутить вперед и назад. Для этого ввел переменную "q" по умолчанию равную 0, при нажатии на кнопку значение меняется на "1".  А по блютузу передаю значения "0, 1, 2, 3" для которых прописанны функции управления двигателем. 

И собственно проблемы при нажатии на кнопку двигатель стремится вращаться а не делать шаг. А по блютуз все с точностью да на оборот по всем командам делает шаг а не постоянно вращается.

Извените что в скетче все так расписанно но я только учусь))


// Загружаем библиотеку для Bluetooth
#include <SoftwareSerial.h>
//////////////////////////////////////////////////////////////////////////////////////////////
//ТУТ ЗАДАЮТСЯ ИСПОЛЬЗУЕМЫЕ ПЕРЕМЕННЫЕ И ПОРТЫ
//////////////////////////////////////////////////////////////////////////////////////////////
// Задаем порты RX, TX  Bluetooth
SoftwareSerial mySerial(6, 7);

// Задаем порты для мотора
int motorPin1 = (8); //  Синий     - pin 1
int motorPin2 = (9); //  Розовый   - pin 2
int motorPin3 = (10); // Желтый    - pin 3
int motorPin4 = (11); // Оранжевый - pin 4

// Задаем порт для кнопки
int buttonPin = 12; // кнопку подключаем к Pin 12 + ГНД.  
boolean  q; // фиксируем нажатие на кнопку.   

long previousMillis = 0;
int count = 0;

int motorSpeed = 1200;  // установить скорость шагового двигателя.

// Шаги для двигателя на 8м пине
int lookup[8] = 
// тут расписаны 8 шагов для управления приводом!!!!!!
//  1   |  2    |  3    |  4    |  5    |  6    |  7    |  8   |
{B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001};

///////////////////////////////////////////////////////////////////////////////////////////////
//setup - это первая функция, выполняемая программой, и выполняемая только один раз, 
//поэтому она используется для установки режима работы портов (pinMode()) или 
//инициализации последовательного соединения 
///////////////////////////////////////////////////////////////////////////////////////////////

void setup() 
{     //setup начало-----------------------------------------------------------------------------

// ЗАДАЕМ ФУНКЦИИ ПОРТОВ ДЛЯ МОТОРА
// Цифровые выводы используются как ВХОД (INPUT) и как ВЫХОД (OUTPUT).
  pinMode(motorPin1, OUTPUT); //пин 8 исходящий.
  pinMode(motorPin2, OUTPUT); //пин 9 исходящий.
  pinMode(motorPin3, OUTPUT); //пин 10 исходящий.
  pinMode(motorPin4, OUTPUT); //пин 11 исходящий.

// Одна нога кнопки подключается к GND, другая к Pin 12
// (никаких внешних резисторов не нужно).
  pinMode(buttonPin, INPUT); // пин 12 выходящий 
// digitalWrite Подает HIGH или LOW значение на цифровой вход/выход (pin)
// HIGH вывод включён LOW вывод выключен!!
  digitalWrite(buttonPin, HIGH);

   mySerial.begin(9600); // Задаем скорость обмена данных Bluetooth
   mySerial.println("GO"); // Кодовое слово Bluetooth для включения управления

}     //setup конец-------------------------------------------------------------------------------

  char incomingByte; // Bluetooth входящие байты

//////////////////////////////////////////////////////////////////////////////////////////////////
//функция loop содержит код, который выполняется постоянно 
//читаются входы, переключаются выходы и т.д. 
//////////////////////////////////////////////////////////////////////////////////////////////////
void loop()
{     //loop начало--------------------------------------------------------------------------------
 
if (digitalRead(buttonPin) == LOW) // если кнопка нажата.
// HIGH может обозначать несколько разное в зависимость от уставки 
// режима порта как INPUT или OUTPUT. Когда порт вход/выхода установлен 
// в режим INPUT с помощью функции pinMode, и считывается функцией 
// digitalRead, микроконтроллер отдаст значение HIGH при напряжение 3В 
// или вышен на указанном порту.
// LOW также разное для режима INPUT и OUTPUT. Когда порт 
// сконфигурирован как INPUT, и считывается функцие digitalRead, 
// микроконтроллер вернет LOW если напряжение на данном порту меньше или равно 2В.
  {
    q++;
    delay(100);
  }
if (digitalRead(buttonPin) == HIGH) // если кнопка нажата.
  {
    q = 0; // меняем значение q на 0
  }  
  
  if (q == 0)STOP(); // СТОП
  if (q == 1)Forward_NORMAL(); // ИДЕТ Нормально ВПЕРЕД !!!!!!!!!!!!!  
  if (q == 2)Forward_FAST();   // ИДЕТ БЫСТРО ВПЕРЕД
  if (q == 3)Backward_FAST();  // ИДЕТ БЫСТРО НАЗАД

 
// --------------------------------Bluetooth-------------------------------
if (mySerial.available()) // Запускаем библиотеку блютуз.
  {
       incomingByte = mySerial.read(); // Считываем байты с порта.
       if(incomingByte == '0') // Если считали "0"
       {
q = 0; // меняем значение q на 0.
if (q == 0)STOP(); // Если значение q равно 0 тогда запускаем соответствующий скрипт
       mySerial.println("Motor STOP!"); // Передаем текст сообщения о выполнении функции.
       }
       if(incomingByte == '1') // Если считали "1"
       {
q = 1; // меняем значение q на 1 
if (q == 1)Forward_NORMAL(); // Если значение q равно 1 тогда запускаем соответствующий скрипт
       mySerial.println("Vpered 1 schag!");// Передаем текст сообщения о выполнении функции.
       }
       if(incomingByte == '2') // Если считали "2"
       {
q = 2; // меняем значение q на 2.
if (q == 2)Forward_FAST(); // Если значение q равно 2 тогда запускаем соответствующий скрипт
       mySerial.println("Vpered bistro!");// Передаем текст сообщения о выполнении функции.
       }
       if(incomingByte == '3') // Если считали "3"
       {
q = 3; // меняем значение q на 3.
if (q == 3)Backward_FAST(); // Если значение q равно 3 тогда запускаем соответствующий скрипт
       mySerial.println("Nazad bistro!");// Передаем текст сообщения о выполнении функции.
       }              
  }
// --------------------------------Bluetooth------------------------------
}      //loop конец--------------------------------------------------------------------------------



// --------------------------------ФУНКЦИИ ДЛЯ УПРАВЛЕНИЯ МОТОРОМ.---------------------------------

void Forward_NORMAL() // Даем название функции "ИДЕТ МЕДЛЕННО ВПЕРЕД"
{
  for(int i = 8; i > 0; i--) // Цыкл равен 8 шагам, Установлен выше 0 шага, И уменьшаем на 1.
// Конструкция for используется для повторения блока операторов, заключенных в фигурные скобки.
// Тип данных int один их наиболее часто используемых типов данных для хранения чисел. 
// int задается в виде массива int lookup[8]={B01000,B01100,B00100,B00110,B00010,B00011,B00001,B01001};
// "-- или ++" уменьшает или увеличивает значение на 1.
  {
    setOutput(i); // Порт установленный в режим выхода — OUTPUT на "i" значение...
    delayMicroseconds(motorSpeed); // Скорость мотора прописанная в переменных.
  }
}
void STOP() // // Даем название функции "СТОИТ"
{
  for(int i = 0; i > 0; i--) // Цыкл равен 0 шагам...
  {
    setOutput(i); // Порт установленный в режим выхода — OUTPUT на "i" значение...
    delayMicroseconds(motorSpeed); // Скорость мотора прописанная в переменных.
  }
}
void Backward_FAST() // // Даем название функции "ИДЕТ БЫСТРО НАЗАД"
{
  for(int i = 0; i < 8; i++) // Цыкл равен 0 шагам, Установлен ниже 8 шага, И увеличиваем на 1.
  {
    setOutput(i); // Порт установленный в режим выхода — OUTPUT на "i" значение...
    delayMicroseconds(motorSpeed); // Скорость мотора прописанная в переменных.
  }
}
void Forward_FAST()// // Даем название функции "ИДЕТ БЫСТРО ВПЕРЕД"
{
  for(int i = 8; i > 0; i--) // Цыкл равен 8 шагам, Установлен выше 0 шага, И уменьшаем на 1.
  {
    setOutput(i); // Порт установленный в режим выхода — OUTPUT на "i" значение...
    delayMicroseconds(motorSpeed); // Скорость мотора прописанная в переменных.
  }
}


// функция поворачивает мотор по часовой стрелке.
void setOutput(int out) // Функции setOutput присваеваем имя "out"
// Ключевое слово void используется при объявлении функций, если функция не возвращает никакого значение при ее 
// вызове (в некоторых языках программирования такие функции называют процедурами).
{
  digitalWrite(motorPin1, bitRead(lookup[out], 0)); // Подаем на (пин 8, считанные с "i" значение, 0)
  // digitalWrite Подает HIGH или LOW значение на цифровой вход/выход (pin).
  // bitRead Считывает биты с номера bitRead(x, n) где: 
     // х - номер, с которого читать 
     // n - Биты считываемые от 0 и далее крайние справа значения бит. Возвращает значение бита (0 или 1)
  digitalWrite(motorPin2, bitRead(lookup[out], 1));
  digitalWrite(motorPin3, bitRead(lookup[out], 2));
  digitalWrite(motorPin4, bitRead(lookup[out], 3));
}

 

 

faraddin
Offline
Зарегистрирован: 11.08.2013

Что у вас за двигатель такой, если он не спалил до сих пор подключенную к нему напрямую ардуину?

c5oloj
Offline
Зарегистрирован: 14.10.2014

Двигатель шаговый 2 фазы, 4 провода, 5 вольт.

Ссылка на продавца. Если нельзя публиковать ссыки то сори...

http://item.taobao.com/item.htm?spm=a230r.1.14.49.HkXdek&id=38304406214&ns=1#detail

подключил на прямую насмотревшись видеоуроков

вот тут https://www.youtube.com/watch?v=etx24iFMilg&list=TLT2HxNRAxFr8qvlgfFKGMzunsHCQ9Ls3B

и т.к. заказанный модуль управления не пришол (((

faraddin
Offline
Зарегистрирован: 11.08.2013

Почему, если q - booleab, вы ждете что он будет равен 2 или 3?

Опять же конструкция:

q=0;

if(q==0).. в чем смысл?

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

осипов отжигает))

c5oloj
Offline
Зарегистрирован: 14.10.2014

q равен 2 или 3 только при передаче данных с блютуза.

часть с (q==0) в связи с тем что двигатель бывало при отпускании кнопки не стоял а вращался примерно 3-4 раза из 10

Если шанс спалить дуину высок а драйвера нет есть ли еще варианты?

faraddin
Offline
Зарегистрирован: 11.08.2013

а то что q это boolen вас не смущает?

если вы присвоили переменную то ее не нужно в следующей строчке проверять, она не может изминиться. а значит проблема в другом

 

c5oloj
Offline
Зарегистрирован: 14.10.2014

поменял значение boolean на "int q;" 

c5oloj
Offline
Зарегистрирован: 14.10.2014

как изменить функцию переменной "1" что бы она исполнялась один раз? а функции "2, 3" до отмены?

я так понимаю что функции 2,3 от блютуза выполняются один раз потому что выполняется функция кнопки о том что если не нажата то 0? можно ли задать время выполнения команд 2,3?

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

в конце функции напишите

if(q == 1) {

q = 0;

}

c5oloj
Offline
Зарегистрирован: 14.10.2014

если написать if(q==1){q=0;} и обнулить deley то мотор крутится без остановки.

а вот если if(q==1){q=1;} то действительно делает практически один шаг скорее 1,2 шага...

 

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

посмотрите свой скетч и перепишите его правильно - и только тогда моя "добавка" как Вы и просили заработает. У вас сейчас не счкетч.

c5oloj
Offline
Зарегистрирован: 14.10.2014
#include <SoftwareSerial.h> 



SoftwareSerial mySerial(6, 7);  
int motorPin1 = (8); 
int motorPin2 = (9); 
int motorPin3 = (10); 
int motorPin4 = (11); 
int buttonPin = 12; //кнопка
int  q; //переменная
int motorSpeed = 1200;  //скорость
int lookup[8] = {B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001}; 



void setup() 
{     
    pinMode(motorPin1, OUTPUT); //пин 8 
    pinMode(motorPin2, OUTPUT); //пин 9
    pinMode(motorPin3, OUTPUT); //пин 10 
    pinMode(motorPin4, OUTPUT); //пин 11

    pinMode(buttonPin, INPUT); // пин 12 
    digitalWrite(buttonPin, HIGH);//питание на пин 12

    mySerial.begin(9600); 
    mySerial.println("GO MOVIT"); 
}     
  
   
    char incomingByte; 


void loop()
{      
    if (digitalRead(buttonPin) == LOW) 
      {
      q = 1;
      if (q == 1)Forward_NORMAL();
      }
      
      
    if (digitalRead(buttonPin) == HIGH) 
      {
      q = 0;
      if (q == 0)STOP();  
      }

// блютуз.
    if (mySerial.available()) 
    {
         incomingByte = mySerial.read(); // Считываем с порта.
         
      if(incomingByte == '0') // Если считали "0"
         {
          q = 0; 
      if (q == 0)STOP(); 
          mySerial.println("Motor STOP!"); 
         }
         
      if(incomingByte == '1') // Если считали "1"
         {
          q = 1;  
      if (q == 1)Forward_NORMAL(); 
          mySerial.println("Vpered 1 schag!");
         }
         
      if(incomingByte == '2') // Если считали "2"
         {
          q = 2; 
      if (q == 2)Forward_FAST(); 
         mySerial.println("Vpered bistro!");
         }
         
      if(incomingByte == '3') // Если считали "3"
         {
          q = 3; 
      if (q == 3)Backward_FAST(); 
         mySerial.println("Nazad bistro!");
         }              
     }//bluetooth конец
}//loop конец

void Forward_NORMAL() //"ИДЕТ МЕДЛЕННО ВПЕРЕД"
{
  for(int i = 8; i > 0; i--) 
  {
    setOutput(i); 
    delayMicroseconds(motorSpeed); 
  }
}
void STOP() // "СТОИТ"
{
  for(int i = 0; i > 0; i--) 
  {
    setOutput(i); 
    delayMicroseconds(motorSpeed); 
  }
}
void Backward_FAST() // "ИДЕТ БЫСТРО НАЗАД"
{
  for(int i = 0; i < 8; i++) 
  {
    setOutput(i); 
    delayMicroseconds(motorSpeed);
  }
}
void Forward_FAST() // "ИДЕТ БЫСТРО ВПЕРЕД"
{
  for(int i = 8; i > 0; i--) 
  {
    setOutput(i); 
    delayMicroseconds(motorSpeed); 
  }
}


void setOutput(int out) 
{
  digitalWrite(motorPin1, bitRead(lookup[out], 0)); 
  digitalWrite(motorPin2, bitRead(lookup[out], 1));
  digitalWrite(motorPin3, bitRead(lookup[out], 2));
  digitalWrite(motorPin4, bitRead(lookup[out], 3));
}

 

c5oloj
Offline
Зарегистрирован: 14.10.2014

Подчистил сделал более читабельным но что именно мне надо тут исправить не понимаю(((( 

Команда кнопок выполняется бесконечно либо бесконечно присваевает переменной q значение 0 либо 1 соответственно мотор либо стоит либо крутится постоянно. команды блютуза выполняются единожды при передачи числа.