Intepretation of output from register. AT90E32 + stm32 - stm32

i have a problem with documentation, which i don't understand. Documentation is here:
Read sequence is on the page 31.
I want to read Phase C voltage RMS.
From this register i get in that order: 0011110010001111.
Value read should be 233.3V.
I am beginner and really don't know hot to interpret this. When i read first byte from right 11110001 that is 241. The next byte read from left is: 00111100 which is 60, but when i multiply this by 0.01V (in documentation is that 1LSB should be multiply'ed by 0.01 - what means 1LSB? ) i get 241,6 V. That is correct? Thanks for any help guys.

Related

Expression in Debugger shows correct value of calculation, but value is rounded when assigning to variable

I read 16 Bit two's complement sensor data byte after byte via I2C with a STM32, so I have to stick the High- and Low-Byte back together and convert this number to a float to get the real value.
My expression in C for this is
// Convert temperature value (256 LSBs/°C with +25°C Offset)
float temp = (tmpData[1] << 8 | tmpData[0])/256.0 + 25.0;
When I use the debugger of the STM32CubeIDE to check the calculation, the expression shows the correct conversion of the data (see screenshot). But the value assigned to the temp variable is always 25! It seems to me like the first term of the expression is always assumed to be 0 or something? I already tried a direct cast of the term in brackets to float, but that does not change anything.
Can anybody point me to the problem? Why is the debugger showing the correct value, but the code is assigning a wrong one?
The expressions in the screenshots below are captured by howering the mouse over the corresponding part of the above code line in debug mode.
Fig. 1: Complete expression of calculation (gives result as expected)
Fig. 2: tmpData content (original two Bytes)
Fig. 3: Result of byte shifting and sticking
Fig. 4: temp result (always 25, even when expression above showes the expected value)
temp is only a volatile for the moment, because I don't use that value yet and the compiler optimizes it out.
many issues in this single line of code.
tmpData[1] << 8 has to be (((uint16_t)tmpData[1]) << 8). If you shift byte 8 times the result will be zero (standard says undefined). You probably got the warning about it.
256.0 & 25.0 are double values and the result will also be double then converted to the float. You shuold use 256.0f and 25.0f.
you can see the difference here: https://godbolt.org/z/Cm-S8T
OK, new morning, new intuition...
The problem wasn't with this code line from the question, but (typ. Murphy) with the stuff I did not post. The I2C is read via DMA to the array and at the point I wanted to do the conversion the peripheral was not done yet. That's why the array elements were always empty when the code accessed them, but at the time I checked the values in the debugger the I2C peripheral had finished the transmission and I saw the expected values.
So the solution is to check if the peripheral is still busy...

Detecting first non silent sample index

I have an audio file that I read with [tabread~]). The audio starts with some silence and I am trying to find the first non silent sample index.
I have tried to use [bonk~], [fiddle~] or [sigmund~] but the results were approximate and not constants.
Does anyone have a solution for this? Thanks.
Pascal
I already answered this question in the Pure Data forum, but I am copying it here (slightly adapted) in case someone else find it useful:
If the sound completely silent up to the point you marked (that is, is the table filled with zeroes up to that point) then you can simply go through the array's elements using [tabread ], starting at the first sample and checking if the absolute value of the subsequent ones is larger than zero. If the signal is not completely silent but near silent, then you will can either use sort of attack detection (such as [bonk~]) or simply use something like this:
...
|
[tabread array1]
|
{abs]
|
[> 0.001]
|
[sel 1]
|
...
Note how I used [> 0.001] instead of [> 0]. Adjust this number (either directly as an argument or via the rightmost inlet of [>]) to control the sensitivity of the detection. Then once [sel 1] receives a float of value 1, you can use its bang to stop the process since you found your first non-silent element.

Matlab not taking last number in array?

