Gyro LSB Degrees per bit calculation - c++

iv set its sensitivity to +-62.5 degrees per second. The gyro has a ADC word length of 16 bits. To calculate the degrees per LSB do i do '62.5 / 2^16' OR '62.5 / 2^15' to account for the fact that the total range -62.5 to 62.5 is 125 (or 125/16^2).
I assume its 62.5 / 2^15 but when I am doing this the data I'm getting back seems to be outside the gyros spec. Any other ideas what could be wrong?
Thanks
The gyro specifically is ICM-42688-P

Related

How can i calculate network load of this camera?

It's part of an assignment that i am trying to solve
Determine the network load from a security camera given the
following camera specs:
a. Resolution: 1200x800
b. Color: 8-bit color gamut
c. Speed: 30 frames pr. second.
d. Compression: 3/1000
How would you go about it? Is it a matter of calculating total bits pr frame?
Based on the information it is not so complicated to calculate:
To get the total number of pixels: 1200*800=960000
Then its unclear about the bits depth if its total number of colours
or per channel (RGB). I assume second (so 3 bytes): 960000*3=2880000
For second we need to multiply by 30 (frames per second)
86400000*30=86400000
To get in consideration compression we multiply by 3 and delete to
1000: 86400000*3/1000=259200 bytes per second
And 259200/1024=253.12 kilobytes per second

compress 4 byte floating point data to 1 byte

I need to compress floating point numbers (4 bytes) to 1 byte(0 to 0xFF) to send to another device. The floating point numbers range from -100000.0 to 100000.0.
The other device will decode from 1 byte back to floating point numbers. How do it do it with minimum data loss?
Thanks, JC
One solution is to use quantization. Divide 100000 to 127 intervals. Send the interval number to which float belongs to and a sign in lowest or highest bit
In your case the interval = 787,4
For example, you have input like 100. Send 1. Input 1000,147732. Send 2
On the device you can restore number by its interval.
The easiest solution is to restore the number as a middle of the interval. For example, every float that belongs to the first interval will be restored as 393.7
If you have some stats for digits distribution and it's not uniform, you can play around it by changing the intervals length and quantize frequent floats more precisely

LabVIEW Complicated If Statements

Background: I am trying to configure a DMX turntable in LabVIEW, it has two settings for rotating: coarse (360 degrees in 255 points) and fine (1 degree in 255 points). I need to be able to firstly execute a command to move to the closest available DMX position in coarse mode, then make up the difference in fine mode.
e.g. I want to turn to 90 degrees, this is equivalent to a DMX value of 63.75 however this is rounded down to 63. The real value in degrees is now 88.94 so I need to make up the extra 1.06 degrees by using the fine setting (I can only make up 1 degree but 89.94 is close enough to 90).
I can execute the coarse setting just fine however I need some kind of "if" statement to say "if real degree value is less than input value, make up the difference". Case Structures do not provide enough control to use this complicated "if" statement, what can I use instead?
255 coarse steps * 255 fine steps per coarse step = 65025 possible steps.
360 degrees / 65025 = ~ 0.00536 degrees per step.
Divide your desired angle by this constant, then use this as the X input to quotient and remainder. Y would be 255. The Quotient will represent the coarse value to adjust and the Remainder represents the fine value.
63 coarse steps and 191 fine steps.
You don't need any condition. Use the Quotient and Remainder function with 255/4 to get 63 and .75. Do the 63 coarse movement, then take the .75 and multiply it by 360. This will tell you many fine steps you need to take (270, which is 255 + 15. You can use Q&R again to know how many whole turns to make and how much you have left in the last turn).

How to get a list of notes present in a wav file?

