• We recently switched our forum platform. If you experience any issues please email support@crystalfontz.com

Calculating a fan's RPM from a fan report

Knight

New member
How is it done? I called up Bryan and got some help, but I'm still confused.

I've got the current code, and it's not creating anything good. :)

'SplitPacket(2) = Fan Number being reported.
'SplitPacket(3) = Number of Fan Tach Cycles
'SplitPacket(4) = MSB Of Fan Timer Ticks
'SplitPacket(5) = LSB of fan Timer Ticks

RPM = ((27692308 / 3) * ((SplitPacket(3) - 3) / SplitPacket(5)))

Any suggestions?

TIA,
David Bussanmas.
Looking for additional LCD resources? Check out our LCD blog for the latest developments in LCD technology.
 

CF Tech

Administrator
I think you left SplitPacket(4) out. The C code uses some pointer + typecast fun to grab the two individual bytes of Fan_Timer_Ticks as a single two-byte value.

It would have to be something like this:
Code:
Sample from data sheet:
    [b]return_value=((27692308L/pulses_per_revolution)*
                  (unsigned long)(number_of_fan_tach_cycles-3))/
                 (Fan_Timer_Ticks);[/b]

based on what your variables are named, it should look something like this:

[b]RPM = ((27692308/3)*(SplitPacket(3)-3))/
      (SplitPacket(4)*256 + SplitPacket(5))[/b]
I am not a Visual Basic expert (and I am not going to become one), but I think VB may have troubles with this statement.

The trouble is that this calculation will overflow the default 16-bit integer. If VB uses 32-bit integers as a default then it should work. That is what the "long" type and "L" suffix on the constant in the C example indicate.

Give it a try, if it works then you are done, if not then you would have to look at using floats or longs somehow in VB.

By the way, it is pretty important to catch the "stop" and "slow" cases before the calculation, otherwise you may get odd results in those cases.
 

Knight

New member
Yeah, I understand about the slow, and stop results. :) I just took that part out of my example code, because I wasn't having any trouble with those parts. :)

I tried the code, and maybe I'm doing something wrong, Well, I've gotta be doing something wrong. :)

On a CPU fan that averages around 5000 RPM (at 100%)according to the 633 test program made by CF, I'm getting via my program speeds of around 200. by the algorythm that is currently in place.

That algorythm is:

RPM = ((27692308 / 3) * (SplitPacket(3) - 3)) / ((SplitPacket(4) * 256) + SplitPacket(5))

I've toyed with the mathmatical precedence, to no avail. The variables are in Decimal form. When I put them into byte form with a function, it then gives me an overflow error. However I do not think it's because VB can't support the large variable.

VB has the ability to let me know WHAT portion of that math statement it is choking on. ((CByte(SplitPacket(4)) * 256) is where it's choking on it. And say's that after it calculates that value, it overflows. I don't think VB's variable size is at fault, since these variables are declared as LONG. I can lookup the exact amount of size a number can be in the long variable if you need me to. I had the 256 changed into a byte, and at that point it overflowed.

So, when ignoring anything except the following, it will overflow.

longvariable = cbyte(256)

which makes me question where you get 256?
 
Last edited:

CF Tech

Administrator
265 can't fit in an 8-bit byte, since it takes 9 bits to represent it :)

Fan_Timer_Ticks is a 16-bit value in the CFA-633. The (upper 8 bits as a byte(=MSB)) * 256 added to the (lower 8 bits as a byte (=LSB)) will re-construct the 16-bit value.

If you can specify a "long" variable in VB, make a bunch of those and assign each of them a small portion of the equation. Then write the equation using only the varaibles. This will force VB to treat them as longs. Once that is working, you could incrementally replace the variables with their source to see when the problem comes back:

delcare these variables as longs:

n1
ppr
c3
sp3
sp4
c256
sp5

initialize them:

n1=27692308
ppr=3
sp3=SplitPacket(3)
c3=3
sp4=SplitPacket(4)
c256=256
sp5=SplitPacket(5)

and use them in the equation, which all now must be longs:

RPM = ((n1/ppr)*(sp3-c3))/ ((sp4*c256) + sp5)
 

Knight

New member
I considered that, but I don't know that that would help, but I will definetly give it a try. :)

It's 2:45 AM here, and I was just about to get to bed, but first thing in the morning I'll give it a shot and see if it works. :)
 

Knight

New member
I'm not quite sure wether I'm doing this correctly. I'm getting erratic results. Your CF test program shows that the fan reports back at really close to 5500 RPM. Does it average the RPM's to obtain this reading?

I made sure that the fan was at 100%. I can post additional readings if needed. The readings are below:

4069
3739
4123
3360
19823
16641
3254
84316
4664
4171
3608

The good thing is I'm no longer having overflow errors. :)

