Magnetometer PICAXE 20M2 program
From ShawnReevesWiki
Jump to navigationJump to searchPICAXE 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