How can I store raw data with respect to time and sort it? - perl

due to Internet communication i could have two (or more) ASCII files in RINEX format (GPS ASCII format) of the same data period, which i would like to merge to one file.
Each data set (epoch) contain more then one line (in this example 19 lines). I would like to merge those files, where it could be that they in some parts overlap each other.
here is an example of RINEX epoch data set:
09 2 21 12 59 59.9000000 0 9G31G23G11G13G32G17G14G20G19
23152606.238 121667768.06047 94806069.43545 23152606.540 23152606.521
1262.605 43.750 31.500
22765313.352 119632547.53447 93220179.18745 22765312.252 22765311.072
3252.769 46.250 32.250
20798168.896 109295128.07748 85165036.96747 20798168.642 20798168.578
-2252.493 52.750 43.250
25363206.177 133284559.23845
3776.403 32.750
20350616.203 106943239.96448 83332404.31147 20350615.386 20350616.499
-929.443 51.000 44.500
21994260.713 115580595.93348 90062809.84446 21994260.826 21994260.114
416.327 49.500 38.250
23964108.994 125932271.15846 98129049.02843 23964107.689 23964107.603
-3561.500 39.250 20.250
20225257.452 106284459.64448 82819085.85247 20225256.341 20225256.964
956.944 52.750 45.250
25623383.323 134651746.21445 104923415.17742 25623386.202 25623384.504
-3991.096 34.250 12.250
The first line contains the time info and below are the raw data for each GPS satellite.
My idea was to open each file separate and stored the raw data in some kind of array relative to time. Each time i read new epoch, i ask my array if i already have something with time so and so, and if not i place the raw data there.
My question is how to store the raw data with respect to time, since it is not one line but something dynamic that could always change.
If you have better idea, please share it with me.
Regards

To store the raw data with respect to time, I would:
Encode the time as a number (# of seconds since Unix "epoch time" or since some arbitrary start time - use microseconds instead of seconds depending on what RINEX time precision is).
Store the raw data as an array (data for each line is 1 array element - stored either as a string, an arrayref of words or a hash of values).
Store the reference to that array as a value in a hash, with the key being the time-encoded-as-a-number.

Related

Flutter acquire data from BLE

Hi I'm trying to get some measurement data from a ble decice and display it in my flutter app. I'm also using flutter_reactive_ble
I have two characteristics, one for reading and one for writing. I subscribe an event listener to the readCharacteristic and then I write a request just like below
_ble!.writeCharacteristicWithoutResponse(characteristicWrite, value: [0x99, 0x00, 0x19]);
As the value parameter i'm sending a list of hex value. Every value has it's role, as the ble's manual defines below:
I'm using the hex values of the manual's example, and the device sends me the 10 first measurements, which is correct, because every req response has maximum 10 measurements. The thing is that, in the scenario of having 20 measurements, I can't get the last 10. I tried of doing the following
await _ble!.writeCharacteristicWithoutResponse(characteristicWrite, value: [0x99, 0x00, 0x01, 0x99]);
I added 0x01 in the values list, because the manual says
value 1: continue with next group
But data is not getting sent.
How is it possible to get all the measurements, and further more, get for example the 5 last? Can anybody help me or give me a hint? Thank you for your time
The data always has to be 3 bytes long that you send. i.e.
[0x<header>, 0x<command>, 0x<checksum>]
In your second example you have too many bytes. It looks like you have an extra command. i.e.
[0x<header>, 0x<command>, 0x<command>, 0x<checksum>]
For the second write take out the 0x00 and make sure the checksum is correct. i.e:
[0x99, 0x01, 0x1A]
You send this second write after you receive the first 10 measurements

ECG data in Simulator differ from the one provided from CSV

I'm trying to supply to Movesense Simulator (2.0.0 - VS2017) ECG data from a CSV file that looks like the following:
LoopingTimestamp:8000
Timestamp,/Meas/ECG/{RequiredSampleRate}
0,0
8,1000
16,2000
24,3000
32,4000
40,5000
48,6000
56,7000
64,8000
72,9000
...
8000,1000000
But it looks like a random(but constant during the simulation) offset is added to data every time I run the simulator.
These are some examples of the first chunk of data I got for each simulation:
41750 42750 43750 44750 45750 46750 47750 48750 49750 50750 51750 52750 53750 54750 55750 56750 (+750)
43125 44125 45125 46125 47125 48125 49125 50125 51125 52125 53125 54125 55125 56125 57125 58125 (+125)
42250 43250 44250 45250 46250 47250 48250 49250 50250 51250 52250 53250 54250 55250 56250 57250 (+250)
The offset is always a multiple of 125, that is the ECG frequency requested by my code.
What am I doing wrong? I'm expecting to get the same exact data I have in the CSV, like I do for HR.
You are seeing the linear interpolation between data points. If the current timestamp is between the timestamps in CSV file the data is a weighted average of the two nearest values. Since your data increments 1000 units per sample and your timestamps are 8 ms apart, the increment in value is 1000/8 = 125.
Full Disclosure: I work for the Movesense team

Unusual unsigned short to bits swapping byte order

I'm reading in a stream of data, 64 bytes to be exact. I want to read 16 bits starting at the 480th bit of the incoming data. Unfortunately, I do not know what the incoming data type is, it's a bunch of random characters/boxes. Reading it in as an unsigned short (v), I get the number I am looking for, which for this example is 13.
my $satt_id = unpack("x60v1"), $msgdata); #$satt_id == 13
This results in $satt_id == 13, which is 00000000 00001101.
If I pull the data as 16 bits (b or B), the string does not reflect the value of 13, but rather is byte-swapped or reversed.
my $satt_idb = unpack("x60b16", $msgdata); #satt_idb == "10110000 00000000"
my $satt_idB = unpack("x60B16", $msgdata); #satt_idB == "00001101 00000000"
Why is this occurring? I want to alter the data and resend out the message, which would be relatively easy if all of the message elements were the same size (16 bits, just pack back as it was unpacked), but some are 6, 4, 2, and 1 bits. Should I just use little-endian b and then reverse? After altering the data reverse it back to original order and then pack it back as b?
Completely separate and not perl related, but this haunted me in a different utility. I just conceded by swapping the values in the Enum designation. It worked, just wasn't very viable when the amount of bits got higher than 4 (16 different values).
Thanks!
EDIT: I'm guessing this is just related to binary notation? Apparently starts from the right? So $satt_idb is correct, if you read right to left. So to make it more user friendly, just reverse, alter, then reverse again and repack?
EDIT2: Basically I'm trying to make a user-friendly method of editing messages coming through a data stream. As I mentioned in the comments, if I want to edit a single bit from 0 to 1 (which in the message represents something as true/false), I don't want the user to have to worry about editing the octet of data received, just select from a dropdown of true/false.
If it works with v, it means the data is in little-endian byte order, which means
0b0000000000001101
is stored as
0b00001101 0b00000000
which is what you got.
Should I just use little-endian b and then reverse?
No. You are likely doing something incorrect if you are converting the numbers to a text representation (binary).
If you did somehow want the binary representation of the number, you could use
sprintf("%16b", $num)

