Magnetometer PICAXE 20M2 program: Difference between revisions
From ShawnReevesWiki
Jump to navigationJump to search
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..." |
(No difference)
|
Latest revision as of 12:52, 14 March 2014
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