Через Serial поступают не те данные от программы к ардуине

timur2008
Offline
Зарегистрирован: 06.03.2013

Здравствуйте. Опять нужна ваша помощь. Я разобрался как передавать данные через Serial от программы к ардуине но возникла проблема. Например я отправляю от программы

currentPort.Write(new byte[] { 0xa0, 0xa1 },0,2);

В ардуине я пытаюсь поймать этот байт

byte my = Serial.read();
byte test = 0xa0;
		if (my == test)
		{
			zero(1, 1);
			delay(10000);
		}

но ничего не происходит :( . Что я не так делаю ?

b707
Offline
Зарегистрирован: 26.05.2017

Давайте весь скетч. видимо ошибка не в том клочке, который вы показываете.

timur2008
Offline
Зарегистрирован: 06.03.2013
	

Хмм ту проблему удалось решить довольно странным образом, я передал байтовый массив состоящий из 2х одинаковых элементов. тогда условие сработало. но вот теперь у меня вопрос возник. Как мне полученную последовательность обработать правильно ? Данные приходят по одному элементу ведь. Пока чтото мозгов только на это хватило

Вот так передаем в порт currentPort.Write(new byte[] { 0xa0, 0xa1, 0xa2 },0,3);

дальше на ардуине:

	        byte my = Serial.read();
		byte test1 = 0xa0;
		byte test2 = 0xa1;
		byte test3 = 0xa2;


а как мне потом правильно их сконтетенировать ? Со строками там все просто ,есть конкатенация и ее потом сравнить с полученным результатом , а тут как ??

if (my == maintest)
		{
			zero(1, 1);
			delay(10000);
		}

Нужно как то в vaintest собрать массив с данными и плюс контролировать чтобы приходило именно то что нужно.

b707
Offline
Зарегистрирован: 26.05.2017

timur2008 пишет:

Нужно как то в vaintest собрать массив с данными и плюс контролировать чтобы приходило именно то что нужно.

Неправильно акценты ставите. Надо сперва контролировать, а потом собирать в массив - собирать только то, что нужно.

И вот тут становится понятно, зачем нужен "заголовок". Схема следующая - вы сравниваете каждый полученный байт с первым байтом заголовка. Если не совпал - байт просто игнорируем, складывать его никуда не нужно. Если совпал - проверяем следующие за ним два байта(если заголовк длиной 3 байта), если они тоже совпали - только тогда начинаем парсить приходящие данные. И еще в пакете данных должен быть "терминатор" - признак окончания, после которого система завершает парсинг.

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

timur2008
Offline
Зарегистрирован: 06.03.2013

ААаа вон оно что , все понял спасибо огромное за помощь :)

timur2008
Offline
Зарегистрирован: 06.03.2013

Блин ничего не могу понять, похоже что помимо моей последовательности туда еще чтото шлется.

Пытаюсь обрабатывать вот так

