Square Root

SAborn

Senior Member
Can someone give me a picaxe math code example of how to extract a square root number from a a ADC reading.

For example lets say ADC = 4900 which equals SQR 70, how do i calculate the 70 in picaxe math.

Yes i know the X1/X2 range of chips has the SQR function, but in this case its a 18m2 chip used.

I must be dumb and cant see the trees from the forest here, so a simple code example would be of great help.
 

Buzby

Senior Member
Try this ...

Code:
' Subroutines	 
' ===========

' Calculate a square root
' -----------------------

SQRroot:
' Newton-Raphson formula
' x2 = (x1 + Q/x1)/2

' Q is the number you want the srqroot of
' x1 is the guess
' x2 is the result

x1 = Q / 2	' Preset 1st guess
tempb5 = 0	' Iteration count
do
	tempw8 = Q / x1						' Make div value
	x2 = x1 + tempw8 / 2					' Make result
	If x1 = x2 then : exit : endif   ' Exit if result not changed
	x1 = x2									' Use result as new guess
   inc tempb5								' Update iteration count

loop until tempb5 = 10					' Iterate maximum of 10 times

return
 

SAborn

Senior Member
Thanks Buzby,

Ny head is still spinning with the example, i guess im not so smart on math problems, but i will chew through it, unless someone else gives a example that i understand better.
 

SAborn

Senior Member
Thanks Westy.

Looking through the code examples it would seem i need more variables than i can afford to do the calculation.
There is a lot to digest to find a solution.

Basically i need to take a ADC reading of a thermister and divide it by the square root to get a somewhat calibrated degrees C value. it dont has to be 100% spot on, just within a few degrees is close enough.
 

SAborn

Senior Member
Do you have the thermistor values vs temp? It may be easier just to curve fit.
Yes, the logged file is attached as code below, it has 6 readings per data block.

Some labels are shortebed because i run out of memory space in the 08m used for testing.


1) is the current calibration value used for the ADC
2) is the raw adc value
3) is the inversion of the raw adc value
4) is the actual calculated calibration value required
5) is the degrees C reading using "1)" as the calibration value presently used
6) is the actual degrees c read from a DS18B20 sensor

The reason why the ADC reading is inverted is the thermistor is NTC, meaning the ADC value goes down as the temp goes up, the ADC reading is inverted so it has a positive gain with temp.

The inverted value needs to be X 10, as i forgot to log that in the program, so 4900 will appear as 490 in the inverted value of the file (3100 as 310... etc)

Code:
Calibrat used     81
Raw ADC value    = 100
Invert ADC value = 655
Calibration req  = 81
Calibrated temp  = 80
Actual temp      = 80

Calibrat used     81
Raw ADC value    = 102
Invert ADC value = 642
Calibration req  = 81
Calibrated temp  = 79
Actual temp      = 79

Calibrat used     81
Raw ADC value    = 105
Invert ADC value = 624
Calibration req  = 80
Calibrated temp  = 77
Actual temp      = 78

Calibrat used     81
Raw ADC value    = 109
Invert ADC value = 601
Calibration req  = 78
Calibrated temp  = 74
Actual temp      = 77

Calibrat used     81
Raw ADC value    = 110
Invert ADC value = 595
Calibration req  = 78
Calibrated temp  = 73
Actual temp      = 76

Calibrat used     81
Raw ADC value    = 114
Invert ADC value = 574
Calibration req  = 76
Calibrated temp  = 70
Actual temp      = 75

Calibrat used     81
Raw ADC value    = 118
Invert ADC value = 555
Calibration req  = 75
Calibrated temp  = 68
Actual temp      = 74

Calibrat used     81
Raw ADC value    = 120
Invert ADC value = 546
Calibration req  = 74
Calibrated temp  = 67
Actual temp      = 73

Calibrat used     81
Raw ADC value    = 123
Invert ADC value = 532
Calibration req  = 73
Calibrated temp  = 65
Actual temp      = 72

Calibrat used     81
Raw ADC value    = 128
Invert ADC value = 511
Calibration req  = 71
Calibrated temp  = 63
Actual temp      = 71

Calibrat used     81
Raw ADC value    = 131
Invert ADC value = 500
Calibration req  = 71
Calibrated temp  = 61
Actual temp      = 70

