MementoMori
Свой-
Постов
1 340 -
Зарегистрирован
-
Посещение
Весь контент MementoMori
-
Не хочу с вами спорить, но мне, с учетом моей задачи, с учетом того, что я все же любитель и некоторые вещи мне нужно, не поверите, осваивать с нуля, с учетом того, что к маю мне бы эту поделку хотелось бы уже эксплуатировать, мне проще сделать следующим образом - взять мой же старый, доказавший свою надежность, проект, в котором обмен осуществлялся текстовыми строками, переделать его с работы со строками на работу со структурами. Это уже получилось. Осталось проработать обработку ошибок и автоматическое восстановление после разрыва связи.
-
Ну зачем ярлычки вешаете? Я тоже повешу свой ярлычок - MODBUS - это стрельба из пушки по воробью (коим является моя задача).
-
А мое устройство молчаливо, говорит только тогда, когда его спрашивают, отвечает строго по уставу и затыкается, пока снова не спросят. Но за замечание спасибо - надо будет перед отправкой запроса предварительно очистить буфер приема.
-
Слишком лестно в мой адрес. Я любитель) В миру же я врач) А железки, байты, транзисторы - это моя вторая натура, ничего с этим не поделаешь) И ведь как тяжело в возрасте после 40-ка вникать в то, что пропустил по молодости. Всякому обучению свое время. Стряхнул пыль с учебников по С++. Блин, я наивно полагал, что если значение указателя это адрес, то и работать с ним можно как с адресом. А оказывается ptr++ увеличивает не на 1 байт, а на размер структуры, на которую ссылается указатель. Удивительное рядом. В итоге работающее решение такое: pAnswerInfo = (tINFO_VAR *)((char*)pAnswerInfo+FData.Length); Я правильно понял суть проблемы и ее решения? Или это случай, когда неверными расчетами случайно пришел к правильному ответу?
-
Подумал, разобрался, оптимизировал прием, все хорошо. До 10 пакетов в 200 байт туда и обратно за одну секунду. Идем дальше, получаем проблемы с извлечением принятых данных. tINFO_VAR ANSWER_INFO_VAR; tINFO_VAR * pAnswerInfo; pAnswerInfo=&ANSWER_INFO_VAR; len_rx=0; while(len_rx<sizeof(ANSWER_INFO_VAR)) // гоняем цикл пока не прочитаем всю структуру { FData=Socket->ReceiveData(100); // получаем то, что есть в буфере на текухий момент. len_rx+=FData.Length;// увеличиваем счетчик прочитанных байт memcpy(pAnswerInfo,FData.data(),FData.Length); //копируем то, что есть, в ANSWER_INFO_WAR pAnswerInfo+=FData.Length; //смещаем указатель на число прочитанных байт } Указанный код запускается по таймеру раз в 50 мсек. При этом в начале кода таймер останавливается и вновь запускается в конце. То есть код запускается раз в 50 мсек, но выполняться может столько сколько нужно. Принцип работы не мной написанной библиотеки таков - нельзя узнать сколько в буфере приема байт, нельзя просто дождаться, пока 200 байт накапает. Нужно читать FData=Socket->ReceiveData(100). А когда данные прочел, содержимое буфера стирается. То есть, повторюсь, нельзя дождаться всей посылки и прочесть ее разом. Читаем кусками и склеиваем. Получается 9-10 кусков, в зависимости от того, в какой момент приема сработает таймер Так вот, первые 15-25 байт (видимо длина первой посылки) читаются нормально. В остальных нули. В процессе работы почти все эти байты заполняются верными данными. Но не все и не сразу. Где собака порылась? Добавлено спустя 10 минут: Собака порылась кажется здесь: pAnswerInfo+=FData.Length; Эта команда дает прирост адреса указателя на 4000. Хотя должна приращивать на 15-25 байт Вот строка для отладки Form1->Memo1->Lines->Add(IntToHex((__int32)pAnswerInfo)+" и "+IntToStr(FData.Length))+" байт"); Она выдает следующее То есть "pAnswerInfo+20" это то же самое, что "адрес pAnswerInfo+4000"
-
Сопряжение с устройством BLE
MementoMori ответил MementoMori тема в В помощь начинающему
Скажите а софт для работы на чем писали? Я имею в виду не для модуля HM-13, а для приложения на телефоне? Мне бы проконсультироваться и на этот счет. -
Потихоньку ковыряю дальше. Выровнял структуру, из 224 байт сэкономил 24. Теперь структура весит 200 байт. Решил поиграть в "эхо" - передаю данные и принимаю их же обратно. Передаю на скорости 115200 бод. Казалось бы, около 10 кбайт в секунду. Цикл следующий - отправка 200 байт с телефона -> прием блютузом -> передача на контроллер -> передача из контроллера в блютуз -> прием в телефоне. Процесс занимает около 1 секунды. Так и должно быть? В скорости передачи собственно байт сомневаться не приходится. Так может быть начало и конец приема и передачи накладывают какие-то задержки? В контроллере модуль HM-13, если что.
-
Момент на валу
MementoMori ответил MementoMori тема в В помощь начинающему
На кошерных шлагбаумах демпфер внизу стоит. Понятно, что он не защищает полностью, но все же. -
Вы правы, был невнимателен, не везде удалил указатели. Поправил - все работает, без new. У меня размер буфера маленький (я сейчас набросал в максимально близком к конечному виде, получилось 224), разницы, естественно, незаметно, но, верю вам, что так лучше.
-
Матом ругается. По-русски причем. А если серьезно, я, опять таки, писал об этом ранее. [bccaarm Error] Unit1.cpp(253): no viable conversion from 'TArray__1<System::Byte> *' (aka 'System::DynamicArray<unsigned char> *') to 'System::TArray__1<System::Byte>' (aka 'System::DynamicArray<unsigned char>')
-
Блин, да в C++ Builder я программирую. И в библиотеках для написания программ под Андроид дух Явы таки имеет место быть, ибо в созданном проекте есть такая строка #include <AndroidApi.JNI.JavaTypes.hpp>
-
Возможно после компиляции он и мог бы работать быстрее. Но компилятор протестует. Г В примере кода для bluetooth от разработчика очень много чего объявляется через new
-
Я писал выше: Опять же, выше я уже написал, что понял это и исправил, все работает. Знаю я про упаковку, я не знаю пока какой окончательный вид будет иметь структура. А узнаю я это в процессе разработки, в процессе испытания устройства, а для этого нужно погонять данные. А это тоже нужно организовать, лоск наведу потом.
-
Делается под конкретную платформу. Для себя, если быть точным. Но намек ясен, будут предложения по унификации, с целью платформонезависимости? Где у меня слабое место?
-
ВОТ ОНО!!!!!! Вот те самые золотые слова, которые толкнули меня в правильном направлении!!! Есть у TArray__1<System::Byte> операция, которая превращает этот массив в массив unsigned char ! Вот как надо было обращаться к массиву: buffer->data() memcpy(buffer->data(),pInfo,sizeof(INFO_VAR)); Итак, передача: typedef struct { unsigned int TimePosition; unsigned char WORK_STATE; unsigned char POWER_REGULATION_MODE; }tINFO_VAR; tINFO_VAR INFO_VAR; .................................. INFO_VAR.TimePosition=0xCCDD; INFO_VAR.POWER_REGULATION_MODE=0xAA; INFO_VAR.WORK_STATE=0xBB; tINFO_VAR * pInfo; pInfo=&INFO_VAR; ................... TArray__1<System::Byte> * buffer = new TArray__1<System::Byte>; buffer->set_length(sizeof(INFO_VAR)); memcpy(buffer->data(),pInfo,sizeof(INFO_VAR)); Socket->SendData(*buffer); delete buffer; прием tINFO_VAR * pInfo; ..... pInfo=&INFO_VAR; usart_buf[usart_bit++] = received_byte; // прием последнего байта memcpy(pInfo,usart_buf,sizeof(INFO_VAR));
-
Ну дык вот, делал уже tINFO_VAR INFO_VAR; tINFO_VAR * pInfo; pInfo=&INFO_VAR; TArray__1<System::Byte> * buffer = new TArray__1<System::Byte>; buffer->set_length(8); memcpy(buffer,pInfo,sizeof(INFO_VAR); Не ругается при компиляции, но ловит какую-то ошибку при работе приложения во время memcpy
-
Да зачем в текст? Я ж писал выше: TArray__1<System::Byte> * buffer = new TArray__1<System::Byte>; buffer->set_length(6); (*buffer)[0] = INFO_VAR.POWER_REGULATION_MODE; (*buffer)[1] = INFO_VAR.WORK_STATE; (*buffer)[2] = INFO_VAR.TimePosition & 0xFF; (*buffer)[3] = INFO_VAR.TimePosition >> 8; (*buffer)[4] = 0xEE; (*buffer)[5] = 0x0D; Socket->SendData(*buffer); delete buffer; Буфер с байтами передается без проблем, преобразование в текст не требуется. Разбирать и собирать можно байты. Я бы уже давно всю структуру (она у меня сложнее, тут я сократил ее с целью облегчения восприятия) таким же образом заполнил, но я хочу понять, как это делается проще, через указатели.
-
Ну может вы прекратите уже спорить? Я тему создал не для выяснения отношений.
-
Вот: (*buffer)[0] = 0xAA; (*buffer)[1] = 0xBB; (*buffer)[2] = 0xCC; (*buffer)[3] = 0xDD; (*buffer)[4] = 0xEE; (*buffer)[5] = 0x0D; И программа это проглотила, и железо передало, а другое железо приняло. Может все таки на вопрос ответите? typedef union { struct data { unsigned int TimePosition; unsigned char WORK_STATE; unsigned char POWER_REGULATION_MODE; }; unsigned char buffer[sizeof(struct data)]; }tINFO_VAR; Хорошо, сделал я так, потом объявил переменную И как тогда обращаться к TimePosition? И как это копировать в buffer, который объявлен в TArray__1<System::Byte> * buffer = new TArray__1<System::Byte>; ?
-
Как на Ваш взгляд, байт - это бинарное, на текст не похожее?
-
Новый вопрос. Есть буфер, объявленный следующим образом TArray__1<System::Byte> * buffer = new TArray__1<System::Byte>; Сразу скажу тем, кто будет предлагать альтернативу - буфер должен быть объявлен так и только так, этого требует библиотека под Андроид, работающая с Bluetooth. Заполнил буфер классически, для эксперимента buffer->set_length(6); (*buffer)[0] = 'r'; (*buffer)[1] = 'e'; (*buffer)[2] = 's'; (*buffer)[3] = 'e'; (*buffer)[4] = 't'; (*buffer)[5] = 0x0D; Работает, ура, микроконтроллер принимает строку "reset" Но, идем дальше, вот структура typedef struct { unsigned int TimePosition; unsigned char WORK_STATE; unsigned char POWER_REGULATION_MODE; } tINFO_VAR; tINFO_VAR INFO_VAR; Как ее скопировать в buffer? Выделить из структуры каждую переменную, разобрать на байты и записать побайтово буфер я могу, но хочется поизящнее. Если пробовать в лоб - buffer=&INFO_VAR -ругается на несоответствие типов.
-
Сопряжение с устройством BLE
MementoMori опубликовал тема в В помощь начинающему
Друзья, есть у меня модуль HM-13 , в нем 2 блютусины сразу, одна обычная, другая BLE С обычной сопряжение (штатными средствами телефона) происходит без проблем, спрашивается PIN, вводится и устройство сопряжено). А вот при обнаружении устройства BLE телефон мне предлагает "Перейдите в приложение с этого устройства, чтобы сопрячь с ним). А "это устройство" - напомню, это модуль, ни с каким приложением он не работает. Может есть какие команды настройки, позволяющие автоматически сопрягать? Чтение даташита https://files.seeedstudio.com/wiki/Grove-BLE-dual_model-v1.0/res/Bluetooth_HM-13_en.pdf ничего не дало. -
Получилось: if(__HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE) != RESET ) //Judging whether it is idle interruption { __HAL_UART_CLEAR_IDLEFLAG(&huart2); //Clear idle interrupt sign (otherwise it will continue to enter interrupt) }
-
Друзья, ваш спор перешел в разряд "с какого конца разбивать яйцо, с острого или тупого". Я решение выбрал, призываю вас не спорить. У меня следующий вопрос. А как бы мне передать структуру по UART? Точнее, как передать, я представляю, беру указатель и по указателю передаю количество байт равное размеру структуры. Что-то вроде этого: void USART_Transmit_block( void *ptr, size_t size) { uint8_t *p = (uint8_t*)ptr; while(size--) USART_Transmit( *p++); } ... USART_Transmit_block((unsigned char*) &TX_Data, sizeof(TX_Data) ); А вот как быть с приемом? Там ведь как - если приходит 0x00, то это считается концом строки. А если в структуре есть байт 0x00? Как быть? Как синхронизировать начало посылки? У меня есть самопальный рабочий пример с передачей текстовых команд - в буфер принимаются байты, пока один из них не равен 0x0D. Как только этот байт ловится, читается все что принято после предыдущего байта 0x0D и это считается текстовой командой. Там сложностей не возникало. А вот со структурами как быть? Там ведь уже не используешь символы конца строки, ибо символы с этим кодом могут быть в структуре.
-
Уже так и сделал. Как это обычно бывает - долго бьешься над проблемой, но как только задашь вопрос на форуме, еще до того как кто-то ответит, решение приходит само собой. Так у меня эта переменная только в main.c и stm32f1xx_it.c используется. Проектик маленький, из-за 3-х функций еще какой-то файл создавать я не стал. А вообще так и делаю - отделяю функционал от распределения.