void loop() {
	etalon = 0;
	Serial.println(stringOne);  // отправляем строку на порт
	char incomingChar;
	isWrite = false;
	if (Serial.available() > 0)
	{
		stringOne = "";
		counts++;
		// считываем полученное с порта значение в переменную
		//incomingChar = Serial.read();
		byte my = Serial.read();
		full += incomingChar;
		byte test = 0xa0;
		
		Serial.println(my);
		if (my == test)
		{
			etalon++;
		}
		else
		{
			etalon = 0;
		}
		
		if (etalon == 3)
		{
			zero(1, 1);
			delay(10000);
		}
	}

функция zero не отрабатывает. Там почемуто не идет одинаковая последовательность,точнее она один раз встречается только и etalon становится равный 1 и все. :(

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

if serial.available выполняется только раз, после этого эталон сбрасывается в 0 во второй строке скетча, поэтому он равен 1. Либо меняйте логику, либо в 6 строке пишите не if а while

timur2008
Offline
Зарегистрирован: 06.03.2013

Penni пишет:

if serial.available выполняется только раз, после этого эталон сбрасывается в 0 во второй строке скетча, поэтому он равен 1. Либо меняйте логику, либо в 6 строке пишите не if а while

блин чето не понял :( Написал while (Serial.available() > 0) вместо if но это нечего не изменило.

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Вы с компа шлете подряд три байта 0xa0 и между ними ничего не шлете?

timur2008
Offline
Зарегистрирован: 06.03.2013

нет , ничего. Но я еще от ардуины пишу строку в порт

String stringOne = "Info from Arduino ";
	Serial.println(stringOne);  // отправляем строку на порт

может это как то влиять ? Хотя я уже пробовал убирать ее , это не помогло

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

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Ну а serial.print(my); что выводит?

timur2008
Offline
Зарегистрирован: 06.03.2013

Да там все сложно :( У меня через этот порт ардуина взаимоействует с приложухой, и serial.print(my) вообщем вообще ничего не выводит.

MaksVV
Offline
Зарегистрирован: 06.08.2015

timur2008 пишет:

Да там все сложно :( У меня через этот порт ардуина взаимоействует с приложухой, и serial.print(my) вообщем вообще ничего не выводит.

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

timur2008
Offline
Зарегистрирован: 06.03.2013

MaksVV пишет:

timur2008 пишет:

Да там все сложно :( У меня через этот порт ардуина взаимоействует с приложухой, и serial.print(my) вообщем вообще ничего не выводит.

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

 

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

timur2008
Offline
Зарегистрирован: 06.03.2013

Скажите а зачем вы в коде приема ставите еще delay когда проверяете заголовок сообщения ? 

MaksVV
Offline
Зарегистрирован: 06.08.2015

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

timur2008
Offline
Зарегистрирован: 06.03.2013

у меня просто пролема сейчас ,я по сути начал как вы делать , но у меня хоть я и пересылаю три подряд одинаковых элемента (типо чтобы скомандовать заголовок) но у меня там почему то доходит какая то мешанина до ардуины. У меня чуть по другому сделано. Сначала ардуина шлет в компорт сообщение hello , на шарпе моя прога сканит все ком порты и в итоге находит компорт откуда пришло это слово. Ну и его запоминает и в ответ пересылает ему инфу. Вот тут я и застопорился. Вроде когда напрямую писал символы ,например температуру воздуха, все норм разбиралось на стороне ардуины. А тут когда пытаюсь сделать поноценный протокол обмена данными , такой затык блин получился :(

MaksVV
Offline
Зарегистрирован: 06.08.2015

Ну сделайте заголовок как у меня с теми же байтами. А далее уже данные как хотите. Вообще чтобы нормально посмотреть , что прилетело с компа, нужно простенький скетч залить, который показывает что прилетело. Попозже скину. И еще , естественно,параметры портов должны совпадать , скорость, сколько бит, проверка на четность, сколько стоп бит.

timur2008
Offline
Зарегистрирован: 06.03.2013

Скажите а может ли мой код быть косячным изза того что в цикле каждый раз сама пишет циклически "Hello" в компорт ?

MaksVV
Offline
Зарегистрирован: 06.08.2015

дак покажи свой код

MaksVV
Offline
Зарегистрирован: 06.08.2015

вот скетч чтобы посмотреть что творится в порту 

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); //R,T   подключаем этот сериал к программе на компе
unsigned long prevTimedelay = 0; 
int Delay = 0;
void setup() {
 Serial.begin (9600);  //     этот сериал служит для вывода в сериал монитор 
mySerial.begin (9600);  //    подключаем этот сериал к программе на компе
}

void loop() {

if (mySerial.available()) {
delay (51);
unsigned long curTimedelay = millis ();
   Delay = curTimedelay-prevTimedelay;
Serial.println (""); Serial.print (Delay); Serial.println ("ms");
prevTimedelay = millis();  
while( mySerial.available()) {
    byte inByte = mySerial.read();
    Serial.print(" ");
    Serial.print(inByte,HEX);
   }
     
    }
}

 

timur2008
Offline
Зарегистрирован: 06.03.2013

Хорошо понял спасибо , завтра утром как на работе буду попробую :)

timur2008
Offline
Зарегистрирован: 06.03.2013

Мда облом , когда я в ардуине ide пытаюсь открыть монитор порта он мне пишет "Ошибка открытия последовательного порта "COM3" (Port busy)"  :(

kalapanga
Offline
Зарегистрирован: 23.10.2016

timur2008 пишет:

Мда облом , когда я в ардуине ide пытаюсь открыть монитор порта он мне пишет "Ошибка открытия последовательного порта "COM3" (Port busy)"  :(

Чтобы воспользоваться этим скетчем Вам нужно соединиться с ардуино по двум различным последовательным портам. (Вы скетч-то смотрели?) Один у Вас есть, а чтобы организовать второй Вам нужен специальный адаптер. О чем MaksVV ​забыл напомнить. Сейчас Вы судя по всему заняли COM3 Вашей программой, а потом пытаетесь ещё и монитором порта к нему же подключиться. Результат предсказуем.

timur2008
Offline
Зарегистрирован: 06.03.2013

да я это уже понял :) , у меня нет двух ардуин . Знаю что занял , но по другому никаак не получается и я не могу понять как мне узнать что там вообще происходит.

b707
Offline
Зарегистрирован: 26.05.2017

timur2008 пишет:

да я это уже понял :) , у меня нет двух ардуин . Знаю что занял , но по другому никаак не получается и я не могу понять как мне узнать что там вообще происходит.

увы, но боюсь без второго порта никак. Либо USB-COM адаптер, либо еще одна ардуина с USART, либо ардуина с несколькими портами.

Я бы взял еще одну ардуину, подешевле, типа Нано. Она сейчас в РФ от двухсот рублей. Вообще советую заказать пару-тройку про запас - в китае по 100 руб - после первого скетча наверняка захочется что-то еще сделать

MaksVV
Offline
Зарегистрирован: 06.08.2015

если есть lcd можно на него байты вывести вместо сериал монитора