Calibrat used     81
Raw ADC value    = 135
Invert ADC value = 485
Calibration req  = 70
Calibrated temp  = 59
Actual temp      = 69

Calibrat used     81
Raw ADC value    = 139
Invert ADC value = 471
Calibration req  = 69
Calibrated temp  = 58
Actual temp      = 68

Calibrat used     81
Raw ADC value    = 143
Invert ADC value = 458
Calibration req  = 68
Calibrated temp  = 56
Actual temp      = 67

Calibrat used     81
Raw ADC value    = 142
Invert ADC value = 461
Calibration req  = 69
Calibrated temp  = 56
Actual temp      = 66

Calibrat used     81
Raw ADC value    = 152
Invert ADC value = 431
Calibration req  = 66
Calibrated temp  = 53
Actual temp      = 65

Calibrat used     81
Raw ADC value    = 156
Invert ADC value = 420
Calibration req  = 65
Calibrated temp  = 51
Actual temp      = 64

Calibrat used     81
Raw ADC value    = 161
Invert ADC value = 407
Calibration req  = 64
Calibrated temp  = 50
Actual temp      = 63

Calibrat used     81
Raw ADC value    = 166
Invert ADC value = 394
Calibration req  = 63
Calibrated temp  = 48
Actual temp      = 62

Calibrat used     81
Raw ADC value    = 176
Invert ADC value = 372
Calibration req  = 60
Calibrated temp  = 45
Actual temp      = 61

Calibrat used     81
Raw ADC value    = 177
Invert ADC value = 370
Calibration req  = 61
Calibrated temp  = 45
Actual temp      = 60

Calibrat used     81
Raw ADC value    = 182
Invert ADC value = 360
Calibration req  = 61
Calibrated temp  = 44
Actual temp      = 59

Calibrat used     81
Raw ADC value    = 189
Invert ADC value = 346
Calibration req  = 59
Calibrated temp  = 42
Actual temp      = 58

Calibrat used     81
Raw ADC value    = 194
Invert ADC value = 337
Calibration req  = 59
Calibrated temp  = 41
Actual temp      = 57

Calibrat used     81
Raw ADC value    = 200
Invert ADC value = 327
Calibration req  = 58
Calibrated temp  = 40
Actual temp      = 56

Calibrat used     81
Raw ADC value    = 206
Invert ADC value = 318
Calibration req  = 57
Calibrated temp  = 39
Actual temp      = 55

Calibrat used     81
Raw ADC value    = 213
Invert ADC value = 307
Calibration req  = 56
Calibrated temp  = 37
Actual temp      = 54

Calibrat used     81
Raw ADC value    = 220
Invert ADC value = 297
Calibration req  = 56
Calibrated temp  = 36
Actual temp      = 53

Calibrat used     81
Raw ADC value    = 227
Invert ADC value = 288
Calibration req  = 55
Calibrated temp  = 35
Actual temp      = 52

Calibrat used     81
Raw ADC value    = 232
Invert ADC value = 282
Calibration req  = 55
Calibrated temp  = 34
Actual temp      = 51

Calibrat used     81
Raw ADC value    = 240
Invert ADC value = 273
Calibration req  = 54
Calibrated temp  = 33
Actual temp      = 50

Calibrat used     81
Raw ADC value    = 248
Invert ADC value = 264
Calibration req  = 53
Calibrated temp  = 32
Actual temp      = 49

Calibrat used     81
Raw ADC value    = 256
Invert ADC value = 255
Calibration req  = 53
Calibrated temp  = 31
Actual temp      = 48

Calibrat used     81
Raw ADC value    = 256
Invert ADC value = 255
Calibration req  = 52
Calibrated temp  = 31
Actual temp      = 49

Calibrat used     81
Raw ADC value    = 256
Invert ADC value = 255
Calibration req  = 53
Calibrated temp  = 31
Actual temp      = 48

Calibrat used     81
Raw ADC value    = 264
Invert ADC value = 248
Calibration req  = 52
Calibrated temp  = 30
Actual temp      = 47

Calibrat used     81
Raw ADC value    = 271
Invert ADC value = 241
Calibration req  = 52
Calibrated temp  = 29
Actual temp      = 46

Calibrat used     81
Raw ADC value    = 279
Invert ADC value = 234
Calibration req  = 52
Calibrated temp  = 28
Actual temp      = 45

