Подскажите как отловить?

adruha
Offline
Зарегистрирован: 21.05.2013

Приветствую всех! Есть у меня небольшой проект чтение данных от драйвера типа модбас но не совсем. 

вот небольшой кусок кода

#include "SoftwareSerial.h"

SoftwareSerial RS485Serial(11, 10); // RX, TX

int in_buffer[8]; // receiving buffer
byte recdata[8];

byte null_recUID[] = {0x01, 0x01, 0x01, 0x02, 0xD0, 0x49};////01 01 01 02 D0 49 //=01 01 02 02 02 39 5D
byte null_reply[] ={0x01, 0x01, 0x02, 0x02, 0x02, 0x39, 0x5D}; //01 01 02 02 02 39 5D - ответ

bool no_validCard(byte * cardMassiv,byte * recUID) {  
  for (byte i = 0; i < 6; i++) {
    if (*(cardMassiv + i) != recUID[i]) return false;
  }
  return true;
}

void setup() {
  Serial.begin(9600); // Init serial communication
  pinMode(3, OUTPUT);
  RS485Serial.begin(9600);
  
  digitalWrite(3, LOW);
}




void loop() {
  
  if(RS485Serial.available() == 6){
    for (int i=0; i < 6; i++){
      in_buffer[i] = RS485Serial.read();
      recdata[i] = in_buffer[i];     
    } 
    

    if(no_validCard(recdata,null_recUID)){////01 01 01 02 D0 49 //=01 01 02 02 02 39 5D
       digitalWrite(3, HIGH);
       RS485Serial.write(null_reply,sizeof(null_reply));
       digitalWrite(3, LOW);
       Serial.println("?");
    }
  }

}

пока данные прилетают по шесть все хорошо но иногда могут прилететь по семь или восемь и тут все сбивается и естественно работает неправильно. Голову уже сломал как мне иногда поймать команду по семь или восемь байт если в основном читаю по шесть. Подскажите если кто в курсе? 

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

А число 6 в строке 32 ни на какие мысли не наводит?

adruha
Offline
Зарегистрирован: 21.05.2013

ну что толку что оно меня наводит как я его динамически могу менять то? и как мне узнать что пришло шесть а не восемь. 

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

А это к Вам вопрос вопрос! Как Вам узнать сколько пришло, зависит от природы сигнала и Вы этого не описали. Как Вы вообще узнаёте сколько пришло? Вот пришло 6, ждать ещё или уже всё? А пришёл седьмой, ждать или уж точно всё? Как Вы это узнаёте? Если Вы этого не знаете, то Ваш вопрос ни о чём.

adruha
Offline
Зарегистрирован: 21.05.2013

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

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

adruha пишет:

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

если вы немного подумаете - то поймете, что подсказали вам верно. Способа, как узнать. что байт в посылке будет 6, или 7, или вообще 22 - в общем случае не существует. Необходимо либо ЗНАТЬ ЭТО ЗАРАНЕЕ (например, из описания протокола) - либо вставлять в приходящие данные особые маркеры. указывающие на начало порции байт и на ее длину.

А без всего этого ваш вопрос ни о чем.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

adruha пишет:

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

Какие у вас ассоциации от слов "заголовок" , "хвост"?

Экзамен.
Преподаватель спрашивает:
- Так...... вопрос на 5. Как меня зовут?
Все молчат.
- Ну хорошо....... вопрос на 4. Какого цвета учебник?
Все молчат.
- Ну ладно..... вопрос на 3. Ну какой предмет вы сейчас сдаете?
Один из учеников:"Ну ахренеть как препад валит!"

 

adruha
Offline
Зарегистрирован: 21.05.2013

b707 пишет:

adruha пишет:

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

если вы немного подумаете - то поймете, что подсказали вам верно. Способа, как узнать. что байт в посылке будет 6, или 7, или вообще 22 - в общем случае не существует. Необходимо либо ЗНАТЬ ЭТО ЗАРАНЕЕ (например, из описания протокола) - либо вставлять в приходящие данные особые маркеры. указывающие на начало порции байт и на ее длину.

А без всего этого ваш вопрос ни о чем.

вот то что приходит

01 04 03 03 00 00 00 4E 
01 03 01 00 F0 48 
01 03 01 00 F0 48 
01 05 02 06 C8 BA FA 
01 05 02 06 C8 BA FA
01 03 01 02 71 89 
01 03 01 00 F0 48
01 04 01 03 01 88 
01 04 03 03 00 98 01 E4 
01 04 01 03 01 88 
01 04 03 03 01 F3 41 9B 
01 04 01 03 01 88 
01 04 03 03 01 F3 41 9B 
01 04 01 03 01 88 
01 04 03 03 01 F3 41 9B 
01 04 01 03 01 88 
01 04 03 03 01 F3 41 9B
 
