Управление координатным столом.

roccosiffredi
Offline
Зарегистрирован: 22.06.2012

Добрый день, происходят конфликты при обмене данными. Прошу помощи разобраться.

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

Проблемы возникают при коммуникации между устройствами в LabVIEW, когда переменно работают команды чтения и записи. Без блока "касание" с функциями serial.println все работает отлично, но это только запись.

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

С уважением, Александр.

//ДШИ 1 ГОРИЗОНТАЛЬ////////////////////////
int dirpin1 = 2;
int steppin1 = 3;
int leftPin1 = 52;
int rightPin1 = 50;
int Stop1 = 54;
int Stop2 = 55;

//ДШИ 2 ВЕРТИКАЛЬ////////////////////////
int dirpin2 = 4;
int steppin2 = 5;
int downPin2 = 53;
int upPin2 = 51;
int Stop3 = 56;
int Stop4 = 57;

int speedPin = 48;          //pin скорости
int datch = 46;                 //pin касания
int magn = 49;                //pin столика

int rstate, lstate, ustate, dstate = 0;

char direct[2];
char st[5];
char sp[2];

void setup() 
{
  Serial.begin(9600);

  pinMode(dirpin1, OUTPUT);
  pinMode(steppin1, OUTPUT);
  pinMode(rightPin1, INPUT);
  pinMode(leftPin1, INPUT);
  pinMode(Stop1, INPUT);
  pinMode(Stop2, INPUT);
  
  pinMode(dirpin2, OUTPUT);
  pinMode(steppin2, OUTPUT);
  pinMode(downPin2, INPUT);
  pinMode(upPin2, INPUT);  
  pinMode(Stop3, INPUT);
  pinMode(Stop4, INPUT);
  
  pinMode(speedPin, INPUT);
  pinMode(datch, INPUT);
  pinMode(magn, OUTPUT);
}

