Problem with comparison.
/Modules/Sensors/MAG01A/SW/Python/MAG_test.ipynb |
---|
0,0 → 1,704 |
{ |
"metadata": { |
"name": "" |
}, |
"nbformat": 3, |
"nbformat_minor": 0, |
"worksheets": [ |
{ |
"cells": [ |
{ |
"cell_type": "markdown", |
"metadata": {}, |
"source": [ |
"Uk\u00e1zka pou\u017eit\u00ed n\u00e1stroje IPython na manipulaci se senzorov\u00fdmi daty\n", |
"=======\n", |
"\n", |
"P\u0159\u00edklad vyu\u017e\u00edv\u00e1 modulovou stavebnici MLAB a jej\u00ed knihovnu [pymlab](https://github.com/MLAB-project/MLAB-I2c-modules). Sn\u00edma\u010d je k po\u010d\u00edta\u010di p\u0159ipojen\u00fd p\u0159es rozhradn\u00ed USB a data jsou vy\u010d\u00edt\u00e1na p\u0159es [I\u00b2C](http://wiki.mlab.cz/doku.php?id=cs:i2c)\n", |
"\n", |
"Pou\u017eit\u00fd sn\u00edma\u010d [HMC5883L](http://www.magneticsensors.com/three-axis-digital-compass.php) m\u00e1 n\u00e1sleduj\u00edc\u00ed katalogov\u00e9 parametry: \n", |
"\n", |
"* M\u011b\u0159\u00edc\u00ed rozsah +/- 800 uT\n", |
"* Rozli\u0161en\u00ed typicky 5 uT\n", |
"* \u010cetnost m\u011b\u0159en\u00ed 75 Hz\n", |
"\n", |
"Zprovozn\u011bn\u00ed demo k\u00f3du\n", |
"---------------------\n", |
"\n", |
"Nejd\u0159\u00edve zjist\u00edme zda m\u00e1me p\u0159\u00edstup pro z\u00e1pis a \u010dten\u00ed do syst\u00e9mov\u00e9ho za\u0159\u00edzen\u00ed. A jak\u00e9 \u010d\u00edslo m\u00e1 I\u00b2C sb\u011brnice na kterou m\u00e1me p\u0159ipojen\u00e1 \u010didla. \n" |
] |
}, |
{ |
"cell_type": "code", |
"collapsed": false, |
"input": [ |
"!i2cdetect -l" |
], |
"language": "python", |
"metadata": {}, |
"outputs": [ |
{ |
"output_type": "stream", |
"stream": "stdout", |
"text": [ |
"i2c-0\ti2c \ti915 gmbus ssc \tI2C adapter\r\n", |
"i2c-1\ti2c \ti915 gmbus vga \tI2C adapter\r\n", |
"i2c-2\ti2c \ti915 gmbus panel \tI2C adapter\r\n", |
"i2c-3\ti2c \ti915 gmbus dpc \tI2C adapter\r\n", |
"i2c-4\ti2c \ti915 gmbus dpb \tI2C adapter\r\n", |
"i2c-5\ti2c \ti915 gmbus dpd \tI2C adapter\r\n", |
"i2c-6\ti2c \tDPDDC-B \tI2C adapter\r\n", |
"i2c-7\ti2c \ti2c-tiny-usb at bus 001 device 070\tI2C adapter\r\n" |
] |
} |
], |
"prompt_number": 1 |
}, |
{ |
"cell_type": "markdown", |
"metadata": {}, |
"source": [ |
"Proto\u017ee pro p\u0159ipojen\u00ed \u010didel k po\u010d\u00edta\u010di pou\u017e\u00edv\u00e1me adapt\u00e9r i2c-tiny-usb. Vid\u00edme, \u017ee sb\u011brnice m\u00e1 aktu\u00e1ln\u011b ozna\u010den\u00ed nap\u0159\u00edklad i2c-8. \n", |
"\n", |
"V p\u0159\u00edpad\u011b, \u017ee v\u00fd\u0161e uveden\u00fd p\u0159\u00edklad vr\u00e1t\u00ed chybu, nebo pojmenov\u00e1n\u00ed \"unknown\" tak nem\u00e1me p\u0159\u00edstup k syst\u00e9mov\u00fdm rozhran\u00edm. Ten z\u00edsk\u00e1me vytvo\u0159en\u00edm souboru s n\u00e1sleduj\u00edc\u00edm obsahem ve slo\u017ece: /etc/udev/rules.d/i2c-devices.rules" |
] |
}, |
{ |
"cell_type": "raw", |
"metadata": {}, |
"source": [ |
"KERNEL==\"i2c-[0-9]*\", GROUP=\"i2c\"" |
] |
}, |
{ |
"cell_type": "markdown", |
"metadata": {}, |
"source": [ |
"Toto ozna\u010den\u00ed budeme je\u0161t\u011b d\u00e1le pot\u0159ebovat, proto si jej ulo\u017e\u00edme da prom\u011bnn\u00e9. " |
] |
}, |
{ |
"cell_type": "code", |
"collapsed": false, |
"input": [ |
"port = 7" |
], |
"language": "python", |
"metadata": {}, |
"outputs": [], |
"prompt_number": 2 |
}, |
{ |
"cell_type": "markdown", |
"metadata": {}, |
"source": [ |
"Budeme pokra\u010dovat na\u010dten\u00edm pot\u0159ebn\u00fdch modul\u016f pro zach\u00e1zen\u00ed s I\u00b2C sn\u00edma\u010di." |
] |
}, |
{ |
"cell_type": "code", |
"collapsed": false, |
"input": [ |
"import time\n", |
"import datetime\n", |
"import sys\n", |
"\n", |
"from pymlab import config\n", |
"import matplotlib.pyplot as plt\n", |
"import numpy as np" |
], |
"language": "python", |
"metadata": {}, |
"outputs": [], |
"prompt_number": 3 |
}, |
{ |
"cell_type": "markdown", |
"metadata": {}, |
"source": [ |
"Nyn\u00ed si nadefinujeme strukturu p\u0159ipojen\u00ed jednotliv\u00fdch \u010didel na I\u00b2C sb\u011brnici." |
] |
}, |
{ |
"cell_type": "code", |
"collapsed": false, |
"input": [ |
"cfg = config.Config(\n", |
" i2c = {\n", |
" \"port\": port,\n", |
" },\n", |
" bus = [\n", |
" {\n", |
" \"type\": \"i2chub\",\n", |
" \"address\": 0x71,\n", |
" \n", |
" \"children\": [\n", |
" {\"name\": \"mag\", \"type\": \"mag01\", \"gauss\": 0.88, \"channel\": 0, }, \n", |
" ],\n", |
" },\n", |
" ],\n", |
")" |
], |
"language": "python", |
"metadata": {}, |
"outputs": [], |
"prompt_number": 26 |
}, |
{ |
"cell_type": "markdown", |
"metadata": {}, |
"source": [ |
"Tuto strukturu inicializujeme, aby jsme dos\u00e1hli definovan\u00e9 konfigurace \u010didel." |
] |
}, |
{ |
"cell_type": "code", |
"collapsed": false, |
"input": [ |
"cfg.initialize()\n", |
"mag_sensor = cfg.get_device(\"mag\")\n", |
"time.sleep(0.5)" |
], |
"language": "python", |
"metadata": {}, |
"outputs": [], |
"prompt_number": 27 |
}, |
{ |
"cell_type": "markdown", |
"metadata": {}, |
"source": [ |
"Nyn\u00ed u\u017e m\u016f\u017eeme p\u0159\u00edmo komunikovat se za\u0159\u00edzen\u00edm pojmenovan\u00fdm jako mag_sensor. A vy\u010d\u00edst z n\u011bj sadu dat." |
] |
}, |
{ |
"cell_type": "code", |
"collapsed": false, |
"input": [ |
"import sys\n", |
"import time\n", |
"from IPython.display import clear_output\n", |
"\n", |
"MEASUREMENTS = 500\n", |
"list_meas = []\n", |
"\n", |
"for n in range(MEASUREMENTS):\n", |
"# mag_sensor.route() #V p\u0159\u00edpad\u011b v\u00edce \u010didel je pot\u0159eba ke ka\u017ed\u00e9mu p\u0159ed jeho pou\u017eit\u00edm nechat vyroutovat cesutu na sb\u011brnici.\n", |
" clear_output()\n", |
" (x, y, z) = mag_sensor.axes()\n", |
" list_meas.append([x, y, z])\n", |
" print (n, list_meas[n])\n", |
" time.sleep(0.2)\n", |
" sys.stdout.flush()" |
], |
"language": "python", |
"metadata": {}, |
"outputs": [ |
{ |
"output_type": "stream", |
"stream": "stdout", |
"text": [ |
"(499, [5.109999999999999, 163.51999999999998, -689.85])\n" |
] |
} |
], |
"prompt_number": 31 |
}, |
{ |
"cell_type": "markdown", |
"metadata": {}, |
"source": [ |
"V\u00fdstupn\u00ed jsou v jednotk\u00e1ch miliGauss a m\u011b\u0159\u00edc\u00ed rozsah je nastaven\u00fd na 0.88 Gauss. Viz konfigurace \u010didel naho\u0159e.\n", |
"Nam\u011b\u0159en\u00e9 hodnoty n\u00e1sledn\u011b ulo\u017e\u00edme do souboru. " |
] |
}, |
{ |
"cell_type": "code", |
"collapsed": false, |
"input": [ |
"np.savez(\"calibration_data_2Dset\", data=list_meas)" |
], |
"language": "python", |
"metadata": {}, |
"outputs": [], |
"prompt_number": 32 |
}, |
{ |
"cell_type": "markdown", |
"metadata": {}, |
"source": [ |
"Zpracov\u00e1n\u00ed dat 2D\n", |
"-----------\n", |
"\n", |
"V dal\u0161\u00ed \u010d\u00e1sti budeme pracovat s daty v ulo\u017een\u00e9m souboru, kter\u00fd na\u010dteme do pol\u00ed x, y, z. " |
] |
}, |
{ |
"cell_type": "code", |
"collapsed": false, |
"input": [ |
"data = np.load('./calibration_data_2Dset.npz')\n", |
"list_meas = data['data']\n", |
"x = list_meas[:, 0]\n", |
"y = list_meas[:, 1]\n", |
"z = list_meas[:, 2]" |
], |
"language": "python", |
"metadata": {}, |
"outputs": [], |
"prompt_number": 33 |
}, |
{ |
"cell_type": "markdown", |
"metadata": {}, |
"source": [ |
"Nam\u011b\u0159en\u00e9 hodnoty vykresl\u00edme do 3D grafu." |
] |
}, |
{ |
"cell_type": "code", |
"collapsed": false, |
"input": [ |
"from mpl_toolkits.mplot3d.axes3d import Axes3D\n", |
"#%pylab qt\n", |
"%pylab inline\n", |
"fig = plt.figure()\n", |
"ax = Axes3D(fig)\n", |
"p = ax.scatter(x,y,z)" |
], |
"language": "python", |
"metadata": {}, |
"outputs": [ |
{ |
"output_type": "stream", |
"stream": "stdout", |
"text": [ |
"Populating the interactive namespace from numpy and matplotlib\n" |
] |
}, |
{ |
"metadata": {}, |
"output_type": "display_data", |
"png": "iVBORw0KGgoAAAANSUhEUgAAAb4AAAEuCAYAAADx63eqAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsnXmYVNWd9z+39qWrF2i6aRqaXUE2FVQQcAX3JWoS9U3G\nSEw0iZNHMxnHzCS+RsdkNMlE8ybjZNHJmOiocdSoEQUXREFF2WRtdmmapRu66drXe+/7R3nK20VV\nde291P08D48JVN977ulb53t+v/NbJFVVVXR0dHR0dCoEQ38PQEdHR0dHp5zowqejo6OjU1Howqej\no6OjU1Howqejo6OjU1Howqejo6OjU1Howqejo6OjU1Howqejo6OjU1Howqejo6OjU1Howqejo6Oj\nU1Howqejo6OjU1Howqejo6OjU1Howqejo6OjU1Howqejo6OjU1Howqejo6OjU1Howqejo6OjU1Ho\nwqejo6OjU1Howqejo6OjU1Howqejo6OjU1Howqejo6OjU1Howqejo6OjU1Howqejo6OjU1Howqej\no6OjU1Howqejo6OjU1Howqejo6OjU1GY+nsAOjqlRFEUYrEYoVAIk8mE0WjEaDRiMBiQJAlJkvp7\niDo6OmVGFz6dIYmiKIRCIQBUVUWWZRRFQVXVxH+1QqgLoo5O5aALn86QQlEUotEoiqLg9XqpqqpK\nCJnRaARI/LvBYEBRFGRZPuE6QghNJhMGg0EXRB2dIYQufDqDHlVVUVU1IWgAkiShqiqxWIxwOIws\nywkBE59XVRVJkjAYDCdcTwhiJBJJ/L34rC6IOjqDG0lVVbW/B6Gjkw/pBA8gEong9/sxGAzY7fbE\nZ8WZn/i8qqoJAdP+SSVmWsHUoguijs7gQhc+nUFHKgHTCl4wGEy4MZ1OJ0ajkWg0mvhMNBpFlmVs\nNlviWsl/ii2I+hmijs7AQXd16gwakgVPKyDhcJhQKITBYMDpdGIymfB4PH0KjDj7E+d/yfcSf4RV\nmUkQ07lMg8EgkiRhNpsT9zQYDIngGt1C1NEpL7rw6Qx4RFSmiMxMJXhGoxGn05kQF+3Piv+KnxHn\nf5kotiBqg2vENcLhcNp7agUxWVB1dHQKQxc+nQGLELxYLJYQLiFeoVAokZtXVVWFyXTiq6y1nopl\nSWUSRCHMqdyw4v7C9ZnKOgQSz5vqntrzQ6PRqFuHOjp5ogufzoBDRGMKARBWk6qqvQTP5XKlFLxk\n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\nRK5CYII=\n", |
"text": [ |
"<matplotlib.figure.Figure at 0x7f5bf89a3590>" |
] |
} |
], |
"prompt_number": 34 |
}, |
{ |
"cell_type": "markdown", |
"metadata": {}, |
"source": [ |
"Pro lep\u0161\u00ed zobrazen\u00ed jednotliv\u00fdch zkreslen\u00ed vykresl\u00edme i 2D pr\u016fm\u011bt dat." |
] |
}, |
{ |
"cell_type": "code", |
"collapsed": false, |
"input": [ |
"plt.plot(x, y,'.')" |
], |
"language": "python", |
"metadata": {}, |
"outputs": [ |
{ |
"metadata": {}, |
"output_type": "pyout", |
"prompt_number": 36, |
"text": [ |
"[<matplotlib.lines.Line2D at 0x7f5bf8806910>]" |
] |
}, |
{ |
"metadata": {}, |
"output_type": "display_data", |
"png": "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\noOMnhJAk4/8DBn8m5sEsux0AAAAASUVORK5CYII=\n", |
"text": [ |
"<matplotlib.figure.Figure at 0x7f5bf88a9ad0>" |
] |
} |
], |
"prompt_number": 36 |
}, |
{ |
"cell_type": "markdown", |
"metadata": {}, |
"source": [ |
"Z grafu je vid\u011bt, \u017ee se uplat\u0148uj\u00ed oba zn\u00e1m\u00e9 deforma\u010dn\u00ed jevy - soft-iron a hard-iron. Pokus\u00edme se je proto kompenzovat. Nejd\u0159\u00edve zkus\u00edme odstranit Hard-iron efekty zp\u016fsobuj\u00edc\u00ed offsety." |
] |
}, |
{ |
"cell_type": "code", |
"collapsed": false, |
"input": [ |
"xoffset = (min(x) + max(x))/2\n", |
"print xoffset" |
], |
"language": "python", |
"metadata": {}, |
"outputs": [ |
{ |
"output_type": "stream", |
"stream": "stdout", |
"text": [ |
"34.675\n" |
] |
} |
], |
"prompt_number": 37 |
}, |
{ |
"cell_type": "code", |
"collapsed": false, |
"input": [ |
"yoffset = (min(y) + max(y))/2\n", |
"print yoffset" |
], |
"language": "python", |
"metadata": {}, |
"outputs": [ |
{ |
"output_type": "stream", |
"stream": "stdout", |
"text": [ |
"-53.29\n" |
] |
} |
], |
"prompt_number": 39 |
}, |
{ |
"cell_type": "code", |
"collapsed": false, |
"input": [ |
"plt.plot(x-xoffset, y-yoffset,'.')" |
], |
"language": "python", |
"metadata": {}, |
"outputs": [ |
{ |
"metadata": {}, |
"output_type": "pyout", |
"prompt_number": 41, |
"text": [ |
"[<matplotlib.lines.Line2D at 0x7f5bf860a410>]" |
] |
}, |
{ |
"metadata": {}, |
"output_type": "display_data", |
"png": "iVBORw0KGgoAAAANSUhEUgAAAX4AAAD/CAYAAAD2Qb01AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3X1wVFWaP/Bv0nnhJS8dCGxkAkwWVLQ2kkACiXkhiMAQ\nRxJcY6n4gpNJBnEL1p2C3bW2CnX84a5TVulOrczIMKFmduOuzvIi41iDWQkKThACEhZcMoBELQwM\nknRHR5KQPr8/zpzc2ze3O92dfrnd/f1UdSV90925t/v2c8997nPOSRBCCBARUdxIjPQKEBFReDHw\nExHFGQZ+IqI4w8BPRBRnGPiJiOIMAz8RUZwJKPAPDQ3he9/7HsrLy1FRUYFTp07h7NmzKC8vR2Vl\nJdatWwdVJbpt2zYUFxejtLQUb731VlBXnoiI/JcUyJN+85vfIDExEQcPHsSBAwfw1FNPAQC2bNmC\nyspKPP7449izZw9KSkrwk5/8BO3t7fjmm29QXl6OpUuXIiUlJagbQUREvgso8NfU1OC73/0uAODC\nhQvIyspCS0sLKisrAQArVqzAvn37YLPZUFZWhuTkZCQnJ2P27Nno6OhAUVFR8LaAiIj8EnCO32az\nYc2aNdiwYQNWr14NfQfg9PR0OBwOOJ1OZGZmjlhORESRE1CLX9mxYwcuXbqEBQsW4Nq1a8PLnU4n\n7HY7MjIy0NfXN7y8r68PWVlZY/mXREQ0ViIAv/zlL8WWLVuEEEI4HA6Rl5cnli1bJlpbW4UQQvzg\nBz8Qr7/+uuju7hb5+fni2rVrore3V8yZM0f09/ePeL1Zs2YJALzxxhtvvPlxmzVrViAhXAQU+P/0\npz+J++67T1RWVorS0lLx5ptvis7OTrFo0SJRWloq6uvrhcvlEkIIsW3bNlFcXCzmz58vdu7cab4S\nCGg1osbmzZsjvQohE8vbJgS3L9rF+vYFGjsDSvWMHz8e//Vf/zVieWtr64hl3//+9/H9738/kH9D\nREQhwA5cRERxhoE/DKqqqiK9CiETy9sGcPuiXaxvX6AS/pwniuxKJCTAAqtBRBRVAo2dbPETEcUZ\nBn4iojjDwE9EFGcY+ImI4gwDPxFRnGHgJyKKMwz8RERxhoGfiCjOMPATEcUZBn4iojjDwE9EFGcY\n+ImI4gwDPxFRnGHgJyKKMwz8RERxhoGfiCjOMPATEcUZBn6ylMZGoKoKqK4Gensjsw5z5gApKUBy\nslwX/XpYYf2IxopTL5JlNDYCr78OOBzyfl2dvB+s1+7sBCZMAJqbAbvd82Ptdm0djOtRVQUcOKAt\nt9uBvXuB/n5g/nzgjTe8v7a/60LkDadepKjX2akF3Kws4NVX3f+uWtvTpwPl5dpPX1rfnZ0yYL/9\nNnDLLd4f39en/X7TTe7rMWGC/FlUJJd3dgLd3UBPD9DSItfRl+1U6zJlirx1dXl/Ds80KJiSIr0C\nRIoKqllZwPHjI1vCKmACwOefu/9UZwtGqnV96pS2rLsbmDcPmDHDvNU9caIW/L/6yv1vzc3yNV99\nVS5X6wwABQXA+PEyQHtrzavnJCYC168DV67IA9hnn5mv+4QJgNMJHDokl994IzBuHDBzJpCRoR04\neAZBPhMWYJHVoAhpaBAiJ0cIu12IqVOFuHDB/HG5uUIAQiQlyZ+ZmfJnUZEQPT3mz1m0SD4GECI1\nVXt8WZm2vK7O/TnZ2XL5hAme10Xp6RGitlaImhr5e06O9rq1tebPeeQR+T+Sk73/H/26q9dNTNSW\nqZtaX7NtodgWaOxkqociTqVLenuBy5eB4mItpaFPcXzrW/Lx168DubnAiRMyz/7OO55bufrUzJkz\n2uMzMrTlxpTS0aPy9U+flq1qb+x2YNcuYPdu+Xt/v/Y3T6nXri7Zyh8clC33lSuBRx8dmcbRr3tb\nG5CdDbhccllSkva3ggLP20JkKsgHoIBYZDXIDw0NskW6YoXn1ravz1uxQmuxqta8ajGbtXq9tfCN\nenpkK9j4eE/Lx+rOO+U6FhR4fm21vWo79NuYl6e9PxcuuK+jel5WlhAnTmh/U2cQd97p+X8G+nmR\ntQUaOy0RcRn4o0tDg5ZmAYSYMsV7QNEHHX2KJTtbC3A1NTLQ61+3psY9SBoDoS/rGe5g58sBxfgY\n/TZ6S0F5em39gcPTZ6F/TF0dDwSxgoGfAqaCQG6uDDxmwcBT8LbZzFur+uebtdrT0swDnLHFPJaW\nuTHYWZV+G41nA75QzzG+p/rPbNo0uTwjQ4j773c/wFr5vSHvwhr4BwYGxEMPPSQqKirEggULxJtv\nvin+8Ic/iLKyMlFRUSEef/xx4XK5hBBCvPrqq6KoqEiUlJSI3/zmN0FdeQoOfYD0FAzMgndWlrY8\nLU1enDVreZq12lWANwa4YKZgAgmikeZp+7210NVzjO+p/jObPNn9s1G/p6R4Ptgb8SzBesIa+Jua\nmsSTTz4phBDi6tWrYvr06WLlypXiwIEDQggh1q5dK3bt2iW++OILkZ+fLwYGBoTD4RD5+fmiv78/\naCtP/lMVNFlZWk7YWC1jFihVEM3OFmLhQvka998vg4aqTlE3Y8vTLJiFKseuF47/ES6+nL2o7X3k\nEfl4Ve2Tna0dlAsLtQNEVpb8LH1t+UfLGVQ8CWvg/+qrr0RfX58QQogrV66Iv/zLvxS5ubnDf9+z\nZ4944oknxJtvvinWrl07vHzVqlXiyJEjI1eCgT9kjK00Y+u+rk6WUKr706aZB0oVVPRpHn3LUaVn\nams9t+YpcP6cvRhLWPXBXZWdekst3XyzTAVlZ7uXmVrpDIpnH1JEcvxOp1MsXrxYNDc3i2nTpg0v\nf/fdd8VDDz0k/v3f/138/d///fDyRx55RLS0tIxcCQb+kNHXlU+e7F7zXVgovzRZWdqyqVNlizEn\nR6YB7Hb3ahH9l18F+MJCLaAIEVstbavw5z3VV0mNVg1l9rr6/L+uPWepz5VnH1LYA/+nn34qioqK\nRFNTkxBCuLX4d+/eLf7mb/5GvPnmm2LdunXDy1etWiXa29tHrgQDf8jog7q+FVhdrX2BVQBXN2Pq\nRv/l0n/5rRQISKPvSBZINdRoHdis0Nq20tlHJAUaOwMapO3SpUuoqqrCK6+8gsWLFwMAVq5ciR/+\n8IdYtGgR1q5diyVLlqCyshJLly7FkSNHcO3aNZSUlODEiRNISUlxe72EhARs3rx5+H5VVRWqqqr8\nXS0ysXSpHEMmPd19DJqcHODjj2Wno95eOX5Nd7f5a9jtwCefcCiAaKI6v6mhJfzR1SWHkDh40LwD\n2w03aPtKTY3svOarYA1QN5bti2atra1obW0dvv/MM88ggBAe2OFi/fr14oYbbhBVVVXDtxMnTohF\nixaJ0tJSUV9fP1zVs23bNlFcXCzmz58vdu7cGdSjFkm+VHxcuOCe9jGeIutbiYWFWv7ebh992AKK\nL/qzSE/DUnjaJ43VYfHcWg+GQGMnh2WOYqr11NEhR4cE3FvyxsclJ8vHXr4su/cbhzrQt6LU8+Kt\nRUWjU2eRhYXAu+8CmzaNbMXrh6/Oy5MD4p07J886jUNe2+0cpjpQAcfOIB58AmaR1bAkb615s/r7\n0Wrwa2uZl6exMV7bMbvQ6qk3sv5m1t9A9ebm/umbQGMnB2mzELMx1/VjtxvHeleDeKWlacvMxrHX\nD/bV1CSHL2arigJlt7vvQ8Y5CgDZclcD4qm5BtTAcgUFQG2tdsap34+vXJH7+tSp8syCcw+ESJAP\nQAGxyGpElHH8G7OW02g9NrOyzPPxrL6hUBpt/9K3+HNzzffjvDzv1WRkLtDYyRy/RehzollZwPnz\nWsXNaLn2eK1woOhQXS1b8WbXlRT9/q+oawjcpz0LNHZyBi6LMM4+ZXbBzBN16k1kRcZZy8zoZzLL\nyJDlpP/xHyMfbywH9ed7Qhq2+C3C2Go3TurNwE6xrLcXeOwxmeDZscNzwNdXsNXVyQq1eP6eBBo7\nGfjDwJ9OK/o5Yq9c8X56TBQPGhvlwWBwUFumvhcPPjh6GimWMfBbmL6nY22tnKrP08FA39LPzQVO\nnoy/nZlIz5j/nzBBVgANDgK33SbTo01N8fk9CTR2spwzDK5e1X4fGJA/PZVp6kvjjEHfrNyTKNbp\n8/+33SYv+l6+LFM+Bw7Ijom+Bn1+hyQG/hBSO9nQkLbs1Cm57NQpeb+oCBg/XtsZt271PIG4t5p+\noljV3CzHBKqtlft/Rob2t8JC/yaY53dIYlVPCKmdTCksBC5e1JZNmyYDvNqhAWDjRs8XqMw6yhDF\nOrvdfSC45mZgzRogIcH/FA+/QxJb/CGkdjLVU/Hdd7VUDwAsWODec3G0nVHfGzIe85lEgCzh7O0F\n+vv9fy6/QxIv7oZIYyOwZ4/MQ95+u2yx2O0jB7jytZMWEUksddbw4m4EeRpj5/JlWXlw4ICWT3zj\nDbmz6nskGsc+ISLPmK4ZO7b4g0BfrjljhkznXLkCXL8ulxUUAPv3M7ATBYPZGfJYJngJ1uQwkcA6\n/jAx6zL+i19olTuTJwNffqk9fto0WcETTTsTUbTxJf3jS9+ZaEsdcayeEDDbUfSVOo2NMp2jgr7N\nJrucK2zpE4WHL+kf43dXBfh4TB0xx++FWc2vcSdR95OS5AHg6lUgNVXm+xn0icLDl2od43dXXZsb\nHJT9BOKp0octfi/0E0T09MjcYnMzMH06cPSo7CoOyJ8JCVoP3f5+YOLE+NmJiCLNlxFqm5uBefNk\nw+zBBwGnEzh0SP4tJ2fk46M59z8a5vg9mDMH+OILOUeoWrWcHGDZMjlcrL43rpKaKoN+vA4YRWR1\n+nx+To5WlAGMzO8bH2ucy9oKWM4ZBPqyzC++kC0C/Xva3Q289pp50C8qAs6cYecQIivTp3va2rSW\nvll+Xz9GUHc3cMstsTO+T9y3+PWnc/pTPyUxUQZx/UBrgLyQm5QkO2P967+y8xVRNDCWgnrrPNnb\nK4O9/qxg/HiZLsrIsEb6h+WcAdKfzo0bB1y7NvIx1dXAsWNyBygoAL797fgdBpYonpgFf8UKpZ9M\n9XjhbShW/anf3Lnmz09Olvm9ujpZqbNrF4M+UTyw2+V3X6WEMjPlz2gv/YyLwG9WlmlWyjVp0sjn\nZmRoU8FxWAWi2GbWSFTBv64OOHEiNq7jxUXgN+ugoQ4GLS1ASor8EFUtsDq622zA++9H9wdMRL7z\nNF6/avjNnBkbDcC4CPz6zh2bNo2cCEUdDNSHO2uWvD80BDz3XERWmYgiIF568cbdxV1f5rStro7v\nCZyJ4lW0DZHOqh4f6YP6rbcCXV0je+ZF24dPRPGJgd+LxkZg717Zq/a222Qw37HDvUyrpsZ9ejci\nIquLSDnn4cOHsXjxYgDA2bNnUV5ejsrKSqxbt254ZbZt24bi4mKUlpbirbfeGsu/C4gaha+7W463\nc+CAdjFX3ylrcDDsq0ZEFBEBB/4XXngBDQ0N6P/zxJd/93d/hy1btuC9996DEAJ79uxBd3c3fvKT\nn+CDDz7A7373O/zjP/4jBvSTzoZBZyfgcGj3ExPlUMqPPuo+9EJKSlhXi4iinLf+QVYXcOCfPXs2\ndu7cOdyyP3bsGCorKwEAK1asQEtLC44cOYKysjIkJycjIyMDs2fPRkdHR3DW3ITZB6Gu0tts8qfL\nJVv9zc1a4LfbZU9cIiJfeSr9jAYBB/577rkHSUnaqM76PFN6ejocDgecTicyVVc33fJQ0X8QN94o\nDwBbt8pSzj9npADIMXbUtIhJScBHH/EiLhH5J5pLP4M2Hn9ionYMcTqdsNvtyMjIQF9f3/Dyvr4+\nZKlB7A2efvrp4d+rqqpQVVXl9zqoDyIxUc55+/bbwMaNMsff2ws89pgcbfPAAe2MYNky2SmDiMgf\nzc3hr/5rbW1Fa2vr2F9IjMEnn3wiSkpKhBBC3H333aK1tVUIIcQPfvAD8frrr4vu7m6Rn58vrl27\nJnp7e8WcOXNEf3//iNcZ42oM6+kRIjtbCBnehUhKEuLCBSEaGoRYtEiIFSvkY+68U/69sFDeJyIK\nFWP8CaZAY+eYW/wJCQkAgBdffBENDQ0YGBjArbfeinvvvRcJCQlYv349Kioq4HK5sGXLFqSE8Cqq\n3Q4UF8uWPiDTORs3you5+rk233iDdfpEFHy+zNMd6RE9gRir429sBE6fBn7/e3kRNyMD6OgAHn+c\nPXGJKPT0IwOoYZtDORIAh2WGPLIeOiSDPiAnVtm40beJmImIxkpdZ8zOBi5elEE/M1PeN4s9kSoJ\njerJ1o2nVepNz8iQQV9Nkg5Y4/SKiGKbuuB78aI2m5+qImxpGZnqiVQaKKpb/MY6WtWy7+gApkwB\nvvpKe7OJiEJNjfCbkSHvp6VppeNZWSPLPs+dkz8zM4Ef/zh86xnVgV+18JOS5Dg7eXmyhZ+ZKfNp\nQHTW2BJRdFON0JISeT8rCzh+fGS6R5WSOxwyLR0uUX1xt7dXdtS6csV9eV2dDPas3CGiSNKP9Ltp\n08iKn7Fe+I2r0Tn1uf3BQZnOUQoK5Ly4mzZpI3LOny9LOHkAIKJIMav4GesQ8HEV+G+4QRtOubpa\nToY+OCh/qvlx9W8yoL3RREThYtZIDWZZZ1wFfptNK9m02WT+7OhRmS9Tb/SpU1oKSJ0FsMVPROGk\nb4DabPJ25IicFyQY4qqO/8+dhQHIETavXAHKy+V9Velz5QowbZqcYIVBn4giQT9+2NAQMDAA3HVX\nZNcJiNLAbwziEyYABw9qvwPydOrUKVntw6BPRJGgqnvU2JT6WBVJURn429vlROnvvy9/rlwpy6Ym\nTQL+9Cegtpa9dIko8lRdv4pZp09rKekbbpAxa+nS8E/kYvkcv7F3rllJlP5iL8ALuURkbcEqPgk0\nx2/5IRuMXZr1I21OnSp76F66pD3eZgtvDzgiIn+plDQgi0/C3cnU8qke4yw3+jdscFCOiaE/4A0N\nAX/7t+FdRyKKHeEYOK25WaakI1V8YvkWv3GWmylTtLp9AEhPB3STfAFwPxAQEfkjHAOn2e3Arl3B\nf11fWT7wq4sjgPwQ9uzRgn5iIpCSIsfqAeRgSAUFshMXEVEgQjGXrtkELd6Wh5rlL+7qGS/iGuXm\nAidPspqHiAI31mEUzJgN16DOJhwO9+X+iNmLu3r9/Z7/Zrcz6BPR2OmzDMFidhbR2akFfbMhm0PJ\n8hd39ebPN1+ekQF89BGDPhFZk9ksgGos/qQkoLU1vPErKgL/nDnyTXn/fTnWvnG+9jvu0Ma1JiKy\nGnUWoQ/uKmZdvw4891x418fyqZ7GRuDsWVmmCWjpnsREOVCbzSYnX+ntZYufiKKHmqUrEpNFWf7i\nrtkF3cmT5WBH+jLO2trIlkcREflDXUQePx7o6gqssidmR+e8enXkMiFYu09E0U2lf7q63OcODwdL\nB/7GRm2iYj3jwSAzk7X7RBSdvPUbCFUvYkunevRpnqQk84NAQgLwySe8uEtE0clbvwGz+n+9mJyB\nKzVV5vIB+YaYHfF++1tgxYoQryARUQRMnw58/rnMapw4MbKBG5M5fv2AbJ5Oc8KVEyMiChVP4/Or\nQO9wABs3Bu//RU3gV8aNk1U96u9WmM2GiGgsOjtlWrunR07Irhq0oSr5tHTgz8tzv5+YCBw+PHI2\nGyKiaKZv5E6aJIebr64Gtm4d2eM3GELegcvlcmHdunXo6OhAamoqfv7zn2PWrFk+PVcd7SZOBL7+\nWnbYqq0FZswA8vNl3ouIKNo1NwOPPSbL0q9cAQ4dkss3bgzNsNAhb/Hv3r0bAwMD+OCDD/DP//zP\n+OEPf+jzc9X4FqWl8n5RETBtWvhrXomIQkmNz797d3h69IY88B86dAjf+c53AAALFy7E0aNHfX6u\n3S5v33wD5OQAv/619qakpWlDNRARRRtPNfpmA7oFW8hTPU6nExkqWgOw2WxwuVxITPR+zGlsBPbu\nBf74R22cno0b5Zty443ydKilBbjlFuDjjzlODxFFF08zfYViWGijkAf+jIwM9OnGV/AU9J9++unh\n36uqqtDZWeU2Ro/drnVwKC6WqR5AXgkP1fRoREShEshMX62trWhtbR3z/w55B66dO3di7969aGpq\nQltbG370ox/hrbfecl8Jk04I1dVacFf31dN6e2VLv7tbvmmhPCUiIgoFY4/dQKZhtGzPXSHEcFUP\nADQ1NeGmm25yXwmTle/tBW6+Gbh8WVb1lJbKC7tqFLutW2XqJ5jToxERRcpowzOYsWzg92klPKx8\nb6+WzweAKVNkzh8IbH5KIiKrUlkOf7IYMTlkw6ZN2oXdwkJg7lz5e3a21sGBVT1EFAtUNc+tt8r+\nSqGMb5Zu8etPfSZPlsE/LU22+lUHB7b8iSiW+JPyickWv7rqnZYGfPmlLN9sa5Mz1gCRmbKMiGgs\nRhtjP5BqH39ZOvBPmSLTOqmp2rLubnmxN9QdHIiIQkHV7+tHH9AfDDIzZcw7e1bGuVCkeyw92XpX\nl3ZhNzVVTrReVCRn22LAJ6JoZNai13fmmjJFxrr+fm2kzmCnsy3d4te/QWfOjGzlh2paMiKiUDEb\nkkEf61QRCwCkpwM//nHw18HSF3eNHRzmzJGpnuRkOWbP+fPaY/UdvIiIook+1gHAX/yFNvtgTY0c\nvM1MTF7c3bRJduB68EH5xnR3y5lorlxxD/oA8NFHkVlHIqKxUuPzqIEpJ07U/paQEPz/Z8kcv+q6\n3NEhR+BUy5KT5e8TJsj8l6rxT0gAPvggMutKRBRs8+fL/H5hIdDUFPzXt2SLX13oUEFfXQQ5elSb\neau8XP4tKUm29jkTFxHFgsZGbSj6XbtCU8hiycCvLnQUFsr8lroI8v/+HzBrlgz6164BNpus6V+y\nRFYAERFFu85O2UG1uzu4E6zrWfLirvGirqLv0WaUmwt89llo15OIKFg8jcbpz5g9gV7ctWSO39NE\nBOpMIDNTXuS12WSe32YDvvUt+Yb5OpwpEVEk6Wv3582Tc4mHa+RhS6Z6PFH1rydOyJ/HjsmWflER\ncPgw5+Elouhx7pz8mZkJTJ2q9ebduFEG/FAO1GbJFr8n6kygsVGWef7DPwAnT8pyT8B9Hl62+onI\nymbOBD7/XGYv1DVKVchSW+s+LaPd7v8kLd5YvsVv1jt3717t6FhQADidstTzq6+0Ls5ERFampiIv\nKpKDT+p78xqHdTAb32csLB/4zTa4v1/7+1dfySvgg4PyfmZmaLo4ExEFk37ohpkz3dM7W7d6PxCM\nlSWrevTMrnAvXSpb9omJ8sLu4KBM83z1lXxOTg7w8cey528wT4+IiEJFX7WYl6dd7G1ulsvMKh1j\ncupFwLy0s7dXjmB3/bq8P26crO1vadGeV1cnrwP4O4clEVG4NTYCv/61vEZZUCCHbPBlsqmYHKsH\ncB/DQtm0Sft9/Hjg//5PTsSuhnRQF3nVfU7YQkRW1tmpjVTw7W+75/9DEbss3+LXUx0efv97beS6\npUuBffuAG26QPd30amqAlJTQ1sMSEfnDrOOWMaWtHjda7IrZFr+eutCrgj6gXfS4fNn9sXa7HMVT\n5f2JiKzArGDFOEa/WaYjmKIq8Ksgn54uf06aJIN7dfXIx379tcyRsVMXEVmJWYVOqAO9UVSletSF\n3h//WPZuu3hRuwCSnKyVdI4bByxcKI+qvox3QUQULp7GIgtEzFb1eKPPi23fDixfLpdXVckB286d\nkx0jOGQzEcWiuAz8voziyTJOIoomnkbtNBOXgd+MsR52/36meYgoevjTcI2Lqh5fGOthGfSJKJoE\ne3gGMzEX+PVvWijmqiQi8pXZIJOjMZZ2hkLAgX/Xrl1YvXr18P22tjaUlJSgvLwczz777PDyZ555\nBgsXLkRZWRmOHDkytrX1QTjeNCIiXwQyqmY4SjsDGo9/w4YN2LdvHwoLC4eXPf7449i5cyfy8vJw\n11134aOPPoLL5cJ7772Hw4cP47PPPsNf//Vf48MPPwzaypvxNHsXEVG4hSNtE4iAAn9ZWRlWrVqF\nn/3sZwAAp9OJ/v5+5OXlAQCWL1+OlpYWpKamYtmyZQCA6dOn4/r16/jyyy8xefLkIK2+d/qr41Om\nyMkOOFInEYVLc3PwavaDyWvg3759O1566SW3ZTt27MB9992H1tbW4WVOpxMZalQhAOnp6Th//jzG\njRvnFuTT09PhcDjCFvj1c1rqO3g1NvKsgIhCz6oZCK+Bv76+HvX19aO+SEZGBvr6+obvO51O2O12\npKSkuC3v6+uD3cNh7+mnnx7+vaqqClVVVaP+39Go0yxAC/rp6ZyohYiiU2trq1ujO2AiQPv37xf3\n33//8P2CggJx7tw54XK5RHV1tfjwww9Fe3u7WLJkiXC5XKKrq0vMnTvX9LXGsBpe9fQIkZMjBOB+\nq6sLyb8jIgqrQGNnwJOtJyQkICEhYfj+T3/6U6xevRpDQ0NYvnw5iouLAQAVFRUoLS2Fy+XCK6+8\nMtbjlF/sdjkT1y23aEM2FxZa6yILEcUuf3rhhlPM9dw109sLrFkDJCTICQ54kZeI/KWC+Llzcmj4\nwUE5EdTQkLw/f76cEEofX2prQzt8DIds8JFZd2irHpWJyDr0scMTfRFJXZ2cD8Q4Z3gwccgGH5nV\n1QbSyYKI4ouKHZmZ2jI1N4iign5BgYwvVu1QGneBv7lZzsnb2QnceKN2WgaYd7IIpMs1EcUeFcRP\nnJDTutbWAidPAjNmaPN7K2qcsHBPsOKruEv1APJDcDjk77m58sPTd7LQp36cTt9muyei2OUtHWyc\n77uoCLj11vBcS2Sqxw/q6DxhAnDwILBpk5yz98EHZaten/o5d04+1mpdrokofLylg/v7td+nTZNp\nna4ua6eP4zLwHz0qW/qnT8vZuYwfqj7109ZmzRwdEYWPignZ2XLKV33qd/58+TMtTbb09Y+3aoMx\nLlM9RvopHN95Ry6bN08evTMyWOlDFO/UbH/6eb5V6re3F7jpJuCPf9SWv/pqeMboYTnnGJhN4cjp\nG4nil6ecvrGRONryUGPgDzL9BxmuCzVEZA36hl9enqzcmTAB2LoV2LhxZEve0/zfocbAH2T6D9Ks\n9x07fRHZ2bH4AAAQoElEQVTFLn3DLzVVS++MHy/TwFZJAbOqJ8j09bfs9EUU24z9dfQdr3QjzuOb\nb+RBINq/92zx+6C3F5g+HUhMBFJSZFXQ449HJqdHRMHn7Zpeb6820KPNJsfmKSgA9u+P/Pc+0NgZ\n8OicscwsjWOzaZ2+ystHdvoiouhldlavjwNtbUBxsVa5o3rmRiu2+E2YHf2nTAGuXJE7gar/J6LY\nYLw4q2bpU429cAy4Fgi2+IPI7Oh/9Khs6R886B70jWcHmzaNPFvghWAiazNOkdjZqQX9rCz3s4BY\nOMtni9+EP6VZxrODy5fd76sdSt9yYJ8AImtTVT1ZWcDx49Y9w2dVTxD5M6Ke8ezAeN9Ty4GIwsdY\ntTPaqLuqquf8eesG/bFgi3+MjGcHxvtmLQemfojCy9gh6+rV2DgLZwcui9IfCFT+v6MD6OmRf4/m\nnY4oGjQ2Ar/+tfzOFRQAEydqHbKysmSrPlobX7y4a1H6i0aq05di1ZH7iGJJZ6fW0Pr2t7VhlNVZ\neLQG/bFg4A8jlf8vKJA7YFOTttPpJ3KeOdM6XcKJop3+ultTk/w9VqpzAsXAH0bNzZ53OP3ZwOef\ny59r1gC7d4d1FYksJRgNoilT5E09x1i6GY8Y+MPI2w6nWiWqSzgAJCSEZ72IrMqsQdTYKL9LvhZI\ndHXJHrctLVrHrHjHck6LUOVj5eXyfmGh+2kpJ3yneKQaRGqgNH2ZtBok8ZZbvH8vrD4bViQw8FuE\nOhvYvVseAN59V2vFcCRQileqQdTR4T4FqgrmgBw8zex7oRpMg4NATY11hlmwApZzRgFOCkPxztj3\nBdBGzPQ0dk48zKLHnrsxTD82eFeX76e4RNHEW0rTeNZrtwMff+x+FmDEFI9nbPFHGdX6V2K1JUPx\nQd+SdzrdJzLXX8AdHJQXZ/05643UdIjhxJ67cUI/KYSVhoclCoQ+HZOT475f66c8ramRkyB5mgo1\nXoUt1eNwOHD33XejqqoKt99+O9ra2gAAbW1tKCkpQXl5OZ599tnhxz/zzDNYuHAhysrKcOTIEb9X\nkNz5copLZGX6lE5yslxWVCQnOzG7gJuWBnz9tdZyZwonCISfNm/eLF5++WUhhBBnzpwR8+bNE0II\nMXfuXHH+/HkhhBDV1dXi+PHjor29Xdxxxx1CCCE+/fRTUVxcbPqaAawGmWhoEGLRIiFWrBCipyfS\na0Nkvk8uWiQEIG8zZggxZYoQd97pvs82NAhRViZEcrL22Lo6+beeHvk79/HAY6ffHbiefPJJpKam\nAgAGBwcxfvx49PX1YWBgAHl5eQCA5cuXo6WlBampqVi2bBkAYPr06bh+/Tq+/PJLTJ48OWgHrnhm\n7NV4+rQ2JsloHVU4QiiFg74D1o03yukL9a381FSZ1zd2rurs1PL96rGqdc+et2PnNdWzfft25Ofn\nu93Onj2LcePGobu7Gw8//DCef/55OBwOZOimok9PT4fD4YDT6URmZuaI5RQc6kv1+efyS6KCvi+n\nwMYqCXYSo1DQp2uuXJH7W1qaltIxdswyPq+gQOb0mdYMLq8t/vr6etTX149YfvLkSTzwwAN48cUX\nUVFRAafTib6+vuG/O51O2O12pKSkuC3v6+uDnZ9e0Og7sQBAZiaweLH74G96+lb+H/6gPcdmc58l\nbN48YMYM384GeOYQHxobgb175ciW8+cDb7wxcoBBs+lHt24FNm6UjRJVlaPfPz2NX+VtXCsKAn9z\nQ6dOnRI333yz6OjocFteUFAgzp07J1wul6iurhYffvihaG9vF0uWLBEul0t0dXWJuXPnesxTbd68\nefi2f//+gPJW8aanR4icHJn/zMoS4sIFz49taBAiM1PLlyYlab9nZ2u/Z2XJ3Koxr+qJPl872mMp\neuk/Z+Nnrf9bdrbch5iXD439+/e7xcoAQrgQQgi/n1VTUyPy8vJEVVWVqKqqErW1tUIIIdra2kRJ\nSYkoLi4W//RP/zT8+KefflosXLhQFBcXi0OHDpmvBC/uBszXL5Txi6tuaWlCTJ7sfvBYsULeLyrS\nXvfmm+WBIztbO8A0NGhf8sJCfqmjnbfiALVPGD9r/T4wcaL7vqXffyg0whb4Q4GBP/TUF1e19AsL\nhZg0SfuS5uZqX1Kzg4n+bCE3Vy7TH0wmT2Y1UbQxBnpvZ289PULU1AhRW+v+GeufM3Wqtm/V1HBf\nCAcGfvJKBfMLF7SgbtayF8K85ZeaKh+bmCjEiRNymXp+WhrTPZEw1vJdY6D3tD94+//6Mz79vkXh\nEWjs5Fg9cUKVwM2cKX/a7e5jAOkvoJmNBlpQIH+6XMBzz8nf1fNLSuR9dqgJr7GO2qqKA7KzgYsX\n5bAIM2fKEssHHxy9uks/peGMGe77FlkbJ2KJY57qoc16Rk6aNHKZen5vr6wEUgGD1T3hoS+V7OmR\nn8No1Vz6z0ZVzly8qNXMJyTIcXAA4LHHgF27Rv//RUXAjh1B2SQKlyCfeQTEIqtBf2aW4x/tIrIv\n1T2R7FkcrP8drm0w/h91PzdXVl2tWCFTK1OmjP6+e/ps1Gvqq7r0t5oa7+vISp3ICzR2WiLiMvAH\nX7iDrC/54WCVfjY0yDLWrKyRXf098fV/mwXYRx7R3kt9qWtOjnt1SzDfb/365uS4/1+zvHxamhDT\npmnrrF8HT5+N/n+oazjp6fJnQQEDejRg4Cc34a6v96X15+/FQyFGH+sFECIvb/Sgm5srH5uR4b2/\ng1nZq75FrPpNGN9bs/fb34OB/vF33un+f1JS5E9VXaXew54e91a/2Wfu6bPRfx7qwiwv0EYXBn5y\nE0iQDbVAUgNmAVVfU15Q4FuHM187panX1gfYadO0g8aJE1rw17+3Zu+3vwdf/eNrakYeZHJzzQOz\n+t8ZGf595kzVRD8GfnITK19qs4Da0yPryVWtuHpMdrZ5qkP/Omlp3tNDZmWvxoPGI4/I/6V/HbVM\nn25RrXZfA7FxW/U9s729htk6U3xg4KeY5MsBTD1GdSAC5IHB+BhfLoQKMTJFYwzIZi15sxRRdbV/\ngTiQi+oU3wKNnZyBi2LGpElaXXlNDTB1qnsZ44MPapPWexvt0ThJ96uvug8Ypqa/1L+OWmazAUND\n8rm1td7LIYnGKuDYGcSDT8AsshoU5VRqRVWkGFvmvraeR7s+4q1lrv4nxy6icAg0drLFTzHDOLm2\nWcs8kNcZyzoQhRInWycyYBCmWMfAT0QUZwKNnRykjYgozjDwExHFGQZ+IqI4w8BPRBRnGPiJiOIM\nAz8RUZxh4CciijMM/EREcYaBn4gozjDwExHFGQZ+IqI4w8BPRBRnGPiJiOIMAz8RUZxh4CciijN+\nB/6vv/4aNTU1WLRoEZYuXYqLFy8CANra2lBSUoLy8nI8++yzw49/5plnsHDhQpSVleHIkSPBW3Mi\nIgqI34H/5z//OYqLi3HgwAE89NBDeOGFFwAAa9euxWuvvYaDBw/i8OHD+Oijj3Ds2DG89957OHz4\nMP7zP/8TTzzxRNA3IBq0trZGehVCJpa3DeD2RbtY375A+R34N2zYgKeeegoA0NXVhaysLPT19WFg\nYAB5eXkAgOXLl6OlpQWHDh3CsmXLAADTp0/H9evX8eWXXwZx9aNDLO98sbxtALcv2sX69gUqydsf\nt2/fjpdeeslt2Y4dOzB//nwsWbIE//u//4t9+/bB4XAgIyNj+DHp6ek4f/48xo0bh8mTJ7stdzgc\nbsuIiCi8vAb++vp61NfXm/7tf/7nf3DmzBncddddOH78OPr6+ob/5nQ6YbfbkZKS4ra8r68Pds56\nTUQUWcJPW7ZsEb/85S+FEEJ89tln4uabbxZCCFFQUCDOnTsnXC6XqK6uFh9++KFob28XS5YsES6X\nS3R1dYm5c+eavuasWbMEAN5444033vy4zZo1y98QLoQQwmuL30x9fT0effRR/OIXv8DQ0BCampoA\nAD/96U+xevVqDA0NYfny5SguLgYAVFRUoLS0FC6XC6+88orpa549e9bf1SAiogAlCCFEpFeCiIjC\nhx24iIjiTFgDf6x3/nI4HLj77rtRVVWF22+/HW1tbQBiZ/uUXbt2YfXq1cP3Y237AMDlcmHt2rW4\n/fbbsXjxYpw7dy7SqxSww4cPY/HixQBkWrW8vByVlZVYt24d1An/tm3bUFxcjNLSUrz11luRXF2/\nDA4O4uGHH0ZlZSUWLlyIvXv3xtQ2Dg0N4Xvf+x7Ky8tRUVGBU6dOBWf7AroyEKCXXnpJ/OhHPxJC\nCLFjxw6xYcMGIYQQc+fOFefPnxdCCFFdXS2OHz8u2tvbxR133CGEEOLTTz8VxcXF4VzVgGzevFm8\n/PLLQgghzpw5I+bNmyeEiJ3tE0KI9evXizlz5ogHHnhgeFlBQUHMbJ/y3//93+Kxxx4TQgjR1tYm\nampqIrxGgfmXf/kXkZ+fL0pLS4UQQtx9993iwIEDQggh1q5dK3bt2iW++OILkZ+fLwYGBoTD4RD5\n+fmiv78/kqvts6amJvHkk08KIYS4evWqmD59uli5cmXMbOPu3btFfX29EEKI1tZWsXLlyqBsn98X\nd8diw4YNcLlcAEbv/JWammra+cvKfQCefPJJpKamApAtkfHjx8fU9gFAWVkZVq1ahZ/97GcAZOlu\nf39/zGyfcujQIXznO98BACxcuBBHjx6N8BoFZvbs2di5cycefvhhAMCxY8dQWVkJAFixYgX27dsH\nm82GsrIyJCcnIzk5GbNnz0ZHRweKiooiueo+qaurw7333gtAnqUlJyfH1DbW1NTgu9/9LgDgwoUL\nyMrKQktLy5i3L2Spnu3btyM/P9/t1t7ejsTERCxZsgT/9m//htraWtPOXw6HA06nE5mZmSOWW4XZ\n9p09exbjxo1Dd3c3Hn74YTz//PMxtX3t7e2477773B7ndDqjcvtGY9wum8023GiJJvfccw+SkrT2\nndDVcsTCZzVx4kSkpaWhr68PdXV1eO6559w+p1jYRpvNhjVr1mDDhg1YvXp1UD7DkLX4Y73zl6ft\nO3nyJB544AG8+OKLqKiogNPpjKntM8rIyIjK7RuNcbtcLhcSE6O/FkK/DeqzMm5rX18fsrKyIrF6\nAfnss89wzz334IknnsADDzyATZs2Df8tVrZxx44duHTpEhYsWIBr164NLw90+8K6Jz///PP41a9+\nBUAeqZOSkpCeno6UlBScP38eQgjs27cPlZWVKCsrw+9+9zsIIfDpp5/C5XJh0qRJ4Vxdv50+fRp1\ndXV47bXXsHz5cgAygMTK9pmJ1e0rKyvDb3/7WwDy4vVtt90W4TUKjsLCQhw4cAAA8Pbbb6OyshIL\nFizA+++/j/7+fjgcDnz88cf4q7/6qwivqW8uXbqEZcuW4YUXXsCaNWsAxNY2/upXv8Lzzz8PABg/\nfjxsNhuKiorGvH1hzfGHovOXlTz11FMYGBjA+vXrAQB2ux27du2Kme1TEhISkJCQMHw/1rYPAFat\nWoV33nkHZWVlADC8r0Yr9Xm9+OKLaGhowMDAAG699Vbce++9SEhIwPr161FRUQGXy4UtW7YgJSUl\nwmvsmy1btsDhcODZZ58drih7+eWXsX79+pjYxnvvvRdr1qzBokWLMDg4iJdffhlz5swZ82fIDlxE\nRHEm+pOWRETkFwZ+IqI4w8BPRBRnGPiJiOIMAz8RUZxh4CciijMM/EREcYaBn4gozvx/NPqvH0fA\nDL4AAAAASUVORK5CYII=\n", |
"text": [ |
"<matplotlib.figure.Figure at 0x7f5bf86a8fd0>" |
] |
} |
], |
"prompt_number": 41 |
}, |
{ |
"cell_type": "markdown", |
"metadata": {}, |
"source": [ |
"Interaktivn\u00ed test, kter\u00fd vypisuje aktua\u00e1ln\u00ed azimut. Lze si na n\u011bm vyzkou\u0161et funkci kompasu. Je vid\u011bt, \u017ee p\u0159i vzniku v\u011bt\u0161\u00edho n\u00e1klonu, dvouos\u00fd kompas za\u010dne ukazovat p\u0159esn\u011b opa\u010dn\u00fd sm\u011br." |
] |
}, |
{ |
"cell_type": "code", |
"collapsed": false, |
"input": [ |
"try:\n", |
"\n", |
" for n in range(MEASUREMENTS):\n", |
" (x, y, z) = mag_sensor.axes()\n", |
" phi = np.arctan2(x-xoffset, y-yoffset)\n", |
" clear_output()\n", |
" print ((phi*180)/pi+180)\n", |
" time.sleep(0.2)\n", |
" sys.stdout.flush()\n", |
"except KeyboardInterrupt:\n", |
" sys.exit(0)" |
], |
"language": "python", |
"metadata": {}, |
"outputs": [ |
{ |
"output_type": "stream", |
"stream": "stdout", |
"text": [ |
"83.1246570299\n" |
] |
} |
], |
"prompt_number": 44 |
}, |
{ |
"cell_type": "markdown", |
"metadata": {}, |
"source": [ |
"Vid\u00edme, \u017ee po tomto zp\u016fsobu korekce m\u00e1 vykreslen\u00fd \u00fatvar od kru\u017enice je\u0161t\u011b v\u00fdznamn\u00e9 odchylky. Nyn\u00ed pot\u0159ebujeme kompenzovat soft-iron efekty. K tomu mus\u00edme pracovat s nam\u011b\u0159en\u00fdmi daty, jako s elipsou a naj\u00edt jej\u00ed hlavn\u00ed a vedlej\u0161\u00ed poloosu. Postup je trochu komplikovan\u011bj\u0161\u00ed, proto adoptujeme k\u00f3d z [PaparazziUAV](http://wiki.paparazziuav.org/wiki/ImuCalibration). Ten pomoc\u00ed fitov\u00e1n\u00ed elipsoindu najde korek\u010dn\u00ed parametry citlivosti pro jednotliv\u00e9 osy. Zanedb\u00e1v\u00e1 ale p\u0159\u00edpadnou rotaci elipsoidu popsanou v \u010dl\u00e1nku [Compensating for Tilt, Hard-Iron, and Soft-Iron Effects](http://www.sensorsmag.com/sensors/motion-velocity-displacement/compensating-tilt-hard-iron-and-soft-iron-effects-6475)\n", |
"Tento p\u0159\u00edstup je tak\u00e9 v\u00fdhodn\u00fd v tom, \u017ee vyu\u017e\u00edv\u00e1 v\u0161echny 3 osy magnetometru. Proto nen\u00ed pot\u0159eba pro kompenzaci n\u00e1klonu pou\u017e\u00edvat akcelerometr. Kompenzace akcererometrem by ale pozd\u011bji m\u011bla b\u00fdt vyu\u017eita ke korekci rotace os magnetometru v\u016f\u010di vn\u011bj\u0161\u00edmu pouzdru.\n", |
"\n", |
"Zpracov\u00e1n\u00ed dat 3D\n", |
"-----------\n", |
"\n", |
"K tomu pou\u017eijeme datov\u00fd set, kde jsou body rozprost\u0159en\u00e9 po cel\u00e9m povrchu koule. " |
] |
}, |
{ |
"cell_type": "code", |
"collapsed": false, |
"input": [ |
"data = np.load('./calibration_data_3Dset.npz')\n", |
"list_meas = data['data']\n", |
"x = list_meas[:, 0]\n", |
"y = list_meas[:, 1]\n", |
"z = list_meas[:, 2]" |
], |
"language": "python", |
"metadata": {}, |
"outputs": [], |
"prompt_number": 1 |
}, |
{ |
"cell_type": "code", |
"collapsed": false, |
"input": [ |
"from mpl_toolkits.mplot3d.axes3d import Axes3D\n", |
"#%pylab qt ## po odkomentovani a zakomentovani nasledujiciho radku udela vystup do QT okna. \n", |
"%pylab inline\n", |
"fig = plt.figure()\n", |
"ax = Axes3D(fig)\n", |
"p = ax.scatter(x,y,z)" |
], |
"language": "python", |
"metadata": {}, |
"outputs": [ |
{ |
"output_type": "stream", |
"stream": "stdout", |
"text": [ |
"Populating the interactive namespace from numpy and matplotlib\n" |
] |
}, |
{ |
"metadata": {}, |
"output_type": "display_data", |
"png": "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\ndK1KAERdWwAAAABJRU5ErkJggg==\n", |
"text": [ |
"<matplotlib.figure.Figure at 0x7f5bf86dd450>" |
] |
} |
], |
"prompt_number": 23 |
}, |
{ |
"cell_type": "code", |
"collapsed": false, |
"input": [ |
"import scipy\n", |
"from scipy import optimize\n", |
"import calibration_utils\n", |
"\n", |
"sensor_ref = 1.\n", |
"sensor_res = 0.73\n", |
"noise_window = 10\n", |
"noise_threshold = 1000" |
], |
"language": "python", |
"metadata": {}, |
"outputs": [], |
"prompt_number": 3 |
}, |
{ |
"cell_type": "markdown", |
"metadata": {}, |
"source": [ |
"Uprav\u00edme strukuturu pole m\u011b\u0159en\u00fdch hodnot do sn\u00e1ze indexovateln\u00e9ho form\u00e1tu." |
] |
}, |
{ |
"cell_type": "code", |
"collapsed": false, |
"input": [ |
"measurements = np.array(list_meas)" |
], |
"language": "python", |
"metadata": {}, |
"outputs": [], |
"prompt_number": 4 |
}, |
{ |
"cell_type": "markdown", |
"metadata": {}, |
"source": [ |
"Spo\u010d\u00edt\u00e1me medi\u00e1n magnitudy zm\u011b\u0159en\u00fdch vektor\u016f. A nastav\u00edme podle n\u011bj rozhodovac\u00ed \u00farove\u0148 pro filtraci a ofiltrujeme nam\u011b\u0159en\u00e1 kalibra\u010dn\u00ed data. " |
] |
}, |
{ |
"cell_type": "code", |
"collapsed": false, |
"input": [ |
"meas_median=scipy.median(scipy.array([scipy.linalg.norm(v) for v in measurements]))\n", |
"noise_threshold = meas_median * 0.8\n", |
"print noise_threshold\n", |
"flt_meas, flt_idx = calibration_utils.filter_meas(measurements, noise_window, noise_threshold)\n", |
"print(\"remaining \"+str(len(flt_meas))+\" after filtering\")" |
], |
"language": "python", |
"metadata": {}, |
"outputs": [ |
{ |
"output_type": "stream", |
"stream": "stdout", |
"text": [ |
"460.895326306\n", |
"remaining 346 after filtering\n" |
] |
} |
], |
"prompt_number": 5 |
}, |
{ |
"cell_type": "markdown", |
"metadata": {}, |
"source": [ |
"Spo\u010d\u00edt\u00e1me odhad elipsoidu z nam\u011b\u0159en\u00fdch minim\u00e1ln\u00edch a maxim\u00e1ln\u00edch hodnot." |
] |
}, |
{ |
"cell_type": "code", |
"collapsed": false, |
"input": [ |
" p0 = calibration_utils.get_min_max_guess(flt_meas, sensor_ref)\n", |
" cp0, np0 = calibration_utils.scale_measurements(flt_meas, p0)\n", |
" print(\"initial guess : avg \"+str(np0.mean())+\" std \"+str(np0.std()))\n", |
"\n", |
" def err_func(p, meas, y):\n", |
" cp, np = calibration_utils.scale_measurements(meas, p)\n", |
" err = y*scipy.ones(len(meas)) - np\n", |
" return err" |
], |
"language": "python", |
"metadata": {}, |
"outputs": [ |
{ |
"output_type": "stream", |
"stream": "stdout", |
"text": [ |
"initial guess : avg 0.999920050427 std 0.0671243703038\n" |
] |
} |
], |
"prompt_number": 6 |
}, |
{ |
"cell_type": "markdown", |
"metadata": {}, |
"source": [ |
"Optimalizujeme odhad fitov\u00e1n\u00edm elipsoidu." |
] |
}, |
{ |
"cell_type": "code", |
"collapsed": false, |
"input": [ |
" p1, cov, info, msg, success = optimize.leastsq(err_func, p0[:], args=(flt_meas, sensor_ref), full_output=1)\n", |
" if not success in [1, 2, 3, 4]:\n", |
" print(\"Optimization error: \", msg)\n", |
" print(\"Please try to provide a clean logfile.\")\n", |
" sys.exit(1)\n", |
"\n", |
" cp1, np1 = calibration_utils.scale_measurements(flt_meas, p1)\n", |
" print(\"optimized guess : avg \"+str(np1.mean())+\" std \"+str(np1.std()))" |
], |
"language": "python", |
"metadata": {}, |
"outputs": [ |
{ |
"output_type": "stream", |
"stream": "stdout", |
"text": [ |
"optimized guess : avg 0.999137645687 std 0.0293532050592\n" |
] |
} |
], |
"prompt_number": 7 |
}, |
{ |
"cell_type": "markdown", |
"metadata": {}, |
"source": [ |
"Vykresl\u00edme v\u00fdsledek filtrace a fitov\u00e1n\u00ed. " |
] |
}, |
{ |
"cell_type": "code", |
"collapsed": false, |
"input": [ |
"%pylab qt\n", |
"#%pylab inline\n", |
"calibration_utils.plot_results(False, measurements, flt_idx, flt_meas, cp0, np0, cp1, np1, sensor_ref)\n", |
"calibration_utils.plot_mag_3d(flt_meas, cp1, p1)" |
], |
"language": "python", |
"metadata": {}, |
"outputs": [ |
{ |
"output_type": "stream", |
"stream": "stdout", |
"text": [ |
"Populating the interactive namespace from numpy and matplotlib\n" |
] |
}, |
{ |
"output_type": "stream", |
"stream": "stderr", |
"text": [ |
"WARNING: pylab import has clobbered these variables: ['cov', 'info']\n", |
"`%pylab --no-import-all` prevents importing * from pylab and numpy\n" |
] |
} |
], |
"prompt_number": 8 |
}, |
{ |
"cell_type": "markdown", |
"metadata": {}, |
"source": [ |
"Nyn\u00ed m\u016f\u017eeme z\u00edskan\u00e9 scale faktory a offsety pou\u017e\u00edt na kompenzaci libovoln\u00e9ho m\u011b\u0159en\u00ed a n\u00e1sledn\u011b vypo\u010d\u00edtat polohov\u00e9 \u00fahly platformy ve sf\u00e9rick\u00fdch sou\u0159adnic\u00edch." |
] |
}, |
{ |
"cell_type": "code", |
"collapsed": false, |
"input": [ |
"for n in range(MEASUREMENTS):\n", |
" m = mag_sensor.axes()\n", |
" sm = (m - p1[0:3])*p1[3:6]\n", |
" r = norm(sm)\n", |
" theta = np.arccos(sm[2]/r)\n", |
" phi = np.arctan2(sm[1],sm[0])\n", |
" clear_output()\n", |
" print (r,(theta*180)/pi,(phi*180)/pi)\n", |
" sys.stdout.flush()" |
], |
"language": "python", |
"metadata": {}, |
"outputs": [ |
{ |
"output_type": "stream", |
"stream": "stdout", |
"text": [ |
"(1.0033330291141624, 159.16410600293204, 61.66914855382452)\n" |
] |
} |
], |
"prompt_number": 35 |
} |
], |
"metadata": {} |
} |
] |
} |
/Modules/Sensors/MAG01A/SW/Python/calibration_data_2Dset.npz |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/Modules/Sensors/MAG01A/SW/Python/calibration_utils.py |
---|
0,0 → 1,282 |
# Copyright (C) 2010 Antoine Drouin |
# |
# This file is part of Paparazzi. |
# |
# Paparazzi is free software; you can redistribute it and/or modify |
# it under the terms of the GNU General Public License as published by |
# the Free Software Foundation; either version 2, or (at your option) |
# any later version. |
# |
# Paparazzi is distributed in the hope that it will be useful, |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
# GNU General Public License for more details. |
# |
# You should have received a copy of the GNU General Public License |
# along with Paparazzi; see the file COPYING. If not, write to |
# the Free Software Foundation, 59 Temple Place - Suite 330, |
# Boston, MA 02111-1307, USA. |
# |
from __future__ import print_function, division |
import re |
import numpy as np |
from numpy import sin, cos |
from scipy import linalg, stats |
import matplotlib |
import matplotlib.pyplot as plt |
from mpl_toolkits.mplot3d import Axes3D |
def get_ids_in_log(filename): |
"""Returns available ac_id from a log.""" |
f = open(filename, 'r') |
ids = [] |
pattern = re.compile("\S+ (\S+)") |
while True: |
line = f.readline().strip() |
if line == '': |
break |
m = re.match(pattern, line) |
if m: |
ac_id = m.group(1) |
if not ac_id in ids: |
ids.append(ac_id) |
return ids |
def read_log(ac_id, filename, sensor): |
"""Extracts raw sensor measurements from a log.""" |
f = open(filename, 'r') |
pattern = re.compile("(\S+) "+ac_id+" IMU_"+sensor+"_RAW (\S+) (\S+) (\S+)") |
list_meas = [] |
while True: |
line = f.readline().strip() |
if line == '': |
break |
m = re.match(pattern, line) |
if m: |
list_meas.append([float(m.group(2)), float(m.group(3)), float(m.group(4))]) |
return np.array(list_meas) |
def read_log_mag_current(ac_id, filename): |
"""Extracts raw magnetometer and current measurements from a log.""" |
f = open(filename, 'r') |
pattern = re.compile("(\S+) "+ac_id+" IMU_MAG_CURRENT_CALIBRATION (\S+) (\S+) (\S+) (\S+)") |
list_meas = [] |
while True: |
line = f.readline().strip() |
if line == '': |
break |
m = re.match(pattern, line) |
if m: |
list_meas.append([float(m.group(2)), float(m.group(3)), float(m.group(4)), float(m.group(5))]) |
return np.array(list_meas) |
def filter_meas(meas, window_size, noise_threshold): |
"""Select only non-noisy data.""" |
filtered_meas = [] |
filtered_idx = [] |
for i in range(window_size, len(meas)-window_size): |
noise = meas[i-window_size:i+window_size, :].std(axis=0) |
if linalg.norm(noise) < noise_threshold: |
filtered_meas.append(meas[i, :]) |
filtered_idx.append(i) |
return np.array(filtered_meas), filtered_idx |
def get_min_max_guess(meas, scale): |
"""Initial boundary based calibration.""" |
max_meas = meas[:, :].max(axis=0) |
min_meas = meas[:, :].min(axis=0) |
n = (max_meas + min_meas) / 2 |
sf = 2*scale/(max_meas - min_meas) |
return np.array([n[0], n[1], n[2], sf[0], sf[1], sf[2]]) |
def scale_measurements(meas, p): |
"""Scale the set of measurements.""" |
l_comp = [] |
l_norm = [] |
for m in meas[:, ]: |
sm = (m - p[0:3])*p[3:6] |
l_comp.append(sm) |
l_norm.append(linalg.norm(sm)) |
return np.array(l_comp), np.array(l_norm) |
def estimate_mag_current_relation(meas): |
"""Calculate linear coefficient of magnetometer-current relation.""" |
coefficient = [] |
for i in range(0, 3): |
gradient, intercept, r_value, p_value, std_err = stats.linregress(meas[:, 3], meas[:, i]) |
coefficient.append(gradient) |
return coefficient |
def print_xml(p, sensor, res): |
"""Print xml for airframe file.""" |
print("") |
print("<define name=\""+sensor+"_X_NEUTRAL\" value=\""+str(int(round(p[0])))+"\"/>") |
print("<define name=\""+sensor+"_Y_NEUTRAL\" value=\""+str(int(round(p[1])))+"\"/>") |
print("<define name=\""+sensor+"_Z_NEUTRAL\" value=\""+str(int(round(p[2])))+"\"/>") |
print("<define name=\""+sensor+"_X_SENS\" value=\""+str(p[3]*2**res)+"\" integer=\"16\"/>") |
print("<define name=\""+sensor+"_Y_SENS\" value=\""+str(p[4]*2**res)+"\" integer=\"16\"/>") |
print("<define name=\""+sensor+"_Z_SENS\" value=\""+str(p[5]*2**res)+"\" integer=\"16\"/>") |
def plot_results(block, measurements, flt_idx, flt_meas, cp0, np0, cp1, np1, sensor_ref): |
"""Plot calibration results in 2D graphs.""" |
plt.subplot(3, 1, 1) |
plt.plot(measurements[:, 0]) |
plt.plot(measurements[:, 1]) |
plt.plot(measurements[:, 2]) |
plt.plot(flt_idx, flt_meas[:, 0], 'ro') |
plt.plot(flt_idx, flt_meas[:, 1], 'ro') |
plt.plot(flt_idx, flt_meas[:, 2], 'ro') |
plt.xlabel('sample number') |
plt.ylabel('miligauss') |
plt.title('Raw sensors') |
plt.subplot(3, 2, 3) |
plt.plot(cp0[:, 0]) |
plt.plot(cp0[:, 1]) |
plt.plot(cp0[:, 2]) |
plt.plot(-sensor_ref*np.ones(len(flt_meas))) |
plt.plot(sensor_ref*np.ones(len(flt_meas))) |
plt.xlabel('sample number') |
plt.ylabel('-') |
plt.title('First approximation') |
plt.subplot(3, 2, 4) |
plt.plot(np0) |
plt.plot(sensor_ref*np.ones(len(flt_meas))) |
plt.xlabel('sample number') |
plt.ylabel('-') |
plt.title('magnitude') |
plt.subplot(3, 2, 5) |
plt.plot(cp1[:, 0]) |
plt.plot(cp1[:, 1]) |
plt.plot(cp1[:, 2]) |
plt.plot(-sensor_ref*np.ones(len(flt_meas))) |
plt.plot(sensor_ref*np.ones(len(flt_meas))) |
plt.xlabel('sample number') |
plt.ylabel('-') |
plt.title('separate axes') |
plt.subplot(3, 2, 6) |
plt.plot(np1) |
plt.plot(sensor_ref*np.ones(len(flt_meas))) |
plt.xlabel('sample number') |
plt.ylabel('-') |
plt.title('magnitude') |
# if we want to have another plot we only draw the figure (non-blocking) |
# also in matplotlib before 1.0.0 there is only one call to show possible |
if block: |
plt.show() |
else: |
plt.draw() |
def plot_mag_3d(measured, calibrated, p): |
"""Plot magnetometer measurements on 3D sphere.""" |
# set up points for sphere and ellipsoid wireframes |
u = np.r_[0:2 * np.pi:20j] |
v = np.r_[0:np.pi:20j] |
wx = np.outer(cos(u), sin(v)) |
wy = np.outer(sin(u), sin(v)) |
wz = np.outer(np.ones(np.size(u)), cos(v)) |
ex = p[0] * np.ones(np.size(u)) + np.outer(cos(u), sin(v)) / p[3] |
ey = p[1] * np.ones(np.size(u)) + np.outer(sin(u), sin(v)) / p[4] |
ez = p[2] * np.ones(np.size(u)) + np.outer(np.ones(np.size(u)), cos(v)) / p[5] |
# measurements |
mx = measured[:, 0] |
my = measured[:, 1] |
mz = measured[:, 2] |
# calibrated values |
cx = calibrated[:, 0] |
cy = calibrated[:, 1] |
cz = calibrated[:, 2] |
# axes size |
left = 0.02 |
bottom = 0.05 |
width = 0.46 |
height = 0.9 |
rect_l = [left, bottom, width, height] |
rect_r = [left/2+0.5, bottom, width, height] |
fig = plt.figure(figsize=plt.figaspect(0.5)) |
if matplotlib.__version__.startswith('0'): |
ax = Axes3D(fig, rect=rect_l) |
else: |
ax = fig.add_subplot(1, 2, 1, position=rect_l, projection='3d') |
# plot measurements |
ax.scatter(mx, my, mz) |
plt.hold(True) |
# plot line from center to ellipsoid center |
ax.plot([0.0, p[0]], [0.0, p[1]], [0.0, p[2]], color='black', marker='+', markersize=10) |
# plot ellipsoid |
ax.plot_wireframe(ex, ey, ez, color='grey', alpha=0.5) |
# Create cubic bounding box to simulate equal aspect ratio |
max_range = np.array([mx.max() - mx.min(), my.max() - my.min(), mz.max() - mz.min()]).max() |
Xb = 0.5 * max_range * np.mgrid[-1:2:2, -1:2:2, -1:2:2][0].flatten() + 0.5 * (mx.max() + mx.min()) |
Yb = 0.5 * max_range * np.mgrid[-1:2:2, -1:2:2, -1:2:2][1].flatten() + 0.5 * (my.max() + my.min()) |
Zb = 0.5 * max_range * np.mgrid[-1:2:2, -1:2:2, -1:2:2][2].flatten() + 0.5 * (mz.max() + mz.min()) |
# add the fake bounding box: |
for xb, yb, zb in zip(Xb, Yb, Zb): |
ax.plot([xb], [yb], [zb], 'w') |
ax.set_title('MAG raw with fitted ellipsoid and center offset') |
ax.set_xlabel('x') |
ax.set_ylabel('y') |
ax.set_zlabel('z') |
if matplotlib.__version__.startswith('0'): |
ax = Axes3D(fig, rect=rect_r) |
else: |
ax = fig.add_subplot(1, 2, 2, position=rect_r, projection='3d') |
ax.plot_wireframe(wx, wy, wz, color='grey', alpha=0.5) |
plt.hold(True) |
ax.scatter(cx, cy, cz) |
ax.set_title('MAG calibrated on unit sphere') |
ax.set_xlabel('x') |
ax.set_ylabel('y') |
ax.set_zlabel('z') |
ax.set_xlim3d(-1, 1) |
ax.set_ylim3d(-1, 1) |
ax.set_zlim3d(-1, 1) |
plt.show() |
def read_turntable_log(ac_id, tt_id, filename, _min, _max): |
""" Read a turntable log. |
return an array which first column is turnatble and next 3 are gyro |
""" |
f = open(filename, 'r') |
pattern_g = re.compile("(\S+) "+str(ac_id)+" IMU_GYRO_RAW (\S+) (\S+) (\S+)") |
pattern_t = re.compile("(\S+) "+str(tt_id)+" IMU_TURNTABLE (\S+)") |
last_tt = None |
list_tt = [] |
while True: |
line = f.readline().strip() |
if line == '': |
break |
m = re.match(pattern_t, line) |
if m: |
last_tt = float(m.group(2)) |
m = re.match(pattern_g, line) |
if m and last_tt and _min < last_tt < _max: |
list_tt.append([last_tt, float(m.group(2)), float(m.group(3)), float(m.group(4))]) |
return np.array(list_tt) |
/Modules/Sensors/MAG01A/SW/Python/calibration_data_3Dset.npz |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/Modules/Sensors/MAG01A/SW/PIC16F887/main.c |
---|
0,0 → 1,42 |
#include "main.h" |
#include "HMC5883L.h" |
#include <math.h> |
void main() |
{ |
setup_adc_ports(NO_ANALOGS|VSS_VDD); |
setup_adc(ADC_CLOCK_DIV_2); |
setup_spi(SPI_SS_DISABLED); |
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); |
setup_timer_1(T1_DISABLED); |
setup_timer_2(T2_DISABLED,0,1); |
setup_ccp1(CCP_OFF); |
setup_comparator(NC_NC_NC_NC); |
printf("Magnetometr: \r\n",); |
printf("(c)mlab.cz kaklik 2013: \r\n",); |
printf("X, Y, Z \r\n",); |
// Init the HMC5883L. Set Mode register for |
// continuous measurements. |
hmc5883l_write_reg(HMC5883L_CFG_A_REG, 0x18); // no average, maximal update range |
hmc5883l_write_reg(HMC5883L_CFG_B_REG, 0x00); // minimal range |
hmc5883l_write_reg(HMC5883L_MODE_REG, 0x00); |
// Continuously read and display the x,y,z results. |
// Wait at least 67 ms between reads, re the HMC5883L data sheet. |
while(TRUE) |
{ |
hmc5883l_read_data(); |
printf("%6Ld %6Ld %6Ld \n\r", compass.x, compass.y, compass.z); |
delay_ms(100); |
} |
} |
/Modules/Sensors/MAG01A/SW/PIC16F887/main.cof |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/Modules/Sensors/MAG01A/SW/PIC16F887/main.err |
---|
0,0 → 1,2 |
Memory usage: ROM=9% RAM=3% - 6% |
0 Errors, 0 Warnings. |
/Modules/Sensors/MAG01A/SW/PIC16F887/main.esym |
---|
0,0 → 1,601 |
D G "__PCM__" 0 44 ""4.106"" |
D G "__DEVICE__" 0 44 "887" |
D G "__DATE__" 0 44 ""25-VIII-13"" |
D G "__TIME__" 0 44 ""18:55:43"" "Standard Header file for the PIC16F887 device ////////////////" |
d G "PIN_A0" 2 20 "40" |
d G "PIN_A1" 2 21 "41" |
d G "PIN_A2" 2 22 "42" |
d G "PIN_A3" 2 23 "43" |
d G "PIN_A4" 2 24 "44" |
d G "PIN_A5" 2 25 "45" |
d G "PIN_A6" 2 26 "46" |
d G "PIN_A7" 2 27 "47" |
d G "PIN_B0" 2 29 "48" |
d G "PIN_B1" 2 30 "49" |
d G "PIN_B2" 2 31 "50" |
d G "PIN_B3" 2 32 "51" |
d G "PIN_B4" 2 33 "52" |
d G "PIN_B5" 2 34 "53" |
d G "PIN_B6" 2 35 "54" |
d G "PIN_B7" 2 36 "55" |
d G "PIN_C0" 2 38 "56" |
d G "PIN_C1" 2 39 "57" |
d G "PIN_C2" 2 40 "58" |
d G "PIN_C3" 2 41 "59" |
d G "PIN_C4" 2 42 "60" |
d G "PIN_C5" 2 43 "61" |
d G "PIN_C6" 2 44 "62" |
d G "PIN_C7" 2 45 "63" |
d G "PIN_D0" 2 47 "64" |
d G "PIN_D1" 2 48 "65" |
d G "PIN_D2" 2 49 "66" |
d G "PIN_D3" 2 50 "67" |
d G "PIN_D4" 2 51 "68" |
d G "PIN_D5" 2 52 "69" |
d G "PIN_D6" 2 53 "70" |
d G "PIN_D7" 2 54 "71" |
d G "PIN_E0" 2 56 "72" |
d G "PIN_E1" 2 57 "73" |
d G "PIN_E2" 2 58 "74" |
d G "PIN_E3" 2 59 "75" |
d G "FALSE" 2 62 "0" |
d G "TRUE" 2 63 "1" |
d G "BYTE" 2 65 "int8" |
d G "BOOLEAN" 2 66 "int1" |
d G "getc" 2 68 "getch" |
d G "fgetc" 2 69 "getch" |
d G "getchar" 2 70 "getch" |
d G "putc" 2 71 "putchar" |
d G "fputc" 2 72 "putchar" |
d G "fgets" 2 73 "gets" |
d G "fputs" 2 74 "puts" |
d G "WDT_FROM_SLEEP" 2 79 "3" |
d G "WDT_TIMEOUT" 2 80 "11" |
d G "MCLR_FROM_SLEEP" 2 81 "19" |
d G "MCLR_FROM_RUN" 2 82 "27" |
d G "NORMAL_POWER_UP" 2 83 "25" |
d G "BROWNOUT_RESTART" 2 84 "26" |
d G "T0_INTERNAL" 2 91 "0" |
d G "T0_EXT_L_TO_H" 2 92 "32" |
d G "T0_EXT_H_TO_L" 2 93 "48" |
d G "T0_DIV_1" 2 95 "8" |
d G "T0_DIV_2" 2 96 "0" |
d G "T0_DIV_4" 2 97 "1" |
d G "T0_DIV_8" 2 98 "2" |
d G "T0_DIV_16" 2 99 "3" |
d G "T0_DIV_32" 2 100 "4" |
d G "T0_DIV_64" 2 101 "5" |
d G "T0_DIV_128" 2 102 "6" |
d G "T0_DIV_256" 2 103 "7" |
d G "T0_8_BIT" 2 106 "0" |
d G "RTCC_INTERNAL" 2 108 "0" "The following are provided for compatibility" |
d G "RTCC_EXT_L_TO_H" 2 109 "32" "with older compiler versions" |
d G "RTCC_EXT_H_TO_L" 2 110 "48" |
d G "RTCC_DIV_1" 2 111 "8" |
d G "RTCC_DIV_2" 2 112 "0" |
d G "RTCC_DIV_4" 2 113 "1" |
d G "RTCC_DIV_8" 2 114 "2" |
d G "RTCC_DIV_16" 2 115 "3" |
d G "RTCC_DIV_32" 2 116 "4" |
d G "RTCC_DIV_64" 2 117 "5" |
d G "RTCC_DIV_128" 2 118 "6" |
d G "RTCC_DIV_256" 2 119 "7" |
d G "RTCC_8_BIT" 2 120 "0" |
d G "WDT_18MS" 2 132 "8" |
d G "WDT_36MS" 2 133 "9" |
d G "WDT_72MS" 2 134 "10" |
d G "WDT_144MS" 2 135 "11" |
d G "WDT_288MS" 2 136 "12" |
d G "WDT_576MS" 2 137 "13" |
d G "WDT_1152MS" 2 138 "14" |
d G "WDT_2304MS" 2 139 "15" |
d G "WDT_ON" 2 143 "0x4100" |
d G "WDT_OFF" 2 144 "0" |
d G "WDT_DIV_16" 2 145 "0x100" |
d G "WDT_DIV_8" 2 146 "0x300" |
d G "WDT_DIV_4" 2 147 "0x500" |
d G "WDT_DIV_2" 2 148 "0x700" |
d G "WDT_TIMES_1" 2 149 "0x900" "Default" |
d G "WDT_TIMES_2" 2 150 "0xB00" |
d G "WDT_TIMES_4" 2 151 "0xD00" |
d G "WDT_TIMES_8" 2 152 "0xF00" |
d G "WDT_TIMES_16" 2 153 "0x1100" |
d G "WDT_TIMES_32" 2 154 "0x1300" |
d G "WDT_TIMES_64" 2 155 "0x1500" |
d G "WDT_TIMES_128" 2 156 "0x1700" |
d G "T1_DISABLED" 2 162 "0" |
d G "T1_INTERNAL" 2 163 "5" |
d G "T1_EXTERNAL" 2 164 "7" |
d G "T1_EXTERNAL_SYNC" 2 165 "3" |
d G "T1_CLK_OUT" 2 167 "8" |
d G "T1_DIV_BY_1" 2 169 "0" |
d G "T1_DIV_BY_2" 2 170 "0x10" |
d G "T1_DIV_BY_4" 2 171 "0x20" |
d G "T1_DIV_BY_8" 2 172 "0x30" |
d G "T1_GATE" 2 174 "0x40" |
d G "T1_GATE_INVERTED" 2 175 "0xC0" |
d G "T2_DISABLED" 2 180 "0" |
d G "T2_DIV_BY_1" 2 181 "4" |
d G "T2_DIV_BY_4" 2 182 "5" |
d G "T2_DIV_BY_16" 2 183 "6" |
d G "CCP_OFF" 2 189 "0" |
d G "CCP_CAPTURE_FE" 2 190 "4" |
d G "CCP_CAPTURE_RE" 2 191 "5" |
d G "CCP_CAPTURE_DIV_4" 2 192 "6" |
d G "CCP_CAPTURE_DIV_16" 2 193 "7" |
d G "CCP_COMPARE_SET_ON_MATCH" 2 194 "8" |
d G "CCP_COMPARE_CLR_ON_MATCH" 2 195 "9" |
d G "CCP_COMPARE_INT" 2 196 "0xA" |
d G "CCP_COMPARE_RESET_TIMER" 2 197 "0xB" |
d G "CCP_PWM" 2 198 "0xC" |
d G "CCP_PWM_PLUS_1" 2 199 "0x1c" |
d G "CCP_PWM_PLUS_2" 2 200 "0x2c" |
d G "CCP_PWM_PLUS_3" 2 201 "0x3c" |
d G "CCP_PWM_H_H" 2 206 "0x0c" |
d G "CCP_PWM_H_L" 2 207 "0x0d" |
d G "CCP_PWM_L_H" 2 208 "0x0e" |
d G "CCP_PWM_L_L" 2 209 "0x0f" |
d G "CCP_PWM_FULL_BRIDGE" 2 211 "0x40" |
d G "CCP_PWM_FULL_BRIDGE_REV" 2 212 "0xC0" |
d G "CCP_PWM_HALF_BRIDGE" 2 213 "0x80" |
d G "CCP_SHUTDOWN_ON_COMP1" 2 215 "0x100000" |
d G "CCP_SHUTDOWN_ON_COMP2" 2 216 "0x200000" |
d G "CCP_SHUTDOWN_ON_COMP" 2 217 "0x300000" |
d G "CCP_SHUTDOWN_ON_INT0" 2 218 "0x400000" |
d G "CCP_SHUTDOWN_ON_COMP1_INT0" 2 219 "0x500000" |
d G "CCP_SHUTDOWN_ON_COMP2_INT0" 2 220 "0x600000" |
d G "CCP_SHUTDOWN_ON_COMP_INT0" 2 221 "0x700000" |
d G "CCP_SHUTDOWN_AC_L" 2 223 "0x000000" |
d G "CCP_SHUTDOWN_AC_H" 2 224 "0x040000" |
d G "CCP_SHUTDOWN_AC_F" 2 225 "0x080000" |
d G "CCP_SHUTDOWN_BD_L" 2 227 "0x000000" |
d G "CCP_SHUTDOWN_BD_H" 2 228 "0x010000" |
d G "CCP_SHUTDOWN_BD_F" 2 229 "0x020000" |
d G "CCP_SHUTDOWN_RESTART" 2 231 "0x80000000" |
d G "CCP_PULSE_STEERING_A" 2 233 "0x01000000" |
d G "CCP_PULSE_STEERING_B" 2 234 "0x02000000" |
d G "CCP_PULSE_STEERING_C" 2 235 "0x04000000" |
d G "CCP_PULSE_STEERING_D" 2 236 "0x08000000" |
d G "CCP_PULSE_STEERING_SYNC" 2 237 "0x10000000" |
d G "SPI_MASTER" 2 245 "0x20" |
d G "SPI_SLAVE" 2 246 "0x24" |
d G "SPI_L_TO_H" 2 247 "0" |
d G "SPI_H_TO_L" 2 248 "0x10" |
d G "SPI_CLK_DIV_4" 2 249 "0" |
d G "SPI_CLK_DIV_16" 2 250 "1" |
d G "SPI_CLK_DIV_64" 2 251 "2" |
d G "SPI_CLK_T2" 2 252 "3" |
d G "SPI_SS_DISABLED" 2 253 "1" |
d G "SPI_SAMPLE_AT_END" 2 255 "0x8000" |
d G "SPI_XMIT_L_TO_H" 2 256 "0x4000" |
d G "UART_ADDRESS" 2 262 "2" |
d G "UART_DATA" 2 263 "4" |
d G "UART_AUTODETECT" 2 264 "8" |
d G "UART_AUTODETECT_NOWAIT" 2 265 "9" |
d G "UART_WAKEUP_ON_RDA" 2 266 "10" |
d G "UART_SEND_BREAK" 2 267 "13" |
d G "NC_NC_NC_NC" 2 273 "0x00" |
d G "NC_NC" 2 274 "0x00" |
d G "CP1_A0_A3" 2 277 "0x00090080" |
d G "CP1_A1_A3" 2 278 "0x000A0081" |
d G "CP1_B3_A3" 2 279 "0x00880082" |
d G "CP1_B1_A3" 2 280 "0x00280083" |
d G "CP1_A0_VREF" 2 281 "0x00010084" |
d G "CP1_A1_VREF" 2 282 "0x00020085" |
d G "CP1_B3_VREF" 2 283 "0x00800086" |
d G "CP1_B1_VREF" 2 284 "0x00200087" |
d G "CP1_OUT_ON_A4" 2 286 "0x00000020" |
d G "CP1_INVERT" 2 287 "0x00000010" |
d G "CP1_ABSOLUTE_VREF" 2 288 "0x20000000" |
d G "CP2_A0_A2" 2 291 "0x00058000" |
d G "CP2_A1_A2" 2 292 "0x00068100" |
d G "CP2_B3_A2" 2 293 "0x00848200" |
d G "CP2_B1_A2" 2 294 "0x00248300" |
d G "CP2_A0_VREF" 2 295 "0x00018400" |
d G "CP2_A1_VREF" 2 296 "0x00028500" |
d G "CP2_B3_VREF" 2 297 "0x00808600" |
d G "CP2_B1_VREF" 2 298 "0x00208700" |
d G "CP2_OUT_ON_A5" 2 300 "0x00002000" |
d G "CP2_INVERT" 2 301 "0x00001000" |
d G "CP2_ABSOLUTE_VREF" 2 302 "0x10000000" |
d G "CP2_T1_SYNC" 2 305 "0x01000000" |
d G "CP2_T1_GATE" 2 306 "0x02000000" |
d G "VREF_LOW" 2 315 "0xa0" |
d G "VREF_HIGH" 2 316 "0x80" |
d G "OSC_31KHZ" 2 322 "1" |
d G "OSC_125KHZ" 2 323 "0x11" |
d G "OSC_250KHZ" 2 324 "0x21" |
d G "OSC_500KHZ" 2 325 "0x31" |
d G "OSC_1MHZ" 2 326 "0x41" |
d G "OSC_2MHZ" 2 327 "0x51" |
d G "OSC_4MHZ" 2 328 "0x61" |
d G "OSC_8MHZ" 2 329 "0x71" |
d G "OSC_INTRC" 2 330 "1" |
d G "OSC_NORMAL" 2 331 "0" |
d G "OSC_STATE_STABLE" 2 333 "4" |
d G "OSC_31KHZ_STABLE" 2 334 "2" |
d G "ADC_OFF" 2 342 "0" "ADC Off" |
d G "ADC_CLOCK_DIV_2" 2 343 "0x100" |
d G "ADC_CLOCK_DIV_8" 2 344 "0x40" |
d G "ADC_CLOCK_DIV_32" 2 345 "0x80" |
d G "ADC_CLOCK_INTERNAL" 2 346 "0xc0" "Internal 2-6us" |
d G "sAN0" 2 350 "1" "| A0" |
d G "sAN1" 2 351 "2" "| A1" |
d G "sAN2" 2 352 "4" "| A2" |
d G "sAN3" 2 353 "8" "| A3" |
d G "sAN4" 2 354 "16" "| A5" |
d G "sAN5" 2 355 "32" "| E0" |
d G "sAN6" 2 356 "64" "| E1" |
d G "sAN7" 2 357 "128" "| E2" |
d G "sAN8" 2 358 "0x10000" "| B2" |
d G "sAN9" 2 359 "0x20000" "| B3" |
d G "sAN10" 2 360 "0x40000" "| B1" |
d G "sAN11" 2 361 "0x80000" "| B4" |
d G "sAN12" 2 362 "0x100000" "| B0" |
d G "sAN13" 2 363 "0x200000" "| B5" |
d G "NO_ANALOGS" 2 364 "0" "None" |
d G "ALL_ANALOG" 2 365 "0x1F00FF" "A0 A1 A2 A3 A5 E0 E1 E2 B0 B1 B2 B3 B4 B5" |
d G "VSS_VDD" 2 368 "0x0000" "| Range 0-Vdd" |
d G "VSS_VREF" 2 369 "0x1000" "| Range 0-Vref" |
d G "VREF_VREF" 2 370 "0x3000" "| Range Vref-Vref" |
d G "VREF_VDD" 2 371 "0x2000" "| Range Vref-Vdd" |
d G "ADC_START_AND_READ" 2 375 "7" "This is the default if nothing is specified" |
d G "ADC_START_ONLY" 2 376 "1" |
d G "ADC_READ_ONLY" 2 377 "6" |
d G "L_TO_H" 2 389 "0x40" |
d G "H_TO_L" 2 390 "0" |
d G "GLOBAL" 2 392 "0x0BC0" |
d G "INT_RTCC" 2 393 "0x000B20" |
d G "INT_RB" 2 394 "0x01FF0B08" |
d G "INT_EXT_L2H" 2 395 "0x50000B10" |
d G "INT_EXT_H2L" 2 396 "0x60000B10" |
d G "INT_EXT" 2 397 "0x000B10" |
d G "INT_AD" 2 398 "0x008C40" |
d G "INT_TBE" 2 399 "0x008C10" |
d G "INT_RDA" 2 400 "0x008C20" |
d G "INT_TIMER1" 2 401 "0x008C01" |
d G "INT_TIMER2" 2 402 "0x008C02" |
d G "INT_CCP1" 2 403 "0x008C04" |
d G "INT_CCP2" 2 404 "0x008D01" |
d G "INT_SSP" 2 405 "0x008C08" |
d G "INT_BUSCOL" 2 406 "0x008D08" |
d G "INT_EEPROM" 2 407 "0x008D10" |
d G "INT_TIMER0" 2 408 "0x000B20" |
d G "INT_OSC_FAIL" 2 409 "0x008D80" |
d G "INT_COMP" 2 410 "0x008D20" |
d G "INT_COMP2" 2 411 "0x008D40" |
d G "INT_ULPWU" 2 412 "0x008D04" |
d G "INT_RB0" 2 413 "0x0010B08" |
d G "INT_RB1" 2 414 "0x0020B08" |
d G "INT_RB2" 2 415 "0x0040B08" |
d G "INT_RB3" 2 416 "0x0080B08" |
d G "INT_RB4" 2 417 "0x0100B08" |
d G "INT_RB5" 2 418 "0x0200B08" |
d G "INT_RB6" 2 419 "0x0400B08" |
d G "INT_RB7" 2 420 "0x0800B08" |
D G "HMC5883L_WRT_ADDR" 3 2 "0x3C" |
D G "HMC5883L_READ_ADDR" 3 3 "0x3D" |
D G "HMC5883L_CFG_A_REG" 3 6 "0x00" |
D G "HMC5883L_CFG_B_REG" 3 7 "0x01" |
D G "HMC5883L_MODE_REG" 3 8 "0x02" |
D G "HMC5883L_X_MSB_REG" 3 9 "0x03" |
D G "MAG_ROZ088" 3 13 "0x00" |
D G "MAG_ROZ130" 3 14 "0x20" |
D G "MAG_ROZ190" 3 15 "0x40" |
D G "MAG_ROZ250" 3 16 "0x60" |
D G "MAG_ROZ400" 3 17 "0x80" |
D G "MAG_ROZ470" 3 18 "0xA0" |
D G "MAG_ROZ560" 3 19 "0xC0" |
D G "MAG_ROZ810" 3 20 "0xE0" |
C L "hmc5883l_write_reg" 4 2 1 "FUNCTION" |
F G "hmc5883l_write_reg" 4 4 "void(int8 reg,int8 data)" |
V L "reg" 4 4 "int8" |
V L "data" 4 4 "int8" |
F G "hmc5883l_read_reg" 4 14 "int8(int8 reg)" |
V L "reg" 4 14 "int8" |
V L "retval" 4 16 "int8" |
T G "hmc5883l_result" 4 35 "{sint16 x,sint16 y,sint16 z}" "This global structure holds the values read" |
V G "compass" 4 39 "hmc5883l_result" |
F G "hmc5883l_read_data" 4 42 "void()" |
V L "x_lsb" 4 44 "int8" |
V L "x_msb" 4 45 "int8" |
V L "y_lsb" 4 47 "int8" |
V L "y_msb" 4 48 "int8" |
V L "z_lsb" 4 50 "int8" |
V L "z_msb" 4 51 "int8" |
C L "hmc5883l_read_data" 4 2 1 "FUNCTION" |
C L "hmc5883l_read_data" 4 2 1 "FUNCTION" |
C L "hmc5883l_read_data" 4 2 1 "FUNCTION" |
D G "MATH_H" 5 21 "" |
D G "PI" 5 26 "3.1415926535897932" |
D G "SQRT2" 5 29 "1.4142135623730950" |
C L "CEIL_FLOOR" 5 2 3 "FUNCTION" |
F G "CEIL_FLOOR" 5 36 "float(float x,int8 n)" |
V L "x" 5 36 "float" |
V L "n" 5 36 "int8" |
V L "y" 5 38 "float" |
V L "res" 5 38 "float" |
V L "l" 5 39 "int16" |
V L "s" 5 40 "int1" |
C L "floor" 5 2 5 "FUNCTION" |
F G "floor" 5 192 "float(float x)" |
V L "x" 5 192 "float" |
C L "ceil" 5 2 5 "FUNCTION" |
F G "ceil" 5 218 "float(float x)" |
V L "x" 5 218 "float" |
D G "fabs" 5 244 "abs" |
C L "fmod" 5 2 6 "FUNCTION" |
F G "fmod" 5 256 "float(float x,float y)" |
V L "x" 5 256 "float" |
V L "y" 5 256 "float" |
V L "i" 5 258 "float" |
D G "LN2" 5 319 "0.6931471805599453" |
V G "pe" 5 321 "float[6]" |
F G "exp" 5 325 "float(float x)" |
V L "x" 5 325 "float" |
V L "y" 5 327 "float" |
V L "res" 5 327 "float" |
V L "r" 5 327 "float" |
V L "n" 5 331 "sint8" |
V L "s" 5 332 "int1" |
C L "exp" 5 2 1 "FUNCTION" |
V G "pl" 5 496 "float[4]" |
V G "ql" 5 497 "float[4]" |
C L "log" 5 2 3 "FUNCTION" |
F G "log" 5 505 "float(float x)" |
V L "x" 5 505 "float" |
V L "y" 5 507 "float" |
V L "res" 5 507 "float" |
V L "r" 5 507 "float" |
V L "y2" 5 507 "float" |
V L "n" 5 511 "sint8" |
C L "log" 5 2 1 "FUNCTION" |
D G "LN10" 5 729 "2.3025850929940456" |
C L "log10" 5 2 3 "FUNCTION" |
F G "log10" 5 737 "float(float x)" |
V L "x" 5 737 "float" |
V L "r" 5 739 "float" |
C L "modf" 5 2 8 "FUNCTION" |
F G "modf" 5 778 "float(float value,*float iptr)" |
V L "value" 5 778 "float" |
V L "iptr" 5 778 "*float" |
C L "pwr" 5 2 6 "FUNCTION" |
F G "pwr" 5 806 "float(float x,float y)" |
V L "x" 5 806 "float" |
V L "y" 5 806 "float" |
C L "pow" 5 2 7 "FUNCTION" |
F G "pow" 5 869 "float(float x,float y)" |
V L "x" 5 869 "float" |
V L "y" 5 869 "float" |
C L "sqrt" 5 2 5 "FUNCTION" |
F G "sqrt" 5 930 "float(float x)" |
V L "x" 5 930 "float" |
V L "y" 5 932 "float" |
V L "res" 5 932 "float" |
V L "p" 5 936 "*int8" |
D G "PI_DIV_BY_TWO" 5 1125 "1.5707963267948966" |
C L "cos" 5 2 3 "FUNCTION" |
F G "cos" 5 1136 "float(float x)" |
V L "x" 5 1136 "float" |
V L "y" 5 1138 "float" |
V L "t" 5 1138 "float" |
V L "t2" 5 1138 "float" |
V L "quad" 5 1139 "int8" |
V L "i" 5 1139 "int8" |
V L "frac" 5 1140 "float" |
V L "p" 5 1141 "float[6]" "by the series definition for cosine" |
C L "cos" 5 2 1 "FUNCTION" |
C L "cos" 5 2 2 "FUNCTION" |
C L "cos" 5 2 1 "FUNCTION" |
C L "cos" 5 2 1 "FUNCTION" |
C L "cos" 5 2 1 "FUNCTION" |
C L "cos" 5 2 1 "FUNCTION" |
C L "cos" 5 2 1 "FUNCTION" |
C L "cos" 5 2 1 "FUNCTION" |
C L "sin" 5 2 5 "FUNCTION" |
F G "sin" 5 1278 "float(float x)" |
V L "x" 5 1278 "float" |
C L "tan" 5 2 5 "FUNCTION" |
F G "tan" 5 1304 "float(float x)" |
V L "x" 5 1304 "float" |
V L "c" 5 1306 "float" |
V L "s" 5 1306 "float" |
V G "pas" 5 1344 "float[3]" |
V G "qas" 5 1345 "float[3]" |
F G "ASIN_COS" 5 1347 "float(float x,int8 n)" |
V L "x" 5 1347 "float" |
V L "n" 5 1347 "int8" |
V L "y" 5 1349 "float" |
V L "res" 5 1349 "float" |
V L "r" 5 1349 "float" |
V L "y2" 5 1349 "float" |
V L "s" 5 1350 "int1" |
C L "ASIN_COS" 5 2 1 "FUNCTION" |
C L "ASIN_COS" 5 2 1 "FUNCTION" |
C L "asin" 5 2 5 "FUNCTION" |
F G "asin" 5 1493 "float(float x)" |
V L "x" 5 1493 "float" |
V L "r" 5 1495 "float" |
C L "acos" 5 2 5 "FUNCTION" |
F G "acos" 5 1527 "float(float x)" |
V L "x" 5 1527 "float" |
V L "r" 5 1529 "float" |
V G "pat" 5 1555 "float[4]" |
V G "qat" 5 1556 "float[4]" |
C L "atan" 5 2 3 "FUNCTION" |
F G "atan" 5 1564 "float(float x)" |
V L "x" 5 1564 "float" |
V L "y" 5 1566 "float" |
V L "res" 5 1566 "float" |
V L "r" 5 1566 "float" |
V L "s" 5 1567 "int1" |
V L "flag" 5 1567 "int1" |
C L "atan" 5 2 1 "FUNCTION" |
C L "atan2" 5 2 7 "FUNCTION" |
F G "atan2" 5 1697 "float(float y,float x)" |
V L "y" 5 1697 "float" |
V L "x" 5 1697 "float" |
V L "z" 5 1699 "float" |
V L "sign" 5 1700 "int1" |
V L "quad" 5 1701 "int8" |
C L "atan2" 5 2 1 "FUNCTION" |
C L "atan2" 5 2 1 "FUNCTION" |
C L "cosh" 5 2 7 "FUNCTION" |
F G "cosh" 5 1919 "float(float x)" |
V L "x" 5 1919 "float" |
C L "sinh" 5 2 6 "FUNCTION" |
F G "sinh" 5 1946 "float(float x)" |
V L "x" 5 1946 "float" |
C L "tanh" 5 2 6 "FUNCTION" |
F G "tanh" 5 1976 "float(float x)" |
V L "x" 5 1976 "float" |
D G "LOG2" 5 2006 ".30102999566398119521" |
F G "frexp" 5 2007 "float(float x,*sint8 exp)" |
V L "x" 5 2007 "float" |
V L "exp" 5 2007 "*sint8" |
V L "res" 5 2009 "float" |
V L "sign" 5 2010 "int1" |
C L "ldexp" 5 2 6 "FUNCTION" |
F G "ldexp" 5 2152 "float(float value,sint8 exp)" |
V L "value" 5 2152 "float" |
V L "exp" 5 2152 "sint8" |
C L "MAIN" 5 2 2 "FUNCTION" |
F G "MAIN" 0 5 "void()" |
C L "MAIN" 0 21 2 "FUNCTION" |
C L "MAIN" 0 21 1 "FUNCTION" |
C L "MAIN" 0 21 1 "FUNCTION" |
C L "MAIN" 0 21 2 "FUNCTION" |
F B "reset_cpu" 0 0 |
F B "abs" 1 0 |
F B "sleep_ulpwu" 1 0 |
F B "sleep" 0 0 |
F B "delay_cycles" 1 0 |
F B "read_bank" 2 0 |
F B "write_bank" 3 0 |
F B "shift_left" 2 2 |
F B "shift_right" 2 2 |
F B "rotate_left" 2 0 |
F B "rotate_right" 2 0 |
F B "_mul" 2 0 |
F B "memset" 3 0 |
F B "isamoung" 2 0 |
F B "isamong" 2 0 |
F B "bit_set" 2 0 |
F B "bit_clear" 2 0 |
F B "bit_test" 2 0 |
F B "toupper" 1 0 |
F B "tolower" 1 0 |
F B "swap" 1 0 |
F B "printf" 1 255 |
F B "fprintf" 1 255 |
F B "sprintf" 1 255 |
F B "make8" 2 0 |
F B "make16" 2 0 |
F B "make32" 1 255 |
F B "label_address" 1 1 |
F B "goto_address" 1 0 |
F B "_va_arg" 1 0 |
F B "offsetofbit" 2 2 |
F B "enable_interrupts" 1 0 |
F B "disable_interrupts" 1 0 |
F B "interrupt_active" 1 0 |
F B "clear_interrupt" 1 0 |
F B "jump_to_isr" 1 0 |
F B "ext_int_edge" 1 2 |
F B "read_eeprom" 1 0 |
F B "write_eeprom" 2 0 |
F B "read_program_eeprom" 1 0 |
F B "write_program_eeprom" 2 0 |
F B "write_program_memory" 4 0 |
F B "write_program_memory8" 4 0 |
F B "read_program_memory" 4 0 |
F B "read_program_memory8" 4 0 |
F B "erase_program_eeprom" 1 0 |
F B "strcpy" 2 0 |
F B "memcpy" 3 0 |
F B "strstr100" 2 0 |
F B "output_high" 1 0 |
F B "output_low" 1 0 |
F B "input" 1 0 |
F B "input_state" 1 0 |
F B "output_float" 1 0 |
F B "output_drive" 1 0 |
F B "output_bit" 1 1 |
F B "output_toggle" 1 0 |
F B "output_a" 1 0 |
F B "output_b" 1 0 |
F B "output_c" 1 0 |
F B "output_d" 1 0 |
F B "output_e" 1 0 |
F B "input_a" 0 0 |
F B "input_b" 0 0 |
F B "input_c" 0 0 |
F B "input_d" 0 0 |
F B "input_e" 0 0 |
F B "set_tris_a" 1 0 |
F B "set_tris_b" 1 0 |
F B "set_tris_c" 1 0 |
F B "set_tris_d" 1 0 |
F B "set_tris_e" 1 0 |
F B "get_tris_a" 0 0 |
F B "get_tris_b" 0 0 |
F B "get_tris_c" 0 0 |
F B "get_tris_d" 0 0 |
F B "get_tris_e" 0 0 |
F B "input_change_a" 0 0 |
F B "input_change_b" 0 0 |
F B "input_change_c" 0 0 |
F B "input_change_d" 0 0 |
F B "input_change_e" 0 0 |
F B "port_b_pullups" 1 0 |
F B "setup_counters" 2 0 |
F B "setup_wdt" 1 0 |
F B "restart_cause" 0 0 |
F B "restart_wdt" 0 0 |
F B "get_rtcc" 0 0 |
F B "set_rtcc" 1 0 |
F B "get_timer0" 0 0 |
F B "set_timer0" 1 0 |
F B "setup_comparator" 1 0 |
F B "setup_port_a" 1 0 |
F B "setup_adc_ports" 1 0 |
F B "setup_adc" 1 0 |
F B "set_adc_channel" 1 0 |
F B "read_adc" 0 1 |
F B "adc_done" 0 0 |
F B "setup_timer_0" 1 0 |
F B "setup_vref" 1 0 |
F B "setup_timer_1" 1 0 |
F B "get_timer1" 0 0 |
F B "set_timer1" 1 0 |
F B "setup_timer_2" 3 0 |
F B "get_timer2" 0 0 |
F B "set_timer2" 1 0 |
F B "setup_ccp1" 1 2 |
F B "set_pwm1_duty" 1 0 |
F B "setup_ccp2" 1 0 |
F B "set_pwm2_duty" 1 0 |
F B "setup_oscillator" 1 2 |
F B "setup_spi" 1 0 |
F B "spi_read" 0 1 |
F B "spi_write" 1 0 |
F B "spi_data_is_in" 0 0 |
F B "setup_spi2" 1 0 |
F B "spi_read2" 0 1 |
F B "spi_write2" 1 0 |
F B "spi_data_is_in2" 0 0 |
F B "brownout_enable" 1 0 |
F B "delay_ms" 1 0 |
F B "delay_us" 1 0 |
F B "i2c_read" 0 2 |
F B "i2c_write" 1 2 |
F B "i2c_start" 0 2 |
F B "i2c_stop" 0 1 |
F B "i2c_isr_state" 0 1 |
F B "putchar" 1 2 |
F B "puts" 1 2 |
F B "getch" 0 1 |
F B "gets" 1 3 |
F B "kbhit" 0 1 |
F B "set_uart_speed" 1 3 |
F B "setup_uart" 1 3 |
/Modules/Sensors/MAG01A/SW/PIC16F887/main.h |
---|
0,0 → 1,21 |
#include <16F887.h> |
#device adc=8 |
#FUSES NOWDT //No Watch Dog Timer |
#FUSES INTRC //Internal RC Osc |
#FUSES NOPUT //No Power Up Timer |
#FUSES MCLR //Master Clear pin enabled |
#FUSES NOPROTECT //Code not protected from reading |
#FUSES NOCPD //No EE protection |
#FUSES NOBROWNOUT //No brownout reset |
#FUSES IESO //Internal External Switch Over mode enabled |
#FUSES FCMEN //Fail-safe clock monitor enabled |
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O |
#FUSES NODEBUG //No Debug mode for ICD |
#FUSES NOWRT //Program memory not write protected |
#FUSES BORV40 //Brownout reset at 4.0V |
#use delay(clock=8000000) |
#use i2c(Master,Slow,sda=PIN_C4,scl=PIN_C3) |
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8) //rcv TXD xmit RXD |
/Modules/Sensors/MAG01A/SW/PIC16F887/main.hex |
---|
0,0 → 1,100 |
:1000000002308A003C2A0000CD306737653AEF366F |
:10001000653A721D20100D050000A831A936EC309C |
:100020006217633DA035E135EC346B103218B1191D |
:100030003A10A0060A005816A02C2C105A100D05D4 |
:100040000001831603178C170C14000000008312A4 |
:100050000C087F39031967280313A70003170D083D |
:100060000313A80003170F080313A90027080C1E89 |
:1000700037289900280803178D0003132908031750 |
:100080008F0083168C170C140000000083120C0DD7 |
:100090000E0D7F39031967280313A70003170D08F6 |
:1000A0000313A80003170F080313A90027080C1E49 |
:1000B00057289900280803178D00031329080317F0 |
:1000C0008F008D0A03198F0A0313212803170313C6 |
:1000D00008000830F80000008711A01120088316DE |
:1000E000870000008312AD0D0712031C7D28201627 |
:1000F0002008831687008128831220122008831687 |
:10010000870000008312A015200883168700831241 |
:10011000871D8828F80B6B2800008711A011200884 |
:10012000831687000000831220162008831687009C |
:10013000000000008312A015200883168700831298 |
:10014000871DA028F8010000071A78148711A01154 |
:1001500020088316870083120712201220088316B6 |
:1001600087008312080020162008831687000000ED |
:100170008312A0152008831687000000831207123F |
:100180002012200883168700000083128711A01117 |
:100190002008831687003C308312AD0069202708B1 |
:1001A000AD0069202808AD006920201220088316C0 |
:1001B000870000008312A015200883168700831291 |
:1001C000871DE0280000E428000020162008831680 |
:1001D00087000000831208000830AE007708AF00E7 |
:1001E000201620088316870000008312A01520081F |
:1001F000831687008312871DFB28071A0314071E26 |
:100200000310F80D0000A011200883168700831248 |
:100210008711AE0BF02820162008831687000000F7 |
:10022000831207122F0803191A2920122008831697 |
:10023000870083120000A015200883168700831210 |
:10024000871D202900008711A01120088316870030 |
:1002500000008312071220122008831687008312E1 |
:100260000800201620088316870000008312A015BE |
:10027000200883168700000083120712201220082E |
:1002800083168700000083128711A01120088316AF |
:1002900087003C308312AD0069200330AD00692037 |
:1002A000201620088316870000008312A01520085E |
:1002B0008316870000008312871D5C290712201215 |
:1002C000200883168700000083128711A0112008E0 |
:1002D000831687003D308312AD0069200130F7009E |
:1002E000EC207808A8000130F700EC207808A7007F |
:1002F0000130F700EC207808AC000130F700EC206A |
:100300007808AB000130F700EC207808AA00F7016C |
:10031000EC207808A900201220088316870000002E |
:100320008312A0152008831687008312871D962943 |
:1003300000009A290000201620088316870000007C |
:1003400083122808A2002708A1002A08A40029086F |
:10035000A3002C08A6002B08A5008A110A12CC2A9B |
:10036000AF010408AE002F10831B2F14A81FC02953 |
:10037000AE172E1EAE0AA709A809A70A0319A80AD4 |
:10038000280EF038AA00AA07E23EAB00323EAD00CC |
:1003900028080F39AB07AB07AD07E93EAC00AC0747 |
:1003A000AC07270E0F39AC07AD07AC0DAD0DAD098D |
:1003B000AD0D27080F39AD07AA0D0730A9000A3087 |
:1003C000AD07AC03031CE029AC07AB03031CE42915 |
:1003D000AB07AA03031CE829AA07A903031CEC29FD |
:1003E00029308400831307302E052E1384032E0535 |
:1003F000031D012A2E1A840A2E1A012A2030F70022 |
:100400001E2A84072D30040203192E170008F70056 |
:10041000031D122A2E1B122A2E1A222AAE19122A64 |
:1004200020301D2AAE1F1A2A2D30F70084032E1308 |
:10043000AE131E2AAE152E123030F70777080C1EA9 |
:100440001F2A9900840A2E1F022A080027308400E0 |
:10045000831300080319392A0230F800F701F70B5B |
:100460002F2AF80B2E2A9730F700F70B352A800B2E |
:100470002C2A8A110A12F82A840183131F3083055B |
:10048000713083168F000F08031787110C30031388 |
:100490009900A230980090308312980083160317B9 |
:1004A0000908C039890003131F129F120030031777 |
:1004B00088008312870188018901FF300313A0009F |
:1004C000A101A201A301A401A501A601831603179E |
:1004D0000908C039890003131F129F120030031747 |
:1004E0008800831203131F139F1383169F13831215 |
:1004F0001F149412A012200883168700831220165E |
:100500002008831687008312A01120088316870015 |
:100510000130831294000030831694000108C7391B |
:1005200008388100831290010030F80092000030FA |
:1005300083169200831220152008831687008312E9 |
:10054000970183169B019C0101309D0083120317C4 |
:1005500087018801890104308D0000308F0003136A |
:1005600021200D3003178D0000308F000313212050 |
:100570001B3003178D0000308F0003132120A701CB |
:100580001830A800B3200130A700A801B320023022 |
:10059000A700A801B3203129003084002208A80058 |
:1005A0002108A700B02120300C1ED42A9900003069 |
:1005B00084002408A8002308A700B02120300C1EC6 |
:1005C000DF2A9900003084002608A8002508A7002B |
:1005D000B02120300C1EEA2A99000A300C1EEE2AA7 |
:1005E00099000D300C1EF22A99006430A700262ACB |
:0405F000CB2A6300AF |
:04400E00F52CFF3F4F |
:00000001FF |
;PIC16F887 |
;CRC=2B66 CREATED="25-VIII-13 18:55" |
/Modules/Sensors/MAG01A/SW/PIC16F887/main.lst |
---|
0,0 → 1,2904 |
CCS PCM C Compiler, Version 4.106, 47914 25-VIII-13 18:55 |
Filename: Z:\home\kaklik\svnMLAB\Modules\Sensors\MAG01A\SW\PIC16F887\main.lst |
ROM used: 762 words (9%) |
Largest free fragment is 2048 |
RAM used: 12 (3%) at main() level |
21 (6%) worst case |
Stack: 2 locations |
* |
0000: MOVLW 02 |
0001: MOVWF 0A |
0002: GOTO 23C |
0003: NOP |
.................... #include "main.h" |
.................... #include <16F887.h> |
.................... //////// Standard Header file for the PIC16F887 device //////////////// |
.................... #device PIC16F887 |
.................... #list |
.................... |
.................... #device adc=8 |
.................... |
.................... #FUSES NOWDT //No Watch Dog Timer |
.................... #FUSES INTRC //Internal RC Osc |
.................... #FUSES NOPUT //No Power Up Timer |
.................... #FUSES MCLR //Master Clear pin enabled |
.................... #FUSES NOPROTECT //Code not protected from reading |
.................... #FUSES NOCPD //No EE protection |
.................... #FUSES NOBROWNOUT //No brownout reset |
.................... #FUSES IESO //Internal External Switch Over mode enabled |
.................... #FUSES FCMEN //Fail-safe clock monitor enabled |
.................... #FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O |
.................... #FUSES NODEBUG //No Debug mode for ICD |
.................... #FUSES NOWRT //Program memory not write protected |
.................... #FUSES BORV40 //Brownout reset at 4.0V |
.................... |
.................... #use delay(clock=8000000) |
* |
0226: MOVLW 27 |
0227: MOVWF 04 |
0228: BCF 03.7 |
0229: MOVF 00,W |
022A: BTFSC 03.2 |
022B: GOTO 239 |
022C: MOVLW 02 |
022D: MOVWF 78 |
022E: CLRF 77 |
022F: DECFSZ 77,F |
0230: GOTO 22F |
0231: DECFSZ 78,F |
0232: GOTO 22E |
0233: MOVLW 97 |
0234: MOVWF 77 |
0235: DECFSZ 77,F |
0236: GOTO 235 |
0237: DECFSZ 00,F |
0238: GOTO 22C |
0239: BCF 0A.3 |
023A: BCF 0A.4 |
023B: GOTO 2F8 (RETURN) |
.................... #use i2c(Master,Slow,sda=PIN_C4,scl=PIN_C3) |
* |
0069: MOVLW 08 |
006A: MOVWF 78 |
006B: NOP |
006C: BCF 07.3 |
006D: BCF 20.3 |
006E: MOVF 20,W |
006F: BSF 03.5 |
0070: MOVWF 07 |
0071: NOP |
0072: BCF 03.5 |
0073: RLF 2D,F |
0074: BCF 07.4 |
0075: BTFSS 03.0 |
0076: GOTO 07D |
0077: BSF 20.4 |
0078: MOVF 20,W |
0079: BSF 03.5 |
007A: MOVWF 07 |
007B: GOTO 081 |
007C: BCF 03.5 |
007D: BCF 20.4 |
007E: MOVF 20,W |
007F: BSF 03.5 |
0080: MOVWF 07 |
0081: NOP |
0082: BCF 03.5 |
0083: BSF 20.3 |
0084: MOVF 20,W |
0085: BSF 03.5 |
0086: MOVWF 07 |
0087: BCF 03.5 |
0088: BTFSS 07.3 |
0089: GOTO 088 |
008A: DECFSZ 78,F |
008B: GOTO 06B |
008C: NOP |
008D: BCF 07.3 |
008E: BCF 20.3 |
008F: MOVF 20,W |
0090: BSF 03.5 |
0091: MOVWF 07 |
0092: NOP |
0093: BCF 03.5 |
0094: BSF 20.4 |
0095: MOVF 20,W |
0096: BSF 03.5 |
0097: MOVWF 07 |
0098: NOP |
0099: NOP |
009A: BCF 03.5 |
009B: BSF 20.3 |
009C: MOVF 20,W |
009D: BSF 03.5 |
009E: MOVWF 07 |
009F: BCF 03.5 |
00A0: BTFSS 07.3 |
00A1: GOTO 0A0 |
00A2: CLRF 78 |
00A3: NOP |
00A4: BTFSC 07.4 |
00A5: BSF 78.0 |
00A6: BCF 07.3 |
00A7: BCF 20.3 |
00A8: MOVF 20,W |
00A9: BSF 03.5 |
00AA: MOVWF 07 |
00AB: BCF 03.5 |
00AC: BCF 07.4 |
00AD: BCF 20.4 |
00AE: MOVF 20,W |
00AF: BSF 03.5 |
00B0: MOVWF 07 |
00B1: BCF 03.5 |
00B2: RETURN |
* |
00EC: MOVLW 08 |
00ED: MOVWF 2E |
00EE: MOVF 77,W |
00EF: MOVWF 2F |
00F0: BSF 20.4 |
00F1: MOVF 20,W |
00F2: BSF 03.5 |
00F3: MOVWF 07 |
00F4: NOP |
00F5: BCF 03.5 |
00F6: BSF 20.3 |
00F7: MOVF 20,W |
00F8: BSF 03.5 |
00F9: MOVWF 07 |
00FA: BCF 03.5 |
00FB: BTFSS 07.3 |
00FC: GOTO 0FB |
00FD: BTFSC 07.4 |
00FE: BSF 03.0 |
00FF: BTFSS 07.4 |
0100: BCF 03.0 |
0101: RLF 78,F |
0102: NOP |
0103: BCF 20.3 |
0104: MOVF 20,W |
0105: BSF 03.5 |
0106: MOVWF 07 |
0107: BCF 03.5 |
0108: BCF 07.3 |
0109: DECFSZ 2E,F |
010A: GOTO 0F0 |
010B: BSF 20.4 |
010C: MOVF 20,W |
010D: BSF 03.5 |
010E: MOVWF 07 |
010F: NOP |
0110: BCF 03.5 |
0111: BCF 07.4 |
0112: MOVF 2F,W |
0113: BTFSC 03.2 |
0114: GOTO 11A |
0115: BCF 20.4 |
0116: MOVF 20,W |
0117: BSF 03.5 |
0118: MOVWF 07 |
0119: BCF 03.5 |
011A: NOP |
011B: BSF 20.3 |
011C: MOVF 20,W |
011D: BSF 03.5 |
011E: MOVWF 07 |
011F: BCF 03.5 |
0120: BTFSS 07.3 |
0121: GOTO 120 |
0122: NOP |
0123: BCF 07.3 |
0124: BCF 20.3 |
0125: MOVF 20,W |
0126: BSF 03.5 |
0127: MOVWF 07 |
0128: NOP |
0129: BCF 03.5 |
012A: BCF 07.4 |
012B: BCF 20.4 |
012C: MOVF 20,W |
012D: BSF 03.5 |
012E: MOVWF 07 |
012F: BCF 03.5 |
0130: RETURN |
.................... #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8) //rcv TXD xmit RXD |
.................... |
.................... |
.................... #include "HMC5883L.h" |
.................... // i2c slave addresses |
.................... #define HMC5883L_WRT_ADDR 0x3C |
.................... #define HMC5883L_READ_ADDR 0x3D |
.................... |
.................... // Register addresses |
.................... #define HMC5883L_CFG_A_REG 0x00 |
.................... #define HMC5883L_CFG_B_REG 0x01 |
.................... #define HMC5883L_MODE_REG 0x02 |
.................... #define HMC5883L_X_MSB_REG 0x03 |
.................... |
.................... //Konstanty nastavujici rozsah |
.................... //pro void set_mag_roz (unsigned int8 h) |
.................... #define MAG_ROZ088 0x00 |
.................... #define MAG_ROZ130 0x20 |
.................... #define MAG_ROZ190 0x40 |
.................... #define MAG_ROZ250 0x60 |
.................... #define MAG_ROZ400 0x80 |
.................... #define MAG_ROZ470 0xA0 |
.................... #define MAG_ROZ560 0xC0 |
.................... #define MAG_ROZ810 0xE0 |
.................... |
.................... |
.................... #include "HMC5883L.c" |
.................... //------------------------------ |
.................... // Low level routines |
.................... //------------------------------ |
.................... void hmc5883l_write_reg(int8 reg, int8 data) |
.................... { |
.................... i2c_start(); |
* |
00B3: BSF 20.4 |
00B4: MOVF 20,W |
00B5: BSF 03.5 |
00B6: MOVWF 07 |
00B7: NOP |
00B8: BCF 03.5 |
00B9: BSF 20.3 |
00BA: MOVF 20,W |
00BB: BSF 03.5 |
00BC: MOVWF 07 |
00BD: NOP |
00BE: BCF 03.5 |
00BF: BCF 07.4 |
00C0: BCF 20.4 |
00C1: MOVF 20,W |
00C2: BSF 03.5 |
00C3: MOVWF 07 |
00C4: NOP |
00C5: BCF 03.5 |
00C6: BCF 07.3 |
00C7: BCF 20.3 |
00C8: MOVF 20,W |
00C9: BSF 03.5 |
00CA: MOVWF 07 |
.................... i2c_write(HMC5883L_WRT_ADDR); |
00CB: MOVLW 3C |
00CC: BCF 03.5 |
00CD: MOVWF 2D |
00CE: CALL 069 |
.................... i2c_write(reg); |
00CF: MOVF 27,W |
00D0: MOVWF 2D |
00D1: CALL 069 |
.................... i2c_write(data); |
00D2: MOVF 28,W |
00D3: MOVWF 2D |
00D4: CALL 069 |
.................... i2c_stop(); |
00D5: BCF 20.4 |
00D6: MOVF 20,W |
00D7: BSF 03.5 |
00D8: MOVWF 07 |
00D9: NOP |
00DA: BCF 03.5 |
00DB: BSF 20.3 |
00DC: MOVF 20,W |
00DD: BSF 03.5 |
00DE: MOVWF 07 |
00DF: BCF 03.5 |
00E0: BTFSS 07.3 |
00E1: GOTO 0E0 |
00E2: NOP |
00E3: GOTO 0E4 |
00E4: NOP |
00E5: BSF 20.4 |
00E6: MOVF 20,W |
00E7: BSF 03.5 |
00E8: MOVWF 07 |
00E9: NOP |
.................... } |
00EA: BCF 03.5 |
00EB: RETURN |
.................... |
.................... //------------------------------ |
.................... int8 hmc5883l_read_reg(int8 reg) |
.................... { |
.................... int8 retval; |
.................... |
.................... i2c_start(); |
.................... i2c_write(HMC5883L_WRT_ADDR); |
.................... i2c_write(reg); |
.................... i2c_start(); |
.................... i2c_write(HMC5883L_READ_ADDR); |
.................... retval = i2c_read(0); |
.................... i2c_stop(); |
.................... |
.................... return(retval); |
.................... } |
.................... |
.................... //------------------------------ |
.................... typedef struct |
.................... { |
.................... signed int16 x; |
.................... signed int16 y; |
.................... signed int16 z; |
.................... }hmc5883l_result; |
.................... |
.................... // This global structure holds the values read |
.................... // from the HMC5883L x,y,z registers. |
.................... hmc5883l_result compass = {0,0,0}; |
* |
0260: CLRF 21 |
0261: CLRF 22 |
0262: CLRF 23 |
0263: CLRF 24 |
0264: CLRF 25 |
0265: CLRF 26 |
.................... |
.................... //------------------------------ |
.................... void hmc5883l_read_data(void) |
.................... { |
.................... unsigned int8 x_lsb; |
.................... unsigned int8 x_msb; |
.................... |
.................... unsigned int8 y_lsb; |
.................... unsigned int8 y_msb; |
.................... |
.................... unsigned int8 z_lsb; |
.................... unsigned int8 z_msb; |
.................... |
.................... i2c_start(); |
* |
0131: BSF 20.4 |
0132: MOVF 20,W |
0133: BSF 03.5 |
0134: MOVWF 07 |
0135: NOP |
0136: BCF 03.5 |
0137: BSF 20.3 |
0138: MOVF 20,W |
0139: BSF 03.5 |
013A: MOVWF 07 |
013B: NOP |
013C: BCF 03.5 |
013D: BCF 07.4 |
013E: BCF 20.4 |
013F: MOVF 20,W |
0140: BSF 03.5 |
0141: MOVWF 07 |
0142: NOP |
0143: BCF 03.5 |
0144: BCF 07.3 |
0145: BCF 20.3 |
0146: MOVF 20,W |
0147: BSF 03.5 |
0148: MOVWF 07 |
.................... i2c_write(HMC5883L_WRT_ADDR); |
0149: MOVLW 3C |
014A: BCF 03.5 |
014B: MOVWF 2D |
014C: CALL 069 |
.................... i2c_write(HMC5883L_X_MSB_REG); // Point to X-msb register |
014D: MOVLW 03 |
014E: MOVWF 2D |
014F: CALL 069 |
.................... i2c_start(); |
0150: BSF 20.4 |
0151: MOVF 20,W |
0152: BSF 03.5 |
0153: MOVWF 07 |
0154: NOP |
0155: BCF 03.5 |
0156: BSF 20.3 |
0157: MOVF 20,W |
0158: BSF 03.5 |
0159: MOVWF 07 |
015A: NOP |
015B: BCF 03.5 |
015C: BTFSS 07.3 |
015D: GOTO 15C |
015E: BCF 07.4 |
015F: BCF 20.4 |
0160: MOVF 20,W |
0161: BSF 03.5 |
0162: MOVWF 07 |
0163: NOP |
0164: BCF 03.5 |
0165: BCF 07.3 |
0166: BCF 20.3 |
0167: MOVF 20,W |
0168: BSF 03.5 |
0169: MOVWF 07 |
.................... i2c_write(HMC5883L_READ_ADDR); |
016A: MOVLW 3D |
016B: BCF 03.5 |
016C: MOVWF 2D |
016D: CALL 069 |
.................... |
.................... x_msb = i2c_read(); |
016E: MOVLW 01 |
016F: MOVWF 77 |
0170: CALL 0EC |
0171: MOVF 78,W |
0172: MOVWF 28 |
.................... x_lsb = i2c_read(); |
0173: MOVLW 01 |
0174: MOVWF 77 |
0175: CALL 0EC |
0176: MOVF 78,W |
0177: MOVWF 27 |
.................... |
.................... z_msb = i2c_read(); |
0178: MOVLW 01 |
0179: MOVWF 77 |
017A: CALL 0EC |
017B: MOVF 78,W |
017C: MOVWF 2C |
.................... z_lsb = i2c_read(); |
017D: MOVLW 01 |
017E: MOVWF 77 |
017F: CALL 0EC |
0180: MOVF 78,W |
0181: MOVWF 2B |
.................... |
.................... y_msb = i2c_read(); |
0182: MOVLW 01 |
0183: MOVWF 77 |
0184: CALL 0EC |
0185: MOVF 78,W |
0186: MOVWF 2A |
.................... y_lsb = i2c_read(0); // do a NACK on last read |
0187: CLRF 77 |
0188: CALL 0EC |
0189: MOVF 78,W |
018A: MOVWF 29 |
.................... |
.................... i2c_stop(); |
018B: BCF 20.4 |
018C: MOVF 20,W |
018D: BSF 03.5 |
018E: MOVWF 07 |
018F: NOP |
0190: BCF 03.5 |
0191: BSF 20.3 |
0192: MOVF 20,W |
0193: BSF 03.5 |
0194: MOVWF 07 |
0195: BCF 03.5 |
0196: BTFSS 07.3 |
0197: GOTO 196 |
0198: NOP |
0199: GOTO 19A |
019A: NOP |
019B: BSF 20.4 |
019C: MOVF 20,W |
019D: BSF 03.5 |
019E: MOVWF 07 |
019F: NOP |
.................... |
.................... // Combine high and low bytes into 16-bit values. |
.................... compass.x = make16(x_msb, x_lsb); |
01A0: BCF 03.5 |
01A1: MOVF 28,W |
01A2: MOVWF 22 |
01A3: MOVF 27,W |
01A4: MOVWF 21 |
.................... compass.y = make16(y_msb, y_lsb); |
01A5: MOVF 2A,W |
01A6: MOVWF 24 |
01A7: MOVF 29,W |
01A8: MOVWF 23 |
.................... compass.z = make16(z_msb, z_lsb); |
01A9: MOVF 2C,W |
01AA: MOVWF 26 |
01AB: MOVF 2B,W |
01AC: MOVWF 25 |
.................... } |
01AD: BCF 0A.3 |
01AE: BCF 0A.4 |
01AF: GOTO 2CC (RETURN) |
.................... |
.................... |
.................... |
.................... |
.................... #include <math.h> |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... //// (C) Copyright 1996,2008 Custom Computer Services //// |
.................... //// This source code may only be used by licensed users of the CCS C //// |
.................... //// compiler. This source code may only be distributed to other //// |
.................... //// licensed users of the CCS C compiler. No other use, reproduction //// |
.................... //// or distribution is permitted without written permission. //// |
.................... //// Derivative programs created using this software in object code //// |
.................... //// form are not restricted in any way. //// |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... //// //// |
.................... //// History: //// |
.................... //// * 9/20/2001 : Improvments are made to sin/cos code. //// |
.................... //// The code now is small, much faster, //// |
.................... //// and more accurate. //// |
.................... //// * 2/21/2007 : Compiler handles & operator differently and does |
.................... //// not return generic (int8 *) so type cast is done //// |
.................... //// //// |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... |
.................... #ifndef MATH_H |
.................... #define MATH_H |
.................... |
.................... #ifdef PI |
.................... #undef PI |
.................... #endif |
.................... #define PI 3.1415926535897932 |
.................... |
.................... |
.................... #define SQRT2 1.4142135623730950 |
.................... |
.................... //float const ps[4] = {5.9304945, 21.125224, 8.9403076, 0.29730279}; |
.................... //float const qs[4] = {1.0000000, 15.035723, 17.764134, 2.4934718}; |
.................... |
.................... ///////////////////////////// Round Functions ////////////////////////////// |
.................... |
.................... float32 CEIL_FLOOR(float32 x, unsigned int8 n) |
.................... { |
.................... float32 y, res; |
.................... unsigned int16 l; |
.................... int1 s; |
.................... |
.................... s = 0; |
.................... y = x; |
.................... |
.................... if (x < 0) |
.................... { |
.................... s = 1; |
.................... y = -y; |
.................... } |
.................... |
.................... if (y <= 32768.0) |
.................... res = (float32)(unsigned int16)y; |
.................... |
.................... else if (y < 10000000.0) |
.................... { |
.................... l = (unsigned int16)(y/32768.0); |
.................... y = 32768.0*(y/32768.0 - (float32)l); |
.................... res = 32768.0*(float32)l; |
.................... res += (float32)(unsigned int16)y; |
.................... } |
.................... |
.................... else |
.................... res = y; |
.................... |
.................... y = y - (float32)(unsigned int16)y; |
.................... |
.................... if (s) |
.................... res = -res; |
.................... |
.................... if (y != 0) |
.................... { |
.................... if (s == 1 && n == 0) |
.................... res -= 1.0; |
.................... |
.................... if (s == 0 && n == 1) |
.................... res += 1.0; |
.................... } |
.................... if (x == 0) |
.................... res = 0; |
.................... |
.................... return (res); |
.................... } |
.................... |
.................... // Overloaded Functions to take care for new Data types in PCD |
.................... // Overloaded function CEIL_FLOOR() for data type - Float48 |
.................... #if defined(__PCD__) |
.................... float48 CEIL_FLOOR(float48 x, unsigned int8 n) |
.................... { |
.................... float48 y, res; |
.................... unsigned int16 l; |
.................... int1 s; |
.................... |
.................... s = 0; |
.................... y = x; |
.................... |
.................... if (x < 0) |
.................... { |
.................... s = 1; |
.................... y = -y; |
.................... } |
.................... |
.................... if (y <= 32768.0) |
.................... res = (float48)(unsigned int16)y; |
.................... |
.................... else if (y < 10000000.0) |
.................... { |
.................... l = (unsigned int16)(y/32768.0); |
.................... y = 32768.0*(y/32768.0 - (float48)l); |
.................... res = 32768.0*(float32)l; |
.................... res += (float48)(unsigned int16)y; |
.................... } |
.................... |
.................... else |
.................... res = y; |
.................... |
.................... y = y - (float48)(unsigned int16)y; |
.................... |
.................... if (s) |
.................... res = -res; |
.................... |
.................... if (y != 0) |
.................... { |
.................... if (s == 1 && n == 0) |
.................... res -= 1.0; |
.................... |
.................... if (s == 0 && n == 1) |
.................... res += 1.0; |
.................... } |
.................... if (x == 0) |
.................... res = 0; |
.................... |
.................... return (res); |
.................... } |
.................... |
.................... |
.................... // Overloaded function CEIL_FLOOR() for data type - Float64 |
.................... float64 CEIL_FLOOR(float64 x, unsigned int8 n) |
.................... { |
.................... float64 y, res; |
.................... unsigned int16 l; |
.................... int1 s; |
.................... |
.................... s = 0; |
.................... y = x; |
.................... |
.................... if (x < 0) |
.................... { |
.................... s = 1; |
.................... y = -y; |
.................... } |
.................... |
.................... if (y <= 32768.0) |
.................... res = (float64)(unsigned int16)y; |
.................... |
.................... else if (y < 10000000.0) |
.................... { |
.................... l = (unsigned int16)(y/32768.0); |
.................... y = 32768.0*(y/32768.0 - (float64)l); |
.................... res = 32768.0*(float64)l; |
.................... res += (float64)(unsigned int16)y; |
.................... } |
.................... |
.................... else |
.................... res = y; |
.................... |
.................... y = y - (float64)(unsigned int16)y; |
.................... |
.................... if (s) |
.................... res = -res; |
.................... |
.................... if (y != 0) |
.................... { |
.................... if (s == 1 && n == 0) |
.................... res -= 1.0; |
.................... |
.................... if (s == 0 && n == 1) |
.................... res += 1.0; |
.................... } |
.................... if (x == 0) |
.................... res = 0; |
.................... |
.................... return (res); |
.................... } |
.................... #endif |
.................... |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // float floor(float x) |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // Description : rounds down the number x. |
.................... // Date : N/A |
.................... // |
.................... float32 floor(float32 x) |
.................... { |
.................... return CEIL_FLOOR(x, 0); |
.................... } |
.................... // Following 2 functions are overloaded functions of floor() for PCD |
.................... // Overloaded function floor() for data type - Float48 |
.................... #if defined(__PCD__) |
.................... float48 floor(float48 x) |
.................... { |
.................... return CEIL_FLOOR(x, 0); |
.................... } |
.................... |
.................... // Overloaded function floor() for data type - Float64 |
.................... float64 floor(float64 x) |
.................... { |
.................... return CEIL_FLOOR(x, 0); |
.................... } |
.................... #endif |
.................... |
.................... |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // float ceil(float x) |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // Description : rounds up the number x. |
.................... // Date : N/A |
.................... // |
.................... float32 ceil(float32 x) |
.................... { |
.................... return CEIL_FLOOR(x, 1); |
.................... } |
.................... // Following 2 functions are overloaded functions of ceil() for PCD |
.................... // Overloaded function ceil() for data type - Float48 |
.................... #if defined(__PCD__) |
.................... float48 ceil(float48 x) |
.................... { |
.................... return CEIL_FLOOR(x, 1); |
.................... } |
.................... |
.................... // Overloaded function ceil() for data type - Float64 |
.................... float64 ceil(float64 x) |
.................... { |
.................... return CEIL_FLOOR(x, 1); |
.................... } |
.................... #endif |
.................... |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // float fabs(float x) |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // Description : Computes the absolute value of floating point number x |
.................... // Returns : returns the absolute value of x |
.................... // Date : N/A |
.................... // |
.................... #define fabs abs |
.................... |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // float fmod(float x) |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // Description : Computes the floating point remainder of x/y |
.................... // Returns : returns the value of x= i*y, for some integer i such that, if y |
.................... // is non zero, the result has the same isgn of x na dmagnitude less than the |
.................... // magnitude of y. If y is zero then a domain error occurs. |
.................... // Date : N/A |
.................... // |
.................... |
.................... float fmod(float32 x,float32 y) |
.................... { |
.................... float32 i; |
.................... if (y!=0.0) |
.................... { |
.................... i=(x/y < 0.0)? ceil(x/y): floor(x/y); |
.................... return(x-(i*y)); |
.................... } |
.................... else |
.................... { |
.................... #ifdef _ERRNO |
.................... { |
.................... errno=EDOM; |
.................... } |
.................... #endif |
.................... } |
.................... } |
.................... //Overloaded function for fmod() for PCD |
.................... // Overloaded function fmod() for data type - Float48 |
.................... #if defined(__PCD__) |
.................... float48 fmod(float48 x,float48 y) |
.................... { |
.................... float48 i; |
.................... if (y!=0.0) |
.................... { |
.................... i=(x/y < 0.0)? ceil(x/y): floor(x/y); |
.................... return(x-(i*y)); |
.................... } |
.................... else |
.................... { |
.................... #ifdef _ERRNO |
.................... { |
.................... errno=EDOM; |
.................... } |
.................... #endif |
.................... } |
.................... } |
.................... // Overloaded function fmod() for data type - Float64 |
.................... float64 fmod(float64 x,float64 y) |
.................... { |
.................... float64 i; |
.................... if (y!=0.0) |
.................... { |
.................... i=(x/y < 0.0)? ceil(x/y): floor(x/y); |
.................... return(x-(i*y)); |
.................... } |
.................... else |
.................... { |
.................... #ifdef _ERRNO |
.................... { |
.................... errno=EDOM; |
.................... } |
.................... #endif |
.................... } |
.................... } |
.................... #endif |
.................... //////////////////// Exponential and logarithmic functions //////////////////// |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // float exp(float x) |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // Description : returns the value (e^x) |
.................... // Date : N/A |
.................... // |
.................... #define LN2 0.6931471805599453 |
.................... |
.................... float const pe[6] = {0.000207455774, 0.00127100575, 0.00965065093, |
.................... 0.0554965651, 0.240227138, 0.693147172}; |
.................... |
.................... |
.................... float32 exp(float32 x) |
.................... { |
.................... float32 y, res, r; |
.................... #if defined(__PCD__) |
.................... int8 data1; |
.................... #endif |
.................... signed int8 n; |
.................... int1 s; |
.................... #ifdef _ERRNO |
.................... if(x > 88.722838) |
.................... { |
.................... errno=ERANGE; |
.................... return(0); |
.................... } |
.................... #endif |
.................... n = (signed int16)(x/LN2); |
.................... s = 0; |
.................... y = x; |
.................... |
.................... if (x < 0) |
.................... { |
.................... s = 1; |
.................... n = -n; |
.................... y = -y; |
.................... } |
.................... |
.................... res = 0.0; |
.................... #if !defined(__PCD__) |
.................... *((unsigned int8 *)(&res)) = n + 0x7F; |
.................... #endif |
.................... |
.................... #if defined(__PCD__) // Takes care of IEEE format for PCD |
.................... data1 = n+0x7F; |
.................... if(bit_test(data1,0)) |
.................... bit_set(*(((unsigned int8 *)(&res)+2)),7); |
.................... rotate_right(&data1,1); |
.................... bit_clear(data1,7); |
.................... *(((unsigned int8 *)(&res)+3)) = data1; |
.................... #endif |
.................... |
.................... y = y/LN2 - (float32)n; |
.................... |
.................... r = pe[0]*y + pe[1]; |
.................... r = r*y + pe[2]; |
.................... r = r*y + pe[3]; |
.................... r = r*y + pe[4]; |
.................... r = r*y + pe[5]; |
.................... |
.................... res = res*(1.0 + y*r); |
.................... |
.................... if (s) |
.................... res = 1.0/res; |
.................... return(res); |
.................... } |
.................... |
.................... |
.................... //Overloaded function for exp() for PCD |
.................... // Overloaded function exp() for data type - Float48 |
.................... #if defined(__PCD__) |
.................... float48 exp(float48 x) |
.................... { |
.................... float48 y, res, r; |
.................... int8 data1; |
.................... signed int8 n; |
.................... int1 s; |
.................... #ifdef _ERRNO |
.................... if(x > 88.722838) |
.................... { |
.................... errno=ERANGE; |
.................... return(0); |
.................... } |
.................... #endif |
.................... n = (signed int16)(x/LN2); |
.................... s = 0; |
.................... y = x; |
.................... |
.................... if (x < 0) |
.................... { |
.................... s = 1; |
.................... n = -n; |
.................... y = -y; |
.................... } |
.................... |
.................... res = 0.0; |
.................... |
.................... data1 = n+0x7F; |
.................... if(bit_test(data1,0)) |
.................... bit_set(*(((unsigned int8 *)(&res)+4)),7); |
.................... rotate_right(&data1,1); |
.................... bit_clear(data1,7); |
.................... *(((unsigned int8 *)(&res)+5)) = data1; |
.................... |
.................... y = y/LN2 - (float48)n; |
.................... |
.................... r = pe[0]*y + pe[1]; |
.................... r = r*y + pe[2]; |
.................... r = r*y + pe[3]; |
.................... r = r*y + pe[4]; |
.................... r = r*y + pe[5]; |
.................... |
.................... res = res*(1.0 + y*r); |
.................... |
.................... if (s) |
.................... res = 1.0/res; |
.................... return(res); |
.................... } |
.................... |
.................... // Overloaded function exp() for data type - Float64 |
.................... float64 exp(float64 x) |
.................... { |
.................... float64 y, res, r; |
.................... unsigned int16 data1, data2; |
.................... unsigned int16 *p; |
.................... signed int16 n; |
.................... int1 s; |
.................... #ifdef _ERRNO |
.................... if(x > 709.7827128) |
.................... { |
.................... errno=ERANGE; |
.................... return(0); |
.................... } |
.................... #endif |
.................... n = (signed int16)(x/LN2); |
.................... s = 0; |
.................... y = x; |
.................... |
.................... if (x < 0) |
.................... { |
.................... s = 1; |
.................... n = -n; |
.................... y = -y; |
.................... } |
.................... |
.................... res = 0.0; |
.................... |
.................... #if !defined(__PCD__) |
.................... *((unsigned int16 *)(&res)) = n + 0x7F; |
.................... #endif |
.................... p= (((unsigned int16 *)(&res))+3); |
.................... data1 = *p; |
.................... data2 = *p; |
.................... data1 = n + 0x3FF; |
.................... data1 = data1 <<4; |
.................... if(bit_test(data2,15)) |
.................... bit_set(data1,15); |
.................... data2 = data2 & 0x000F; |
.................... data1 ^= data2; |
.................... |
.................... *(((unsigned int16 *)(&res)+3)) = data1; |
.................... |
.................... |
.................... y = y/LN2 - (float64)n; |
.................... |
.................... r = pe[0]*y + pe[1]; |
.................... r = r*y + pe[2]; |
.................... r = r*y + pe[3]; |
.................... r = r*y + pe[4]; |
.................... r = r*y + pe[5]; |
.................... |
.................... res = res*(1.0 + y*r); |
.................... |
.................... if (s) |
.................... res = 1.0/res; |
.................... return(res); |
.................... } |
.................... |
.................... #ENDIF |
.................... |
.................... |
.................... /************************************************************/ |
.................... |
.................... float32 const pl[4] = {0.45145214, -9.0558803, 26.940971, -19.860189}; |
.................... float32 const ql[4] = {1.0000000, -8.1354259, 16.780517, -9.9300943}; |
.................... |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // float log(float x) |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // Description : returns the the natural log of x |
.................... // Date : N/A |
.................... // |
.................... float32 log(float32 x) |
.................... { |
.................... float32 y, res, r, y2; |
.................... #if defined(__PCD__) |
.................... unsigned int8 data1,data2; |
.................... #endif |
.................... signed int8 n; |
.................... #ifdef _ERRNO |
.................... if(x <0) |
.................... { |
.................... errno=EDOM; |
.................... } |
.................... if(x ==0) |
.................... { |
.................... errno=ERANGE; |
.................... return(0); |
.................... } |
.................... #endif |
.................... y = x; |
.................... |
.................... if (y != 1.0) |
.................... { |
.................... #if !defined(__PCD__) |
.................... *((unsigned int8 *)(&y)) = 0x7E; |
.................... #endif |
.................... |
.................... #if defined(__PCD__) // Takes care of IEEE format |
.................... data2 = *(((unsigned int8 *)(&y))+3); |
.................... *(((unsigned int8 *)(&y))+3) = 0x3F; |
.................... data1 = *(((unsigned int8 *)(&y))+2); |
.................... bit_clear(data1,7); |
.................... *(((unsigned int8 *)(&y))+2) = data1; |
.................... if(bit_test(data2,7)) |
.................... bit_set(*(((unsigned int8 *)(&y))+3),7); |
.................... #endif |
.................... |
.................... y = (y - 1.0)/(y + 1.0); |
.................... |
.................... y2=y*y; |
.................... |
.................... res = pl[0]*y2 + pl[1]; |
.................... res = res*y2 + pl[2]; |
.................... res = res*y2 + pl[3]; |
.................... |
.................... r = ql[0]*y2 + ql[1]; |
.................... r = r*y2 + ql[2]; |
.................... r = r*y2 + ql[3]; |
.................... |
.................... res = y*res/r; |
.................... #if !defined(__PCD__) |
.................... n = *((unsigned int8 *)(&x)) - 0x7E; |
.................... #endif |
.................... #if defined(__PCD__) |
.................... data1 = *(((unsigned int8 *)(&x)+3)); |
.................... rotate_left(&data1,1); |
.................... data2 = *(((unsigned int8 *)(&x)+2)); |
.................... if(bit_test (data2,7)) |
.................... bit_set(data1,0); |
.................... n = data1 - 0x7E; |
.................... #endif |
.................... |
.................... if (n<0) |
.................... r = -(float32)-n; |
.................... else |
.................... r = (float32)n; |
.................... |
.................... res += r*LN2; |
.................... } |
.................... |
.................... else |
.................... res = 0.0; |
.................... |
.................... return(res); |
.................... } |
.................... |
.................... //Overloaded function for log() for PCD |
.................... // Overloaded function log() for data type - Float48 |
.................... #if defined(__PCD__) |
.................... float48 log(float48 x) |
.................... { |
.................... float48 y, res, r, y2; |
.................... unsigned int8 data1,data2; |
.................... signed int8 n; |
.................... #ifdef _ERRNO |
.................... if(x <0) |
.................... { |
.................... errno=EDOM; |
.................... } |
.................... if(x ==0) |
.................... { |
.................... errno=ERANGE; |
.................... return(0); |
.................... } |
.................... #endif |
.................... y = x; |
.................... |
.................... if (y != 1.0) |
.................... { |
.................... |
.................... #if !defined(__PCD__) |
.................... *((unsigned int8 *)(&y)) = 0x7E; |
.................... #endif |
.................... data2 = *(((unsigned int8 *)(&y))+5); |
.................... *(((unsigned int8 *)(&y))+5) = 0x3F; |
.................... data1 = *(((unsigned int8 *)(&y))+4); |
.................... bit_clear(data1,7); |
.................... *(((unsigned int8 *)(&y))+4) = data1; |
.................... |
.................... if(bit_test(data2,7)) |
.................... bit_set(*(((unsigned int8 *)(&y))+4),7); |
.................... y = (y - 1.0)/(y + 1.0); |
.................... |
.................... y2=y*y; |
.................... |
.................... res = pl[0]*y2 + pl[1]; |
.................... res = res*y2 + pl[2]; |
.................... res = res*y2 + pl[3]; |
.................... |
.................... r = ql[0]*y2 + ql[1]; |
.................... r = r*y2 + ql[2]; |
.................... r = r*y2 + ql[3]; |
.................... |
.................... res = y*res/r; |
.................... |
.................... data1 = *(((unsigned int8 *)(&x)+5)); |
.................... rotate_left(&data1,1); |
.................... data2 = *(((unsigned int8 *)(&x)+4)); |
.................... if(bit_test (data2,7)) |
.................... bit_set(data1,0); |
.................... |
.................... n = data1 - 0x7E; |
.................... |
.................... if (n<0) |
.................... r = -(float48)-n; |
.................... else |
.................... r = (float48)n; |
.................... |
.................... res += r*LN2; |
.................... } |
.................... |
.................... else |
.................... res = 0.0; |
.................... |
.................... return(res); |
.................... } |
.................... |
.................... // Overloaded function log() for data type - Float48 |
.................... #if defined(__PCD__) |
.................... float32 const pl_64[4] = {0.45145214, -9.0558803, 26.940971, -19.860189}; |
.................... float32 const ql_64[4] = {1.0000000, -8.1354259, 16.780517, -9.9300943}; |
.................... #endif |
.................... float64 log(float64 x) |
.................... { |
.................... float64 y, res, r, y2; |
.................... unsigned int16 data1,data2; |
.................... unsigned int16 *p; |
.................... signed int16 n; |
.................... #ifdef _ERRNO |
.................... if(x <0) |
.................... { |
.................... errno=EDOM; |
.................... } |
.................... if(x ==0) |
.................... { |
.................... errno=ERANGE; |
.................... return(0); |
.................... } |
.................... #endif |
.................... y = x; |
.................... |
.................... if (y != 1.0) |
.................... { |
.................... #if !defined(__PCD__) |
.................... *((unsigned int8 *)(&y)) = 0x7E; |
.................... #endif |
.................... p= (((unsigned int16 *)(&y))+3); |
.................... data1 = *p; |
.................... data2 = *p; |
.................... data1 = 0x3FE; |
.................... data1 = data1 <<4; |
.................... if(bit_test (data2,15)) |
.................... bit_set(data1,15); |
.................... data2 = data2 & 0x000F; |
.................... data1 ^=data2; |
.................... |
.................... *p = data1; |
.................... |
.................... y = (y - 1.0)/(y + 1.0); |
.................... |
.................... y2=y*y; |
.................... |
.................... res = pl_64[0]*y2 + pl_64[1]; |
.................... res = res*y2 + pl_64[2]; |
.................... res = res*y2 + pl_64[3]; |
.................... |
.................... r = ql_64[0]*y2 + ql_64[1]; |
.................... r = r*y2 + ql_64[2]; |
.................... r = r*y2 + ql_64[3]; |
.................... |
.................... res = y*res/r; |
.................... |
.................... p= (((unsigned int16 *)(&x))+3); |
.................... data1 = *p; |
.................... bit_clear(data1,15); |
.................... data1 = data1 >>4; |
.................... n = data1 - 0x3FE; |
.................... |
.................... |
.................... if (n<0) |
.................... r = -(float64)-n; |
.................... else |
.................... r = (float64)n; |
.................... |
.................... res += r*LN2; |
.................... } |
.................... |
.................... else |
.................... res = 0.0; |
.................... |
.................... return(res); |
.................... } |
.................... #endif |
.................... |
.................... |
.................... #define LN10 2.3025850929940456 |
.................... |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // float log10(float x) |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // Description : returns the the log base 10 of x |
.................... // Date : N/A |
.................... // |
.................... float32 log10(float32 x) |
.................... { |
.................... float32 r; |
.................... |
.................... r = log(x); |
.................... r = r/LN10; |
.................... return(r); |
.................... } |
.................... |
.................... //Overloaded functions for log10() for PCD |
.................... // Overloaded function log10() for data type - Float48 |
.................... #if defined(__PCD__) |
.................... float48 log10(float48 x) |
.................... { |
.................... float48 r; |
.................... |
.................... r = log(x); |
.................... r = r/LN10; |
.................... return(r); |
.................... } |
.................... |
.................... // Overloaded function log10() for data type - Float64 |
.................... float64 log10(float64 x) |
.................... { |
.................... float64 r; |
.................... |
.................... r = log(x); |
.................... r = r/LN10; |
.................... return(r); |
.................... } |
.................... #endif |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // float modf(float x) |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // Description :breaks the argument value int integral and fractional parts, |
.................... // ach of which have the same sign as the argument. It stores the integral part |
.................... // as a float in the object pointed to by the iptr |
.................... // Returns : returns the signed fractional part of value. |
.................... // Date : N/A |
.................... // |
.................... |
.................... float32 modf(float32 value,float32 *iptr) |
.................... { |
.................... *iptr=(value < 0.0)? ceil(value): floor(value); |
.................... return(value - *iptr); |
.................... } |
.................... //Overloaded functions for modf() for PCD |
.................... // Overloaded function modf() for data type - Float48 |
.................... #if defined(__PCD__) |
.................... float48 modf(float48 value,float48 *iptr) |
.................... { |
.................... *iptr=(value < 0.0)? ceil(value): floor(value); |
.................... return(value - *iptr); |
.................... } |
.................... // Overloaded function modf() for data type - Float64 |
.................... float64 modf(float64 value,float64 *iptr) |
.................... { |
.................... *iptr=(value < 0.0)? ceil(value): floor(value); |
.................... return(value - *iptr); |
.................... } |
.................... #endif |
.................... |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // float pwr(float x,float y) |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // Description : returns the value (x^y) |
.................... // Date : N/A |
.................... // Note : 0 is returned when the function will generate an imaginary number |
.................... // |
.................... float32 pwr(float32 x,float32 y) |
.................... { |
.................... if(0 > x && fmod(y, 1) == 0) { |
.................... if(fmod(y, 2) == 0) { |
.................... return (exp(log(-x) * y)); |
.................... } else { |
.................... return (-exp(log(-x) * y)); |
.................... } |
.................... } else if(0 > x && fmod(y, 1) != 0) { |
.................... return 0; |
.................... } else { |
.................... if(x != 0 || 0 >= y) { |
.................... return (exp(log(x) * y)); |
.................... } |
.................... } |
.................... } |
.................... //Overloaded functions for pwr() for PCD |
.................... // Overloaded function pwr() for data type - Float48 |
.................... #if defined(__PCD__) |
.................... float48 pwr(float48 x,float48 y) |
.................... { |
.................... if(0 > x && fmod(y, 1) == 0) { |
.................... if(fmod(y, 2) == 0) { |
.................... return (exp(log(-x) * y)); |
.................... } else { |
.................... return (-exp(log(-x) * y)); |
.................... } |
.................... } else if(0 > x && fmod(y, 1) != 0) { |
.................... return 0; |
.................... } else { |
.................... if(x != 0 || 0 >= y) { |
.................... return (exp(log(x) * y)); |
.................... } |
.................... } |
.................... } |
.................... // Overloaded function pwr() for data type - Float64 |
.................... float64 pwr(float64 x,float64 y) |
.................... { |
.................... if(0 > x && fmod(y, 1) == 0) { |
.................... if(fmod(y, 2) == 0) { |
.................... return (exp(log(-x) * y)); |
.................... } else { |
.................... return (-exp(log(-x) * y)); |
.................... } |
.................... } else if(0 > x && fmod(y, 1) != 0) { |
.................... return 0; |
.................... } else { |
.................... if(x != 0 || 0 >= y) { |
.................... return (exp(log(x) * y)); |
.................... } |
.................... } |
.................... } |
.................... #endif |
.................... |
.................... //////////////////// Power functions //////////////////// |
.................... |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // float pow(float x,float y) |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // Description : returns the value (x^y) |
.................... // Date : N/A |
.................... // Note : 0 is returned when the function will generate an imaginary number |
.................... // |
.................... float32 pow(float32 x,float32 y) |
.................... { |
.................... if(0 > x && fmod(y, 1) == 0) { |
.................... if(fmod(y, 2) == 0) { |
.................... return (exp(log(-x) * y)); |
.................... } else { |
.................... return (-exp(log(-x) * y)); |
.................... } |
.................... } else if(0 > x && fmod(y, 1) != 0) { |
.................... return 0; |
.................... } else { |
.................... if(x != 0 || 0 >= y) { |
.................... return (exp(log(x) * y)); |
.................... } |
.................... } |
.................... } |
.................... //Overloaded functions for pow() for PCD |
.................... // Overloaded function for pow() data type - Float48 |
.................... #if defined(__PCD__) |
.................... float48 pow(float48 x,float48 y) |
.................... { |
.................... if(0 > x && fmod(y, 1) == 0) { |
.................... if(fmod(y, 2) == 0) { |
.................... return (exp(log(-x) * y)); |
.................... } else { |
.................... return (-exp(log(-x) * y)); |
.................... } |
.................... } else if(0 > x && fmod(y, 1) != 0) { |
.................... return 0; |
.................... } else { |
.................... if(x != 0 || 0 >= y) { |
.................... return (exp(log(x) * y)); |
.................... } |
.................... } |
.................... } |
.................... |
.................... // Overloaded function pow() for data type - Float64 |
.................... float64 pow(float64 x,float64 y) |
.................... { |
.................... if(0 > x && fmod(y, 1) == 0) { |
.................... if(fmod(y, 2) == 0) { |
.................... return (exp(log(-x) * y)); |
.................... } else { |
.................... return (-exp(log(-x) * y)); |
.................... } |
.................... } else if(0 > x && fmod(y, 1) != 0) { |
.................... return 0; |
.................... } else { |
.................... if(x != 0 || 0 >= y) { |
.................... return (exp(log(x) * y)); |
.................... } |
.................... } |
.................... } |
.................... #endif |
.................... |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // float sqrt(float x) |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // Description : returns the square root of x |
.................... // Date : N/A |
.................... // |
.................... float32 sqrt(float32 x) |
.................... { |
.................... float32 y, res; |
.................... #if defined(__PCD__) |
.................... unsigned int16 data1,data2; |
.................... #endif |
.................... BYTE *p; |
.................... |
.................... #ifdef _ERRNO |
.................... if(x < 0) |
.................... { |
.................... errno=EDOM; |
.................... } |
.................... #endif |
.................... |
.................... if( x<=0.0) |
.................... return(0.0); |
.................... |
.................... y=x; |
.................... |
.................... #if !defined(__PCD__) |
.................... p=&y; |
.................... (*p)=(BYTE)((((unsigned int16)(*p)) + 127) >> 1); |
.................... #endif |
.................... |
.................... #if defined(__PCD__) |
.................... p = (((unsigned int8 *)(&y))+3); |
.................... data1 = *(((unsigned int8 *)(&y))+3); |
.................... data2 = *(((unsigned int8 *)(&y))+2); |
.................... rotate_left(&data1,1); |
.................... if(bit_test(data2,7)) |
.................... bit_set(data1,0); |
.................... data1 = ((data1+127) >>1); |
.................... bit_clear(data2,7); |
.................... if(bit_test(data1,0)) |
.................... bit_set(data2,7); |
.................... data1 = data1 >>1; |
.................... *(((unsigned int8 *)(&y))+3) = data1; |
.................... *(((unsigned int8 *)(&y))+2) = data2; |
.................... |
.................... #endif |
.................... |
.................... do { |
.................... res=y; |
.................... y+=(x/y); |
.................... |
.................... #if !defined(__PCD__) |
.................... (*p)--; |
.................... #endif |
.................... |
.................... #if defined(__PCD__) |
.................... data1 = *(((unsigned int8 *)(&y))+3); |
.................... data2 = *(((unsigned int8 *)(&y))+2); |
.................... rotate_left(&data1,1); |
.................... if(bit_test(data2,7)) |
.................... bit_set(data1,0); |
.................... data1--; |
.................... bit_clear(data2,7); |
.................... if(bit_test(data1,0)) |
.................... bit_set(data2,7); |
.................... data1 = data1 >>1; |
.................... *(((unsigned int8 *)(&y))+3) = data1; |
.................... *(((unsigned int8 *)(&y))+2) = data2; |
.................... |
.................... #endif |
.................... } while(res != y); |
.................... |
.................... return(res); |
.................... } |
.................... //Overloaded functions for sqrt() for PCD |
.................... // Overloaded function sqrt() for data type - Float48 |
.................... #if defined(__PCD__) |
.................... float48 sqrt(float48 x) |
.................... { |
.................... float48 y, res; |
.................... unsigned int16 data1,data2; |
.................... BYTE *p; |
.................... |
.................... #ifdef _ERRNO |
.................... if(x < 0) |
.................... { |
.................... errno=EDOM; |
.................... } |
.................... #endif |
.................... |
.................... if( x<=0.0) |
.................... return(0.0); |
.................... |
.................... y=x; |
.................... |
.................... #if !defined(__PCD__) |
.................... p=&y; |
.................... (*p)=(BYTE)((((unsigned int16)(*p)) + 127) >> 1); |
.................... #endif |
.................... |
.................... #if defined(__PCD__) |
.................... p = (((unsigned int8 *)(&y))+5); |
.................... data1 = *(((unsigned int8 *)(&y))+5); |
.................... data2 = *(((unsigned int8 *)(&y))+4); |
.................... rotate_left(&data1,1); |
.................... if(bit_test(data2,7)) |
.................... bit_set(data1,0); |
.................... data1 = ((data1+127) >>1); |
.................... bit_clear(data2,7); |
.................... if(bit_test(data1,0)) |
.................... bit_set(data2,7); |
.................... data1 = data1 >>1; |
.................... *(((unsigned int8 *)(&y))+5) = data1; |
.................... *(((unsigned int8 *)(&y))+4) = data2; |
.................... |
.................... #endif |
.................... |
.................... do { |
.................... res=y; |
.................... y+=(x/y); |
.................... |
.................... #if !defined(__PCD__) |
.................... (*p)--; |
.................... #endif |
.................... |
.................... data1 = *(((unsigned int8 *)(&y))+5); |
.................... data2 = *(((unsigned int8 *)(&y))+4); |
.................... rotate_left(&data1,1); |
.................... if(bit_test(data2,7)) |
.................... bit_set(data1,0); |
.................... data1--; |
.................... bit_clear(data2,7); |
.................... if(bit_test(data1,0)) |
.................... bit_set(data2,7); |
.................... data1 = data1 >>1; |
.................... *(((unsigned int8 *)(&y))+5) = data1; |
.................... *(((unsigned int8 *)(&y))+4) = data2; |
.................... |
.................... } while(res != y); |
.................... |
.................... return(res); |
.................... } |
.................... |
.................... // Overloaded function sqrt() for data type - Float64 |
.................... float64 sqrt(float64 x) |
.................... { |
.................... float64 y, res; |
.................... unsigned int16 *p; |
.................... unsigned int16 temp1,temp2; |
.................... |
.................... #ifdef _ERRNO |
.................... if(x < 0) |
.................... { |
.................... errno=EDOM; |
.................... } |
.................... #endif |
.................... |
.................... if( x<=0.0) |
.................... return(0.0); |
.................... |
.................... y=x; |
.................... p= (((unsigned int16 *)(&y))+3); |
.................... temp1 = *p; |
.................... temp2 = *p; |
.................... bit_clear(temp1,15); |
.................... temp1 = (temp1>>4)+1023; |
.................... temp1 = temp1 >> 1; |
.................... temp1 = (temp1<<4) & 0xFFF0; |
.................... if(bit_test(temp2,15)) |
.................... bit_set(temp1,15); |
.................... temp2 = temp2 & 0x000F; |
.................... temp1 ^= temp2; |
.................... |
.................... (*p) = temp1; |
.................... |
.................... do { |
.................... res=y; |
.................... y+=(x/y); |
.................... temp1 = *p; |
.................... temp2 = *p; |
.................... bit_clear(temp1,15); |
.................... temp1 = (temp1>>4); |
.................... temp1--; |
.................... temp1 = (temp1<<4) & 0xFFF0; |
.................... if(bit_test(temp2,15)) |
.................... bit_set(temp1,15); |
.................... temp2 = temp2 & 0x000F; |
.................... temp1 ^= temp2; |
.................... (*p) = temp1; |
.................... |
.................... } while(res != y); |
.................... |
.................... return(res); |
.................... } |
.................... #endif |
.................... |
.................... ////////////////////////////// Trig Functions ////////////////////////////// |
.................... #ifdef PI_DIV_BY_TWO |
.................... #undef PI_DIV_BY_TWO |
.................... #endif |
.................... #define PI_DIV_BY_TWO 1.5707963267948966 |
.................... #ifdef TWOBYPI |
.................... #undef TWOBYPI |
.................... #define TWOBYPI 0.6366197723675813 |
.................... #endif |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // float cos(float x) |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // Description : returns the cosine value of the angle x, which is in radian |
.................... // Date : 9/20/2001 |
.................... // |
.................... float32 cos(float32 x) |
.................... { |
.................... float32 y, t, t2 = 1.0; |
.................... unsigned int8 quad, i; |
.................... float32 frac; |
.................... float32 p[6] = { //by the series definition for cosine |
.................... -0.5, // sum ( ( (-1)^n * x^2n )/(2n)! ) |
.................... 0.04166666666667, |
.................... -0.00138888888889, |
.................... 0.00002480158730, |
.................... -0.00000027557319, |
.................... 0.00000000208767, |
.................... //-0.00000000001147, |
.................... // 0.00000000000005 |
.................... }; |
.................... |
.................... if (x < 0) x = -x; // absolute value of input |
.................... |
.................... quad = (unsigned int8)(x / PI_DIV_BY_TWO); // quadrant |
.................... frac = (x / PI_DIV_BY_TWO) - quad; // fractional part of input |
.................... quad = quad % 4; // quadrant (0 to 3) |
.................... |
.................... if (quad == 0 || quad == 2) |
.................... t = frac * PI_DIV_BY_TWO; |
.................... else if (quad == 1) |
.................... t = (1-frac) * PI_DIV_BY_TWO; |
.................... else // should be 3 |
.................... t = (frac-1) * PI_DIV_BY_TWO; |
.................... |
.................... y = 1.0; |
.................... t = t * t; |
.................... for (i = 0; i <= 5; i++) |
.................... { |
.................... t2 = t2 * t; |
.................... y = y + p[i] * t2; |
.................... } |
.................... |
.................... if (quad == 2 || quad == 1) |
.................... y = -y; // correct sign |
.................... |
.................... return (y); |
.................... } |
.................... |
.................... |
.................... //Overloaded functions for cos() for PCD |
.................... // Overloaded function cos() for data type - Float48 |
.................... #if defined(__PCD__) |
.................... float48 cos(float48 x) |
.................... { |
.................... float48 y, t, t2 = 1.0; |
.................... unsigned int8 quad, i; |
.................... float48 frac; |
.................... float48 p[6] = { //by the series definition for cosine |
.................... -0.5, // sum ( ( (-1)^n * x^2n )/(2n)! ) |
.................... 0.04166666666667, |
.................... -0.00138888888889, |
.................... 0.00002480158730, |
.................... -0.00000027557319, |
.................... 0.00000000208767, |
.................... //-0.00000000001147, |
.................... // 0.00000000000005 |
.................... }; |
.................... |
.................... if (x < 0) x = -x; // absolute value of input |
.................... |
.................... quad = (unsigned int8)(x / PI_DIV_BY_TWO); // quadrant |
.................... frac = (x / PI_DIV_BY_TWO) - quad; // fractional part of input |
.................... quad = quad % 4; // quadrant (0 to 3) |
.................... |
.................... if (quad == 0 || quad == 2) |
.................... t = frac * PI_DIV_BY_TWO; |
.................... else if (quad == 1) |
.................... t = (1-frac) * PI_DIV_BY_TWO; |
.................... else // should be 3 |
.................... t = (frac-1) * PI_DIV_BY_TWO; |
.................... |
.................... y = 0.999999999781; |
.................... t = t * t; |
.................... for (i = 0; i <= 5; i++) |
.................... { |
.................... t2 = t2 * t; |
.................... y = y + p[i] * t2; |
.................... } |
.................... |
.................... if (quad == 2 || quad == 1) |
.................... y = -y; // correct sign |
.................... |
.................... return (y); |
.................... } |
.................... |
.................... // Overloaded function cos() for data type - Float48 |
.................... float64 cos(float64 x) |
.................... { |
.................... float64 y, t, t2 = 1.0; |
.................... unsigned int8 quad, i; |
.................... float64 frac; |
.................... float64 p[6] = { //by the series definition for cosine |
.................... -0.5, // sum ( ( (-1)^n * x^2n )/(2n)! ) |
.................... 0.04166666666667, |
.................... -0.00138888888889, |
.................... 0.00002480158730, |
.................... -0.00000027557319, |
.................... 0.00000000208767, |
.................... //-0.00000000001147, |
.................... // 0.00000000000005 |
.................... }; |
.................... |
.................... if (x < 0) x = -x; // absolute value of input |
.................... |
.................... quad = (unsigned int8)(x / PI_DIV_BY_TWO); // quadrant |
.................... frac = (x / PI_DIV_BY_TWO) - quad; // fractional part of input |
.................... quad = quad % 4; // quadrant (0 to 3) |
.................... |
.................... if (quad == 0 || quad == 2) |
.................... t = frac * PI_DIV_BY_TWO; |
.................... else if (quad == 1) |
.................... t = (1-frac) * PI_DIV_BY_TWO; |
.................... else // should be 3 |
.................... t = (frac-1) * PI_DIV_BY_TWO; |
.................... |
.................... y = 0.999999999781; |
.................... t = t * t; |
.................... for (i = 0; i <= 5; i++) |
.................... { |
.................... t2 = t2 * t; |
.................... y = y + p[i] * t2; |
.................... } |
.................... |
.................... if (quad == 2 || quad == 1) |
.................... y = -y; // correct sign |
.................... |
.................... return (y); |
.................... } |
.................... |
.................... #endif |
.................... |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // float sin(float x) |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // Description : returns the sine value of the angle x, which is in radian |
.................... // Date : 9/20/2001 |
.................... // |
.................... float32 sin(float32 x) |
.................... { |
.................... return cos(x - PI_DIV_BY_TWO); |
.................... } |
.................... |
.................... //Overloaded functions for sin() for PCD |
.................... // Overloaded function sin() for data type - Float48 |
.................... #if defined(__PCD__) |
.................... float48 sin(float48 x) |
.................... { |
.................... return cos(x - PI_DIV_BY_TWO); |
.................... } |
.................... |
.................... // Overloaded function sin() for data type - Float48 |
.................... float64 sin(float64 x) |
.................... { |
.................... return cos(x - PI_DIV_BY_TWO); |
.................... } |
.................... #endif |
.................... |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // float tan(float x) |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // Description : returns the tangent value of the angle x, which is in radian |
.................... // Date : 9/20/2001 |
.................... // |
.................... float32 tan(float32 x) |
.................... { |
.................... float32 c, s; |
.................... |
.................... c = cos(x); |
.................... if (c == 0.0) |
.................... return (1.0e+36); |
.................... |
.................... s = sin(x); |
.................... return(s/c); |
.................... } |
.................... //Overloaded functions for tan() for PCD |
.................... // Overloaded function tan() for data type - Float48 |
.................... #if defined(__PCD__) |
.................... float48 tan(float48 x) |
.................... { |
.................... float48 c, s; |
.................... |
.................... c = cos(x); |
.................... if (c == 0.0) |
.................... return (1.0e+36); |
.................... |
.................... s = sin(x); |
.................... return(s/c); |
.................... } |
.................... |
.................... // Overloaded function tan() for data type - Float48 |
.................... float64 tan(float64 x) |
.................... { |
.................... float64 c, s; |
.................... |
.................... c = cos(x); |
.................... if (c == 0.0) |
.................... return (1.0e+36); |
.................... |
.................... s = sin(x); |
.................... return(s/c); |
.................... } |
.................... #endif |
.................... |
.................... float32 const pas[3] = {0.49559947, -4.6145309, 5.6036290}; |
.................... float32 const qas[3] = {1.0000000, -5.5484666, 5.6036290}; |
.................... |
.................... float32 ASIN_COS(float32 x, unsigned int8 n) |
.................... { |
.................... float32 y, res, r, y2; |
.................... int1 s; |
.................... #ifdef _ERRNO |
.................... if(x <-1 || x > 1) |
.................... { |
.................... errno=EDOM; |
.................... } |
.................... #endif |
.................... s = 0; |
.................... y = x; |
.................... |
.................... if (x < 0) |
.................... { |
.................... s = 1; |
.................... y = -y; |
.................... } |
.................... |
.................... if (y > 0.5) |
.................... { |
.................... y = sqrt((1.0 - y)/2.0); |
.................... n += 2; |
.................... } |
.................... |
.................... y2=y*y; |
.................... |
.................... res = pas[0]*y2 + pas[1]; |
.................... res = res*y2 + pas[2]; |
.................... |
.................... r = qas[0]*y2 + qas[1]; |
.................... r = r*y2 + qas[2]; |
.................... |
.................... res = y*res/r; |
.................... |
.................... if (n & 2) // |x| > 0.5 |
.................... res = PI_DIV_BY_TWO - 2.0*res; |
.................... if (s) |
.................... res = -res; |
.................... if (n & 1) // take arccos |
.................... res = PI_DIV_BY_TWO - res; |
.................... |
.................... return(res); |
.................... } |
.................... |
.................... //Overloaded functions for ASIN_COS() for PCD |
.................... // Overloaded function ASIN_COS() for data type - Float48 |
.................... #if defined(__PCD__) |
.................... float48 ASIN_COS(float48 x, unsigned int8 n) |
.................... { |
.................... float48 y, res, r, y2; |
.................... int1 s; |
.................... #ifdef _ERRNO |
.................... if(x <-1 || x > 1) |
.................... { |
.................... errno=EDOM; |
.................... } |
.................... #endif |
.................... s = 0; |
.................... y = x; |
.................... |
.................... if (x < 0) |
.................... { |
.................... s = 1; |
.................... y = -y; |
.................... } |
.................... |
.................... if (y > 0.5) |
.................... { |
.................... y = sqrt((1.0 - y)/2.0); |
.................... n += 2; |
.................... } |
.................... |
.................... y2=y*y; |
.................... |
.................... res = pas[0]*y2 + pas[1]; |
.................... res = res*y2 + pas[2]; |
.................... |
.................... r = qas[0]*y2 + qas[1]; |
.................... r = r*y2 + qas[2]; |
.................... |
.................... res = y*res/r; |
.................... |
.................... if (n & 2) // |x| > 0.5 |
.................... res = PI_DIV_BY_TWO - 2.0*res; |
.................... if (s) |
.................... res = -res; |
.................... if (n & 1) // take arccos |
.................... res = PI_DIV_BY_TWO - res; |
.................... |
.................... return(res); |
.................... } |
.................... |
.................... // Overloaded function ASIN_COS() for data type - Float64 |
.................... float64 ASIN_COS(float64 x, unsigned int8 n) |
.................... { |
.................... float64 y, res, r, y2; |
.................... int1 s; |
.................... #ifdef _ERRNO |
.................... if(x <-1 || x > 1) |
.................... { |
.................... errno=EDOM; |
.................... } |
.................... #endif |
.................... s = 0; |
.................... y = x; |
.................... |
.................... if (x < 0) |
.................... { |
.................... s = 1; |
.................... y = -y; |
.................... } |
.................... |
.................... if (y > 0.5) |
.................... { |
.................... y = sqrt((1.0 - y)/2.0); |
.................... n += 2; |
.................... } |
.................... |
.................... y2=y*y; |
.................... |
.................... res = pas[0]*y2 + pas[1]; |
.................... res = res*y2 + pas[2]; |
.................... |
.................... r = qas[0]*y2 + qas[1]; |
.................... r = r*y2 + qas[2]; |
.................... |
.................... res = y*res/r; |
.................... |
.................... if (n & 2) // |x| > 0.5 |
.................... res = PI_DIV_BY_TWO - 2.0*res; |
.................... if (s) |
.................... res = -res; |
.................... if (n & 1) // take arccos |
.................... res = PI_DIV_BY_TWO - res; |
.................... |
.................... return(res); |
.................... } |
.................... #endif |
.................... |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // float asin(float x) |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // Description : returns the arcsine value of the value x. |
.................... // Date : N/A |
.................... // |
.................... float32 asin(float32 x) |
.................... { |
.................... float32 r; |
.................... |
.................... r = ASIN_COS(x, 0); |
.................... return(r); |
.................... } |
.................... //Overloaded functions for asin() for PCD |
.................... // Overloaded function asin() for data type - Float48 |
.................... #if defined(__PCD__) |
.................... float48 asin(float48 x) |
.................... { |
.................... float48 r; |
.................... |
.................... r = ASIN_COS(x, 0); |
.................... return(r); |
.................... } |
.................... |
.................... // Overloaded function asin() for data type - Float64 |
.................... float64 asin(float64 x) |
.................... { |
.................... float64 r; |
.................... |
.................... r = ASIN_COS(x, 0); |
.................... return(r); |
.................... } |
.................... #endif |
.................... |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // float acos(float x) |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // Description : returns the arccosine value of the value x. |
.................... // Date : N/A |
.................... // |
.................... float32 acos(float32 x) |
.................... { |
.................... float32 r; |
.................... |
.................... r = ASIN_COS(x, 1); |
.................... return(r); |
.................... } |
.................... //Overloaded functions for acos() for PCD |
.................... // Overloaded function acos() for data type - Float48 |
.................... #if defined(__PCD__) |
.................... float48 acos(float48 x) |
.................... { |
.................... float48 r; |
.................... |
.................... r = ASIN_COS(x, 1); |
.................... return(r); |
.................... } |
.................... |
.................... // Overloaded function acos() for data type - Float64 |
.................... float64 acos(float64 x) |
.................... { |
.................... float64 r; |
.................... |
.................... r = ASIN_COS(x, 1); |
.................... return(r); |
.................... } |
.................... #endif |
.................... |
.................... float32 const pat[4] = {0.17630401, 5.6710795, 22.376096, 19.818457}; |
.................... float32 const qat[4] = {1.0000000, 11.368190, 28.982246, 19.818457}; |
.................... |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // float atan(float x) |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // Description : returns the arctangent value of the value x. |
.................... // Date : N/A |
.................... // |
.................... float32 atan(float32 x) |
.................... { |
.................... float32 y, res, r; |
.................... int1 s, flag; |
.................... |
.................... s = 0; |
.................... flag = 0; |
.................... y = x; |
.................... |
.................... if (x < 0) |
.................... { |
.................... s = 1; |
.................... y = -y; |
.................... } |
.................... |
.................... if (y > 1.0) |
.................... { |
.................... y = 1.0/y; |
.................... flag = 1; |
.................... } |
.................... |
.................... res = pat[0]*y*y + pat[1]; |
.................... res = res*y*y + pat[2]; |
.................... res = res*y*y + pat[3]; |
.................... |
.................... r = qat[0]*y*y + qat[1]; |
.................... r = r*y*y + qat[2]; |
.................... r = r*y*y + qat[3]; |
.................... |
.................... res = y*res/r; |
.................... |
.................... |
.................... if (flag) // for |x| > 1 |
.................... res = PI_DIV_BY_TWO - res; |
.................... if (s) |
.................... res = -res; |
.................... |
.................... return(res); |
.................... } |
.................... //Overloaded functions for atan() for PCD |
.................... // Overloaded function atan() for data type - Float48 |
.................... #if defined(__PCD__) |
.................... float48 atan(float48 x) |
.................... { |
.................... float48 y, res, r; |
.................... int1 s, flag; |
.................... |
.................... s = 0; |
.................... flag = 0; |
.................... y = x; |
.................... |
.................... if (x < 0) |
.................... { |
.................... s = 1; |
.................... y = -y; |
.................... } |
.................... |
.................... if (y > 1.0) |
.................... { |
.................... y = 1.0/y; |
.................... flag = 1; |
.................... } |
.................... |
.................... res = pat[0]*y*y + pat[1]; |
.................... res = res*y*y + pat[2]; |
.................... res = res*y*y + pat[3]; |
.................... |
.................... r = qat[0]*y*y + qat[1]; |
.................... r = r*y*y + qat[2]; |
.................... r = r*y*y + qat[3]; |
.................... |
.................... res = y*res/r; |
.................... |
.................... |
.................... if (flag) // for |x| > 1 |
.................... res = PI_DIV_BY_TWO - res; |
.................... if (s) |
.................... res = -res; |
.................... |
.................... return(res); |
.................... } |
.................... |
.................... // Overloaded function atan() for data type - Float64 |
.................... float64 atan(float64 x) |
.................... { |
.................... float64 y, res, r; |
.................... int1 s, flag; |
.................... |
.................... s = 0; |
.................... flag = 0; |
.................... y = x; |
.................... |
.................... if (x < 0) |
.................... { |
.................... s = 1; |
.................... y = -y; |
.................... } |
.................... |
.................... if (y > 1.0) |
.................... { |
.................... y = 1.0/y; |
.................... flag = 1; |
.................... } |
.................... |
.................... res = pat[0]*y*y + pat[1]; |
.................... res = res*y*y + pat[2]; |
.................... res = res*y*y + pat[3]; |
.................... |
.................... r = qat[0]*y*y + qat[1]; |
.................... r = r*y*y + qat[2]; |
.................... r = r*y*y + qat[3]; |
.................... |
.................... res = y*res/r; |
.................... |
.................... |
.................... if (flag) // for |x| > 1 |
.................... res = PI_DIV_BY_TWO - res; |
.................... if (s) |
.................... res = -res; |
.................... |
.................... return(res); |
.................... } |
.................... #endif |
.................... |
.................... ///////////////////////////////////////////////////////////////////////////// |
.................... // float atan2(float y, float x) |
.................... ///////////////////////////////////////////////////////////////////////////// |
.................... // Description :computes the principal value of arc tangent of y/x, using the |
.................... // signs of both the arguments to determine the quadrant of the return value |
.................... // Returns : returns the arc tangent of y/x. |
.................... // Date : N/A |
.................... // |
.................... |
.................... float32 atan2(float32 y,float32 x) |
.................... { |
.................... float32 z; |
.................... int1 sign; |
.................... unsigned int8 quad; |
.................... sign=0; |
.................... quad=0; //quadrant |
.................... quad=((y<=0.0)?((x<=0.0)?3:4):((x<0.0)?2:1)); |
.................... if(y<0.0) |
.................... { |
.................... sign=1; |
.................... y=-y; |
.................... } |
.................... if(x<0.0) |
.................... { |
.................... x=-x; |
.................... } |
.................... if (x==0.0) |
.................... { |
.................... if(y==0.0) |
.................... { |
.................... #ifdef _ERRNO |
.................... { |
.................... errno=EDOM; |
.................... } |
.................... #endif |
.................... } |
.................... else |
.................... { |
.................... if(sign) |
.................... { |
.................... return (-(PI_DIV_BY_TWO)); |
.................... } |
.................... else |
.................... { |
.................... return (PI_DIV_BY_TWO); |
.................... } |
.................... } |
.................... } |
.................... else |
.................... { |
.................... z=y/x; |
.................... switch(quad) |
.................... { |
.................... case 1: |
.................... { |
.................... return atan(z); |
.................... break; |
.................... } |
.................... case 2: |
.................... { |
.................... // return (atan(z)+PI_DIV_BY_TWO); //2L3122 |
.................... return (PI-atan(z)); |
.................... break; |
.................... } |
.................... case 3: |
.................... { |
.................... return (atan(z)-PI); |
.................... break; |
.................... } |
.................... case 4: |
.................... { |
.................... return (-atan(z)); |
.................... break; |
.................... } |
.................... } |
.................... } |
.................... } |
.................... |
.................... //Overloaded functions for atan2() for PCD |
.................... // Overloaded function atan2() for data type - Float48 |
.................... #if defined(__PCD__) |
.................... float48 atan2(float48 y,float48 x) |
.................... { |
.................... float48 z; |
.................... int1 sign; |
.................... unsigned int8 quad; |
.................... sign=0; |
.................... quad=0; //quadrant |
.................... quad=((y<=0.0)?((x<=0.0)?3:4):((x<0.0)?2:1)); |
.................... if(y<0.0) |
.................... { |
.................... sign=1; |
.................... y=-y; |
.................... } |
.................... if(x<0.0) |
.................... { |
.................... x=-x; |
.................... } |
.................... if (x==0.0) |
.................... { |
.................... if(y==0.0) |
.................... { |
.................... #ifdef _ERRNO |
.................... { |
.................... errno=EDOM; |
.................... } |
.................... #endif |
.................... } |
.................... else |
.................... { |
.................... if(sign) |
.................... { |
.................... return (-(PI_DIV_BY_TWO)); |
.................... } |
.................... else |
.................... { |
.................... return (PI_DIV_BY_TWO); |
.................... } |
.................... } |
.................... } |
.................... else |
.................... { |
.................... z=y/x; |
.................... switch(quad) |
.................... { |
.................... case 1: |
.................... { |
.................... return atan(z); |
.................... break; |
.................... } |
.................... case 2: |
.................... { |
.................... // return (atan(z)+PI_DIV_BY_TWO); //2L3122 |
.................... return (PI-atan(z)); |
.................... break; |
.................... } |
.................... case 3: |
.................... { |
.................... return (atan(z)-PI); |
.................... break; |
.................... } |
.................... case 4: |
.................... { |
.................... return (-atan(z)); |
.................... break; |
.................... } |
.................... } |
.................... } |
.................... } |
.................... |
.................... // Overloaded function atan2() for data type - Float64 |
.................... float64 atan2(float64 y,float64 x) |
.................... { |
.................... float64 z; |
.................... int1 sign; |
.................... unsigned int8 quad; |
.................... sign=0; |
.................... quad=0; //quadrant |
.................... quad=((y<=0.0)?((x<=0.0)?3:4):((x<0.0)?2:1)); |
.................... if(y<0.0) |
.................... { |
.................... sign=1; |
.................... y=-y; |
.................... } |
.................... if(x<0.0) |
.................... { |
.................... x=-x; |
.................... } |
.................... if (x==0.0) |
.................... { |
.................... if(y==0.0) |
.................... { |
.................... #ifdef _ERRNO |
.................... { |
.................... errno=EDOM; |
.................... } |
.................... #endif |
.................... } |
.................... else |
.................... { |
.................... if(sign) |
.................... { |
.................... return (-(PI_DIV_BY_TWO)); |
.................... } |
.................... else |
.................... { |
.................... return (PI_DIV_BY_TWO); |
.................... } |
.................... } |
.................... } |
.................... else |
.................... { |
.................... z=y/x; |
.................... switch(quad) |
.................... { |
.................... case 1: |
.................... { |
.................... return atan(z); |
.................... break; |
.................... } |
.................... case 2: |
.................... { |
.................... // return (atan(z)+PI_DIV_BY_TWO); //2L3122 |
.................... return (PI-atan(z)); |
.................... break; |
.................... } |
.................... case 3: |
.................... { |
.................... return (atan(z)-PI); |
.................... break; |
.................... } |
.................... case 4: |
.................... { |
.................... return (-atan(z)); |
.................... break; |
.................... } |
.................... } |
.................... } |
.................... } |
.................... #endif |
.................... |
.................... //////////////////// Hyperbolic functions //////////////////// |
.................... |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // float cosh(float x) |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // Description : Computes the hyperbolic cosine value of x |
.................... // Returns : returns the hyperbolic cosine value of x |
.................... // Date : N/A |
.................... // |
.................... |
.................... float32 cosh(float32 x) |
.................... { |
.................... return ((exp(x)+exp(-x))/2); |
.................... } |
.................... //Overloaded functions for cosh() for PCD |
.................... // Overloaded function cosh() for data type - Float48 |
.................... #if defined(__PCD__) |
.................... float48 cosh(float48 x) |
.................... { |
.................... return ((exp(x)+exp(-x))/2); |
.................... } |
.................... |
.................... // Overloaded function cosh() for data type - Float64 |
.................... float64 cosh(float64 x) |
.................... { |
.................... return ((exp(x)+exp(-x))/2); |
.................... } |
.................... #endif |
.................... |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // float sinh(float x) |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // Description : Computes the hyperbolic sine value of x |
.................... // Returns : returns the hyperbolic sine value of x |
.................... // Date : N/A |
.................... // |
.................... |
.................... float32 sinh(float32 x) |
.................... { |
.................... |
.................... return ((exp(x) - exp(-x))/2); |
.................... } |
.................... //Overloaded functions for sinh() for PCD |
.................... // Overloaded function sinh() for data type - Float48 |
.................... #if defined(__PCD__) |
.................... float48 sinh(float48 x) |
.................... { |
.................... |
.................... return ((exp(x) - exp(-x))/2); |
.................... } |
.................... |
.................... // Overloaded function sinh() for data type - Float48 |
.................... float64 sinh(float64 x) |
.................... { |
.................... |
.................... return ((exp(x) - exp(-x))/2); |
.................... } |
.................... #endif |
.................... |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // float tanh(float x) |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // Description : Computes the hyperbolic tangent value of x |
.................... // Returns : returns the hyperbolic tangent value of x |
.................... // Date : N/A |
.................... // |
.................... |
.................... float32 tanh(float32 x) |
.................... { |
.................... return(sinh(x)/cosh(x)); |
.................... } |
.................... //Overloaded functions for tanh() for PCD |
.................... // Overloaded function tanh() for data type - Float48 |
.................... #if defined(__PCD__) |
.................... float48 tanh(float48 x) |
.................... { |
.................... return(sinh(x)/cosh(x)); |
.................... } |
.................... |
.................... // Overloaded function tanh() for data type - Float64 |
.................... float64 tanh(float64 x) |
.................... { |
.................... return(sinh(x)/cosh(x)); |
.................... } |
.................... #endif |
.................... |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // float frexp(float x, signed int *exp) |
.................... //////////////////////////////////////////////////////////////////////////// |
.................... // Description : breaks a floating point number into a normalized fraction and an integral |
.................... // power of 2. It stores the integer in the signed int object pointed to by exp. |
.................... // Returns : returns the value x, such that x is a double with magnitude in the interval |
.................... // [1/2,1) or zero, and value equals x times 2 raised to the power *exp.If value is zero, |
.................... // both parts of the result are zero. |
.................... // Date : N/A |
.................... // |
.................... |
.................... #define LOG2 .30102999566398119521 |
.................... float32 frexp(float32 x, signed int8 *exp) |
.................... { |
.................... float32 res; |
.................... int1 sign = 0; |
.................... if(x == 0.0) |
.................... { |
.................... *exp=0; |
.................... return (0.0); |
.................... } |
.................... if(x < 0.0) |
.................... { |
.................... x=-x; |
.................... sign=1; |
.................... } |
.................... if (x > 1.0) |
.................... { |
.................... *exp=(ceil(log10(x)/LOG2)); |
.................... res=x/(pow(2, *exp)); |
.................... if (res == 1) |
.................... { |
.................... *exp=*exp+1; |
.................... res=.5; |
.................... } |
.................... } |
.................... else |
.................... { |
.................... if(x < 0.5) |
.................... { |
.................... *exp=-1; |
.................... res=x*2; |
.................... } |
.................... else |
.................... { |
.................... *exp=0; |
.................... res=x; |
.................... } |
.................... } |
.................... if(sign) |
.................... { |
.................... res=-res; |
.................... } |
.................... return res; |
.................... } |
.................... |
.................... //Overloaded functions for frexp() for PCD |
.................... // Overloaded function frexp() for data type - Float48 |
.................... #if defined(__PCD__) |
.................... float48 frexp(float48 x, signed int8 *exp) |
.................... { |
.................... float48 res; |
.................... int1 sign = 0; |
.................... if(x == 0.0) |
.................... { |
.................... *exp=0; |
.................... return (0.0); |
.................... } |
.................... if(x < 0.0) |
.................... { |
.................... x=-x; |
.................... sign=1; |
.................... } |
.................... if (x > 1.0) |
.................... { |
.................... *exp=(ceil(log10(x)/LOG2)); |
.................... res=x/(pow(2, *exp)); |
.................... if (res == 1) |
.................... { |
.................... *exp=*exp+1; |
.................... res=.5; |
.................... } |
.................... } |
.................... else |
.................... { |
.................... if(x < 0.5) |
.................... { |
.................... *exp=-1; |
.................... res=x*2; |
.................... } |
.................... else |
.................... { |
.................... *exp=0; |
.................... res=x; |
.................... } |
.................... } |
.................... if(sign) |
.................... { |
.................... res=-res; |
.................... } |
.................... return res; |
.................... } |
.................... |
.................... // Overloaded function frexp() for data type - Float64 |
.................... float64 frexp(float64 x, signed int8 *exp) |
.................... { |
.................... float64 res; |
.................... int1 sign = 0; |
.................... if(x == 0.0) |
.................... { |
.................... *exp=0; |
.................... return (0.0); |
.................... } |
.................... if(x < 0.0) |
.................... { |
.................... x=-x; |
.................... sign=1; |
.................... } |
.................... if (x > 1.0) |
.................... { |
.................... *exp=(ceil(log10(x)/LOG2)); |
.................... res=x/(pow(2, *exp)); |
.................... if (res == 1) |
.................... { |
.................... *exp=*exp+1; |
.................... res=.5; |
.................... } |
.................... } |
.................... else |
.................... { |
.................... if(x < 0.5) |
.................... { |
.................... *exp=-1; |
.................... res=x*2; |
.................... } |
.................... else |
.................... { |
.................... *exp=0; |
.................... res=x; |
.................... } |
.................... } |
.................... if(sign) |
.................... { |
.................... res=-res; |
.................... } |
.................... return res; |
.................... } |
.................... #endif |
.................... |
.................... ////////////////////////////////////////////////////////////////////////////// |
.................... // float ldexp(float x, signed int *exp) |
.................... ////////////////////////////////////////////////////////////////////////////// |
.................... // Description : multiplies a floating point number by an integral power of 2. |
.................... // Returns : returns the value of x times 2 raised to the power exp. |
.................... // Date : N/A |
.................... // |
.................... |
.................... float32 ldexp(float32 value, signed int8 exp) |
.................... { |
.................... return (value * pow(2,exp)); |
.................... } |
.................... //Overloaded functions for ldexp() for PCD |
.................... // Overloaded function ldexp() for data type - Float48 |
.................... |
.................... #if defined(__PCD__) |
.................... float48 ldexp(float48 value, signed int8 exp) |
.................... { |
.................... return (value * pow(2,exp)); |
.................... } |
.................... // Overloaded function ldexp() for data type - Float64 |
.................... float64 ldexp(float64 value, signed int8 exp) |
.................... { |
.................... return (value * pow(2,exp)); |
.................... } |
.................... #endif |
.................... |
.................... #endif |
.................... |
.................... |
.................... void main() |
.................... { |
* |
023C: CLRF 04 |
023D: BCF 03.7 |
023E: MOVLW 1F |
023F: ANDWF 03,F |
0240: MOVLW 71 |
0241: BSF 03.5 |
0242: MOVWF 0F |
0243: MOVF 0F,W |
0244: BSF 03.6 |
0245: BCF 07.3 |
0246: MOVLW 0C |
0247: BCF 03.6 |
0248: MOVWF 19 |
0249: MOVLW A2 |
024A: MOVWF 18 |
024B: MOVLW 90 |
024C: BCF 03.5 |
024D: MOVWF 18 |
024E: BSF 03.5 |
024F: BSF 03.6 |
0250: MOVF 09,W |
0251: ANDLW C0 |
0252: MOVWF 09 |
0253: BCF 03.6 |
0254: BCF 1F.4 |
0255: BCF 1F.5 |
0256: MOVLW 00 |
0257: BSF 03.6 |
0258: MOVWF 08 |
0259: BCF 03.5 |
025A: CLRF 07 |
025B: CLRF 08 |
025C: CLRF 09 |
.................... setup_adc_ports(NO_ANALOGS|VSS_VDD); |
* |
0266: BSF 03.5 |
0267: BSF 03.6 |
0268: MOVF 09,W |
0269: ANDLW C0 |
026A: MOVWF 09 |
026B: BCF 03.6 |
026C: BCF 1F.4 |
026D: BCF 1F.5 |
026E: MOVLW 00 |
026F: BSF 03.6 |
0270: MOVWF 08 |
.................... setup_adc(ADC_CLOCK_DIV_2); |
0271: BCF 03.5 |
0272: BCF 03.6 |
0273: BCF 1F.6 |
0274: BCF 1F.7 |
0275: BSF 03.5 |
0276: BCF 1F.7 |
0277: BCF 03.5 |
0278: BSF 1F.0 |
.................... setup_spi(SPI_SS_DISABLED); |
0279: BCF 14.5 |
027A: BCF 20.5 |
027B: MOVF 20,W |
027C: BSF 03.5 |
027D: MOVWF 07 |
027E: BCF 03.5 |
027F: BSF 20.4 |
0280: MOVF 20,W |
0281: BSF 03.5 |
0282: MOVWF 07 |
0283: BCF 03.5 |
0284: BCF 20.3 |
0285: MOVF 20,W |
0286: BSF 03.5 |
0287: MOVWF 07 |
0288: MOVLW 01 |
0289: BCF 03.5 |
028A: MOVWF 14 |
028B: MOVLW 00 |
028C: BSF 03.5 |
028D: MOVWF 14 |
.................... setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); |
028E: MOVF 01,W |
028F: ANDLW C7 |
0290: IORLW 08 |
0291: MOVWF 01 |
.................... setup_timer_1(T1_DISABLED); |
0292: BCF 03.5 |
0293: CLRF 10 |
.................... setup_timer_2(T2_DISABLED,0,1); |
0294: MOVLW 00 |
0295: MOVWF 78 |
0296: MOVWF 12 |
0297: MOVLW 00 |
0298: BSF 03.5 |
0299: MOVWF 12 |
.................... setup_ccp1(CCP_OFF); |
029A: BCF 03.5 |
029B: BSF 20.2 |
029C: MOVF 20,W |
029D: BSF 03.5 |
029E: MOVWF 07 |
029F: BCF 03.5 |
02A0: CLRF 17 |
02A1: BSF 03.5 |
02A2: CLRF 1B |
02A3: CLRF 1C |
02A4: MOVLW 01 |
02A5: MOVWF 1D |
.................... setup_comparator(NC_NC_NC_NC); |
02A6: BCF 03.5 |
02A7: BSF 03.6 |
02A8: CLRF 07 |
02A9: CLRF 08 |
02AA: CLRF 09 |
.................... |
.................... printf("Magnetometr: \r\n",); |
02AB: MOVLW 04 |
02AC: MOVWF 0D |
02AD: MOVLW 00 |
02AE: MOVWF 0F |
02AF: BCF 03.6 |
02B0: CALL 021 |
.................... printf("(c)mlab.cz kaklik 2013: \r\n",); |
02B1: MOVLW 0D |
02B2: BSF 03.6 |
02B3: MOVWF 0D |
02B4: MOVLW 00 |
02B5: MOVWF 0F |
02B6: BCF 03.6 |
02B7: CALL 021 |
.................... printf("X, Y, Z \r\n",); |
02B8: MOVLW 1B |
02B9: BSF 03.6 |
02BA: MOVWF 0D |
02BB: MOVLW 00 |
02BC: MOVWF 0F |
02BD: BCF 03.6 |
02BE: CALL 021 |
.................... |
.................... |
.................... // Init the HMC5883L. Set Mode register for |
.................... // continuous measurements. |
.................... hmc5883l_write_reg(HMC5883L_CFG_A_REG, 0x18); // no average, maximal update range |
02BF: CLRF 27 |
02C0: MOVLW 18 |
02C1: MOVWF 28 |
02C2: CALL 0B3 |
.................... hmc5883l_write_reg(HMC5883L_CFG_B_REG, 0x00); // minimal range |
02C3: MOVLW 01 |
02C4: MOVWF 27 |
02C5: CLRF 28 |
02C6: CALL 0B3 |
.................... hmc5883l_write_reg(HMC5883L_MODE_REG, 0x00); |
02C7: MOVLW 02 |
02C8: MOVWF 27 |
02C9: CLRF 28 |
02CA: CALL 0B3 |
.................... |
.................... // Continuously read and display the x,y,z results. |
.................... // Wait at least 67 ms between reads, re the HMC5883L data sheet. |
.................... |
.................... |
.................... while(TRUE) |
.................... { |
.................... |
.................... hmc5883l_read_data(); |
02CB: GOTO 131 |
.................... printf("%6Ld %6Ld %6Ld \n\r", compass.x, compass.y, compass.z); |
02CC: MOVLW 00 |
02CD: MOVWF 04 |
02CE: MOVF 22,W |
02CF: MOVWF 28 |
02D0: MOVF 21,W |
02D1: MOVWF 27 |
02D2: CALL 1B0 |
02D3: MOVLW 20 |
02D4: BTFSS 0C.4 |
02D5: GOTO 2D4 |
02D6: MOVWF 19 |
02D7: MOVLW 00 |
02D8: MOVWF 04 |
02D9: MOVF 24,W |
02DA: MOVWF 28 |
02DB: MOVF 23,W |
02DC: MOVWF 27 |
02DD: CALL 1B0 |
02DE: MOVLW 20 |
02DF: BTFSS 0C.4 |
02E0: GOTO 2DF |
02E1: MOVWF 19 |
02E2: MOVLW 00 |
02E3: MOVWF 04 |
02E4: MOVF 26,W |
02E5: MOVWF 28 |
02E6: MOVF 25,W |
02E7: MOVWF 27 |
02E8: CALL 1B0 |
02E9: MOVLW 20 |
02EA: BTFSS 0C.4 |
02EB: GOTO 2EA |
02EC: MOVWF 19 |
02ED: MOVLW 0A |
02EE: BTFSS 0C.4 |
02EF: GOTO 2EE |
02F0: MOVWF 19 |
02F1: MOVLW 0D |
02F2: BTFSS 0C.4 |
02F3: GOTO 2F2 |
02F4: MOVWF 19 |
.................... delay_ms(100); |
02F5: MOVLW 64 |
02F6: MOVWF 27 |
02F7: GOTO 226 |
.................... } |
02F8: GOTO 2CB |
.................... |
.................... } |
.................... |
.................... |
.................... |
02F9: SLEEP |
Configuration Fuses: |
Word 1: 2CF5 INTRC NOWDT NOPUT MCLR NOPROTECT NOCPD NOBROWNOUT IESO FCMEN NOLVP NODEBUG |
Word 2: 3FFF NOWRT BORV40 |
/Modules/Sensors/MAG01A/SW/PIC16F887/main.pjt |
---|
0,0 → 1,31 |
[PROJECT] |
Target=main.hex |
Development_Mode= |
Processor_Text=PIC16F887 |
ToolSuite=CCS |
Processor=0x887F |
[main] |
Type=4 |
Path= |
FileList= |
BuildTool= |
OptionString= |
AdditionalOptionString= |
[mru-list] |
1=main.c |
[Windows] |
0=0000 %S 0 0 796 451 3 0 |
[Opened Files] |
1=main.c |
2=main.h |
3=C:\Program Files (x86)\PICC\devices\16F887.h |
4=HMC5883L.h |
5=HMC5883L.c |
6=C:\Program Files (x86)\PICC\drivers\math.h |
7= |
[Target Data] |
OptionString=-p +FM |
FileList=Z:\home\kaklik\svnMLAB\Modules\Sensors\MAG01A\SW\PIC16F887\main.c |
[Units] |
Count=1 |
1=main (main) |
/Modules/Sensors/MAG01A/SW/PIC16F887/main.sta |
---|
0,0 → 1,59 |
ROM used: 762 (9%) |
762 (9%) including unused fragments |
0 Average locations per line |
2 Average locations per statement |
RAM used: 12 (3%) at main() level |
21 (6%) worst case |
Stack used: 2 worst case (out of 8 total available) |
Lines Stmts % Files |
----- ----- --- ----- |
43 19 6 main.c |
22 0 0 main.h |
423 0 0 C:\Program Files (x86)\PICC\devices\16F887.h |
25 0 0 HMC5883L.h |
76 28 9 HMC5883L.c |
2172 260 85 C:\Program Files (x86)\PICC\drivers\math.h |
----- ----- |
2761 307 Total |
Page ROM % RAM Vol Diff Functions: |
---- --- --- --- --- ---- ---------- |
0 22 3 1 @delay_ms1 |
0 69 9 3 @I2C_READ_1 |
0 74 10 1 @I2C_WRITE_1 |
0 57 7 2 102 1.8 hmc5883l_write_reg |
0 127 17 6 636 3.3 hmc5883l_read_data |
0 190 25 0 595 3.3 MAIN |
0 9 1 0 78 2.7 @const229 |
0 72 9 3 722 3.9 @PSTRINGC7_9600_62_63 |
0 14 2 0 @const231 |
0 6 1 0 @const232 |
0 118 15 9 @PRINTF_LD_9600_62_63 |
Program metrics: |
Functions 5 |
Statements 307 |
Comments 356 |
Volume (V) 2913 |
Difficilty (D) 14.9 |
Effort to implement (E) 43483 |
Time to implement (T) 40 minutes |
Est Delivered Bugs (B) 0 |
Cyclomatic Complexity 1 |
Maintainability (MI) 95 |
Segment Used Free |
----------- ---- ---- |
00000-00003 4 0 |
00004-007FF 758 1286 |
00800-00FFF 0 2048 |
01000-017FF 0 2048 |
01800-01FFF 0 2048 |
/Modules/Sensors/MAG01A/SW/PIC16F887/main.sym |
---|
0,0 → 1,95 |
004-005 @READ_PROGRAM_MEMORY8.P1 |
004 @WRITE_PROGRAM_MEMORY8.P2 |
015 CCP_1 |
015 CCP_1_LOW |
016 CCP_1_HIGH |
01B CCP_2_LOW |
01B CCP_2 |
01C CCP_2_HIGH |
020 @TRIS_C |
021-026 compass |
027 hmc5883l_write_reg.reg |
027 @delay_ms1.P1 |
027 hmc5883l_read_data.x_lsb |
027-028 @PRINTF_LD_9600_62_63.P1 |
027 @PSTRINGC7_9600_62_63.@SCRATCH1 |
028 hmc5883l_write_reg.data |
028 hmc5883l_read_data.x_msb |
028 @PSTRINGC7_9600_62_63.@SCRATCH2 |
029 hmc5883l_read_data.y_lsb |
029 @PSTRINGC7_9600_62_63.@SCRATCH3 |
029 @PRINTF_LD_9600_62_63.@SCRATCH1 |
02A hmc5883l_read_data.y_msb |
02A @PRINTF_LD_9600_62_63.@SCRATCH2 |
02B hmc5883l_read_data.z_lsb |
02B @PRINTF_LD_9600_62_63.@SCRATCH3 |
02C hmc5883l_read_data.z_msb |
02C @PRINTF_LD_9600_62_63.@SCRATCH4 |
02D @I2C_READ_1.P1 |
02D @I2C_WRITE_1.P2 |
02D @PRINTF_LD_9600_62_63.@SCRATCH5 |
02E @I2C_READ_1.@SCRATCH1 |
02E @PRINTF_LD_9600_62_63.@SCRATCH6 |
02F @I2C_READ_1.@SCRATCH2 |
02F @PRINTF_LD_9600_62_63.@SCRATCH7 |
077 @SCRATCH |
078 @SCRATCH |
078 _RETURN_ |
079 @SCRATCH |
07A @SCRATCH |
107.6 C1OUT |
108.6 C2OUT |
10D-10E @WRITE_PROGRAM_MEMORY8.P1 |
10D-10E @READ_PROGRAM_MEMORY8.P2 |
ROM Allocation: |
0226 @delay_ms1 |
00EC @I2C_READ_1 |
0069 @I2C_WRITE_1 |
00B3 hmc5883l_write_reg |
0131 hmc5883l_read_data |
023C MAIN |
0004 @const229 |
0021 @PSTRINGC7_9600_62_63 |
000D @const231 |
001B @const232 |
01B0 @PRINTF_LD_9600_62_63 |
023C @cinit |
User Memory space: |
User Memory space: |
Project Directory: |
Z:\home\kaklik\svnMLAB\Modules\Sensors\MAG01A\SW\PIC16F887\ |
Project Files: |
main.c |
main.h |
C:\Program Files (x86)\PICC\devices\16F887.h |
HMC5883L.h |
HMC5883L.c |
C:\Program Files (x86)\PICC\drivers\math.h |
Units: |
Z:\home\kaklik\svnMLAB\Modules\Sensors\MAG01A\SW\PIC16F887\main (main) |
Compiler Settings: |
Processor: PIC16F887 |
Pointer Size: 16 |
ADC Range: 0-255 |
Opt Level: 9 |
Short,Int,Long: UNSIGNED: 1,8,16 |
Float,Double: 32,32 |
Output Files: |
Errors: main.err |
Ext Symbols: main.esym |
INHX8: main.hex |
Symbols: main.sym |
List: main.lst |
Debug/COFF: main.cof |
Project: main.PJT |
Call Tree: main.tre |
Statistics: main.sta |
/Modules/Sensors/MAG01A/SW/PIC16F887/main.tre |
---|
0,0 → 1,32 |
ÀÄmain |
ÀÄMAIN 0/190 Ram=0 |
ÃÄ??0?? |
ÃÄ@PSTRINGC7_9600_62_63 0/72 Ram=3 |
ÃÄ@PSTRINGC7_9600_62_63 0/72 Ram=3 |
ÃÄ@PSTRINGC7_9600_62_63 0/72 Ram=3 |
ÃÄhmc5883l_write_reg 0/57 Ram=2 |
³ ÃÄ@I2C_WRITE_1 0/74 Ram=1 |
³ ÃÄ@I2C_WRITE_1 0/74 Ram=1 |
³ ÀÄ@I2C_WRITE_1 0/74 Ram=1 |
ÃÄhmc5883l_write_reg 0/57 Ram=2 |
³ ÃÄ@I2C_WRITE_1 0/74 Ram=1 |
³ ÃÄ@I2C_WRITE_1 0/74 Ram=1 |
³ ÀÄ@I2C_WRITE_1 0/74 Ram=1 |
ÃÄhmc5883l_write_reg 0/57 Ram=2 |
³ ÃÄ@I2C_WRITE_1 0/74 Ram=1 |
³ ÃÄ@I2C_WRITE_1 0/74 Ram=1 |
³ ÀÄ@I2C_WRITE_1 0/74 Ram=1 |
ÃÄhmc5883l_read_data 0/127 Ram=6 |
³ ÃÄ@I2C_WRITE_1 0/74 Ram=1 |
³ ÃÄ@I2C_WRITE_1 0/74 Ram=1 |
³ ÃÄ@I2C_WRITE_1 0/74 Ram=1 |
³ ÃÄ@I2C_READ_1 0/69 Ram=3 |
³ ÃÄ@I2C_READ_1 0/69 Ram=3 |
³ ÃÄ@I2C_READ_1 0/69 Ram=3 |
³ ÃÄ@I2C_READ_1 0/69 Ram=3 |
³ ÃÄ@I2C_READ_1 0/69 Ram=3 |
³ ÀÄ@I2C_READ_1 0/69 Ram=3 |
ÃÄ@PRINTF_LD_9600_62_63 0/118 Ram=9 |
ÃÄ@PRINTF_LD_9600_62_63 0/118 Ram=9 |
ÃÄ@PRINTF_LD_9600_62_63 0/118 Ram=9 |
ÀÄ@delay_ms1 0/22 Ram=1 |
/Modules/Sensors/MAG01A/SW/PIC16F887/HMC5883L.c |
---|
0,0 → 1,75 |
//------------------------------ |
// Low level routines |
//------------------------------ |
void hmc5883l_write_reg(int8 reg, int8 data) |
{ |
i2c_start(); |
i2c_write(HMC5883L_WRT_ADDR); |
i2c_write(reg); |
i2c_write(data); |
i2c_stop(); |
} |
//------------------------------ |
int8 hmc5883l_read_reg(int8 reg) |
{ |
int8 retval; |
i2c_start(); |
i2c_write(HMC5883L_WRT_ADDR); |
i2c_write(reg); |
i2c_start(); |
i2c_write(HMC5883L_READ_ADDR); |
retval = i2c_read(0); |
i2c_stop(); |
return(retval); |
} |
//------------------------------ |
typedef struct |
{ |
signed int16 x; |
signed int16 y; |
signed int16 z; |
}hmc5883l_result; |
// This global structure holds the values read |
// from the HMC5883L x,y,z registers. |
hmc5883l_result compass = {0,0,0}; |
//------------------------------ |
void hmc5883l_read_data(void) |
{ |
unsigned int8 x_lsb; |
unsigned int8 x_msb; |
unsigned int8 y_lsb; |
unsigned int8 y_msb; |
unsigned int8 z_lsb; |
unsigned int8 z_msb; |
i2c_start(); |
i2c_write(HMC5883L_WRT_ADDR); |
i2c_write(HMC5883L_X_MSB_REG); // Point to X-msb register |
i2c_start(); |
i2c_write(HMC5883L_READ_ADDR); |
x_msb = i2c_read(); |
x_lsb = i2c_read(); |
z_msb = i2c_read(); |
z_lsb = i2c_read(); |
y_msb = i2c_read(); |
y_lsb = i2c_read(0); // do a NACK on last read |
i2c_stop(); |
// Combine high and low bytes into 16-bit values. |
compass.x = make16(x_msb, x_lsb); |
compass.y = make16(y_msb, y_lsb); |
compass.z = make16(z_msb, z_lsb); |
} |
/Modules/Sensors/MAG01A/SW/PIC16F887/HMC5883L.h |
---|
0,0 → 1,23 |
// i2c slave addresses |
#define HMC5883L_WRT_ADDR 0x3C |
#define HMC5883L_READ_ADDR 0x3D |
// Register addresses |
#define HMC5883L_CFG_A_REG 0x00 |
#define HMC5883L_CFG_B_REG 0x01 |
#define HMC5883L_MODE_REG 0x02 |
#define HMC5883L_X_MSB_REG 0x03 |
//Konstanty nastavujici rozsah |
//pro void set_mag_roz (unsigned int8 h) |
#define MAG_ROZ088 0x00 |
#define MAG_ROZ130 0x20 |
#define MAG_ROZ190 0x40 |
#define MAG_ROZ250 0x60 |
#define MAG_ROZ400 0x80 |
#define MAG_ROZ470 0xA0 |
#define MAG_ROZ560 0xC0 |
#define MAG_ROZ810 0xE0 |
#include "HMC5883L.c" |
/Modules/Sensors/MAG01A/SW/PIC16F887/main.bak |
---|
0,0 → 1,32 |
#include "main.h" |
#include "HMC5883L.h" |
void main() |
{ |
setup_adc_ports(NO_ANALOGS|VSS_VDD); |
setup_adc(ADC_CLOCK_DIV_2); |
setup_spi(SPI_SS_DISABLED); |
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); |
setup_timer_1(T1_DISABLED); |
setup_timer_2(T2_DISABLED,0,1); |
setup_ccp1(CCP_OFF); |
setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard |
printf("Magnetometr: \r\n",); |
printf("(c)mlab JACHO 2013: \r\n",); |
printf("Vysledky z jednotlivych os:\r\n",); |
signed int16 X,Y,Z; |
while(true) |
{ |
printf("Vysledky z jednotlivych os:\r\n",); |
X = mag_readX(); |
Y = mag_readY(); |
Z = mag_readZ(); |
printf("X: %Ld \r\n", X); |
printf("Y %Ld \r\n", Y); |
printf("Z: %Ld \r\n", Z); |
Delay_ms(500); |
} |
} |