I am writing a program to help people learn guitar. To do this, I need to be able to look at a sample of time and see what note(s) they played. I looked at FFTW but I don't understand how to get this to work. I also tried to figure out the Goertzel algorithm but it seems like that is just for single-frequency notes like dial tones (not sure about that though). To be clear, I do need to be able to detect multiple notes (to see if a chord is played), but it doesn't matter too much if a few harmonics get in there too.
I'm coding this in C++, and would prefer a solution that is cross-platform.
UPDATE: I've realized it isn't so important to detect specific notes; what I really need is to check that certain frequencies are present, and that others aren't. For example, if someone plays a C, I want to check that a C frequency is present (about 262 Hz), as well as probably 524 Hz and 786 Hz, and check that nearby notes that are not near in the overtone series (like B and D) are not present.
Notes are not present in a wav file. Sampled sound is.
Humans might perceive some notes that might have been played to create the sound in some wav file, but doing automatic polyphonic pitch estimation/recognition from recorded sound into transcribed music for rich and complex waveforms, such as produced by guitars, still appears to be an advanced research topic.
When possible for certain very restricted types of music sounds, some non-trivial DSP will be involved. FFTW might be useful for a small part of the more sophisticated DSP processing needed for pitch estimation, Goertzel filtering less so.
I can't point you to specifics but I believe what you need would be a Fourier transform to detect the frequency you're looking for. There's also a similar question here
What about this pdf? http://miracle.otago.ac.nz/tartini/papers/A_Smarter_Way_to_Find_Pitch.pdf
The problem with the FFT is that if you do a 256 sample FFT, you will get only 256 outputs. Essentially, what this means is that it will divide your your frequency space, where there are infinite number of frequencies, into a limited set of frequencies.
This is because if you only check 256 samples (256 can be replace by N, the number of samples used for the FFT), any frequency which is related by a multiple of 256 will look the same.
In other words, if you check 256 evenly spaced samples, taken at time 0, 1/256, 2/256, 3/256, ... 255/256. Then, the two signals sin(2 pi 80 x), which has frequency 80 cycles/sec, and sin(2 pi (80 + 9*256) x), which has frequency (80+9*256), will have the same samples.
Here, 9 can be replaced by k, the multiple to use. You could replace 9 with 1,2,3,4,5, etc. You can replace 256 (N) with any value as well.
As an example, sampling both at 200/256, one of the samples, we have:
sin(2 pi (80 + 9*256) (200/256)) = sin(2 pi 80 (200/256) + 2 pi * 9 * 200)
Because multiples of 2 pi don't affect sin, this is the same as
sin(2 pi 80 (200/256)).
More generically,
sin(2 pi (M + k*N) j/N) = sin (2 pi M (j/N) + 2 pi k*j) = sin (2 pi M (j/N) ), where j is any integer 0,..., N - 1, N is the number of samples, (j/N) is the time to sample, M is the number of cycles per second, k is any integer ... -2, -1, 0, 1, 2 ...
From Nyquist sampling, if you want to distinguish, -128, -127, -126, -125, ..., 125, 126, 127 cycles per second you would take 256 samples/sec. 256 samples/sec means distinguishing 256 frequencies. However, 0 cycles/sec, 256 cycles/sec, 512 cycles/sec, 1024 cycles/sec would all look the same.

compact representation and delivery of point data

I have an array of point data, the values of points are represented as x co-ordinate and y co-ordinate.
These points could be in the range of 500 upto 2000 points or more.
The data represents a motion path which could range from the simple to very complex and can also have cusps in it.
Can I represent this data as one spline or a collection of splines or some other format with very tight compression.
I have tried representing them as a collection of beziers but at best I am getting a saving of 40 %.
For instance if I have an array of 500 points , that gives me 500 x and 500 y values so I have 1000 data pieces.
I around 100 quadratic beziers from this. each bezier is represented as controlx, controly, anchorx, anchory.
which gives me 100 x 4 = 400 pcs of data.
So input = 1000pcs , output = 400pcs.
I would like to further tighen this, any suggestions?
By its nature, spline is an approximation. You can reduce the number of splines you use to reach a higher compression ratio.
You can also achieve lossless compression by using some kind of encoding scheme. I am just making this up as I am typing, using the range example in previous answer (1000 for x and 400 for y),
Each point only needs 19 bits (10 for x, 9 for y). You can use 3 bytes to represent a coordinate.
Use 2 byte to represent displacement up to +/- 63.
Use 1 byte to represent short displacement up to +/- 7 for x, +/- 3 for y.
To decode the sequence properly, you would need some prefix to identify the type of encoding. Let's say we use 110 for full point, 10 for displacement and 0 for short displacement.
The bit layout will look like this,
Coordinates: 110xxxxxxxxxxxyyyyyyyyyy
Dislacement: 10xxxxxxxyyyyyyy
Short Displacement: 0xxxxyyy
Unless your sequence is totally random, you can easily achieve high compression ratio with this scheme.
Let's see how it works using a short example.
3 points: A(500, 400), B(550, 380), C(545, 381)
Let's say you were using 2 byte for each coordinate. It will take 16 bytes to encode this without compression.
To encode the sequence using the compression scheme,
A is first point so full coordinate will be used. 3 bytes.
B's displacement from A is (50, -20) and can be encoded as displacement. 2 bytes.
C's displacement from B is (-5, 1) and it fits the range of short displacement 1 byte.
So you save 10 bytes out of 16 bytes. Real compression ratio is totally depending on the data pattern. It works best on points forming a moving path. If the points are random, only 25% saving can be achieved.
If for example you use 32-bit integers for point coords and there is range limit, like x: 0..1000, y:0..400, you can pack (x, y) into a single 32-bit variable.
That way you achieve another 50% compression.
You could do a frequency analysis of the numbers you are trying to encode and use varying bit lengths to represent them, of course here I am vaguely describing Huffman coding
Firstly, only keep enough decimal points in your data that you actually need. Removing these would reduce your accuracy, but its a calculated loss. To do that, try converting your number to a string, locating the dot's position, and cutting of those many characters from the end. That could process faster than math, IMO. Lastly you can convert it back to a number.
150.234636746 -> "150.234636746" -> "150.23" -> 150.23
Secondly, try storing your data relative to the last number ("relative values"). Basically subtract the last number from this one. Then later to "decompress" it you can keep an accumulator variable and add them up.
A A A A R R
150, 200, 250 -> 150, 50, 50