передача массива в порт и подсчёт контрольной суммы
- Войдите на сайт для отправки комментариев
добрый день возникла проблема с передачей данных в последовательный порт из массива с подсчётом контрольной суммы посылки вобщем обясню на примерах
в идеале должно быть так на запрос получаем ответ смотрите ниже
//запросм
01 01 02 02 D0 B9
//ответ
01 01 1D AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA CB 91
на данны момент вожусь с отправкой ответа до сюда все нормально если без контрольной суммы
01 01 1D AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA
контрольная сумма для этой посылки должна быть CB 91
а вот что получается если отправлять с контрольной суммой
01 01 1D AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA CB 00
последний байт контрольной суммы почемуто нулевой а должен быть 91
код
/* termo_atmega328p Version: 1.0.0.0 Release: 16.08.2017 */ //--------------------------------------------------------------------------- // Подключаем библиотеки: #include <Keypad.h> //--------------------------------------------------------------------------- #define MaxLenghtTrBuf 33 //размер буфера передаваемых по UART данных #define Hi(int) (byte) (int>>8) #define Low(int) (byte) (int) #define time_Key_ask 10 // #define USART_USB_RATE 9600 // #define TX_RX_pin 2 //--------------------------------------------------------------------------- byte CRC16; unsigned int Adress = 0; // char key; char Last_Key = 0; unsigned char KpdState = 0; unsigned long msNow = 0; unsigned long time_Key = 0; //--------------------------------------------------------------------------- const byte ROWS = 4; // 4 строки const byte COLS = 4; // 4 столбца char keys[ROWS][COLS] = { {'1','2','3','A',}, {'4','5','6','B',}, {'7','8','9','C',}, {'*','0','#','D' } }; // Строки клавиатуры ROW0, ROW1, ROW2 и ROW3. Подключение к контактам Arduino. byte rowPins[ROWS] = {3, 4, 6, 7};// // Столбцы клавиатуры COL0, COL1, COL2 и COL3. Подключение к контактам Arduino. byte colPins[COLS] = {8, 10, 11, 12};// // Создадим клавиатуру Keypad kpd = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS); //--------------------------------------------------------------------------- void Key_Ask(); unsigned int GetCRC16(byte *buf, byte bufsize); //--------------------------------------------------------------------------- byte cmTrBuf1[MaxLenghtTrBuf]; //буфер передаваемых данных //массивы для быстрого расчета кода CRC-16 byte srCRCHi[256]={ 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 }; byte srCRCLo[256]={ 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40 }; //--------------------------------------------------------------------------- void Key_Ask() { time_Key = millis() + time_Key_ask; key = kpd.getKey(); if(key) Last_Key = key; // тоже самое что if(key != NO_KEY) KpdState = kpd.getState(); if(2 == kpd.getState()) Last_Key = 'N'; switch (key) { case 'D': Adress = 1; Last_Key = 'N'; break; //ВЫБОР } if(Adress != 0) //если адрес подвески < 0 тогда отправляем запрос в порт. { byte calculated_crc=0; byte n=0; //Отправка температуры digitalWrite(TX_RX_pin, HIGH); //включаем передачу по rs485 cmTrBuf1[0]=Adress;//системный номер устройсва cmTrBuf1[1]=0x01;//команда (Чтение данных измерения) чтение температуры cmTrBuf1[2]=0x1D;//количесво байт данных cmTrBuf1[3]=0xAA;//данные температуры cmTrBuf1[4]=0xAA;//данные температуры cmTrBuf1[5]=0xAA;//данные температуры cmTrBuf1[6]=0xAA;//данные температуры cmTrBuf1[7]=0xAA;//данные температуры cmTrBuf1[8]=0xAA;//данные температуры cmTrBuf1[9]=0xAA;//данные температуры cmTrBuf1[10]=0xAA;//данные температуры cmTrBuf1[11]=0xAA;//данные температуры cmTrBuf1[12]=0xAA;//данные температуры cmTrBuf1[13]=0xAA;//данные температуры cmTrBuf1[14]=0xAA;//данные температуры cmTrBuf1[15]=0xAA;//данные температуры cmTrBuf1[16]=0xAA;//данные температуры cmTrBuf1[17]=0xAA;//данные температуры cmTrBuf1[18]=0xAA;//данные температуры cmTrBuf1[19]=0xAA;//данные температуры cmTrBuf1[20]=0xAA;//данные температуры cmTrBuf1[21]=0xAA;//данные температуры cmTrBuf1[22]=0xAA;//данные температуры cmTrBuf1[23]=0xAA;//данные температуры cmTrBuf1[24]=0xAA;//данные температуры cmTrBuf1[25]=0xAA;//данные температуры cmTrBuf1[26]=0xAA;//данные температуры cmTrBuf1[27]=0xAA;//данные температуры cmTrBuf1[28]=0xAA;//данные температуры cmTrBuf1[29]=0xAA;//данные температуры cmTrBuf1[30]=0xAA;//данные температуры n = cmTrBuf1[2];//количесво байт данных n = n + 2;//кол-во передаваемых байт без CRC calculated_crc = GetCRC16(cmTrBuf1, n);//подсчет КС посылки cmTrBuf1[n++] = Low(calculated_crc);//Контрольная сумма младший байт cmTrBuf1[n++] = Hi(calculated_crc); //Контрольная сумма старший байт for (int j = 0; j < n; j++)//В цикле выводим данные в порт { Serial.write(cmTrBuf1[j]); } delay(50);//время для передачи посылки digitalWrite(TX_RX_pin, LOW); //включаем приём по rs485 Adress = 0; } } //----------------------------------------------------------------- //функция вычисляет код CRC-16 на входе указатель на начало //буфера и количество байт сообщения (без принятого кода CRC-16) unsigned int GetCRC16(byte *buf, byte bufsize) { byte CRC_Low = 0xFF; byte CRC_High = 0xFF; byte k; byte carry; for (k = 0; k < bufsize; k++) { carry = CRC_Low ^ buf[k]; CRC_Low = CRC_High ^ srCRCHi[carry]; CRC_High = srCRCLo[carry]; }; return((CRC_High << 8)|CRC_Low); }//end GetCRC16() //********************************************************** void setup() { pinMode(TX_RX_pin, OUTPUT); // ножка управления режимом RX/TX RS485 Serial.begin(USART_USB_RATE, SERIAL_8E1);//инициализация UART kpd.setHoldTime (20); // kpd.setDebounceTime (10); // задержка от дребезга } //--------------------------------------------------------------------------- void loop() { msNow = millis(); if (time_Key < msNow) Key_Ask();//циклический опрос клавиатуры по времени } //---------------------------------------------------------------------------
так как мне неудалось добится нормальной работы от преведущего варианта кода попроюовал заменить функцию вычесления контрольной суммы на другую вот что из этого получилось, работает стабильно мусора в порт неотправляет.
В порт шлёт 01 01 1D AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA CB 91
то что и должно было слать. Так и непонял почему неработает табличная функция вычисления контрольной суммы она быстрее должна работать.