-
-
Save Dhee2211/5b0fc1060e2b07682f4107cff8a15dec to your computer and use it in GitHub Desktop.
Reading the PNI RM3100 Magnetometer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Reading the PNI RM3100 Magnetometer\n", | |
"### with FTDI USB/i2c\n", | |
"- PNI RM3100 Magnetometer: https://www.pnicorp.com/product/rm3100-evaluation-board/\n", | |
"- AdaFruit FT232H USB to i2c interface: https://www.adafruit.com/product/2264\n", | |
"- PyFtdi library: http://eblot.github.io/pyftdi/index.html" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"from pyftdi.i2c import I2cController\n", | |
"from os import environ\n", | |
"\n", | |
"import math\n", | |
"import time\n", | |
"\n", | |
"import struct" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"###############################################################################\n", | |
"def recast24to32(byte0,byte1,byte2):\n", | |
" # pack 24 bits (3 bytes) into 32 bits byte-type\n", | |
" b24 = struct.pack('xBBB',byte0,byte1,byte2)\n", | |
"\n", | |
" # unpack to unsigned long integer\n", | |
" uL = struct.unpack('>L',b24)[0]\n", | |
"\n", | |
" # this is for 2's complement signed numbers - \n", | |
" # if negative assign sign bits for 32 bit case\n", | |
" if (uL & 0x00800000):\n", | |
" uL = uL | 0xFF000000\n", | |
"\n", | |
" # repack as 32 bit unsigned long byte-type\n", | |
" packed = struct.pack('>L', uL)\n", | |
" # unpack as 32 bit signed long integer\n", | |
" unpacked = struct.unpack('>l', packed)[0]\n", | |
"\n", | |
" return unpacked" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"class FTDIi2c:\n", | |
" def __init__(self):\n", | |
" self.i2c = I2cController()\n", | |
" url = environ.get('FTDI_DEVICE', 'ftdi://ftdi:232h/1')\n", | |
" self.i2c.configure(url, clockstretching=False)\n", | |
"\n", | |
" def connect(self,address):\n", | |
" port = self.i2c.get_port(address)\n", | |
" return port\n", | |
"\n", | |
" def close(self):\n", | |
" # Close the I2C connection\n", | |
" self.i2c.terminate()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"###############################################################################\n", | |
"class i2cMAG:\n", | |
"\n", | |
" # default RM3100 I2C Address\n", | |
"## rm3100_ADDRESS = 0x20 # 0b0100000 - pins SA0:low, SA1:low\n", | |
"# rm3100_ADDRESS = 0x23 # 0b0100000 - pins SA0:high, SA1:high\n", | |
"\n", | |
" # RM3100 Register map \n", | |
" rm3100_POLL = 0x00\n", | |
" rm3100_CMM = 0x01\n", | |
" rm3100_NOS = 0x0A\n", | |
" rm3100_TMRC = 0x0B\n", | |
"\n", | |
" rm3100_CCx1 = 0x04\n", | |
" rm3100_CCx0 = 0x05\n", | |
" rm3100_CCy1 = 0x06\n", | |
" rm3100_CCy0 = 0x07\n", | |
" rm3100_CCz1 = 0x08\n", | |
" rm3100_CCz0 = 0x09\n", | |
"\n", | |
" rm3100_Mx2w = 0x24\n", | |
" rm3100_Mxyz = 0x70\n", | |
"\n", | |
" rm3100_BIST = 0x33\n", | |
" rm3100_STATUS = 0x34\n", | |
" rm3100_HSHAKE = 0x35\n", | |
" rm3100_REVID = 0x36\n", | |
"\n", | |
"# CCP0 = 0x64 # 100 Cycle Count\n", | |
"# CCP1 = 0x00\n", | |
"# CCP0 = 0xC8 # 200 Cycle Count\n", | |
"# CCP1 = 0x00\n", | |
" CCP0 = 0x90 # 400 Cycle Count\n", | |
" CCP1 = 0x01\n", | |
"\n", | |
" NOS = 0x01 # Number of Samples for averaging\n", | |
" TMRC = 0x04 # Default rate 125 Hz\n", | |
"\n", | |
" rm3100_set = [None]*8\n", | |
" rm3100_set[0] = CCP1 # CCPX1\n", | |
" rm3100_set[1] = CCP0 # CCPX0\n", | |
" rm3100_set[2] = CCP1 # CCPY1\n", | |
" rm3100_set[3] = CCP0 # CCPY0\n", | |
" rm3100_set[4] = CCP1 # CCPZ1\n", | |
" rm3100_set[5] = CCP0 # CCPZ0\n", | |
" rm3100_set[6] = NOS\n", | |
" rm3100_set[7] = TMRC\n", | |
"\n", | |
"# rm3100_resolution = 13.0*2.0 # nT/lsb, 100 cycle @ 1 avg\n", | |
"# rm3100_resolution = 13.0 # nT/lsb, 200 cycle @ 1 avg\n", | |
" rm3100_resolution = 13.0/2.0 # nT/lsb, 400 cycle @ 1 avg\n", | |
"\n", | |
" ###########################################################################\n", | |
" def __init__(self,port):\n", | |
" self.port = port\n", | |
" \n", | |
" def configure(self):\n", | |
" # clears MAG and BEACON register and any pending measurement\n", | |
" self.port.write_to(self.rm3100_POLL, [0x00, 0x00]);\n", | |
" # write list of settings to device\n", | |
" self.port.write_to(self.rm3100_CCx1, self.rm3100_set)\n", | |
" return self.rm3100_set\n", | |
"\n", | |
" def device_ID(self):\n", | |
" device_id = self.port.exchange([self.rm3100_REVID], 1)[0]\n", | |
" return device_id\n", | |
"\n", | |
" ###########################################################################\n", | |
" # Read the magnetometer\n", | |
" def read(self):\n", | |
" # initiate single measurement of all 3 axes\n", | |
" self.port.write_to(self.rm3100_POLL, [self.rm3100_Mxyz])\n", | |
" raw = self.port.read_from(self.rm3100_Mx2w, 9)\n", | |
" if raw == []:\n", | |
" return []\n", | |
" results = []\n", | |
" for i in range(0, 9, 3):\n", | |
" data = float(recast24to32(raw[i],raw[i+1],raw[i+2]))*self.rm3100_resolution\n", | |
" results.append(data)\n", | |
" return results" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Device Config: b'\\x01\\x90\\x01\\x90\\x01\\x90\\x01\\x04'\n", | |
"Device ID: 0x22\n", | |
" \n", | |
"magXYZ: [-12889.5, 10127.0, 45812.0] \t |M|: 48656.29130184503\n", | |
"magXYZ: [-12876.5, 10075.0, 45831.5] \t |M|: 48660.41789278016\n", | |
"magXYZ: [-12844.0, 10062.0, 45792.5] \t |M|: 48612.39796852239\n", | |
"magXYZ: [-12824.5, 10029.5, 45844.5] \t |M|: 48649.530837922786\n", | |
"magXYZ: [-12870.0, 10068.5, 45844.5] \t |M|: 48669.59803100905\n", | |
"magXYZ: [-12876.5, 10036.0, 45877.0] \t |M|: 48695.22232467986\n", | |
"magXYZ: [-12811.5, 10075.0, 45825.0] \t |M|: 48637.1337791404\n", | |
"magXYZ: [-12863.5, 10068.5, 45844.5] \t |M|: 48667.879599896274\n", | |
"magXYZ: [-12889.5, 10094.5, 45825.0] \t |M|: 48661.77930881689\n", | |
"magXYZ: [-12941.5, 10068.5, 45844.5] \t |M|: 48688.55404250572\n" | |
] | |
} | |
], | |
"source": [ | |
"i2c = FTDIi2c()\n", | |
"\n", | |
"port_rm3100 = i2c.connect(0x23)\n", | |
"MAG = i2cMAG(port_rm3100)\n", | |
"\n", | |
"deviceConfig = MAG.configure()\n", | |
"print ('Device Config: ', bytes(deviceConfig))\n", | |
"id = MAG.device_ID()\n", | |
"print ('Device ID: ',hex(id))\n", | |
"print(' ')\n", | |
"\n", | |
"for i in range(10):\n", | |
" magXYZ = MAG.read()\n", | |
" print ('magXYZ: ',magXYZ, '\\t |M|: ',math.sqrt(magXYZ[0]**2 + magXYZ[1]**2 + magXYZ[2]**2))\n", | |
" time.sleep(0.1)\n", | |
"\n", | |
"i2c.close()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.7.1" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment