Управление ШД через Ардуину подключенную к другой ардуине

Kamikadze
Offline
Зарегистрирован: 09.03.2017

День добрый. Мега управляет двумя ШД посылая сигналы на УНО. Те в свою очередь принимая полученый сигнал передают сигнал на драйвера. Эмулятор в протусе 7 версии работает корректно, на практике, моторы вообще не реагируют на получаемый сигнал. Подскажите пожалуйста в акую сторону рыть. Скетч Меги и одной из уно ниже.

Скетч для меги

/*Схема подачи сигнала для управления моторами
 * На МЕГЕ  Pin4/7  Pin5/8  Pin6/9 ==> В УНО Pin2 / Pin3 / Pin4
    СТОП    0     0     0
    ВПЕРЕД  1     0     0     
    НАЗАД   0     1     0
    Right90 0     0     1
    Left90  1     1     1
 */

int motor1Pin4 = 4, motor1Pin5 = 5, motor1Pin6 = 6; //Ардуино-мотор 1 (правый)
int motor2Pin7 = 7, motor2Pin8 = 8, motor2Pin9 = 9; //Ардуино-мотор 2 (левый)
int CLKuno1Pin10 = 10;                                  //Разрешить/Запретить запись в УНО
int CLKuno2Pin11 = 11;

int Direct = 0;   //Номер элемента Массива
int MassGoToMotors[5] = {           //Массив хранящий поведение моторов
                         B0000000,   //Стоп Моторы
                         B0100100,   //Вперед
                         B0010010,   //Назад
                         B0001000,   //Поворот на 90гр направо
                         B0000001    //Поворот на 90гр налево
                        }; 

void setup()
{
  Serial.begin(9600);
  pinMode(motor1Pin4, OUTPUT);
  pinMode(motor1Pin5, OUTPUT);
  pinMode(motor1Pin6, OUTPUT);
  pinMode(motor2Pin7, OUTPUT);
  pinMode(motor2Pin8, OUTPUT);
  pinMode(motor2Pin9, OUTPUT);
  pinMode(CLKuno1Pin10, OUTPUT);
  pinMode(CLKuno2Pin11, OUTPUT);
  digitalWrite(CLKuno1Pin10, LOW);
  digitalWrite(CLKuno2Pin11, LOW);  
}

//****************************************************************************************************************************ППОСЛЕ СЕТАП***********************************************************************************************************

void loop()
{
  int SelectDirect = Serial.parseInt();
  switch (SelectDirect)
  {
    case 0:                           //Стоп мотор
      digitalWrite(CLKuno1Pin10, HIGH);
      digitalWrite(CLKuno2Pin11, HIGH);
      SlDirect(0);

      Serial.println("Motor Stop");
      
      delay(20);
      digitalWrite(CLKuno1Pin10, LOW);
      digitalWrite(CLKuno2Pin11, LOW);
      break;
    case 1:                           //Вперед
      digitalWrite(CLKuno1Pin10, HIGH);
      digitalWrite(CLKuno2Pin11, HIGH);
      SlDirect(1);

      Serial.println("Motor FORWARD");
      
      delay(20);
      digitalWrite(CLKuno1Pin10, LOW);
      digitalWrite(CLKuno2Pin11, LOW);
      break;
    case 2:                           //Назад
      digitalWrite(CLKuno1Pin10, HIGH);
      digitalWrite(CLKuno2Pin11, HIGH);
      SlDirect(2);
      
      Serial.println("Motor BACKWARD");
      
      delay(20);
      digitalWrite(CLKuno1Pin10, LOW);
      digitalWrite(CLKuno2Pin11, LOW);
      break;
    case 3:                           //Поворот на 90гр [хз куда
      digitalWrite(CLKuno1Pin10, HIGH);
      digitalWrite(CLKuno2Pin11, HIGH);
      SlDirect(3);
      
      Serial.println("Turn 90");
      
      delay(20);
      digitalWrite(CLKuno1Pin10, LOW);
      digitalWrite(CLKuno2Pin11, LOW);    
      break;
    case 4:                           //Поворот на 90гр [хз куда
      digitalWrite(CLKuno1Pin10, HIGH);
      digitalWrite(CLKuno2Pin11, HIGH);
      SlDirect(4);
      delay(20);
            
      Serial.println("Turn 90");
 
      digitalWrite(CLKuno1Pin10, LOW);
      digitalWrite(CLKuno2Pin11, LOW);    
      break;        
  }
End Loop
}