Calibrat used     81
Raw ADC value    = 288
Invert ADC value = 227
Calibration req  = 51
Calibrated temp  = 28
Actual temp      = 44

Calibrat used     81
Raw ADC value    = 294
Invert ADC value = 222
Calibration req  = 51
Calibrated temp  = 27
Actual temp      = 43

Calibrat used     81
Raw ADC value    = 305
Invert ADC value = 214
Calibration req  = 50
Calibrated temp  = 26
Actual temp      = 42

Calibrat used     81
Raw ADC value    = 306
Invert ADC value = 214
Calibration req  = 49
Calibrated temp  = 26
Actual temp      = 43

Calibrat used     81
Raw ADC value    = 306
Invert ADC value = 214
Calibration req  = 50
Calibrated temp  = 26
Actual temp      = 42

Calibrat used     81
Raw ADC value    = 314
Invert ADC value = 208
Calibration req  = 50
Calibrated temp  = 25
Actual temp      = 41

Calibrat used     81
Raw ADC value    = 324
Invert ADC value = 202
Calibration req  = 50
Calibrated temp  = 24
Actual temp      = 40

Calibrat used     81
Raw ADC value    = 333
Invert ADC value = 196
Calibration req  = 50
Calibrated temp  = 24
Actual temp      = 39

Calibrat used     81
Raw ADC value    = 343
Invert ADC value = 191
Calibration req  = 50
Calibrated temp  = 23
Actual temp      = 38

Calibrat used     81
Raw ADC value    = 343
Invert ADC value = 191
Calibration req  = 48
Calibrated temp  = 23
Actual temp      = 39

Calibrat used     81
Raw ADC value    = 343
Invert ADC value = 191
Calibration req  = 50
Calibrated temp  = 23
Actual temp      = 38

Calibrat used     81
Raw ADC value    = 352
Invert ADC value = 186
Calibration req  = 50
Calibrated temp  = 22
Actual temp      = 37

Calibrat used     81
Raw ADC value    = 362
Invert ADC value = 181
Calibration req  = 50
Calibrated temp  = 22
Actual temp      = 36

Calibrat used     81
Raw ADC value    = 371
Invert ADC value = 176
Calibration req  = 50
Calibrated temp  = 21
Actual temp      = 35

Calibrat used     81
Raw ADC value    = 382
Invert ADC value = 171
Calibration req  = 50
Calibrated temp  = 21
Actual temp      = 34

Calibrat used     81
Raw ADC value    = 394
Invert ADC value = 166
Calibration req  = 50
Calibrated temp  = 20
Actual temp      = 33

Calibrat used     81
Raw ADC value    = 393
Invert ADC value = 166
Calibration req  = 48
Calibrated temp  = 20
Actual temp      = 34

Calibrat used     81
Raw ADC value    = 392
Invert ADC value = 167
Calibration req  = 50
Calibrated temp  = 20
Actual temp      = 33

Calibrat used     81
Raw ADC value    = 403
Invert ADC value = 162
Calibration req  = 50
Calibrated temp  = 20
Actual temp      = 32

Calibrat used     81
Raw ADC value    = 415
Invert ADC value = 157
Calibration req  = 50
Calibrated temp  = 19
Actual temp      = 31

Calibrat used     81
Raw ADC value    = 415
Invert ADC value = 157
Calibration req  = 49
Calibrated temp  = 19
Actual temp      = 32

Calibrat used     81
Raw ADC value    = 414
Invert ADC value = 158
Calibration req  = 50
Calibrated temp  = 19
Actual temp      = 31
 

Armp

Senior Member
Do you have the thermistor values ie resistance vs Temp. Do you have a part number or datasheet for it?
Maybe you can explain the Inverted value, and calibration?
 

g6ejd

Senior Member
Newton-Raphson process is quite easy, try it on a calculator to see:

1. Take your number (that you want SQRT of)
2. Divide by a guess (any number will do, sue the same as the requirement)
3. Take the result of 2 and add the same guess
4. Take the result of 3 and divide by 2
5. The result is your new guess (and the eventual SQRT)
6. Repeat

Example, find SQRT of 2.
2/2 = 1
1 + 2 = 3
3 / 2 = 1.5

