Форум программистов, компьютерный форум, киберфорум
Simulink
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.58/131: Рейтинг темы: голосов - 131, средняя оценка - 4.58
 Аватар для Алексей89
34 / 34 / 4
Регистрация: 19.02.2013
Сообщений: 118
21.02.2016, 11:16
Студворк — интернет-сервис помощи студентам
Попробовал:
если использовать
Matlab M
1
Data=double(fscanf(RS));
(прямо в строке чтения), то получается точно то же самое.
Если пробовать
Matlab M
1
[Data,Cnts]=double(fscanf(RS));
То не возвращается ни Data ни Cnts, без каких-либо дополнительных предупреждений.

Я всё-таки решил пойти по пути использования только рабочих бит.
Т.е. АЦП выдаёт 10-битные значения (всё равно не меньше 2-х байт), а если использовать только средние 6 бит в каждом байте, то этого всё равно хватает.
Таким образом, в каждом передаваемом байте первый бит всегда 1, а последний всегда 0.
Тестовый код такой:
Matlab M
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function [  ] = COMRspnd(  )
RS = serial('COM3','Baudrate',9600,'Parity','none','DataBits',8,'StopBits',1,'FlowControl', 'none','InputBufferSize',2048,'Terminator','LF'); %Инициализация COM-порта
fopen(RS);  %Открытие потока
try     %Обработчик исключений
  RS.Timeout=5;
  for adcU=0:1023
    LDgt=uint8(1+rem(adcU,64).*2);
    HDgt=uint8(1+fix(adcU./64).*2);
    fwrite(RS,LDgt);
    fwrite(RS,HDgt);
  end
  [Data, Cnts]=fscanf(RS);
catch err   %Обработка возможных ошибок
    disp('Некорректные данные - проверьте соединение');    
end
fclose(RS); %Закрытие потока
for i=1:1024
  LDgt=Data(2*i-1);
  HDgt=Data(2*i);
  Res(i)=double((LDgt-1)./2+32.*(HDgt-1));
end
end
всё работает правильно, осталось только перенести цикл "кодирования" на контроллер.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
21.02.2016, 11:16
Ответы с готовыми решениями:

Чтение из COM порта, При чтении из порта зависает read()
Каждому рано или поздно приходится программировать com порт. Вот и мой черед пришол. Я ужу умею: Откривать,закривать, писать. а читать не...

Чтение COM - порта
Здравствуйте. Опишу для начала свой проект. У меня есть устройство АКИП. Я пишу программу для дистанционной работы с ним. Все хорошо,...