//*****************************************************************************************************************************ПОСЕ ЛООП***********************************************************************************************************

void SlDirect (int Direct)      //Процедура для направления движения
{
  digitalWrite(motor1Pin4, bitRead(MassGoToMotors[Direct], 5));
  digitalWrite(motor1Pin5, bitRead(MassGoToMotors[Direct], 4));
  digitalWrite(motor1Pin6, bitRead(MassGoToMotors[Direct], 3));
  digitalWrite(motor2Pin7, bitRead(MassGoToMotors[Direct], 2));
  digitalWrite(motor2Pin8, bitRead(MassGoToMotors[Direct], 1));
  digitalWrite(motor2Pin9, bitRead(MassGoToMotors[Direct], 0)); 
}

скетч для Уно1

/*
 
МАТРИЦА ДЕЙСТВИЙ
      Pin2  Pin3  Pin4
СТОП    0     0     0
ВПЕРЕД  1     0     0     для второго шаговика значения нужно поменять местами
НАЗАД   0     1     0
Right90 0     0     1
Left90  1     1     1
 
*/
#include <stepperQ.h>
 
int dir_pin = 5, step_pin = 6;    //Пин на драйвер
const int MaxSpeed = 1500;
const int Acceleration = 6666;
const long moveToGo = 160000;  
 
int Pin2 = 2, Pin3 = 3, Pin4 = 4;   //Входящие пины от Меги
int CLKPin10 = 10;              //Разрешить/Запретить запись в УНО
 
 
void setup()
{
  pinMode(Pin2, INPUT);
  pinMode(Pin3, INPUT);
  pinMode(Pin4, INPUT);
  pinMode(CLKPin10, INPUT);
 
  pinMode(dir_pin, OUTPUT);
  pinMode(step_pin, OUTPUT);  
  stepperq.setMaxSpeed(MaxSpeed);
  stepperq.setAcceleration(Acceleration);
  stepperq.moveTo(moveToGo);
}
 
void loop()
{
  if (digitalRead(CLKPin10) == HIGH)
  {
    if (digitalRead(Pin2) == 0 && digitalRead(Pin3) == 0 && digitalRead(Pin4) == 0)   //стоп мотор
    {
      stepperq.stop();
    }
    else if (digitalRead(Pin2) == 1 && digitalRead(Pin3) == 0 && digitalRead(Pin4) == 0)  //Вперед для второй уны нужно сменить знак для MoveTo
    {
      stepperq.start();
    }
    else if (digitalRead(Pin2) == 0 && digitalRead(Pin3) == 1 && digitalRead(Pin4) == 0)  //Назад для второй уны нужно сменить знак для MoveTo
    {
      stepperq.moveTo(moveToGo * -1);    //для второй уны знак меняется на противоположный
      stepperq.start();
    }
    else
    {
      stepperq.stop();    //нужно дописать поворот на 90 градусов, но это потом    
    }
  }
}
Kamikadze
Offline
Зарегистрирован: 09.03.2017
/*

МАТРИЦА ДЕЙСТВИЙ
      Pin2  Pin3  Pin4
СТОП    0     0     0
ВПЕРЕД  1     0     0     для второго шаговика значения нужно поменять местами
НАЗАД   0     1     0
Right90 0     0     1
Left90  1     1     1

*/
#include <stepperQ.h>

int dir_pin = 5, step_pin = 6;    //Пин на драйвер
const int MaxSpeed = 1500;
const int Acceleration = 6666;
const long moveToGo = 160000;  