1.5 is the new guess:

2 / 1.5 = 1.333
1.333 + 1.5 = 2.833
2.833 / 2 = 1.416

2 / 1.416 = 1.4124293
1.4124293 + 1.416 = 2.833
2.8284293 / 2 = 1.4142146 (2.0000029 when squared)

You can use nearly the same routine to determine the nth root with some minor changes.

And so on.
 

SAborn

Senior Member
Do you have the thermistor values ie resistance vs Temp. Do you have a part number or datasheet for it?
Maybe you can explain the Inverted value, and calibration?
I dont see the need to know those particulars as all i require is a square root of the ADC, but seen you asked...

Its a 10K thermistor and a 10K resistor setup as a voltage divider and the ADC reading the junction voltage.
The recorder data tells the actual values.

The inversion of ADC value is explained above and the line of code is.......
W2 = 65535/ W1

Where W2 is the inverted value and W1 is the ADC reading.
 

SAborn

Senior Member
Yes i do want the temp, but from the recorded data it appears the temp in degrees C, is the ADC value divided by the square root of the ADC reading, so i need the SQR to calculate the temp.
 

westaust55

Moderator
Can you make do with a form of lookup table with entries 1, 4, 9, 16, 25, 36, 49, 81, 121, 144, etc as the squares
Then test your value against each
Eg
IF value <36 and value >= 25 THEN Sqrt = 5
But that needs 256 entries.
A math routine could be implemented to do this in less code along lines Buzby originally suggested using a "guess" technique.
Will have a think once I get some time this morning
 

westaust55

Moderator
After a delay (wrote some code and managed to delete before posting :mad: then sun came out so was gardening time :) )
here is something to try - an integer only SQRT function (akin to the X1/X2 parts SQR function)
It does still use quite a few variables some you may need to poke and peek to save some before running the code.
With some further tweaking you can put the two DO..LOOPs into a outer loop which may save some program space if things are getting tight.
Code:
SYMBOL Entry	= w1
SYMBOL Intermed	= w2
SYMBOL Tempry2	= w3
SYMBOL Result 	= b8
SYMBOL Tempry1	= b9



Main:

; Entry = 64	; sqrt = 8
; Entry = 625	; sqrt = 25
; Entry = 400 	; sqrt = 20
; Entry = 1000 	; sqrt=  31
; Entry = 2000	; sqrt = 44
; Entry = 23456	; sqrt = 153
; Entry = 42356	; sqrt = 205


Tempry1 = Entry / 10000
LOOKUP Tempry1, (0,1,1,1,2,2,2), Result
Intermed = Result * Result
Intermed = Tempry1 - Intermed * 100
Tempry1 = Tempry1 * 100
Tempry1 = Entry / 100 - Tempry1
Intermed = Intermed + Tempry1

Tempry1 = 255 ; = -1 so first increment = 0
DO
  INC Tempry1
  Tempry2 = Result * 20 + Tempry1 * Tempry1
LOOP UNTIL Tempry2 >= Intermed

IF Tempry2 > Intermed THEN : DEC Tempry1 : ENDIF
Tempry2 = Result * 20 + Tempry1 * Tempry1
Result = Result * 10 + Tempry1

Intermed = Intermed - Tempry2 * 100
Tempry2 = Entry // 100
Intermed = Intermed + Tempry2

Tempry1 = 255 ; = -1 so first increment = 0
DO
  INC Tempry1
  IF result <10 THEN
    Tempry2 = Result * 20 + Tempry1 * Tempry1
  ELSE
    Tempry2 = Result/10*10
    Tempry2 = Result + Tempry2 * 10 + Tempry1 * Tempry1
  ENDIF
LOOP UNTIL Tempry2 >= Intermed


  IF Tempry2 > Intermed THEN : DEC Tempry1 : ENDIF
; next line only needed if you want to go further to decimal places
; Tempry2 = Result * 20 + Tempry1 * Tempry1
Result = Result * 10 + Tempry1

SERTXD (#RESULT,cr,lf)
PAUSE 1000
 
Last edited:

SAborn

Senior Member
Thanks Westy, your a legend mate!!

That works well, although its 41 bytes too big to fit into the remaining program space, time to do a little gardening on my program and axe a few sections out to make room.
 

westaust55

Moderator
A bug has been observed in the Squareroot code affecting mid range numbers (ie 4 digits numbers. small numbers and 5 digit numbers were seemingly okay)
Updated the code at post 14

EDIT: and now provided in full ;-)
 