b707
Offline
Зарегистрирован: 26.05.2017

qwone пишет:

Экзамен.
Преподаватель спрашивает:

ну да, у нас было другое окончание:

Вопрос на 3...

Один из студентов. вставая: "пошли, ребята, халява не прошла!"

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

adruha пишет:

вот то что приходит

01 04 03 03 00 00 00 4E 
01 03 01 00 F0 48 
01 03 01 00 F0 48 
01 05 02 06 C8 BA FA 
01 05 02 06 C8 BA FA
01 03 01 02 71 89 
01 03 01 00 F0 48
01 04 01 03 01 88 
01 04 03 03 00 98 01 E4 
01 04 01 03 01 88 
01 04 03 03 01 F3 41 9B 
01 04 01 03 01 88 
01 04 03 03 01 F3 41 9B 
01 04 01 03 01 88 
01 04 03 03 01 F3 41 9B 
01 04 01 03 01 88 
01 04 03 03 01 F3 41 9B
 

Ну вот. здесь же все просто.

Видно, что пакеты начинающиеся с

01 04 03 - имеют длину 8 байт

01 04 01 и 01 03 01 - длина 6 байт

01 05 02 - длина 7 байт

По этим пакетам формула длины пакета  равна "третий байт + 5". Вопрос только. выполняется ли это правило для всех пакетов.

 

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

adruha пишет:

 

вот то что приходит

01 04 03 03 00 00 00 4E 
01 03 01 00 F0 48
 

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

adruha
Offline
Зарегистрирован: 21.05.2013

не, иногда падает и вот такое

01 04 01 03 01 88

01 04 01 03 01 88

01 04 01 03 01 88

01 03 01 00 f0 48

01 03 01 00 f0 48

01 04 01 03 01 88

01 04 01 03 01 88

01 05 02 00 4c b9 39

01 05 02 00 4c b9 39

01 03 01 02 71 89

01 03 01 02 71 89

01 04 01 03 01 88

adruha
Offline
Зарегистрирован: 21.05.2013

дык я бы с удовольствием взял бы это описание если бы было и голову не ломал. нет его

sadman41
Онлайн
Зарегистрирован: 19.10.2016

А чего тогда остальным голову ломаете? Нет описания, не понимаете как пакет формируется - забудьте про задачу и водку пейте.

AlexanderNO
Offline
Зарегистрирован: 08.11.2018

3-й байт: 01 - 6, 02 - 7, 03 - 8...

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

http://www.cnc-club.ru/forum/viewtopic.php?f=42&p=142995  Может это поможет отцу российской демократии.

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

adruha пишет:

не, иногда падает и вот такое

01 04 01 03 01 88

01 04 01 03 01 88

01 04 01 03 01 88

01 03 01 00 f0 48

01 03 01 00 f0 48

01 04 01 03 01 88

01 04 01 03 01 88

01 05 02 00 4c b9 39

01 05 02 00 4c b9 39

01 03 01 02 71 89

01 03 01 02 71 89

01 04 01 03 01 88

И в чём проблема? Правило  "третий байт + 5" действует

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

adruha пишет:

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

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

adruha
Offline
Зарегистрирован: 21.05.2013

может где есть кусок кода что бы велосипед не строить как организовать проверку первых трех четырех с последующим чтением +6 меньше или больше в зависимости от первых трех четырех?

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

Боюсь, что самому придется. А чего там, читаешь первые 5 (они явно какая-то заголовочная структура), а потом дочитываешь столько, сколько написано в третьем байте. Какой тут ещё готовый код, о чём вообще?

Только меня терзает вопрос, если Вы не знаете структуры этих данных и что в них где находится, нафига их Вам вообще читать? Ну, прочитаете, и что Вы с ними будете делать, не зная, что они означают?

adruha
Offline
Зарегистрирован: 21.05.2013

Ладно вроде разобрался, всем спасибо за ответы и мысли. 

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

adruha пишет:

может где есть кусок кода что бы велосипед не строить как организовать проверку первых трех четырех с последующим чтением +6 меньше или больше в зависимости от первых трех четырех?

да в вашем собственном коде (если он ваш :) - и есть такой пример. Вот вы там читаете 6 байт пакета - остановитесь на третьем, прочитайте его и прибавьте к его значению 2 - получите число байт, которые еще осталось прочитать.

Пытайтесь думать сами, задачка-то простейшая

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

мне не понятно зачем два буфера причем разных типов ?