int Pin2 = 2, Pin3 = 3, Pin4 = 4;   //Входящие пины от Меги
int CLKPin10 = 10;              //Разрешить/Запретить запись в УНО


void setup()
{
  pinMode(Pin2, INPUT);
  pinMode(Pin3, INPUT);
  pinMode(Pin4, INPUT);
  pinMode(CLKPin10, INPUT);

  pinMode(dir_pin, OUTPUT);
  pinMode(step_pin, OUTPUT);  
  stepperq.setMaxSpeed(MaxSpeed);
  stepperq.setAcceleration(Acceleration);
  stepperq.moveTo(moveToGo);
}

void loop()
{
  if (digitalRead(CLKPin10) == HIGH)
  {
    if (digitalRead(Pin2) == 0 && digitalRead(Pin3) == 0 && digitalRead(Pin4) == 0)   //стоп мотор
    {
      stepperq.stop();
    }
    else if (digitalRead(Pin2) == 1 && digitalRead(Pin3) == 0 && digitalRead(Pin4) == 0)  //Вперед для второй уны нужно сменить знак для MoveTo
    {
      stepperq.start();
    }
    else if (digitalRead(Pin2) == 0 && digitalRead(Pin3) == 1 && digitalRead(Pin4) == 0)  //Назад для второй уны нужно сменить знак для MoveTo
    {
      stepperq.moveTo(moveToGo * -1);    //для второй уны знак меняется на противоположный
      stepperq.start();
    }
    else
    {
      stepperq.stop();    //нужно дописать поворот на 90 градусов, но это потом    
    }
  }
}

 

Kamikadze
Offline
Зарегистрирован: 09.03.2017

Ппц, редактировать посты нельзя, в скетче для Меги сразу после Луп строка не скопировалась

while(Serial.available() == 0);     //ждем ввод данных

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

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

Смотрите, например, строки 47-49. Вы сначала выдаёте HIGH на пины, разрешающие чтение, а только потом вызваете SlDirect - выставляете нужные значения на информационных пинах. А надо наоборот! В момент включения разрешающего пина, на информационных пинах уже должно быть правильное значение. Так, как у Вас сейчас, слейв может начать чтение информационных пинов до того, как на них вывелось нужное значение. Я понятно сказал?

Тоже самое и в других местах - строки 58-60, 69-71 и т.п.

Kamikadze
Offline
Зарегистрирован: 09.03.2017

Да я понял попробую, спасибо за совет, но дело в том что в протеусе, когда в Мастере записан такой вот скетч,    

      digitalWrite(CLKuno2Pin11, HIGH);
      SlDirect(0);
      delay(20);
      digitalWrite(CLKuno2Pin11, LOW);
      delay(2000);
      digitalWrite(CLKuno2Pin11, HIGH);
      SlDirect(1);
      delay(20);
      digitalWrite(CLKuno2Pin11, LOW);
      delay(2000);

А в уно в соответствующем месте цикла

  if (digitalRead(CLKPin10) == HIGH)
  {
    if (digitalRead(Pin2) == 0 && digitalRead(Pin3) == 0 && digitalRead(Pin4) == 0)   //стоп мотор
    {
      digitalWrite(dir_pin, LOW);
      //stepperq.stop();
    }
    else if (digitalRead(Pin2) == 1 && digitalRead(Pin3) == 0 && digitalRead(Pin4) == 0)  //Вперед для второй уны нужно сменить знак для MoveTo
    {
      digitalWrite(dir_pin, HIGH);
//      stepperq.moveTo(moveToGo);
//      stepperq.start();
    }

Пин от уно на (светодиод выведен в Протеусе), Работает нормально

Но вообще я думал о том что не успевает слейв прочесть. Вечером проверю, и отпишусь.

Kamikadze
Offline
Зарегистрирован: 09.03.2017

Я в переменные для Дир и Степ объявил, а вот в библиотеке их не инициировал 

  stepperq.init(dir_pin,step_pin);

Из за этого и не работало