Last edited:

SAborn

Senior Member
Hmmm? i think the code in post #14 is a little short, we at least one of us are missing something..... proberly me?
 

Armp

Senior Member
May I suggest an alternative to using square root?

Linearize the data by changing the 10K resistor to Vcc to a ~3K resistor.
(3K is close to the value of the thermistor at your midpoint of 55C, at least it is for the Vishay 10K NTC, as used by Pete Anderson, which I use.)

The resulting raw ADC readings are then almost linear and the temperature is of the form DegC = A - B.ADC
In my case DegC = 112 - 0.11xADC need to scale for picaxe

ADC= 750, C= 29.5
ADC=300, C= 79.0

May or may not work for your device, I can't tell without the characteristics.
 

SAborn

Senior Member
Thanks Armp,

I will give that a try, as its easy to log the data for a simple resistor change.

I must admit a thermistor is a little of a black art to me on a linear calibration curve, i have used many as a threshold setting point, but never attempted to calibrate one across a wide scale reading.

I had thought there should be a point in resistance across a voltage divider where the ADC voltage should equal the degrees C, but had dismissed that with other solutions.
So good to have a reality check and also test your principal on a balance of mid range resistance.

I will post back with some recorded data on that theory.
 

manuka

Senior Member
Although cheap, NTC thermistors are of course pretty small beer for PICAXE temp. work. Why hence are you using them? The esteemed DS18B20 can be read to a fraction of a degree directly by even a humble 08M. They're somewhat more costly,but have long been the industry standard.

If price is an issue (which often concerns cash strapped schools etc), a thermistor NTC may however have skinflint merit. Check this simple 100k/10k voltage divider schoolie approach -the LED suitably "winks" out readings. A modern bright LED of course can be seen 100s of metres away after dark - more with binoculars.

I recall students took their circuitry home for visual reading of various night time outdoor temperatures-greenhouse etc. One even attached it to a horse blanket to check their darling pony wasn't getting too cold!
 

Dippy

Moderator
Whilst Steinhart is probably a little too tough for PICAXE check out the techniques for linearising thermistors.
This HERE may give you some starting points.
 

SAborn

Senior Member
Stan,

Yes i am aware of the DS18B20 and presently using one as a reference to data log the thermistor calibration, the reason for the thermistor is to replace a DS18B20 that cant handle the temperature range required.
It is for my solar hot water controller, as the DS sensor on the panel outlet pipe suffered a early death. :mad:

Dippy,
Some interesting information in the link.

If i was to do the project again i would use a 20x2 that supports the SQR function, but the controller is already built using a 18m2, so i was looking for a software solution for the SQR to do a simple retrofit of the thermistor.
 

manuka

Senior Member
to replace a DS18B20 that cant handle the temperature range required.
SABorn: DS18B20 failure in SHW (Solar Heated Water)? Mate you're surely joking -are you handling steam?

DS18B20 are rated as good to -55 C to 125 Celsius! I've long used them at temps up to 100 C with absolutely no issues. Although I've heard of occasional high temp woes,these seem to relate to rough power supplies, stressed associated components, leaks, corrosion & unreliable mechanical connections etc. Even in an Adelaide summer SHW is unlikely to be more than ~80 C, so I'd suspect the culprits above should be considered in your case too.

If hot water is >>80 C then you'll run the risk of $eriou$ plumbing woes from failed seals & connections. This can near ruin dwellings if you're away & ignorant of the resulting liquid nightmare. I'd friends here in Nelson (NZ) who had just this happen last summer with their new home. Perhaps make that ex friends, as it was me who'd recommended their (commercial) system...
 

SAborn

Senior Member
Mate you're surely joking -are you handling steam?
No joke mate!
The poor little DS darling was dead as a door nail, and its only been 4 months, and we havent even got to summer yet.

You need to remember as this is a pressurized system the temp can exceed 100C and not boil the water (steam).

The sensor is located on the outlet pipe just outside the panels, so by the time the sensor reaches a temp switch point the water in the panels is much higher, and when the pump turns on it pushes super heated water past the temp sensor, and would seem the 100C+ water is enought to fail the DS sensor over time.

