hi folks,
Since the Picaxe does not have floating point, it can be a pain to do units conversions. To keep from constantly reinventing the wheel, I use a conversion procedure that takes care of most stuff. Since the analog inputs on the Picaxe are not hi-res, I usually just convert to 0.1 units resolution.
The attached .pdf shows how I handled analog inputs in my Kayak Control project (misc. projects section). I used a version with no zero offsets to save code space, but here’s the full version.
; USED WITH linearConversion proc shown below
; Following Always Need to be Reserved for Doing Scale Conversions :_
symbol scale1Lo = w6 ; place to put "from" scale bottom
symbol scale1Hi = w7 ; place to put "from" scale top
symbol scale2Lo = w8 ; place to put "to" scale bottom
symbol scale2Hi = w9 ; place to put "to" scale top
symbol span1 = w10 ; place to put "from" scale span
symbol span2 = w11 ; place to put "to" scale span
symbol scale1Val = w12 ; place to put input value (value to be converted)
symbol outValue = w13 ; place to put output value (result of conversion)
symbol outValueLo = b26 ; lo-byte of output value (result of conversion)
symbol outValueHi = b27 ; hi-byte of output value (result of conversion)
; linearConversion -- (v1.00a by M. Ballew 02-01-2015)
; convert value between linear scales
; be aware that Picaxe can only deal with numbers 0...65535, so if the proc gets an
; answer > 65535, it will be incorrect
; i.e. ((scale1Val - scale1Lo) * span2) Must be < 65536
; to verify you're not going over 65535, need to know:
; maxInputValue (which should be = scale1Hi)
; scale1Lo (usually 0, but may be offset)
; span2 (scale2Hi - scale2Lo)
; e.g. to display battery voltage range 0..15.0vdc (1 decimal place)
; scale1Hi (our max input value) = 255, span2Value = 150, scale1Lo = 0
; to test: (255 - 0) * 150 = 38250 (good, well under 65536)
;
; Status: (works ok)
; Don't like that this proc uses so many byte/word registers.
; Consider using RAM (28...511) registers for plugging in conversion scales
; this would cause a loss of speed, but would not tie up so many word regs
;
; Revisions:
; none
;
; Arguments:
; scale1Lo "from" scale bottom
; scale1Hi "from" scale top
; scale2Lo "to" scale bottom
; scale2Hi "to" scale top
; scale1Val "from" scale value to be converted
;
; Results:
; outValue contains scale2 equivalent of scale1Val
; w4...w13 altered
;
; Example:
; let scale1Lo = 0 : let scale1Hi = 255 : let scale2Lo = 0 : let scale2Hi = 5000 ; plug in scales
; let scale1Val = 112 ; value to convert
; gosub linearConversion
;
linearConversion:
let span1 = scale1Hi - scale1Lo
let span2 = scale2Hi - scale2Lo
let outValue = scale1Val - scale1Lo * span2 / span1 + scale2Lo
; round off remainder
let w5 = scale1Val * span2 // span1 ; get remainder
let w4 = span1 / 2
if w5 > w4 then
let outValue = outValue + 1
endif
return
Since the Picaxe does not have floating point, it can be a pain to do units conversions. To keep from constantly reinventing the wheel, I use a conversion procedure that takes care of most stuff. Since the analog inputs on the Picaxe are not hi-res, I usually just convert to 0.1 units resolution.
The attached .pdf shows how I handled analog inputs in my Kayak Control project (misc. projects section). I used a version with no zero offsets to save code space, but here’s the full version.
; USED WITH linearConversion proc shown below
; Following Always Need to be Reserved for Doing Scale Conversions :_
symbol scale1Lo = w6 ; place to put "from" scale bottom
symbol scale1Hi = w7 ; place to put "from" scale top
symbol scale2Lo = w8 ; place to put "to" scale bottom
symbol scale2Hi = w9 ; place to put "to" scale top
symbol span1 = w10 ; place to put "from" scale span
symbol span2 = w11 ; place to put "to" scale span
symbol scale1Val = w12 ; place to put input value (value to be converted)
symbol outValue = w13 ; place to put output value (result of conversion)
symbol outValueLo = b26 ; lo-byte of output value (result of conversion)
symbol outValueHi = b27 ; hi-byte of output value (result of conversion)
; linearConversion -- (v1.00a by M. Ballew 02-01-2015)
; convert value between linear scales
; be aware that Picaxe can only deal with numbers 0...65535, so if the proc gets an
; answer > 65535, it will be incorrect
; i.e. ((scale1Val - scale1Lo) * span2) Must be < 65536
; to verify you're not going over 65535, need to know:
; maxInputValue (which should be = scale1Hi)
; scale1Lo (usually 0, but may be offset)
; span2 (scale2Hi - scale2Lo)
; e.g. to display battery voltage range 0..15.0vdc (1 decimal place)
; scale1Hi (our max input value) = 255, span2Value = 150, scale1Lo = 0
; to test: (255 - 0) * 150 = 38250 (good, well under 65536)
;
; Status: (works ok)
; Don't like that this proc uses so many byte/word registers.
; Consider using RAM (28...511) registers for plugging in conversion scales
; this would cause a loss of speed, but would not tie up so many word regs
;
; Revisions:
; none
;
; Arguments:
; scale1Lo "from" scale bottom
; scale1Hi "from" scale top
; scale2Lo "to" scale bottom
; scale2Hi "to" scale top
; scale1Val "from" scale value to be converted
;
; Results:
; outValue contains scale2 equivalent of scale1Val
; w4...w13 altered
;
; Example:
; let scale1Lo = 0 : let scale1Hi = 255 : let scale2Lo = 0 : let scale2Hi = 5000 ; plug in scales
; let scale1Val = 112 ; value to convert
; gosub linearConversion
;
linearConversion:
let span1 = scale1Hi - scale1Lo
let span2 = scale2Hi - scale2Lo
let outValue = scale1Val - scale1Lo * span2 / span1 + scale2Lo
; round off remainder
let w5 = scale1Val * span2 // span1 ; get remainder
let w4 = span1 / 2
if w5 > w4 then
let outValue = outValue + 1
endif
return
Attachments
-
452.8 KB Views: 12