Чтение из COM-порта
Здравствуйте! Никак не могу правильно прочитать данные из COM-порта. Мой процессор отправляет в компорт в бесконечном цикле (каждые...

74
370 / 133 / 44
Регистрация: 05.02.2015
Сообщений: 901
06.06.2016, 15:22  [ТС]
Скажите, а как вы в matlab ответ из байт собираете? ну вот допустим:
Matlab M
1
2
3
4
5
6
m =48     4     0    22     0     2   148    46 % формируем строку запроса
s = serial ('COM4'); 
fopen(s); 
fwrite(s,m);
c = fread(s);
c =48     4     4    65   214    42    56    48    49
отсюда нас интересует вектор: 65 214 42 56. как определить какому числу он принадлежит? кстати, я хоть и спросил про вещественные, но тот же вопрос и про целые.
0
 Аватар для Алексей89
34 / 34 / 4
Регистрация: 19.02.2013
Сообщений: 118
06.06.2016, 16:11
Честно говоря, не совсем врубился что именно надо сделать,
В моём случае, я знаю которые байты служебные и просто их удаляю из массива.
Т.е. в Вашем случае, если служебные байты с 1 по 3 и два последних, то можно сделать так.
Matlab M
1
2
с(1:3)=[];
c(end-1:end)=[];
0
370 / 133 / 44
Регистрация: 05.02.2015
Сообщений: 901
06.06.2016, 16:20  [ТС]
Это-то можно проще:
Matlab M
1
2
3
c =fread(s);
d = c(3:7);
% и далее работаем с d.
я вот что спрашивал: я получил интересующие байты, а как из них одно число сделать? ну например, интересующие байты [1 2 3 4], а какое число прибор передал? как их интерпретировать? хотелось
0
 Аватар для Алексей89
34 / 34 / 4
Регистрация: 19.02.2013
Сообщений: 118
06.06.2016, 16:34
Ну есть наверное и более правильный способ, но я делаю топорно.
В одном байте 8 бит. Каждый байт можно считать разрядом в числе. Тогда вес разряда =2^8*номер разряда (считая с 0).
Например:
Matlab M
1
2
3
4
5
a=[ 3 2 7 25] %входной вектор
Res=0;          %Число - результат
for i=1:size(a,2)
  Res=Res+a(i)*256^(i-1);
end
Т.е. по всем итерациям
Res=3+2*256+7*256^2+25*256^3
1
370 / 133 / 44
Регистрация: 05.02.2015
Сообщений: 901
06.06.2016, 20:00  [ТС]
Спасибо, попробую. А этот метод будет работать, если число с плавающей точкой или оно только для целых чисел годится? просто пока не уловил суть.

Добавлено через 19 минут
воспользовался вашим кодом и вашим же входным вектором. и вот какое число у меня получилось: 419889667. разве может хоть 1 прибор выдать такой результат? что-то тут не так...
0
 Аватар для Алексей89
34 / 34 / 4
Регистрация: 19.02.2013
Сообщений: 118
06.06.2016, 20:31
Этот метод годится для натуральных чисел.
С плавающей точкой числа в памяти компьютера записаны тоже при помощи целых.
Это установлено международным стандартом.

Почти все приборы выдают свои числа посимвольно (1 байт = 1 цифра в ANSII кодировке).
Я пошёл по собственной кодировке, чтобы сократить время передачи каждого сэмпла с АЦП. Я смог так сделать потому что и прибор сам прошивал.

Кроме того в матлабе есть один баг - когда по ком-порту приходит байт из одних нулей он не отображается вообще никак. В таблице ansii это символ null, нет соответствующей буквы - символьный буфер не увеличивается, как следствие, принятым байт числится, а в принятых данных его просто нет.

Поэтому настоятельно рекомендую использовать стандартную кодировку.
попробуй считывать так:
Matlab M
1
[Data, Cnts]=fscanf(port,'%d');
0
370 / 133 / 44
Регистрация: 05.02.2015
Сообщений: 901
07.06.2016, 11:01  [ТС]
Нет, так не пойдет. во втором входном параметре получил 9 (количество прочитанных байт), в первом - 0. в любом случае так читать нельзя, потому что, во-первых, matlab не знает, какие байты нам нужны, а какие нет, во-вторых, на хранение мантиссы и порядка в matlab отводится 8 байт, и опять же matlab не знает , где ставить точку. есть идея попробовать побайтово перевести ответ в двоичный вид, далее из всех байтов сформировать одну строку, и перевести обратно в десятичное число. буду пробовать.
0
 Аватар для Алексей89
34 / 34 / 4
Регистрация: 19.02.2013
Сообщений: 118
07.06.2016, 11:31
м.б. давайте лучше плясать от того - что у вас за прибор.

Если смотреть хэлпик, то ключ %s интерпретирует полученные данные "как серии символов пока не найдёт пустое пространство", т.е пробел.
Есть ключи для Floating-point number, чтобы попробовать их, у меня под рукой сейчас нет ком порта.
Во всяком случае, я уверен, что то что вы хотите сделать - уже реализовано в матлабе.
И надо бы знать наверняка в каком формате ваш прибор шлёт данные, и можно ли (и стоит ли) этот формат изменять.

Если хочешь поэкспериментировать с форматом данных, так чтобы самому выбирать что придёт на вход, можно замкнуть 2-ю и 3-ю ноги ком-порта (советую резистором в 20 кОм, но я пробовал просто отвёрткой - и ничего не сжёг).
Так во входной буфер будет поступать всё в точности то, что ты сам отошлёшь с ком-порта.

А да, и можешь быть уверен, что базовые типы данных в матлабе абсолютно точно такие же как и на С или джаве, ли где угодно. И определены они тем документов что есть в статье по ссылке.
1
370 / 133 / 44
Регистрация: 05.02.2015
Сообщений: 901
07.06.2016, 18:58  [ТС]
Еще раз здравствуйте. у меня несколько приборов, названия, думаю, ничего не скажут, но попробую по сути. 1 из них аналоговый, т.е. работает через ацп (газоанализатор). так вот, с него я считываю 1 регистр (вход ацп) я знаю, что ацп передает только положительные числа. соответственно нужных мне 2 байта. далее младший байт я беру как он пришел и прибавляю к нему старший байт, домноженный на 2 в степени 8 или 256. получаю требуемое число. кстати, все считываю через fread. все в порядке. далее у меня есть цифровые термометр (ттрм 138) он выдает ответ вещественным числом (в градусах с десятыми). так вот и хотелось бы обработать также, как обрабатывал прибор, с которого нужно было считать целые значения. но тут есть несколько подводных камней. как представляется вещественное число в matlab? насколько я знаю, на тип double отводится 8 байт. значит, чтобы корректно обработать поступившее число, мне его нужно допполнить четырьмя байтами справа? и умножать старший байт не на 256^2 а на 256^4? посути и вся задача, как из 4 байт получить вещественное число, при условии, что я знаю, как из 4 байт получить целое.
0
 Аватар для Алексей89
34 / 34 / 4
Регистрация: 19.02.2013
Сообщений: 118
07.06.2016, 22:56
В матлабе есть тип данных и single, полный список типов данных тут.
Есть вероятность, что некоторые встроенные функции (вроде аппроксимации) определены только для double-типа.
Чтобы всё работало, можно сделать приведение типов данных:
double(Data); - возвращает те же данные (что и data(любого типа)), только преобразованные к double

Если посмотреть хэлпик по функции fread(), то там есть третий возможный аргумент precision он определяет способ интерпретации полученных с прибора байт.
Похоже, что тебе достаточно корректно считать данные и сделать приведение типов (если необходимо).
Вдаваться в подробности, вроде того сколько бит под какое поле в double по идее не обязательно.
0
370 / 133 / 44
Регистрация: 05.02.2015
Сообщений: 901
08.06.2016, 09:52  [ТС]
а вот это уже интереснее:
1) допустим я указываю вторым аргументом к fread double, так тогда он мне переведет все число, как объяснить функции fread, что надо обработать с 4 по 7 байт, первые 3 и последние 2 выкинуть.
2. с помощью каких функций можно собрать число? я просто не врубаюсь, что вы имеете ввиду, вот допустим пишу:
Matlab M
1
2
3
a = [1 3 4 6 7]
b = double(a)
b
получаю тот же вектор, а не число, а как число-то получить?
0
 Аватар для Алексей89