Do you think i would go to the trouble of using a thermistor if i thought the DS would prove to be reliable enough, which is proven not to be, (it had been glitchy for a while before failure)

I did raise a forum thread about the use of a DS sensor for this application some months back, and the general view was the sensor would fail, so the forum was correct, although i felt it was worth trying to find out if the DS would handle it. (and it didnt)
 

manuka

Senior Member
Apologies - I'd not recalled an earlier thread & hadn't realised your setup was "pressurized". Have you mentioned if this sensing is intended just for temperature monitoring, or process (pump?) control ? If the latter I'd still be concerned. Such elevated temps in early season are just asking for high summer plumbing problems of course! Thermistors are not bullet proof either - I'd have more faith in thermocouples.

I've lived with 3 commercial solar water heating systems (pumped & thermosiphon) here in NZ over the last 35 years, & all systems have been problematic. One failure was thermistor related (in winter too). I'll spare you details of the consequences, but relate that I'd now not normally consider SWH as worth the expense & effort, especially since there's little domestic demand for excessive hot water in summer.

PV systems of course have become so cheap that "wired sunlight" is now more feasible,with excess then used to create "coolth" via an air conditioner or beer fridge. Grid tie is always possible too. Apologies again if I've posted this here already, but the late 90's insights of Dougherty,Fanny & Richardson make great reading.
.
 

SAborn

Senior Member
Yes it is pump system and i also agree with the use of thermocouples, for now it was just a quick fix to get the system back into operation after the DS sensor failure, as i have been venting steam for the last week on good days.

One might guess you had a freeze problem with your winter failure, thats why my SHW panels were free, as one had a split pipe due to frost bite, 1/2 hour to pull it apart and weld up the split and Presto... free solar collectors.

As for expense on SHW, thats debateable as in my case the 4m2 of panels were given to me free, and the cost of setup was rather small, other than a little effort on my part.
There is also rebates here for installing SHW, although not for secondhand retro fit systems.

I do have 1.5Kw of grid tied PV panels, and 5Kw of PV on a stand alone off grid system, so the SHW was just a addition to lower the energy needs from the grid, my last power bill was $700.00 credit.

I do enjoy not being fully grid relient for my energy needs, and my out of pocket expences have been very low for all setup costs, as much of it has been supplied free or at low cost through people in the industry, for example my Sunny Island inverter (new in box) was 1/10 of retail cost due to it being old stock. (right place at the right time)
1Kw of panels were purchased as scrap, they had been hit by lightning and replaced under insurance, $10.00 of diodes from China and they are back to full output, that deal also included a 2Kw sunny boy inverter, and after i done some minor repairs its also used on the off grid system (AC coupled system controlled by the Sunny Island)

4Kw of my panels are old design to todays standards, and are lower output per M2, but i dont give a hoot as they were free and i have the roof space to fit them.

I am not able to upgrade the grid tied system above 1.5Kw, or i will loose the higher Kw feed in tarrif i have ($0.58/Kw and drop to $0.06/Kw) and the condition on the free panels were that they not be grid connected.(not used for profit)

I basically live off one bloody big UPS power system, and use the grid for a backup.
Perhaps its not everyones cup of tea, but it suits me, and with just 1 year payback i aint complaining.
 

hippy

Ex-Staff (retired)
Can you make do with a form of lookup table with entries 1, 4, 9, 16, 25, 36, 49, 81, 121, 144, etc as the squares
Then test your value against each
An alternative for determining an integer square root of a 16-bit number is to look up on the MSB of the number, get the maximum value the root could be, then decrement while that value squared is greater than the number you need to determine the root of.

That should involve few iterations so be reasonably fast, though the iterations increase if the number you need to find the root of is below 256.
 

SAborn

Senior Member
For my purpose the calibration problem of the thermistor has been solved for now, and the system is back in use.

There is the possibility i will be back with a new question in a new thread later on the sane project. (Stan said so ;) )

For now the system is back in operation, so problem solved.

I appreciate the efforts from Westaust55 that he put into developing some code to extract the square root of a number.

At this point the system is up and running, with the thread closed from my present point, thanks to all who replied.

Although it is a worth while topic others might like to add code or points of view solutions to.
 
Top