I really appreciate your'e help on this,
 

CF Tech

Administrator
I am glad you are getting somewhere with it.

Typically for a fan at 100%, Fan_Timer_Ticks will be greater than 32767--those might get interpreted as negative numbers.

Can you post what you have so far and I'll let you know if I see anything?
 

Knight

New member
I temporarily did the following:

Modified the original RPM algorythm to be the following:

Code:
RPM = ((sp4 * c256) + sp5)
Then I took and logged that. The results are below:


3798
3542
8662
13526
5334
31190
24022
28895
12759
17367
8407
59350
5079
64214
21207
19159
47062
63446
38870
35798
37078
64214
61142
27598
49111
 

CF Tech

Administrator
Ya, so that looks like a list of correct vaues for Fan_Timer_Ticks, you just need to do the rest of the equation:
Code:
RPM = ((n1/ppr)*(sp3-c3))/ ((sp4*c256) + sp5)
 

Knight

New member
Sure, and it looks good, but whenever I punch in the new algorythm, which is the same as a little bit before, I get erratic fan results.

Below are the RPM's that were calculated with the following algorythm: RPM = ((n1 / ppr) * (sp3 - c3)) / ((sp4 * c256) + sp5)

12569
3444
12754
4487
3991
7100
4279
6876
7161
10321
8755
12390
10838
5662
4607
4534
10704
8755
7221
4638
3918
4204
4184
3897
26912
4855
5625
6922
12569
3534
10939
12044
5463
4799
4631
3866
4330
4893
7692
 

Knight

New member
I KNOW the fan isn't fluctiating THAT much. And your test program shows a fluctuation of MAYBE 15 - 20 RPM's, over ten minutes, it's that little of a difference in fluctuations. But these seem like they are WAY off sometimes... and other times off by as much as 100 rpm's..... That doesn't seem right.
 

CF Tech

Administrator
As a debug thing, make your program write out each of the "SplitPacket()" values in a line, separated by commas. Then write out each of the intermediate variables. Then write out the result.

Bring the whole thing into a spread sheet and then you can analyze what is happening.
 
I've only the last week noticed that my fan numbers from the 0x81, 15, and 16 commands seemed irregular. I haven't solved it by any measure, and this might be a red herring.

Some time ago I was quite befuddled by the return packets from the 18 (Read DOW Device Information) command. I saw no usefull pattern in how the 633 was ordering my temperature probes (1,2,3,...n) based on the DOW one wire 64 bit unique ROM IDs.

Previously, I had concluded that there was an error in the CFA_633.pdf's , p. 15, 0x82 description of automatic temperature report packets. I had to swap MSB and LSB bytes to get meaningfull temperature data.

Back to command 18 -- following the same hunch, except this time at the bit level, I experimented with the idea that within a single 8 bit byte, the bits were endian scrambled. I wrote an endian swap routine and was pleasantly suprised:

Code:
mk4:/usr/src/633-port-19-endian# ./test633
3=open (/dev/ttyS1, 2)
tcgetattr(3, -1073743680 )
 #   type  ID  ID  ID   ?   ?   ?  IDCRC        ID  ID  ID   ?   ?   ?  IDCRC
 0   28   66  82  64   0   0   0   243         66  74   2   0   0   0   207
 1   28  162 106  64   0   0   0    96         69  86   2   0   0   0     6
 2   28  114 214  64   0   0   0   202         78 107   2   0   0   0    83
 3   28  218 182  64   0   0   0    38         91 109   2   0   0   0   100
 4   28   94 100  64   0   0   0   205        122  38   2   0   0   0   179
 5   28  129 101  64   0   0   0   224        129 166   2   0   0   0     7
 6   28   89 179  64   0   0   0    71        154 205   2   0   0   0   226
 7   28   57  84  64   0   0   0    15        156  42   2   0   0   0   240
 8   28  205 250  63   0   0   0     2        179  95 252   0   0   0    64
 9   28  157  33  64   0   0   0    48        185 132   2   0   0   0    12
 A   28   19 179  64   0   0   0   253        200 205   2   0   0   0   191
 B   28  123 155  64   0   0   0    89        222 217   2   0   0   0   154
 C   28    7  97  64   0   0   0   167        224 134   2   0   0   0   229
 D,E,F,10,11,12,13,14,15,16,17,18,19,1A,1B,1C,1D,1E,1F,-
 29.9375 C=83(19 = Set Temp. Rpt),L=0,D="",CRC=0xF6D8
 29.4375 29.3125 29.3750 29.8750 29.8750 29.9375 29.6250 29.8125 29.6250 29.9375 30.2500 29.9375 29.5625
 29.4375 29.2500 29.3750 29.8125 29.8750 29.8750 29.6250 29.8125 29.6250 29.9375 30.2500 30.0000 29.6250
 29.4375 29.2500 29.3750 29.8125 29.8750 29.8750 29.6250 29.8750 29.6250 29.9375 30.3125 30.0000 29.6250
 29.4375 29.3125 29.3750 29.8125 29.8750 29.8750 29.6250 29.8750 29.6875 29.9375 30.2500 30.0625 29.6250
 29.4375 29.2500 29.3750 29.8125 29.8750 29.9375 29.6250 29.8750 29.6875 29.9375 30.2500 30.0625 29.6250