extract Date and Time from two 16-bit modbus registers

I'm using an ElNet energy&power meter that communicates with my processor via Modbus RTU protocol.
There are two 16-bit ElNet registers that contain information about the Date and Time (separately) in a Win Format (registers 85-86, page 6 of this document). I'm able to read these two registers. However, I'm unable to extract information about the Date and Time.
For example, Date register contains decimal value of 17841 for today's date (31/07/2015). Is there any person willing to explain me how to convert 17841 into 31/07/2015?
I have the same problem with the time. My time register contains a decimal value of 55296. Can you help me extract the time from this number?
This thread addresses the same problem:
HEX/Decimal to date and time from modbus
However, I'm not sure I understand the extraction algorithm applied there. My point of operation is processor with the code written in C or C++.
Thank you very much for your time and effort to help me.
Sincerely,
Bojan.
The MS-DOS date/time format is described here: https://archive.is/2bVlz (was http://proger.i-forge.net/MS-DOS_date_and_time_format/OFz but is gone)
It makes sense for the 17256 value mentioned in the other question, as it translates to 2013-11-08. See here how to do it:
Register bit description: 0bYYYYYYYMMMMDDDDD
Registervalue: 17256 0b0100001101101000
Yearmask: 0b1111111000000000
Yearpart: 0b0100001000000000
Yearpart rightshifted 9 steps: 0b0000000000100001 = 33 years after 1980
Monthmask: 0b0000000111100000
Monthpart: 0b0000000101100000
Monthpart rightshifted 5 steps: 0b0000000000001011 = 11
Daymask: 0b0000000000011111
Daypart: 0b0000000000001000 = 8
Unfortunately your register value 17841 does not make sense, as it translates to 2014-13-17 (That is month 13).
Are you sure that:
you read the correct register? (change the time setting in the instrument, and see what happens to the register value)
you do not mix up the two bytes in the register?
the time setting is correct?

Create a certain size file and filled with no data on iOS

I'm developing an iphone app, I need to create a certain size file on filesystem and filled with NO data first, then seek to a offset and write data when get data from somewhere else
How can I do it?
The lseek BSD function is explicitly capable of that.
man lseek:
The lseek() function allows the file offset to be set beyond the end of the
existing end-of-file of the file. If data is later written at this point,
subsequent reads of the data in the gap return bytes of zeros (until data is
actually written into the gap).
NSMutableData or fseek is probably what you want