I've got a Subscripted assignment dimension mismatch problem.
I've already localized the issue, and know exactly what is going on, I just don't know why.
Here's the problematic piece of code:
mFrames(:,i) = vSignal(round(start:1:frameLength*samplingRate));
start=start+frameShift*samplingRate;
frameLength = frameLength+frameShift;
I've already checked what's going on in debugmode; usually my resulting column length of mFrames is 128, this stays the same until i=1004. Then, my column length changes to 127.
I've checked the values involved while in debug mode, and it simply does not make sense what is going on. At i==1004 start=32097 and frameLength*samplingRate=32224.
That's a difference of 127 meaning 128 points, that should work.
BUT when i assign a vector A=round(start:1:frameLength*samplingRate)
OR B=start:1:frameLength*samplingRate
In both cases I get a vector going from 32097 to 32223. This ALTHOUGH when I give in frameLength*samplingRate matlab is giving me 32224.
In other words, matlab is telling me it's using one number, but when I test I find it's using a different one.
Any help appreciated.
I suspect your 32224 is not actually 32224. MATLAB's default format only displays so many decimal places, so when dealing with floating point numbers, what is printed on screen is not necessarily the "exact" value.
Let's go back a step and look at how the synatx x = start:step:end works.
1:1:10 should give us numbers in steps of 1 from 1 to 10. Fair enough, that makes sense. What if we set the end value to something that's slightly above 10?
e.g.:
1:1:10.1
Well, it still gives us 1:1:10, (or 1:10, 1 being the default step) because we can't have values higher than the end-point, so 11 isn't a correct step.
So what about this:
1:1:9.99
Spoiler: it's the same as 1:9
And this?
1:1:9.9999999
Yep, still 1:9
But if we do this:
a = 9.9999999;
Then with default format, the value of a will be shown on the command line and in your list of workspace variables as 10.0000.
Now, if frameLength and samplingRate are both stored as floating point numbers, it's possible that the number you see as 32224 is not 32224 but very slightly below that. You can check this by changing your default format - e.g. format long at the command line - to show more decimal places.
The simplest solution is probably to do something like:
B=start:1:round(frameLength*samplingRate)
Or try to store the relevant values as integers (e.g., uint32).

MicroProgramming - Decrement jump not Zero

I'm trying to get my head around Micro Programming and OpCodes. I'm looking at DJNZ or Decrement Jump Not Zero. I've been trying to get this to work with no luck. My code with irrelevant parts removed is as follows.
044 alu:=ac If Z then goto 79
079 ac:=ac+(-1) read Goto 80
080 mar:=ac write Goto 0
My listing for OPCodes is this
DESP: sp:=sp-y
JNZE: if ac /= then pc:=x
So far I believe I have it to jump on not Zero to 79, then it might do a decrement and write back. I'm unsure.
I'm using this to test
begin: loco 8
loop1: jnze loop1
loop2: jump loop2
With this output
If someone can say if I'm on the correct lines and then help me implement the jump on NOT zero and give me a pointer on the correct way to decrement and write back it would be fantastic.
Unsure if this is the correct site, and I was unsure for the tags as well so if someone could fix or point me in correct direction would be great.

Pi value estimation with series

Here's my problem:
Compute the value of π using the following series:
((π^2)-8)/16=[sum from 1 to pos. infinity] 1/(((2n−1)^2)*((2n+1)^2))
• Find the smallest number of terms required to obtain an absolute value of the error on π smaller than 10e−8.
Here's my code:
x=0;
for i=1:1000
x=x+(1/((((2*i)-1)^2)*(((2*i)+1)^2)));
z=sqrt((x*16)+8);
error=abs(z-pi);
if (error < 10e-8)
i
break
end
end
The answer that I get is 81 when the loop breaks, but it is not the right answer. I have been trying to figure out what is wrong with my code that it doesn't do what I need.
I've been staring at the code for quite a while and cant see where I made a mistake.
I found the problem. The error is supposed to be less than 10^-8 not 10e-8. Somehow the numbers got changed over when copying.