In the left col. of 3 ID bytes, there is no pattern to say why one ds18b20 is # 1 and why one is # C. To the right, at least the first ROM ID byte is sorted to match the 633's ordering 1 to C...(and why use more than one byte, 2^8 IDs, on a controller that accepts only 32, 2^5, devices -- ignoring the other 2 ID bytes is fine...)

So anyway, the number scrambling struck me as similar, though I have not yet applied it at all at all.


( My code that made the above table is a modification of CF's 633-linux-port.tar.gz -- has that been truly GPL'ed as the LCDproc site claims? =Am I free to attatch it here?)

I see my table posted in poorly. The attatchment has a table file that looks properly columned in vi. Eh? where'd the attacthment button go?
 
Last edited:

starlon

New member
Same issue

I followed this thread to make some sense of the numbers. I'm getting really similar results to the OP.

Code:
Fan #: 0, Fan tach cycles: 8, MSB: 177, LSB: 205, RPM: 1013
Fan #: 0, Fan tach cycles: 7, MSB: 68, LSB: 164, RPM: 2101
Fan #: 0, Fan tach cycles: 8, MSB: 246, LSB: 205, RPM: 730
Fan #: 0, Fan tach cycles: 8, MSB: 240, LSB: 205, RPM: 748
Fan #: 0, Fan tach cycles: 7, MSB: 95, LSB: 164, RPM: 1508
Fan #: 0, Fan tach cycles: 8, MSB: 158, LSB: 205, RPM: 1135
Fan #: 0, Fan tach cycles: 8, MSB: 168, LSB: 205, RPM: 1068
Fan #: 0, Fan tach cycles: 8, MSB: 6, LSB: 205, RPM: 26509
Fan #: 0, Fan tach cycles: 8, MSB: 25, LSB: 205, RPM: 6987
Fan #: 0, Fan tach cycles: 8, MSB: 8, LSB: 206, RPM: 20476
Fan #: 0, Fan tach cycles: 8, MSB: 243, LSB: 205, RPM: 739
Fan #: 0, Fan tach cycles: 8, MSB: 139, LSB: 206, RPM: 1289
Fan #: 0, Fan tach cycles: 8, MSB: 140, LSB: 206, RPM: 1280
Fan #: 0, Fan tach cycles: 7, MSB: 138, LSB: 164, RPM: 1040
Fan #: 0, Fan tach cycles: 8, MSB: 218, LSB: 205, RPM: 823
Fan #: 0, Fan tach cycles: 8, MSB: 27, LSB: 206, RPM: 6484
Fan #: 0, Fan tach cycles: 8, MSB: 186, LSB: 206, RPM: 965
Fan #: 0, Fan tach cycles: 8, MSB: 167, LSB: 206, RPM: 1074
Are those numbers supposed to jump around so much?
 
I'm getting really similar results to the OP.
Code:
Fan #: 0, Fan tach cycles: 8, MSB: 177, LSB: 205, RPM: 1013
Fan #: 0, Fan tach cycles: 7, MSB: 68, LSB: 164, RPM: 2101
Fan #: 0, Fan tach cycles: 8, MSB: 246, LSB: 205, RPM: 730
Fan #: 0, Fan tach cycles: 8, MSB: 240, LSB: 205, RPM: 748
Fan #: 0, Fan tach cycles: 7, MSB: 95, LSB: 164, RPM: 1508
Fan #: 0, Fan tach cycles: 8, MSB: 158, LSB: 205, RPM: 1135
Are those numbers supposed to jump around so much?
Look at the correlation of tach cycles to LSB. The readings with 7 tach cycles all have LSB around 164; the readings with 8 tach cycles all have readings near 205. The MSB is quite variable, which it shouldn't be. The conclusion: you have the LSB and MSB swapped.
 

CF Tech

Administrator
I am not sure what you have going there. The MSB and LSB are switched, but there is still something else wrong.

I put your data in a spreadsheet, it looks fine with the right calculation:



The spreadsheet is attached.
 

Attachments

starlon

New member
Thanks. It's working great now. The PDF has those assignments backwards for Fan Speed report packets is where the confusion rests. I thought there was something different between temperature reports and fan reports formats. I should have followed through with the feeling.
 
Top