int in_buffer[8]; // receiving buffer
byte recdata[8];

 

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

xDriver пишет:

мне не понятно зачем два буфера причем разных типов ?

int in_buffer[8]; // receiving buffer
byte recdata[8];

 

да нет смысла спрашивать - наверняка код найден ТС в инете

Алексей.
Алексей. аватар
Offline
Зарегистрирован: 02.02.2018

На модбас похож.
1-й байт для однобайтной адресации - адрес слейва, 2-й байт код функции (команда), 3-й длина данных, за ним данные и в конце crc16 модбаса
немножко проверил crc вроде всё совпало.

#include <stdio.h>

unsigned short crc16(const unsigned char* data, size_t size) {
	unsigned short result = 0xFFFF;
	while (size--) {
		// the debug output
		printf("%02X ", *data);
		//////////////////
		result ^= *data++;
		for (int n = 0; n < 8; n++) {
			if (result & 1) {
				result = (result >> 1) ^ 0xA001;
			} else {
				result = result >> 1;
			}
		}
	}
	// the debug output
	printf("%02X %02X\n", result & 0xff, (result >> 8) & 0xff);
	//////////////////
	return result;
}

int main() {
							// 01 04 03 03 00 00 00 4E
	unsigned char data01[] = {0x01, 0x04, 0x03, 0x03, 0x00, 0x00};
							// 01 03 01 00 F0 48
	unsigned char data02[] = {0x01, 0x03, 0x01, 0x00};
							// 01 05 02 06 C8 BA FA
	unsigned char data03[] = {0x01, 0x05, 0x02, 0x06, 0xC8};
							// 01 03 01 02 71 89
	unsigned char data04[] = {0x01, 0x03, 0x01, 0x02};
							// 01 03 01 00 F0 48
	unsigned char data05[] = {0x01, 0x03, 0x01, 0x00};
							// 01 04 01 03 01 88
	unsigned char data06[] = {0x01, 0x04, 0x01, 0x03};
							// 01 04 03 03 00 98 01 E4
	unsigned char data07[] = {0x01, 0x04, 0x03, 0x03, 0x00, 0x98};
							// 01 04 03 03 01 F3 41 9B
	unsigned char data08[] = {0x01, 0x04, 0x03, 0x03, 0x01, 0xF3};
							// 01 03 01 00 f0 48
	unsigned char data09[] = {0x01, 0x03, 0x01, 0x00};
							// 01 05 02 00 4c b9 39
	unsigned char data10[] = {0x01, 0x05, 0x02, 0x00, 0x4c};
	crc16(data01, sizeof(data01));
	crc16(data02, sizeof(data02));
	crc16(data03, sizeof(data03));
	crc16(data04, sizeof(data04));
	crc16(data05, sizeof(data05));
	crc16(data06, sizeof(data06));
	crc16(data07, sizeof(data07));
	crc16(data08, sizeof(data08));
	crc16(data09, sizeof(data09));
	crc16(data10, sizeof(data10));
	return 0;
}

вывод:

01 04 03 03 00 00 00 4E
01 03 01 00 F0 48
01 05 02 06 C8 BA FA
01 03 01 02 71 89
01 03 01 00 F0 48
01 04 01 03 01 88
01 04 03 03 00 98 01 E4
01 04 03 03 01 F3 41 9B
01 03 01 00 F0 48
01 05 02 00 4C B9 39

 

adruha
Offline
Зарегистрирован: 21.05.2013

ну конечно это модбас я об этом сразу написал только вроде в модбасе все время 8 байт передается или я ошибаюсь? 

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

я хотел помочь, даже код набросал, но мне опять не понятно ка это 

no_validCard(recdata, null_recUID)

с recdata разбирается не зная размерности ? я бы понял если оно занулялось каждый раз

или она знает правило length = 

recdata[2]+3

???

короче пока не буду ни чего выкладывать...

adruha
Offline
Зарегистрирован: 21.05.2013

да все четко Алексей написал тож отлично подходит. Всем спасибо вопрос закрыт

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

xDriver пишет:

короче пока не буду ни чего выкладывать...

зачем чего-то выкладывать, если человек сам не знает, чего хочет?

 

xDriver
xDriver аватар
Offline
Зарегистрирован: 14.08.2015

adruha пишет:

да все четко Алексей написал тож отлично подходит. Всем спасибо вопрос закрыт

вам это несколько раньше b707 написал.

a5021
Offline
Зарегистрирован: 07.07.2013

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

AlexanderNO
Offline
Зарегистрирован: 08.11.2018

Так то оно так. Но ТС вначале написАл: "чтение данных от драйвера типа модбас но не совсем". Чем запутал и себя и других.