Skip to content

Instantly share code, notes, and snippets.

@Dhee2211
Forked from aprovecharLab/magRM3100.ipynb
Created August 19, 2021 17:29
Show Gist options
  • Save Dhee2211/5b0fc1060e2b07682f4107cff8a15dec to your computer and use it in GitHub Desktop.
Save Dhee2211/5b0fc1060e2b07682f4107cff8a15dec to your computer and use it in GitHub Desktop.
Reading the PNI RM3100 Magnetometer
Display the source blob
Display the rendered blob
Raw
{
"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