Easier/Faster way to convert Hex numbers to binary?
4 views (last 30 days)
Show older comments
I have an input file that has multiple columns of data, I am only interested in two of them. Right now I have both columns importing into MatLab and the first one, timestamps, is fine and I don't have any problems with it. The next one however, is a HEX number in the format 0x ####, I don't like how long it takes to run.
Currently I'm importing my dataArray,
filename = 'D:\MatLab Files\Import Files\InputFile.txt';
delimiter = ',';
startRow = 2;
formatSpec = '%*s%s%*s%s%s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%*s%[^\n\r]';
fileID = fopen(filename,'r');
dataArray = textscan(fileID, formatSpec, 'Delimiter', delimiter, 'HeaderLines' ,startRow-1, 'ReturnOnError', false);
fclose(fileID);
dataArray{1} = datenum(dataArray{1}, 'HH:MM:SS.FFF');
Timestamp = dataArray{:, 1};
then having to run:
MsgInfo = dec2bin(hex2dec(cellfun(@(x)(x(4:end)),dataArray{:, 2}, 'UniformOutput', false)),16);
This gets me my variable into a 16 character binary number so that I can then get the bits I need out of the data. I have a total of seven bits that get set depending on if there are any errors detected in the data stream. This is how I'm currently doing this:
% using the sum function to total the number of times the bit is set to 1, giving me the total number of errors for each error type
ManchesterErrors = sum(bind2dec(MSGInfo(:,16)));
ParityErrors = sum(bind2dec(MSGInfo(:,15)));
OverRunErrors = sum(bind2dec(MSGInfo(:,14)));
TimeOutErrors = sum(bind2dec(MSGInfo(:,13)));
BroadcastMsg = sum(bind2dec(MSGInfo(:,11)));
ModeCodeNoData = sum(bind2dec(MSGInfo(:,10)));
TotalMessageErrors = sum(bind2dec(MSGInfo(:,9)));
However, this adds a lot of time (30+ minutes) to my data analysis. I'm hoping to speed this up. I found the following on the forums,
typecast(uint16(sscanf('MYHEXSTRINGHERE', '%x')), 'int16')
and tried to do this:
MSGInfoHexNumbers = cellfun(@(x)(x(4:end)),dataArray{:, 2},'UniformOutput',false); %outputs a Nx1 cell array (iscellstr = 1)
MSGInfoBinaryNumbes = typecast(uint16(sscanf(MSGInfoHexNumbers,'%x')),'int16');
but I can't get it to work for my data. I keep getting the error "First argument must be a string".
I'm using MatLab R2012b if this helps when providing answers, and I've attached a sample file (Test File.txt) of my input data, and a copy of my code to date (Hex 2 binary help.txt).
0 Comments
Answers (2)
Walter Roberson
on 23 Dec 2015
MSGInfoBinaryNumbes = cellfun(@(S) typecast(uint16(sscanf(S(4:end),'%x')),'int16'), dataArray(:,2) );
5 Comments
dpb
on 23 Dec 2015
Edited: dpb
on 23 Dec 2015
Try the profiler???
I'm not sure you need the typecast nor uint16 (altho they're not likely contributing much), do you? I also don't know if a format string of '0x %X' and eliminating the substring addressing would help much or not, but I'd give it a shot.
Friedrich Welck
on 22 Mar 2016
MsgInfo = dec2bin(hex2dec(cellfun(@(x)(x(4:end)),dataArray{:, 2}, 'UniformOutput', false)),16);
is slow (cellfun is rarely fast). hex2dec, base2dec etc. work fastest on character arrays. Try
dataArray{2} = char(dataArray{2});
MsgInfo = dec2bin(base2dec(dataArray{2}(:,4:7),16),16);
Also there's no need to convert back to decimal for summation of errors. Try
ManchesterErrors = sum(MsgInfo(:,16)=='1');
ParityErrors = sum(MsgInfo(:,15)=='1');
OverRunErrors = sum(MsgInfo(:,14)=='1');
TimeOutErrors = sum(MsgInfo(:,13)=='1');
BroadcastMsg = sum(MsgInfo(:,11)=='1');
ModeCodeNoData = sum(MsgInfo(:,10)=='1');
TotalMessageErrors = sum(MsgInfo(:,9)=='1');
0 Comments
See Also
Categories
Find more on String Parsing in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!