void loop()
{
  int i, n, a, b, spPin, rval, lval, rightStop, leftStop, uval, dval, upStop, downStop, S, V, dat;
  
  int k = 0;
  char buffer[12];  
  
  a = 500;                                  //КОНЕЧНАЯ СКОРОСТЬ
  n = 1000;                                //НАЧАЛЬНАЯ СКОРОСТЬ
  b = 10;                                     //ШАГОВАЯ СКОРОСТЬ
  
  rval = digitalRead(rightPin1);              //Переменные горизонтального ДШИ1
  lval = digitalRead(leftPin1);
  rightStop = digitalRead(Stop1);
  leftStop = digitalRead(Stop2);
  
  uval = digitalRead(upPin2);                 //Переменные вертикального ДШИ2
  dval = digitalRead(downPin2);
  upStop = digitalRead(Stop3);
  downStop = digitalRead(Stop4);
  
  spPin = digitalRead(speedPin);
  dat = digitalRead(datch);
 
  if(Serial.available())   //если есть данные - читаем
  {
    
       while( Serial.available() && k < 12)     //загоняем прочитанное в буфер
     {
       delay(100);
         buffer[k++] = Serial.read();
     }
     buffer[k++]='\0';                          //закрываем массив
  }
          if(k>0)                               //если буфер наполнен
        {       
          sscanf(buffer, "%[^','],%[^','],%[^','],%[^',']", &direct, &st, &sp);      //разбераем его на части отделенные запятой 
        }
        
            S = String(st).toInt();
            V = String(sp).toInt();
    
  if ((String)direct == "a")
  {    
     // ДАТЧИК КАСАНИЯ.
     if (dat == HIGH)                                        // Контакт.
     {
       Serial.println(1, DEC);
     }
     
     if (dat == LOW)                                         // Нет контакта.
     {
       Serial.println(2, DEC);
     }   
  }


  //Крутим вправо (RIGHT)////////////////////////////////////
 
     if ((String)direct == "r" && rightStop == LOW)
     {
      digitalWrite(magn, LOW);
        for (i=0; i<S; i++)
        {
           digitalWrite(dirpin1, LOW);                       // Выбираем направление.
             digitalWrite(steppin1, LOW);
             digitalWrite(steppin1, HIGH);
               delay(V); 
        }
      digitalWrite(magn, HIGH);
        direct [0] = '\0';
        st [0] = '\0';
        
     }
     
  //Крутим влево (LEFT)//////////////////////////////////////

     if ((String)direct == "l" && leftStop == LOW)
     {
      digitalWrite(magn, LOW);
        for (i=0; i<S; i++)
        {
           digitalWrite(dirpin1, HIGH);                       // Выбираем направление.
             digitalWrite(steppin1, LOW);
             digitalWrite(steppin1, HIGH);
               delay(V); 
        }
      digitalWrite(magn, HIGH);
        direct [0] = '\0';
        st [0] = '\0';
        
     }
     
  //Крутим вверх (UP)//////////////////////////////////////////

     if ((String)direct == "u" && upStop == LOW) 
     {
      
        for (i=0; i<S; i++)
        {    
           digitalWrite(dirpin2, LOW);                       // Выбираем направление.
             digitalWrite(steppin2, LOW);
             digitalWrite(steppin2, HIGH);
               delay(V); 
        }
        direct [0] = '\0';
        st [0] = '\0';
        
     }
     
  //Крутим вниз (DOWN)//////////////////////////////////////////

    if ((String)direct == "d" && downStop == LOW) 
     {
       
        for (i=0; i<S; i++)
        {    
           digitalWrite(dirpin2, HIGH);                       // Выбираем направление.
             digitalWrite(steppin2, LOW);
             digitalWrite(steppin2, HIGH);
               delay(V); 
        }
        direct [0] = '\0';
        st [0] = '\0';
        
     }   
  }

 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Сходу, при объявлении буфера, увеличьте его размер до 13, поскольку в строке 082, Вы пишите в k++, а k может иметь значение 12 (посмотрите сами условие выхода k < 12, т.е. при k == 12 выход, а потом Вы пишите в buffer[12], а это уже за пределами массива. Остальное не смотрел.

roccosiffredi
Offline
Зарегистрирован: 22.06.2012

Большое спасибо, немного переделал. В целом все работает, только работать начинает спустя примерно 9-10 секунд после запуска. Вполне возможно, что проблема на стороне labview, но я хотел бы убедиться что с этим кодом все впорядке. Был бы очень благодарен, если бы опытный глаз произвел оценку.

С уважением, Александр.


#include <string.h>

//ДШИ 1 ГОРИЗОНТАЛЬ////////////////////////
int dirpin1 = 2;
int steppin1 = 3;
int leftPin1 = 52;
int rightPin1 = 50;
int Stop1 = 54;
int Stop2 = 55;

//ДШИ 2 ВЕРТИКАЛЬ////////////////////////
int dirpin2 = 4;
int steppin2 = 5;
int downPin2 = 53;
int upPin2 = 51;
int Stop3 = 56;
int Stop4 = 57;

int speedPin = 48;            //pin скорости
int datch = 46;               //pin касания
int magn = 49;                //pin столика

int rstate, lstate, ustate, dstate = 0;

char direct[2];
char st[5];
char sp[2];

void setup() 
{
  Serial.begin(115200);

  pinMode(dirpin1, OUTPUT);
  pinMode(steppin1, OUTPUT);
  pinMode(rightPin1, INPUT);
  pinMode(leftPin1, INPUT);
  pinMode(Stop1, INPUT);
  pinMode(Stop2, INPUT);
  
  pinMode(dirpin2, OUTPUT);
  pinMode(steppin2, OUTPUT);
  pinMode(downPin2, INPUT);
  pinMode(upPin2, INPUT);  
  pinMode(Stop3, INPUT);
  pinMode(Stop4, INPUT);
  
  pinMode(speedPin, INPUT);
  pinMode(datch, INPUT);
  pinMode(magn, OUTPUT);
}

void loop()
{
  int i, n, a, b, spPin, rval, lval, rightStop, leftStop, uval, dval, upStop, downStop, S, V, dat;
  
  int k = 0;
  char buffer[10];  
  
  a = 500;                                    //КОНЕЧНАЯ СКОРОСТЬ
  n = 1000;                                   //НАЧАЛЬНАЯ СКОРОСТЬ
  b = 10;                                     //ШАГОВАЯ СКОРОСТЬ
  
  rval = digitalRead(rightPin1);              //Переменные горизонтального ДШИ1
  lval = digitalRead(leftPin1);
  rightStop = digitalRead(Stop1);
  leftStop = digitalRead(Stop2);
  
  uval = digitalRead(upPin2);                 //Переменные вертикального ДШИ2
  dval = digitalRead(downPin2);
  upStop = digitalRead(Stop3);
  downStop = digitalRead(Stop4);
  
  spPin = digitalRead(speedPin);
  dat = digitalRead(datch);


  if(Serial.available())                        //если есть данные - читаем
  {
    delay(50);
       while( Serial.available() && k < 9)     //загоняем прочитанное в буфер
     {       
         buffer[k++] = Serial.read();
     }
     buffer[k++]='\n';                          //закрываем массив
  }
          if(k>0)                               //если буфер наполнен
        {       
          sscanf(buffer, "%[^','],%[^','],%[^',']", &direct, &st, &sp);      //разбераем его на части отделенные запятой 
        }
        
            S = String(st).toInt();
            V = String(sp).toInt();
    
  if ((String)direct == "a")
  {    
     // ДАТЧИК КАСАНИЯ.
     if (dat == HIGH)                                        // Контакт.
     {
       Serial.print(1, DEC);
       Serial.print("\n");
       direct [0] = '\n';
       st [0] = '\n';
       sp [0] = '\n';
     }
     
     if (dat == LOW)                                         // Нет контакта.
     {
       Serial.print(2, DEC);
       Serial.print("\n");
       direct [0] = '\n';
       st [0] = '\n';
       sp [0] = '\n';     
     }   
  }


  //Крутим вправо (RIGHT)//////////////////////////    
     if ((String)direct == "r" && rightStop == LOW)
     {
      digitalWrite(magn, LOW);
        for (i=0; i<S; i++)
        {
           digitalWrite(dirpin1, LOW);                       // Выбираем направление.
             digitalWrite(steppin1, LOW);
             digitalWrite(steppin1, HIGH);
               delay(V); 
        }
      digitalWrite(magn, HIGH);
        direct [0] = '\n';
        st [0] = '\n';
        sp [0] = '\n';
     }
     
  //Крутим влево (LEFT)///////////////////////////
     if ((String)direct == "l" && leftStop == LOW)
     {
      digitalWrite(magn, LOW);
        for (i=0; i<S; i++)
        {
           digitalWrite(dirpin1, HIGH);                       // Выбираем направление.
             digitalWrite(steppin1, LOW);
             digitalWrite(steppin1, HIGH);
               delay(V); 
        }
      digitalWrite(magn, HIGH);
        direct [0] = '\n';
        st [0] = '\n';
        st [0] = '\n';
        sp [0] = '\n';
     }
     
  //Крутим вверх (UP)///////////////////////////
     if ((String)direct == "u" && upStop == LOW) 
     {
      digitalWrite(magn, LOW);
        for (i=0; i<S; i++)
        {    
           digitalWrite(dirpin2, LOW);                       // Выбираем направление.
             digitalWrite(steppin2, LOW);
             digitalWrite(steppin2, HIGH);
               delay(V); 
        }
      digitalWrite(magn, HIGH);
        direct [0] = '\n';
        st [0] = '\n';
        sp [0] = '\n';
     }
     
  //Крутим вниз (DOWN)///////////////////////////
    if ((String)direct == "d" && downStop == LOW) 
     {
      digitalWrite(magn, LOW);
        for (i=0; i<S; i++)
        {    
           digitalWrite(dirpin2, HIGH);                       // Выбираем направление.
             digitalWrite(steppin2, LOW);
             digitalWrite(steppin2, HIGH);
               delay(V); 
        }
      digitalWrite(magn, HIGH);
        direct [0] = '\n';
        st [0] = '\n';
        sp [0] = '\n';
     }   
  }

 

leshak
Offline
Зарегистрирован: 29.09.2011

Сильно не вникал, но 

delay(50);

выглядит не красиво.

Лучше _внутри_ цикла чтения ожидать следующего байта примерно так:

while(!Serial.available()){}

И вот это:

 buffer[k++]='\n';                          //закрываем массив

КРАЙНЕ смущает. В языке C, признаком конца строки (для встроеных функций работы со стороками) является нулевой байт, а не "перевод строки".

Кстати 

 if(k>0)                               //если буфер наполнен

Может подключивать, принимая символ конца строки за "мы что-то получили" (вообщем давать истину на пустых строках).

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

 

1. Форматирование текста - не мудрено, что очень сложно разобраться. Ctrl+T помогает, делает автоформатирование.

2. Про '\n' уже сказали - это просто нельзя. Пишите '\0'. Хотя можно и просто 0, но я пишу всегда в строковые '\0', так понятней тип данных.

3. Про if(k>0) - это всё правильно теперь, не исправляйте ничего.

4. 079 строка - непонятный delay

5. 77-85 - если данных нет, то проходим дальше и начинаем парсить пустые строки. Зачем? Явно чтобы глюки словить.

6. Совсем не понимаю, зачем очищать входные буферы (direct & прочие) в каждом условии. Очистите их перед строкой 77 и забудьте.

7. Ниже 93 строки не смотрел почти, это всего лишь обработка, там чуть проще.

8. В 105 строку просто вставьте "else", а 106 строку удалите, так будет правильней.