Управление координатным столом.
- Войдите на сайт для отправки комментариев
Ср, 26/12/2012 - 16:11
Добрый день, происходят конфликты при обмене данными. Прошу помощи разобраться.
В программе упущен еще большой блок ручного управления, потому есть лишние переменные.
Проблемы возникают при коммуникации между устройствами в 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';
}
}
Сходу, при объявлении буфера, увеличьте его размер до 13, поскольку в строке 082, Вы пишите в k++, а k может иметь значение 12 (посмотрите сами условие выхода k < 12, т.е. при k == 12 выход, а потом Вы пишите в buffer[12], а это уже за пределами массива. Остальное не смотрел.
Большое спасибо, немного переделал. В целом все работает, только работать начинает спустя примерно 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'; } }Сильно не вникал, но
delay(50);
выглядит не красиво.
Лучше _внутри_ цикла чтения ожидать следующего байта примерно так:
while(!Serial.available()){}И вот это:
КРАЙНЕ смущает. В языке C, признаком конца строки (для встроеных функций работы со стороками) является нулевой байт, а не "перевод строки".
Кстати
Может подключивать, принимая символ конца строки за "мы что-то получили" (вообщем давать истину на пустых строках).
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 строку удалите, так будет правильней.