Magnetometer PICAXE 20M2 program

From ShawnReevesWiki
Revision as of 12:52, 14 March 2014 by Shawn (talk | contribs) (Created page with "===PICAXE Program=== This program works with the circuit described in Magnetometer, when programmed on a [http://picaxe.com PICAXE] 20M2. ;2014 Shawn Reeves ;TEST RESULT...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

PICAXE Program

This program works with the circuit described in Magnetometer, when programmed on a PICAXE 20M2.

;2014 Shawn Reeves
;TEST RESULTS:
; Power consumption:6mA at 5V, i.e. 30mW
; ADC readings:163 to 870, zero at 514
; Not absolutely linear—Use lookup table for accuracy.

;Power with a 5V DC supply. Use either USB, phone charger, or 9V battery via voltage regulator.
#picaxe 20m2

;Choose which output(s) to use:
#define useLCD
#define useSerial

symbol adcPin = C.7	;20M2 pin 3 to SS49 pin 3
symbol dataOut = B.3 ;20M2 pin 15 to DOGM pin 28
symbol SCK = B.2 ;20M2 pin 16 to DOGM pin 29
symbol CSB = B.6 ;20M2 pin 12 to DOGM pin 38
symbol RS = B.4 ;20M2 pin 14 to DOGM pin 39
;assign bit memory first
symbol negabit = bit0	;all PICAXE maths are positive integers, so we use this bit to signify negative
symbol overflowbit = bit1
;assign byte memory next, avoiding conflicts with above (divide above highest by 8, round down, add one)
symbol ones = b1;these will hold ASCII values for each digit
symbol tens = b2
symbol hundreds = b3
symbol thousands = b4
symbol tenthousands = b5
symbol counter = b6
symbol byteOut = b7
;assign word memory next, avoiding conflicts with above (divide above highest by two, round down, add one)
symbol reading = w4
symbol Gauss = w5
symbol clearCommand = 1
symbol homeCommand = 2

;This routine should initialize the Electronic Assembly DOG-ME-081 8 character LCD display
;use symbol command to assign CSB, RS, dataOut, and SCK to out pins
;assign a byte variable to byteOut and shiftCounter
initDOG:
high CSB ;in case spurious signals were received during powerup
low SCK;prepare clock to work on rise
low CSB;select chip
low RS;sending commands, not data
;The following lines from Electronic Assembly's data sheet, with cursor mode altered.
;One might repeat the following command many times to get the attention of the ST7032 driver
byteOut = %00110000 ;Function Set, 1 line, instruction table 0
gosub shiftout_MSBFirst
pauseus 27;recommended by ST7032 datasheet

byteOut = %00110001 ;Function Set, 1 line, instruction table 1
gosub shiftout_MSBFirst
pauseus 27;recommended by ST7032 datasheet

byteOut = %00110001 ;Function Set, 1 line, instruction table 1, repeat request recommended by ST7032 datasheet
gosub shiftout_MSBFirst
pauseus 27;recommended by ST7032 datasheet

byteOut = %00011100 ;Bias 1/4, 1 line LCD
gosub shiftout_MSBFirst
pauseus 27;recommended by ST7032 datasheet

byteOut = %01010001 ;Booster off, set contrast C5, C4
gosub shiftout_MSBFirst
pauseus 27;recommended by ST7032 datasheet

byteOut = %01101010 ;set voltage follower on, gain 2/7
gosub shiftout_MSBFirst
pause 200;recommended by ST7032 datasheet

byteOut = %01110100 ;set contrast C3, C2, C1
gosub shiftout_MSBFirst
pauseus 27;recommended by ST7032 datasheet

byteOut = %00001100 ;display on, cursor off, blink cursor position
gosub shiftout_MSBFirst
pauseus 27;recommended by ST7032 datasheet

byteOut = %00000001 ;clear display, home cursor
gosub shiftout_MSBFirst
pauseus 2

byteOut = %00000110 ;entry from right to left (or opposite?), no scrolling.
gosub shiftout_MSBFirst
high RS;switch to data mode

main:

readHallSensor:
readadc10 adcPin, reading 	;get a 10-bit ADC into a word

convertToGauss:
;we have a number from 0 to 1023, representing voltage from 0 to 5V (or VCC)
;The SS49E Hall Sensor, at room temp, will output 0.8V at -1000 Gauss to 4V for 1000 Gauss, with zero at 2.5V
;We use a rough linear interpolation rather than a lookup table or polynomial curve
;According to measurements, the output goes from 163 to 871, a range we assume to represent -1000 to 1000 Gauss
;So, we multiply by the fraction 2000/708 to get Gauss from the adc reading.
;To make sure we don't go over 65535, the limit on our 16 bit positive integer math, we reduce the fraction to 175/62:
;;Maximum reading = 354*175 = 61950 < 65535

negabit=0
overflowbit = 0
if reading > 870 then
	overflowbit = 1
elseif reading > 516 then
	reading = reading-516
	Gauss=reading*175/62
elseif reading = 516 then
	Gauss = 0
elseif reading > 163 then
	reading = 516-reading
	Gauss = reading*175/62
	negabit = 1
else
	overflowbit = 1
	negabit = 1
endif
displayDigits:

#ifdef useSerial
	if negabit = 1 then
		sertxd ("-")
	endif
	if overflowbit = 1 then
		sertxd ("out of range",13,10)
	else
		sertxd (#Gauss," Gauss",13,10)	;baud 4800 8N1
	endif
#endif

#ifdef useLCD
;split the result into digits
bintoascii Gauss, tenthousands, thousands, hundreds, tens, ones;Convert to digits and add 48 to each.
;We use an Electronic Assembly (Germany) DOGM081W-A, with 8 digits and an ST7036 controller capable of SPI comm.
low RS	;for outputting command
byteOut = clearCommand; alternatively set DRAM address to beginning of display. This may take too long:maybe we just go home and overwrite?
gosub shiftout_MSBFirst
pause 2	;clear takes between 1 and 2 ms to execute.
high RS	;for outputting data
if negabit = 1 then
	byteOut =  %00101101	;code for negative sign
	gosub shiftout_MSBFirst
endif
if overflowbit = 1 then
	if negabit = 0 then
		byteOut = "o";ascii byte for 'o'
		gosub shiftout_MSBFirst
		byteOut = "v"
		gosub shiftout_MSBFirst
		byteOut = "e"
		gosub shiftout_MSBFirst
		byteOut = "r"
		gosub shiftout_MSBFirst
	else
		byteOut = "u"
		gosub shiftout_MSBFirst
		byteOut = "n"
		gosub shiftout_MSBFirst
		byteOut = "d"
		gosub shiftout_MSBFirst
		byteOut = "e"
		gosub shiftout_MSBFirst
		byteOut = "r"
		gosub shiftout_MSBFirst
	endif
else
	byteOut =  thousands
	gosub shiftout_MSBFirst
	byteOut =  hundreds
	gosub shiftout_MSBFirst
	byteOut =  tens
	gosub shiftout_MSBFirst
	byteOut =  ones
	gosub shiftout_MSBFirst
endif
#endif

pause 490	;wait half a second, minus a bit to account for display routine

goto main	;do it all again

shiftout_MSBFirst:
for counter = 1 to 8
	if byteOut > 127 then ;MSb must be 1
		high dataOut
	else
		low dataOut
	endif
	;data must be set at least 10ns before clock rises. If overclocking, uncomment the following line:
	;pauseus 1
	high SCK
	byteOut = byteOut * 2	;Shift the value so we mask the next bit
	;data must remain set at least 150ns after clock rises.
	pauseus 1	;wait 10 microseconds.
	low SCK
next counter
return