34 / 34 / 4
Регистрация: 19.02.2013
Сообщений: 118
08.06.2016, 10:33
Ностальгирую по юности.
Была у меня когда то похожая проблема.
Под итожим. Считать интерпретируя, как float-point нет возможности, т.к. нужно считывать не с четвёртого а с третьего байта. Остаётся один вариант - комбинировать число из байт.
У меня была аналогичная проблема на С++. Для её решения существуют так называемые объединения (union). В коде оно описывается в точности как класс, однако по сути это разные способы трактовки данных записанных в одной памяти. Т.е. если к классу мы обращаемся: MyClass.f1 - получаем доступ к первому полю класса, MyClass.f2 - ко второму полю класса (разная информация). То в объединении можно сделать так. MyUnnn.uint32=7845; res=MyUnnn.single - те же битики что и в uint, только они будут интерпретироваться как single. Byte=MyUnnn.char[2] - второй байт отдельно от остальных в char-интерпретации и.т.д.

Вот только в матлабе union означает совсем другое.
Немного покопавшись нашёл тему с точно таким вопросом, вроде бы там дали ответ.
В худшем случае придётся разбираться в джаве.
1
370 / 133 / 44
Регистрация: 05.02.2015
Сообщений: 901
08.06.2016, 13:04  [ТС]
или читать 2 раза, например:
Matlab M
1
2
a = fread(s, 3) %считываем служебные байты
b =fread(s, 4, 'single') % считываем интересующие байты.
только вот долго все это( выполняться будет медленно.

Добавлено через 51 минуту
нет, через single тоже не работает. выдает какоето очень неправильное число в -7 степени. вообщем, проблема осталась. как из байтов 65
216
4
40 получить число 26.3?

Добавлено через 1 час 21 минуту
Ну хорошо, а подскажите, есть ли какой-либо способ считать с компорта то, что пришло в двоичном или 16-ричном формате? я просто вроде нашел проблему, но без исходных (не приведенных) тьипов ее не решить. все-таки matlab до java и C++ не дотягивает.
0
 Аватар для Алексей89
34 / 34 / 4
Регистрация: 19.02.2013
Сообщений: 118
08.06.2016, 14:32
можно преобразовать твои целочисленные uint8 значения при помощи
dec2bin()
dec2hex()
но они возвращают текстовые строки
0
370 / 133 / 44
Регистрация: 05.02.2015
Сообщений: 901
08.06.2016, 14:46  [ТС]
не пойдет. мне нужны коды, изначально приходящие на компорт. ведь это уже сам matlab преобразует их в 10 - ричный формат. и преобразует неправильно, применяя функцию hex2dec вместо hex2num.
0
 Аватар для Алексей89
34 / 34 / 4
Регистрация: 19.02.2013
Сообщений: 118
08.06.2016, 15:45
Мне кажется, что если бы матлаб преобразовывал некорректно, не работало бы ничего ни у кого, а так, по крайней мере цифры из матлаба и из других терминальных прог совпадают.
Про Ваш термометр написано, что он использует протокол ОВЕН, Modbus ASCII/RTU
Вот модбас, вот овен.
На сколько я понял, у каждого есть несколько режимов, но везде такой принцип, что один байт информации кодируется двумя ASCII символами.
Сама таблица ASCII вот.

Для того чтобы такое правило выполнялось коды должны быть в пределах 0x30-0x39 (48-57-й символ) для цифр 0-9;
и 0x41-0x46 (65-70-й) символ для букв A-F.
Можно было бы попробовать по отображать и по инвертировать получаемые коды, но они все должны быть меньше 127 (или все больше). Так что, что делать с вашими циферками, пока не понятно.

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

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

Вот, возможно тут что-то найдёшь.
0
370 / 133 / 44
Регистрация: 05.02.2015
Сообщений: 901
08.06.2016, 17:03  [ТС]
Большое спасибо за желание помочь. Маленькая поправочка: когда я говорю, что matlab некорректно переводит из 16-ричной системы, я имею ввиду дробные числа. ему ничего не известно о данных, которые приходят на компорт, и он все воспринимает как целочисленные. если не верите, поэкспериментируйте так: пусть:
Matlab M
1
2
3
a =1.3
b =num2hex(a) %корректно переведете число
c = hex2dec(b) %число не совпадет с a.
так вот, когда на компорт приходят данные, он их конвертирует с помощью функции hex2dec, как будто пришло целое число. отсюда и пляски с бубном.
вы скорее всего работаете только с целочисленными данными в matlab, поэтому вам с этими плясками сталкиваться не приходилось. кстати, частично я решил свою проблему с помощью комбинаций num2hex и hex2dec, правда погрешность пдо 0.5 градуса из-за округления. на C++ c# java есть свои методы, "собирающие" из байтов число. в матлабе по ходу такого нет.
а modbus протокол я хорошо знаю. почему я это говорю, потому что тестировал с помощью C# и там данные получал корректные.
0
 Аватар для Алексей89
34 / 34 / 4
Регистрация: 19.02.2013
Сообщений: 118
08.06.2016, 19:46
Если в протоколе есть описание сколько бит под степень, знаки и мантиссу (и в каком порядке), могу присоветовать, как собрать байты вручную (на манер того, как с uint).
1
370 / 133 / 44
Регистрация: 05.02.2015
Сообщений: 901
08.06.2016, 20:05  [ТС]
Обязательно расскажите!! это по сути и есть суть моего вопроса как собрать вручную, а документация на протокол и прибор у меня есть ))
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
08.06.2016, 20:05

