[erlang-questions] Binaries
Bob Cowdery
bob@REDACTED
Wed Jun 20 12:07:40 CEST 2018
I seem to have arrived at something that works. This is only a hack for
testing. I picked hexstr_to_bin up to do the conversion. I had trouble
with some of the other methods on offer but that's probably me.
The target docs I have say nothing about flow control so I set it to all
available options but gen_serial:bsend/2 was more often than not hanging
although the command was executed. I have used gen_serial:asend/2 which
seems to work reliably so don't know what the issue is. I'm sure the
code can be reduced quite a lot.
hexstr_to_bin(S) ->
hexstr_to_bin(S, []).
hexstr_to_bin([], Acc) ->
list_to_binary(lists:reverse(Acc));
hexstr_to_bin([X,Y|T], Acc) ->
{ok, [V], []} = io_lib:fread("~16u", [X,Y]),
hexstr_to_bin(T, [V | Acc]);
hexstr_to_bin([X|T], Acc) ->
{ok, [V], []} = io_lib:fread("~16u", lists:flatten([X,"0"])),
hexstr_to_bin(T, [V | Acc]).
I ended up with this code:
open(Device) ->
case gen_serial:open(Device, [{baud, 9600},{stop_bits,
2},{flow_control, none}]) of
{ok, Port} ->
Port;
{error, Reason} ->
io:format("Error opening serial port ~w~n", Reason),
{error, Reason}
end.
set_freq(Port, Freq) ->
% The command is 4 hex freq bytes followed by 0x01 (set_freq command)
SFreq = integer_to_list(floor(Freq*100000)),
io:format("~w~n", [SFreq]),
SPadded = string:right(SFreq, 8, $0),
io:format("~w~n", [SPadded]),
BinFreq = hex:hexstr_to_bin(SPadded),
BinCmd = <<16#01>>,
Bin = << BinFreq/binary, BinCmd/binary >>,
io:format("~w~n", [Bin]),
gen_serial:asend(Port, Bin),
io:format("Done send~n"),
gen_serial:recv(Port, 5, 2000),
io:format("Done response~n").
C:\Users\User>erl
Running .erlang
Eshell V9.3 (abort with ^G)
1> Port = cat_client:open(3).
{gen_serial,<0.59.0>,#Port<0.519>}
2> cat_client:set_freq(Port, 3.8).
[51,56,48,48,48,48]
[48,48,51,56,48,48,48,48]
<<0,56,0,0,1>>
Done send
Done response
ok
On 6/20/2018 2:21 AM, zxq9 wrote:
> On 2018年6月19日 火曜日 16:32:49 Bob Cowdery wrote:
>> If I have a number, say 1450000001 and I want to represent that as a
>> binary in the form
>>
>> <<16#14,16#50,16#00,16#00,16#01>> what's the best way.
>>
>> I'm not sure what list_to_binary(integer_to_list(1450000001)) which
>> prints as <<"1450000001">> produces but I guess its 10 bytes not 5.
> Binary syntax can be a bit of a wonderland at first.
>
> The form you present above works just fine. Keep in mind that it yields the following:
>
> 1> <<16#14,16#50,16#00,16#00,16#01>>.
> <<20,80,0,0,1>>
>
> If we want to encode it using your original decimal representation (or as an integer programatically generated as a variable), and pack it into the same 40-bit space (5 8-bit bytes):
>
> 2> <<1450000001:40>>.
> <<0,86,109,62,129>>
>
> What, what? These aren't the same!
>
> There are two reasons:
> - The hexadecimal modifier 16# means 10#14 =/= 16#14
> - Your version splits this integer value up into decimal-determined fields
>
> It appears that you don't actually want to encode the number 1450000001, but rather want five 8-bit fields carrying the values 14, 50, 00, 00, and 01, in that order. Is this correct?
>
> If you're starting with an integer that is *actually* 1,450,000,001 and you want to break it up by its decimal value then you'll want to div/rem it down by 100s to break it into chunks and then encode each chunk:
>
> 1> Split = fun
> 1> Chunk(0, Parts) -> Parts;
> 1> Chunk(Z, Parts) -> Chunk(Z div 100, [Z rem 100 | Parts])
> 1> end.
> #Fun<erl_eval.36.99386804>
> 2> Pack = fun
> 2> Stuff([], Bin) -> Bin;
> 2> Stuff([H | T], Bin) -> Stuff(T, <<Bin/binary, H:8>>)
> 2> end.
> #Fun<erl_eval.36.99386804>
> 3> N = 1450000001.
> 1450000001
> 4> Splitted = Split(N, []).
> [14,50,0,0,1]
> 5> Packed = Pack(Splitted, <<>>).
> <<14,50,0,0,1>>
>
> BUT THAT IS A LITTLE BIT RIDICULOUS.
>
> On your sensor side you should have this "number" as a byte array of some sort. Figure out what the field sizes are in bits or bytes and interpret it accordingly. That's a much more sane way to do business.
>
> -Craig
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
More information about the erlang-questions
mailing list