Чтение из com-порта
Здраствуйте реализовал простенькую програмку по отправке данных на порт теперь же нужно их от туда забрать и вывести на экран #include...

Чтение из COM порта
Приветствую всех! Для чтения из COM порта использую функцию ReadFile. Третьим параметром в данной функции указывается число байт для...

Чтение из com порта
Понять не могу, что происходит. Шлю в ериал порт данные с дискретом в 20 миллисекунд. Скрипт на Руби шикарно читает данные....

Чтение COM порта
Не отсылайте в гугл, я от туда весь день не вылазию.... Помогите разобраться с чтением порта. Нашел TComPort, но не могу его...

Чтение из COM-порта
Ребят помогите глупому Пашке разобраться с багом в программе. Проблема в том, что программа висит во время чтения из Arduino (я знаю, это...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
Baragoz - DPS/HPS бот для WoW 3.3.5a, многоязычный
AmbA 26.10.2026
Хотите ещё ботов? У меня есть один! А я пока отдохну от него. https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=12062&stc=1&d=1793007952 Инструкция внутри. Сразу отвечу: А в PvP с ним. . .
Особенности gif сгенерированных в Си
russiannick 21.10.2026
Рассмотрим генерацию gif файлов, которые в Си имеют свои особенности. Gif представляет собой графический формат популярный в интернете. Посмотрим на палитру. Gif файл сгенерированный в си отличается. . .
FPS контроллер с анимированными Y-Bot и 3D-звуком miniaudio (Box3D, Recast, BehaviorTree.CPP, ozz-animation, ImGui, OpenGL и SDL3)
8Observer8 18.10.2026
Содержание блога | English Version Полное мультиплатформенное руководство по стартовому проекту с FPS-контроллером игрока, анимированными роботами Y-Bot с 4-слойным блендингом, 3D-физикой Box3D,. . .
Локальный http сервер
Argus19 17.10.2026
Локальный http сервер На работе, на двух локальных компьютерах круглосуточно работают программы опроса приборов с записью в книги Excel,которые раз в сутки записываются на сервер компании. Т. к. . . .
Копировать Windows на новый диск на UEFI
damix 17.10.2026
https:/ / uriesk. wordpress. com/ 2016/ 11/ 01/ move-window-10-to-ssd-on-a-uefi-dualboot-system-with-basic-linux-tools/ TL DR Вставляем диск, а старый подключаем через переходник, грузимся с лайва. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru