├── .gitignore ├── images ├── partion2.png ├── activate_ssh.png ├── partition_01.png ├── partitions_01.png ├── pi_imager_01.png ├── pi_imager_02.png ├── pi_imager_03.png ├── pi_imager_04.png ├── pi_imager_05.png ├── pi_imager_06.png ├── pi_imager_07.png ├── Screenshot from 2021-05-16 12-51-28.png ├── Screenshot from 2021-05-16 13-04-00.png └── Screenshot from 2021-05-16 13-32-03.png ├── jupyter ├── examples │ ├── data │ │ └── 2021-08-14--01-03-41_10V_log.xlsx │ ├── pyvisa │ │ └── pyvisa.ipynb │ ├── instrumentControl │ │ ├── HP3458A.ipynb │ │ ├── HP34401A.ipynb │ │ ├── raw.ipynb │ │ ├── Fluke_5730A.ipynb │ │ ├── K34470A.ipynb │ │ ├── Fluke_8588A.ipynb │ │ └── log_voltage.ipynb │ ├── tutorial │ │ ├── 01_testgear lib │ │ │ └── 01_basiscs.ipynb │ │ └── 00_Jupyter Lab │ │ │ └── basics.ipynb │ └── analysis │ │ ├── plot_log.ipynb │ │ └── INL_example.ipynb ├── jupyter.service └── maintenance │ ├── shutdown.ipynb │ ├── rebuild_gpib.ipynb │ ├── backup.ipynb │ └── update.ipynb ├── scripts ├── cron_nightly.sh └── cron_hourly.sh ├── rebuild_gpib.sh ├── example_HP3458A.py ├── samba └── smb.conf ├── install_image.md ├── LICENSE ├── README.md ├── gpib └── gpib.conf └── install.sh /.gitignore: -------------------------------------------------------------------------------- 1 | .ipynb_checkpoints 2 | -------------------------------------------------------------------------------- /images/partion2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PhilippCo/meas_rpi/HEAD/images/partion2.png -------------------------------------------------------------------------------- /images/activate_ssh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PhilippCo/meas_rpi/HEAD/images/activate_ssh.png -------------------------------------------------------------------------------- /images/partition_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PhilippCo/meas_rpi/HEAD/images/partition_01.png -------------------------------------------------------------------------------- /images/partitions_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PhilippCo/meas_rpi/HEAD/images/partitions_01.png -------------------------------------------------------------------------------- /images/pi_imager_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PhilippCo/meas_rpi/HEAD/images/pi_imager_01.png -------------------------------------------------------------------------------- /images/pi_imager_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PhilippCo/meas_rpi/HEAD/images/pi_imager_02.png -------------------------------------------------------------------------------- /images/pi_imager_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PhilippCo/meas_rpi/HEAD/images/pi_imager_03.png -------------------------------------------------------------------------------- /images/pi_imager_04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PhilippCo/meas_rpi/HEAD/images/pi_imager_04.png -------------------------------------------------------------------------------- /images/pi_imager_05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PhilippCo/meas_rpi/HEAD/images/pi_imager_05.png -------------------------------------------------------------------------------- /images/pi_imager_06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PhilippCo/meas_rpi/HEAD/images/pi_imager_06.png -------------------------------------------------------------------------------- /images/pi_imager_07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PhilippCo/meas_rpi/HEAD/images/pi_imager_07.png -------------------------------------------------------------------------------- /images/Screenshot from 2021-05-16 12-51-28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PhilippCo/meas_rpi/HEAD/images/Screenshot from 2021-05-16 12-51-28.png -------------------------------------------------------------------------------- /images/Screenshot from 2021-05-16 13-04-00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PhilippCo/meas_rpi/HEAD/images/Screenshot from 2021-05-16 13-04-00.png -------------------------------------------------------------------------------- /images/Screenshot from 2021-05-16 13-32-03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PhilippCo/meas_rpi/HEAD/images/Screenshot from 2021-05-16 13-32-03.png -------------------------------------------------------------------------------- /jupyter/examples/data/2021-08-14--01-03-41_10V_log.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PhilippCo/meas_rpi/HEAD/jupyter/examples/data/2021-08-14--01-03-41_10V_log.xlsx -------------------------------------------------------------------------------- /scripts/cron_nightly.sh: -------------------------------------------------------------------------------- 1 | cd /home/pi/notebooks/cron/nightly 2 | 3 | for f in *.ipynb; do 4 | /home/pi/.local/bin/jupyter nbconvert --to html --execute "$f" 5 | done 6 | -------------------------------------------------------------------------------- /scripts/cron_hourly.sh: -------------------------------------------------------------------------------- 1 | cd /home/pi/notebooks/cron/hourly 2 | 3 | for f in *.ipynb; do 4 | /home/pi/.local/bin/jupyter nbconvert --to html --execute "$f" 5 | done 6 | 7 | -------------------------------------------------------------------------------- /rebuild_gpib.sh: -------------------------------------------------------------------------------- 1 | #install Kernel Module 2 | cd /usr/local/src/linux-gpib-code/linux-gpib-kernel/ 3 | sudo make clean 4 | sudo make 5 | sudo make install 6 | 7 | #install User Module 8 | cd /usr/local/src/linux-gpib-code/linux-gpib-user/ 9 | sudo make clean 10 | sudo ./bootstrap 11 | sudo ./configure 12 | sudo make 13 | sudo make install 14 | 15 | echo ---------------------- 16 | echo - DONE please reboot - 17 | echo ---------------------- -------------------------------------------------------------------------------- /jupyter/jupyter.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Jupyter Lab 3 | [Service] 4 | Type=simple 5 | PIDFile=/run/jupyter.pid 6 | ExecStart=/bin/bash -c "~/venv/bin/jupyter lab --ip="0.0.0.0" --no-browser --notebook-dir=/home/pi/notebooks --NotebookApp.password='argon2:$argon2id$v=19$m=10240,t=10,p=8$QEKtYZwdlvPF/FJkJx6xyg$+X7sj7NnWq/wlu+7VZDB7Q'" 7 | User=pi 8 | Group=pi 9 | WorkingDirectory=/home/pi/notebooks 10 | Restart=always 11 | RestartSec=10 12 | [Install] 13 | WantedBy=multi-user.target 14 | -------------------------------------------------------------------------------- /example_HP3458A.py: -------------------------------------------------------------------------------- 1 | # Just a plain python example. 2 | 3 | # The idea of this package is to use Jupyter Lab instead of plain python files 4 | 5 | # Start your Browser and go to http://:8888 6 | # or if you are using a GUI on your Pi http://localhost:8888 7 | 8 | # the password is 1281 9 | 10 | 11 | import pyvisa 12 | rm = pyvisa.ResourceManager('@py') 13 | 14 | inst = rm.open_resource("GPIB0::22::INSTR") 15 | 16 | inst.write("END ALWAYS") 17 | 18 | print(inst.query("ID?")) 19 | 20 | #get reading 21 | print(inst.read()) 22 | -------------------------------------------------------------------------------- /samba/smb.conf: -------------------------------------------------------------------------------- 1 | [global] 2 | workgroup = VOLTNUTS 3 | log file = /var/log/samba/log.%m 4 | max log size = 1000 5 | logging = file 6 | panic action = /usr/share/samba/panic-action %d 7 | 8 | server role = standalone server 9 | 10 | obey pam restrictions = yes 11 | 12 | unix password sync = yes 13 | 14 | passwd program = /usr/bin/passwd %u 15 | passwd chat = *Enter\snew\s*\spassword:* %n\n *Retype\snew\s*\spassword:* %n\n *password\supdated\ssuccessfully* . 16 | pam password change = yes 17 | map to guest = bad user 18 | 19 | [homes] 20 | comment = Home Directories 21 | browseable = yes 22 | read only = no 23 | create mask = 0700 24 | directory mask = 0700 25 | valid users = %S 26 | -------------------------------------------------------------------------------- /install_image.md: -------------------------------------------------------------------------------- 1 | use 2 | https://www.raspberrypi.org/software/ 3 | 4 | 5 | ![Image 1](images/pi_imager_01.png "start Pi Imager") 6 | 7 | click on "CHOOSE STORAGE" 8 | 9 | ![Image 1](images/pi_imager_02.png "choose Storage") 10 | 11 | 12 | click on "CHOOSE OS" then "Raspberry Pi OS (other)" 13 | 14 | ![Image 1](images/pi_imager_03.png "choose OS") 15 | 16 | 17 | click on "Raspberry Pi OS Lite (32-bit)" 18 | 19 | ![Image 1](images/pi_imager_04.png "choose OS") 20 | 21 | click on "CHOOSE STORAGE" 22 | 23 | ![Image 1](images/pi_imager_05.png "choose OS") 24 | 25 | click on "CHOOSE STORAGE" 26 | 27 | ![Image 1](images/pi_imager_06.png "choose OS") 28 | 29 | click on "CHOOSE STORAGE" 30 | 31 | ![Image 1](images/pi_imager_07.png "choose OS") -------------------------------------------------------------------------------- /jupyter/maintenance/shutdown.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "d6bbe5be-0346-4ea8-ac09-fa377b0cb0fe", 6 | "metadata": {}, 7 | "source": [ 8 | "# Shutdown Raspberry Pi\n", 9 | "Running this notebook will shutdown the Raspberry Pi" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": null, 15 | "id": "b86b7526-7fc7-4fb7-9d77-7fce0240d610", 16 | "metadata": {}, 17 | "outputs": [], 18 | "source": [ 19 | "!sudo shutdown -h now" 20 | ] 21 | } 22 | ], 23 | "metadata": { 24 | "kernelspec": { 25 | "display_name": "Python 3", 26 | "language": "python", 27 | "name": "python3" 28 | }, 29 | "language_info": { 30 | "codemirror_mode": { 31 | "name": "ipython", 32 | "version": 3 33 | }, 34 | "file_extension": ".py", 35 | "mimetype": "text/x-python", 36 | "name": "python", 37 | "nbconvert_exporter": "python", 38 | "pygments_lexer": "ipython3", 39 | "version": "3.8.10" 40 | } 41 | }, 42 | "nbformat": 4, 43 | "nbformat_minor": 5 44 | } 45 | -------------------------------------------------------------------------------- /jupyter/maintenance/rebuild_gpib.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "dbbb71ff-f33b-4f0a-a94a-1bedcbb70b12", 6 | "metadata": {}, 7 | "source": [ 8 | "# Rebuild linux-gpib\n", 9 | "\n", 10 | "Use this notebook to rebuild linux-gpib after a kernel update" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": null, 16 | "id": "5719da85-b909-4689-9939-900efe0c381f", 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "! ~/repos/meas_rpi/rebuild_gpib.sh" 21 | ] 22 | } 23 | ], 24 | "metadata": { 25 | "kernelspec": { 26 | "display_name": "Python 3 (ipykernel)", 27 | "language": "python", 28 | "name": "python3" 29 | }, 30 | "language_info": { 31 | "codemirror_mode": { 32 | "name": "ipython", 33 | "version": 3 34 | }, 35 | "file_extension": ".py", 36 | "mimetype": "text/x-python", 37 | "name": "python", 38 | "nbconvert_exporter": "python", 39 | "pygments_lexer": "ipython3", 40 | "version": "3.7.3" 41 | } 42 | }, 43 | "nbformat": 4, 44 | "nbformat_minor": 5 45 | } 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 PhilippCo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /jupyter/maintenance/backup.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "2ce4b281-0127-4bcf-a35c-e37c83a128c3", 6 | "metadata": {}, 7 | "source": [ 8 | "# Backup\n", 9 | "This Notebook creates a compressed backup of the notebooks folder in the backups folder. Don't forget to download the backup!!" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": null, 15 | "id": "28d52a41-4faf-44d8-9951-e193f1d96ba0", 16 | "metadata": {}, 17 | "outputs": [], 18 | "source": [ 19 | "!now=`date +\"%Y-%m-%d\"` && tar -zcvf backups/backup-${now}.tar.gz /home/pi/notebooks" 20 | ] 21 | } 22 | ], 23 | "metadata": { 24 | "kernelspec": { 25 | "display_name": "Python 3 (ipykernel)", 26 | "language": "python", 27 | "name": "python3" 28 | }, 29 | "language_info": { 30 | "codemirror_mode": { 31 | "name": "ipython", 32 | "version": 3 33 | }, 34 | "file_extension": ".py", 35 | "mimetype": "text/x-python", 36 | "name": "python", 37 | "nbconvert_exporter": "python", 38 | "pygments_lexer": "ipython3", 39 | "version": "3.7.3" 40 | } 41 | }, 42 | "nbformat": 4, 43 | "nbformat_minor": 5 44 | } 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Short tutorial about installing GPIB on a Raspberry Pi 2 | 3 | The purpose of this repository is to prepare a Raspberry Pi as a GPIB controller and make this as easy as possible. The provided installation bash script will install the following things: 4 | 5 | - linux-gpib 6 | - PyVISA for Python3 7 | - Driver for Agilent 82357A (Agilent 82357B) 8 | - support for NI GPIB-USB-HS 9 | - VXI11 Server (poor mans Agilent E5810A GPIB to Ethernet Bridge https://github.com/PhilippCo/python-vxi11-server) 10 | - Testgear lib (https://github.com/PhilippCo/testgear) 11 | - Jupyter Lab as a Service (Passwort: 1281) 12 | 13 | The linux-gpib setup is based on MiDis description on the EEVBlog Forum: https://www.eevblog.com/forum/metrology/raspberry-pi23-logging-platform-for-voltnuts/msg2008349/#msg2008349 14 | 15 | 16 | ## install Raspbian 17 | 18 | [Install Raspberry Pi Image](install_image.md) 19 | 20 | Since some time the default user isn't 'pi' anymore. But a lot of scripts rely on paths for this user. Therefore, it is absolutely neccessary to use the username pi! 21 | 22 | ## Update Raspbian and install everything you need 23 | 24 | log in via ssh or console and just copy and paste this line 25 | 26 | ``` 27 | sudo apt install -y git && mkdir ~/repos && cd ~/repos && git clone https://github.com/PhilippCo/meas_rpi.git && meas_rpi/install.sh 28 | ``` 29 | -------------------------------------------------------------------------------- /jupyter/examples/pyvisa/pyvisa.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "id": "dec3e6e8-d55e-4a01-8747-188bcf2cf0e3", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import pyvisa" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": null, 16 | "id": "48bb228f-8ae7-4d3c-8842-2086187cc667", 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "rm = pyvisa.ResourceManager()" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": null, 26 | "id": "88d715ff-f4b1-48e7-8ce9-98d31eeba32b", 27 | "metadata": {}, 28 | "outputs": [], 29 | "source": [ 30 | "rm.list_resources()" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": null, 36 | "id": "8aa130d9-c7a4-4ca5-8e02-4ae2c80839c7", 37 | "metadata": {}, 38 | "outputs": [], 39 | "source": [] 40 | } 41 | ], 42 | "metadata": { 43 | "kernelspec": { 44 | "display_name": "Python 3 (ipykernel)", 45 | "language": "python", 46 | "name": "python3" 47 | }, 48 | "language_info": { 49 | "codemirror_mode": { 50 | "name": "ipython", 51 | "version": 3 52 | }, 53 | "file_extension": ".py", 54 | "mimetype": "text/x-python", 55 | "name": "python", 56 | "nbconvert_exporter": "python", 57 | "pygments_lexer": "ipython3", 58 | "version": "3.7.3" 59 | } 60 | }, 61 | "nbformat": 4, 62 | "nbformat_minor": 5 63 | } 64 | -------------------------------------------------------------------------------- /jupyter/examples/instrumentControl/HP3458A.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "id": "thermal-powder", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import testgear" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": null, 16 | "id": "raised-patrick", 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "inst = testgear.HPAK.HP3458A(gpib=22)" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": null, 26 | "id": "ef82db69-4cc3-49f2-9773-507889057864", 27 | "metadata": {}, 28 | "outputs": [], 29 | "source": [ 30 | "inst" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": null, 36 | "id": "designing-joyce", 37 | "metadata": {}, 38 | "outputs": [], 39 | "source": [ 40 | "inst.get_reading()" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": null, 46 | "id": "intellectual-reference", 47 | "metadata": {}, 48 | "outputs": [], 49 | "source": [] 50 | } 51 | ], 52 | "metadata": { 53 | "kernelspec": { 54 | "display_name": "Python 3", 55 | "language": "python", 56 | "name": "python3" 57 | }, 58 | "language_info": { 59 | "codemirror_mode": { 60 | "name": "ipython", 61 | "version": 3 62 | }, 63 | "file_extension": ".py", 64 | "mimetype": "text/x-python", 65 | "name": "python", 66 | "nbconvert_exporter": "python", 67 | "pygments_lexer": "ipython3", 68 | "version": "3.8.10" 69 | } 70 | }, 71 | "nbformat": 4, 72 | "nbformat_minor": 5 73 | } 74 | -------------------------------------------------------------------------------- /jupyter/examples/instrumentControl/HP34401A.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "id": "disturbed-harvey", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import testgear" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": null, 16 | "id": "decreased-courage", 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "inst = testgear.HPAK.HP34401A(gpib=3)" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": null, 26 | "id": "cf875fe8-75bc-43ea-9d2a-e5684e0a85a1", 27 | "metadata": {}, 28 | "outputs": [], 29 | "source": [ 30 | "inst" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": null, 36 | "id": "prescribed-concord", 37 | "metadata": {}, 38 | "outputs": [], 39 | "source": [ 40 | "inst.get_reading()" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": null, 46 | "id": "funded-vegetarian", 47 | "metadata": {}, 48 | "outputs": [], 49 | "source": [] 50 | } 51 | ], 52 | "metadata": { 53 | "kernelspec": { 54 | "display_name": "Python 3", 55 | "language": "python", 56 | "name": "python3" 57 | }, 58 | "language_info": { 59 | "codemirror_mode": { 60 | "name": "ipython", 61 | "version": 3 62 | }, 63 | "file_extension": ".py", 64 | "mimetype": "text/x-python", 65 | "name": "python", 66 | "nbconvert_exporter": "python", 67 | "pygments_lexer": "ipython3", 68 | "version": "3.8.10" 69 | } 70 | }, 71 | "nbformat": 4, 72 | "nbformat_minor": 5 73 | } 74 | -------------------------------------------------------------------------------- /jupyter/maintenance/update.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "adult-bryan", 6 | "metadata": {}, 7 | "source": [ 8 | "# Update Libs\n", 9 | "This Jupyter Notebook will update your Pi regarding the MeasPi Setup" 10 | ] 11 | }, 12 | { 13 | "cell_type": "markdown", 14 | "id": "opponent-walker", 15 | "metadata": {}, 16 | "source": [ 17 | "## update testgear lib" 18 | ] 19 | }, 20 | { 21 | "cell_type": "code", 22 | "execution_count": null, 23 | "id": "miniature-linux", 24 | "metadata": {}, 25 | "outputs": [], 26 | "source": [ 27 | "!cd ~/repos/testgear && git reset --hard origin/main && git pull" 28 | ] 29 | }, 30 | { 31 | "cell_type": "markdown", 32 | "id": "suspended-flesh", 33 | "metadata": {}, 34 | "source": [ 35 | "## update meas_rpi" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": null, 41 | "id": "judicial-stupid", 42 | "metadata": {}, 43 | "outputs": [], 44 | "source": [ 45 | "!cd ~/repos/meas_rpi && git reset --hard origin/main && git pull" 46 | ] 47 | }, 48 | { 49 | "cell_type": "markdown", 50 | "id": "aquatic-composer", 51 | "metadata": {}, 52 | "source": [ 53 | "## update Vxi11 Server" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": null, 59 | "id": "given-township", 60 | "metadata": {}, 61 | "outputs": [], 62 | "source": [ 63 | "!cd ~/repos/python-vxi11-server && git reset --hard origin/master && git pull" 64 | ] 65 | } 66 | ], 67 | "metadata": { 68 | "kernelspec": { 69 | "display_name": "Python 3", 70 | "language": "python", 71 | "name": "python3" 72 | }, 73 | "language_info": { 74 | "codemirror_mode": { 75 | "name": "ipython", 76 | "version": 3 77 | }, 78 | "file_extension": ".py", 79 | "mimetype": "text/x-python", 80 | "name": "python", 81 | "nbconvert_exporter": "python", 82 | "pygments_lexer": "ipython3", 83 | "version": "3.8.10" 84 | } 85 | }, 86 | "nbformat": 4, 87 | "nbformat_minor": 5 88 | } 89 | -------------------------------------------------------------------------------- /jupyter/examples/instrumentControl/raw.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "4911580d-9f23-483a-a7df-c19c125348e1", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import testgear" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": 2, 16 | "id": "656c7574-d187-4e6a-9599-c93059bd06ac", 17 | "metadata": {}, 18 | "outputs": [ 19 | { 20 | "name": "stdout", 21 | "output_type": "stream", 22 | "text": [ 23 | "pyvisa initialized..\n" 24 | ] 25 | } 26 | ], 27 | "source": [ 28 | "inst = testgear.base_classes.instrument(gpib=5, gwip=\"192.168.2.88\")" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": 3, 34 | "id": "c85c12ac-f190-4a82-8f65-4a1e03e94af4", 35 | "metadata": {}, 36 | "outputs": [ 37 | { 38 | "data": { 39 | "text/plain": [ 40 | "============ Testgear Instrument ============\n", 41 | "Class:\t\tinstrument\n", 42 | "VISA String:\tTCPIP::192.168.2.88::gpib0,5::INSTR\n", 43 | "ID String:\t\n", 44 | "Timeout:\t2.000 s" 45 | ] 46 | }, 47 | "execution_count": 3, 48 | "metadata": {}, 49 | "output_type": "execute_result" 50 | } 51 | ], 52 | "source": [ 53 | "inst" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": 4, 59 | "id": "83a09b4c-2129-4335-9691-571a6dcaac9f", 60 | "metadata": {}, 61 | "outputs": [ 62 | { 63 | "data": { 64 | "text/plain": [ 65 | "'HEWLETT-PACKARD,53131A,0,3703\\n'" 66 | ] 67 | }, 68 | "execution_count": 4, 69 | "metadata": {}, 70 | "output_type": "execute_result" 71 | } 72 | ], 73 | "source": [ 74 | "inst.query(\"*IDN?\")" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": null, 80 | "id": "08f32f46-acd9-43dd-b1ba-d1dca4f3e4c5", 81 | "metadata": {}, 82 | "outputs": [], 83 | "source": [] 84 | } 85 | ], 86 | "metadata": { 87 | "kernelspec": { 88 | "display_name": "Python 3", 89 | "language": "python", 90 | "name": "python3" 91 | }, 92 | "language_info": { 93 | "codemirror_mode": { 94 | "name": "ipython", 95 | "version": 3 96 | }, 97 | "file_extension": ".py", 98 | "mimetype": "text/x-python", 99 | "name": "python", 100 | "nbconvert_exporter": "python", 101 | "pygments_lexer": "ipython3", 102 | "version": "3.8.10" 103 | } 104 | }, 105 | "nbformat": 4, 106 | "nbformat_minor": 5 107 | } 108 | -------------------------------------------------------------------------------- /jupyter/examples/instrumentControl/Fluke_5730A.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "d881fba4-0ea7-4a5f-a54d-c432a6f80da4", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import testgear" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": 2, 16 | "id": "5d00f240-480d-4e2c-88dc-38194043d8e2", 17 | "metadata": {}, 18 | "outputs": [ 19 | { 20 | "name": "stdout", 21 | "output_type": "stream", 22 | "text": [ 23 | "pyvisa initialized..\n", 24 | "Fluke 5730A calibrator detected\n" 25 | ] 26 | } 27 | ], 28 | "source": [ 29 | "cal = testgear.Fluke.F5730A(gpib=2, gwip=\"10.112.145.89\")" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": 3, 35 | "id": "dacc0249-a38a-4382-aa85-631371e5abeb", 36 | "metadata": {}, 37 | "outputs": [], 38 | "source": [ 39 | "cal.set_output(voltage=1, frequency=0, enabled=True)" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": 4, 45 | "id": "773f36ea-374b-48ba-afba-8138051b661c", 46 | "metadata": {}, 47 | "outputs": [ 48 | { 49 | "data": { 50 | "text/plain": [ 51 | "============ Channel 1 ============\n", 52 | "enabled:\tTrue\n", 53 | "\n", 54 | "set_voltage:\t1.000000 V\n", 55 | "set_current:\tnan A\n", 56 | "\n", 57 | "voltage:\t1.000000 V\n", 58 | "current:\tnan A\n", 59 | "\n", 60 | "frequency:\t0.000000 Hz\n", 61 | "waveform:\tDC\n", 62 | "\n", 63 | "resistance:\tnan Ohm" 64 | ] 65 | }, 66 | "execution_count": 4, 67 | "metadata": {}, 68 | "output_type": "execute_result" 69 | } 70 | ], 71 | "source": [ 72 | "cal.get_output()" 73 | ] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": null, 78 | "id": "6dbc3867-fe13-4ec3-8a9e-b1cb167d7c8f", 79 | "metadata": {}, 80 | "outputs": [], 81 | "source": [] 82 | } 83 | ], 84 | "metadata": { 85 | "kernelspec": { 86 | "display_name": "Python 3", 87 | "language": "python", 88 | "name": "python3" 89 | }, 90 | "language_info": { 91 | "codemirror_mode": { 92 | "name": "ipython", 93 | "version": 3 94 | }, 95 | "file_extension": ".py", 96 | "mimetype": "text/x-python", 97 | "name": "python", 98 | "nbconvert_exporter": "python", 99 | "pygments_lexer": "ipython3", 100 | "version": "3.8.10" 101 | } 102 | }, 103 | "nbformat": 4, 104 | "nbformat_minor": 5 105 | } 106 | -------------------------------------------------------------------------------- /jupyter/examples/instrumentControl/K34470A.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "disturbed-harvey", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import testgear" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": 2, 16 | "id": "decreased-courage", 17 | "metadata": {}, 18 | "outputs": [ 19 | { 20 | "name": "stdout", 21 | "output_type": "stream", 22 | "text": [ 23 | "pyvisa initialized..\n" 24 | ] 25 | } 26 | ], 27 | "source": [ 28 | "inst = testgear.HPAK.K34470A(gpib=11, gwip=\"10.112.145.89\")" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": 3, 34 | "id": "91780808-0109-40bb-b188-abf2b84160e5", 35 | "metadata": {}, 36 | "outputs": [ 37 | { 38 | "data": { 39 | "text/plain": [ 40 | "============ Testgear Instrument ============\n", 41 | "Class:\t\tK34470A\n", 42 | "VISA String:\tTCPIP::10.112.145.89::gpib0,11::INSTR\n", 43 | "ID String:\tKeysight Technologies,34470A,MY54700780,A.03.00-02.40-03.00-00.52-02-01\n", 44 | "Timeout:\t10.000 s" 45 | ] 46 | }, 47 | "execution_count": 3, 48 | "metadata": {}, 49 | "output_type": "execute_result" 50 | } 51 | ], 52 | "source": [ 53 | "inst" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": 4, 59 | "id": "cf875fe8-75bc-43ea-9d2a-e5684e0a85a1", 60 | "metadata": {}, 61 | "outputs": [], 62 | "source": [ 63 | "inst.conf_function_DCV()" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 5, 69 | "id": "prescribed-concord", 70 | "metadata": {}, 71 | "outputs": [ 72 | { 73 | "data": { 74 | "text/plain": [ 75 | "-0.00576038906" 76 | ] 77 | }, 78 | "execution_count": 5, 79 | "metadata": {}, 80 | "output_type": "execute_result" 81 | } 82 | ], 83 | "source": [ 84 | "inst.get_reading()" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": 6, 90 | "id": "2845358c-3631-4d9c-b069-90f4eef2d0ec", 91 | "metadata": {}, 92 | "outputs": [], 93 | "source": [ 94 | "inst.close()" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": null, 100 | "id": "5e332f57-cec8-445f-adbb-6e377cfad73b", 101 | "metadata": {}, 102 | "outputs": [], 103 | "source": [] 104 | } 105 | ], 106 | "metadata": { 107 | "kernelspec": { 108 | "display_name": "Python 3", 109 | "language": "python", 110 | "name": "python3" 111 | }, 112 | "language_info": { 113 | "codemirror_mode": { 114 | "name": "ipython", 115 | "version": 3 116 | }, 117 | "file_extension": ".py", 118 | "mimetype": "text/x-python", 119 | "name": "python", 120 | "nbconvert_exporter": "python", 121 | "pygments_lexer": "ipython3", 122 | "version": "3.8.10" 123 | } 124 | }, 125 | "nbformat": 4, 126 | "nbformat_minor": 5 127 | } 128 | -------------------------------------------------------------------------------- /gpib/gpib.conf: -------------------------------------------------------------------------------- 1 | /*********************************************************************** 2 | GPIB.CONF IEEE488 library config file 3 | ------------------- 4 | 5 | copyright : (C) 2002 by Frank Mori Hess 6 | (C) 1994 by C.Schroeter 7 | email : fmhess@users.sourceforge.net 8 | ***************************************************************************/ 9 | /*************************************************************************** 10 | * 11 | * Syntax: 12 | * 13 | * interface { ... } starts new interface board section 14 | * device {...} device configuration 15 | * 16 | ***************************************************************************/ 17 | 18 | /* This section configures the configurable driver characteristics 19 | * for an interface board, such as board address, and interrupt level. 20 | * minor = 0 configures /dev/gpib0, minor = 1 configures /dev/gpib1, etc. 21 | */ 22 | 23 | interface { 24 | minor = 0 /* board index, minor = 0 uses /dev/gpib0, minor = 1 uses /dev/gpib1, etc. */ 25 | board_type = "agilent_82357a" /* type of interface board being used */ 26 | name = "violet" /* optional name, allows you to get a board descriptor using ibfind() */ 27 | pad = 0 /* primary address of interface */ 28 | sad = 0 /* secondary address of interface */ 29 | timeout = T3s /* timeout for commands */ 30 | 31 | eos = 0x0a /* EOS Byte, 0xa is newline and 0xd is carriage return */ 32 | set-reos = yes /* Terminate read if EOS */ 33 | set-bin = no /* Compare EOS 8-bit */ 34 | set-xeos = no /* Assert EOI whenever EOS byte is sent */ 35 | set-eot = yes /* Assert EOI with last byte on writes */ 36 | 37 | /* settings for boards that lack plug-n-play capability */ 38 | base = 0 /* Base io ADDRESS */ 39 | irq = 0 /* Interrupt request level */ 40 | dma = 0 /* DMA channel (zero disables) */ 41 | 42 | /* pci_bus and pci_slot can be used to distinguish two pci boards supported by the same driver */ 43 | /* pci_bus = 0 */ 44 | /* pci_slot = 7 */ 45 | 46 | master = yes /* interface board is system controller */ 47 | } 48 | 49 | /* This is how you might set up a pcIIa board on /dev/gpib1, uncomment to use. */ 50 | /******************* 51 | interface { 52 | minor = 1 53 | board_type = "pcIIa" 54 | pad = 0 55 | sad = 0 56 | timeout = T3s 57 | 58 | eos = 0x0a 59 | set-reos = yes 60 | set-bin = no 61 | 62 | base = 0x2e1 63 | irq = 7 64 | dma = 1 65 | 66 | master = yes 67 | } 68 | *********************/ 69 | 70 | /* Now the device sections define the device characteristics for each device. 71 | * These are only used if you want to open the device using ibfind() (instead 72 | * of ibdev() ) 73 | */ 74 | 75 | device { 76 | minor = 0 /* minor number for interface board this device is connected to */ 77 | name = "voltmeter" /* device mnemonic */ 78 | pad = 7 /* The Primary Address */ 79 | sad = 0 /* Secondary Address */ 80 | 81 | eos = 0xa /* EOS Byte */ 82 | set-reos = no /* Terminate read if EOS */ 83 | set-bin = no /* Compare EOS 8-bit */ 84 | } 85 | 86 | device { 87 | minor = 0 88 | name = "scope" 89 | pad = 8 90 | sad = 0 91 | } 92 | 93 | 94 | -------------------------------------------------------------------------------- /jupyter/examples/tutorial/01_testgear lib/01_basiscs.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "contained-sarah", 6 | "metadata": {}, 7 | "source": [ 8 | "# TestGear Lib" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": 1, 14 | "id": "certified-naples", 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "import testgear" 19 | ] 20 | }, 21 | { 22 | "cell_type": "markdown", 23 | "id": "finnish-encounter", 24 | "metadata": {}, 25 | "source": [ 26 | "### create an instance of a dummy instrument" 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "execution_count": 2, 32 | "id": "cordless-richards", 33 | "metadata": {}, 34 | "outputs": [ 35 | { 36 | "data": { 37 | "text/plain": [ 38 | "============ Testgear Instrument ============\n", 39 | "Class:\t\tdummy\n", 40 | "VISA String:\tGPIB0::22::INSTR\n", 41 | "ID String:\tdummy instrument\n", 42 | "Timeout:\t1.000 s" 43 | ] 44 | }, 45 | "execution_count": 2, 46 | "metadata": {}, 47 | "output_type": "execute_result" 48 | } 49 | ], 50 | "source": [ 51 | "inst = testgear.CoTech.dummy(gpib=22)\n", 52 | "inst" 53 | ] 54 | }, 55 | { 56 | "cell_type": "markdown", 57 | "id": "contemporary-mailman", 58 | "metadata": {}, 59 | "source": [] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": 3, 64 | "id": "increased-mustang", 65 | "metadata": {}, 66 | "outputs": [ 67 | { 68 | "data": { 69 | "text/plain": [ 70 | "10.000116494985464" 71 | ] 72 | }, 73 | "execution_count": 3, 74 | "metadata": {}, 75 | "output_type": "execute_result" 76 | } 77 | ], 78 | "source": [ 79 | "inst.get_reading()" 80 | ] 81 | }, 82 | { 83 | "cell_type": "code", 84 | "execution_count": 4, 85 | "id": "quality-timothy", 86 | "metadata": {}, 87 | "outputs": [ 88 | { 89 | "data": { 90 | "text/plain": [ 91 | "{'mean': 9.999995905654286,\n", 92 | " 'std': 0.00011217360153415041,\n", 93 | " 'std_ppm': 11.217364746191967}" 94 | ] 95 | }, 96 | "execution_count": 4, 97 | "metadata": {}, 98 | "output_type": "execute_result" 99 | } 100 | ], 101 | "source": [ 102 | "inst.read_avg(10)" 103 | ] 104 | }, 105 | { 106 | "cell_type": "code", 107 | "execution_count": null, 108 | "id": "champion-poster", 109 | "metadata": {}, 110 | "outputs": [], 111 | "source": [] 112 | } 113 | ], 114 | "metadata": { 115 | "kernelspec": { 116 | "display_name": "Python 3", 117 | "language": "python", 118 | "name": "python3" 119 | }, 120 | "language_info": { 121 | "codemirror_mode": { 122 | "name": "ipython", 123 | "version": 3 124 | }, 125 | "file_extension": ".py", 126 | "mimetype": "text/x-python", 127 | "name": "python", 128 | "nbconvert_exporter": "python", 129 | "pygments_lexer": "ipython3", 130 | "version": "3.8.10" 131 | } 132 | }, 133 | "nbformat": 4, 134 | "nbformat_minor": 5 135 | } 136 | -------------------------------------------------------------------------------- /jupyter/examples/instrumentControl/Fluke_8588A.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "d84d286c-c461-4602-b6d1-997d2fb514f1", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import testgear" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": 2, 16 | "id": "7f1e37e6-42e2-4b50-8faf-fa284164b21c", 17 | "metadata": {}, 18 | "outputs": [ 19 | { 20 | "name": "stdout", 21 | "output_type": "stream", 22 | "text": [ 23 | "pyvisa initialized..\n" 24 | ] 25 | } 26 | ], 27 | "source": [ 28 | "inst = testgear.Fluke.F8588A(gpib=3, gwip=\"10.112.145.89\")" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": 3, 34 | "id": "2be0f777-1f8e-4ac7-be3a-ef3c73f79473", 35 | "metadata": {}, 36 | "outputs": [ 37 | { 38 | "data": { 39 | "text/plain": [ 40 | "============ Testgear Instrument ============\n", 41 | "Class:\t\tF8588A\n", 42 | "VISA String:\tTCPIP::10.112.145.89::gpib0,3::INSTR\n", 43 | "ID String:\tFLUKE,8588A,480576185,1.26\n", 44 | "Timeout:\t30.000 s" 45 | ] 46 | }, 47 | "execution_count": 3, 48 | "metadata": {}, 49 | "output_type": "execute_result" 50 | } 51 | ], 52 | "source": [ 53 | "inst" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": 4, 59 | "id": "ffa3aeea-50ba-417f-bb4c-77e879307847", 60 | "metadata": {}, 61 | "outputs": [], 62 | "source": [ 63 | "inst.conf_function_DCV(mrange=1)" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 5, 69 | "id": "fd182351-8d8c-4efc-b3b5-4f2ecea6a87f", 70 | "metadata": {}, 71 | "outputs": [ 72 | { 73 | "data": { 74 | "text/plain": [ 75 | "0.9999972" 76 | ] 77 | }, 78 | "execution_count": 5, 79 | "metadata": {}, 80 | "output_type": "execute_result" 81 | } 82 | ], 83 | "source": [ 84 | "inst.get_reading()" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": 6, 90 | "id": "beeb2e25-29ef-4d86-8406-903b9304000e", 91 | "metadata": {}, 92 | "outputs": [ 93 | { 94 | "data": { 95 | "text/plain": [ 96 | "{'mean': 0.9999972, 'std': 0.0, 'std_ppm': 0.0}" 97 | ] 98 | }, 99 | "execution_count": 6, 100 | "metadata": {}, 101 | "output_type": "execute_result" 102 | } 103 | ], 104 | "source": [ 105 | "data = inst.read_avg(3)\n", 106 | "data" 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": null, 112 | "id": "1a7473f4-c528-4b66-bf6f-701df7261c7a", 113 | "metadata": {}, 114 | "outputs": [], 115 | "source": [] 116 | } 117 | ], 118 | "metadata": { 119 | "kernelspec": { 120 | "display_name": "Python 3", 121 | "language": "python", 122 | "name": "python3" 123 | }, 124 | "language_info": { 125 | "codemirror_mode": { 126 | "name": "ipython", 127 | "version": 3 128 | }, 129 | "file_extension": ".py", 130 | "mimetype": "text/x-python", 131 | "name": "python", 132 | "nbconvert_exporter": "python", 133 | "pygments_lexer": "ipython3", 134 | "version": "3.8.10" 135 | } 136 | }, 137 | "nbformat": 4, 138 | "nbformat_minor": 5 139 | } 140 | -------------------------------------------------------------------------------- /jupyter/examples/instrumentControl/log_voltage.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "b0925ea7-4e58-4613-8bc1-4727cc628522", 6 | "metadata": {}, 7 | "source": [ 8 | "# simple data logging example" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": 1, 14 | "id": "4911580d-9f23-483a-a7df-c19c125348e1", 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "import testgear #testgear support\n", 19 | "import datetime #generates a datetime object to log the point in time of our measurement\n", 20 | "import time #access to current time and sleep functions\n", 21 | "import openpyxl as xls #access to Excel files" 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "id": "acbb3fa4-24a0-4705-9241-d4e0562ce994", 27 | "metadata": {}, 28 | "source": [ 29 | "In this example we want to log a voltage source" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": 2, 35 | "id": "656c7574-d187-4e6a-9599-c93059bd06ac", 36 | "metadata": {}, 37 | "outputs": [ 38 | { 39 | "name": "stdout", 40 | "output_type": "stream", 41 | "text": [ 42 | "pyvisa initialized..\n" 43 | ] 44 | } 45 | ], 46 | "source": [ 47 | "#choose your weapon..\n", 48 | "\n", 49 | "# here are a few meters which are currently supported for this action\n", 50 | "dmm = testgear.HPAK.HP34401A(gpib=3, gwip=\"192.168.2.88\") #gpib3 behind my E5810A\n", 51 | "#dmm = testgear.HPAK.HP3458A()\n", 52 | "#dmm = testgear.HPAK.K34461A()\n", 53 | "#dmm = testgear.HPAK.K34470A()\n", 54 | "#dmm = testgear.Fluke.F8508A()\n", 55 | "#dmm = testgear.Fluke.F8588A()\n", 56 | "#dmm = testgear.Keithley.K182()\n", 57 | "#dmm = testgear.Keithley.K617()\n", 58 | "# ..." 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": 3, 64 | "id": "c85c12ac-f190-4a82-8f65-4a1e03e94af4", 65 | "metadata": {}, 66 | "outputs": [ 67 | { 68 | "data": { 69 | "text/plain": [ 70 | "============ Testgear Instrument ============\n", 71 | "Class:\t\tHP34401A\n", 72 | "VISA String:\tTCPIP::192.168.2.88::gpib0,3::INSTR\n", 73 | "ID String:\tHEWLETT-PACKARD,34401A,0,10-5-2\n", 74 | "Timeout:\t10.000 s" 75 | ] 76 | }, 77 | "execution_count": 3, 78 | "metadata": {}, 79 | "output_type": "execute_result" 80 | } 81 | ], 82 | "source": [ 83 | "dmm" 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": 4, 89 | "id": "3de4c6c0-8e61-40e9-899c-42bbebc7a7c5", 90 | "metadata": {}, 91 | "outputs": [], 92 | "source": [ 93 | "#configure the DMM for 10V DC fixed range, 100NPLC and high input impedance\n", 94 | "#this call is independend of the choosen meter. Everything which is special to a specific\n", 95 | "#meter is handled in the testgear lib\n", 96 | "\n", 97 | "dmm.conf_function_DCV(mrange=10, nplc=100, HiZ=True)" 98 | ] 99 | }, 100 | { 101 | "cell_type": "code", 102 | "execution_count": 5, 103 | "id": "83a09b4c-2129-4335-9691-571a6dcaac9f", 104 | "metadata": {}, 105 | "outputs": [], 106 | "source": [ 107 | "filename = \"../data/\"+time.strftime(\"%Y-%m-%d--%H-%M-%S\")+\"_10V_log.xlsx\" #generate filename\n", 108 | "\n", 109 | "wb = xls.Workbook() #create Excel Workbook\n", 110 | "ws = wb.active #select active worksheet\n", 111 | "\n", 112 | "ws.append([\"timestamp\", \"value\"]) #we're using the first line in our Excel file for some headers" 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": 6, 118 | "id": "08f32f46-acd9-43dd-b1ba-d1dca4f3e4c5", 119 | "metadata": {}, 120 | "outputs": [ 121 | { 122 | "name": "stdout", 123 | "output_type": "stream", 124 | "text": [ 125 | "0 [datetime.datetime(2021, 8, 14, 1, 21, 54, 677573), 7.1857292]\n", 126 | "1 [datetime.datetime(2021, 8, 14, 1, 21, 58, 794682), 7.1857296]\n", 127 | "2 [datetime.datetime(2021, 8, 14, 1, 22, 2, 833786), 7.1857308]\n", 128 | "3 [datetime.datetime(2021, 8, 14, 1, 22, 6, 875121), 7.1857296]\n", 129 | "4 [datetime.datetime(2021, 8, 14, 1, 22, 10, 912796), 7.1857295]\n", 130 | "5 [datetime.datetime(2021, 8, 14, 1, 22, 14, 951985), 7.1857296]\n", 131 | "6 [datetime.datetime(2021, 8, 14, 1, 22, 18, 991227), 7.1857305]\n", 132 | "7 [datetime.datetime(2021, 8, 14, 1, 22, 23, 55435), 7.1857301]\n", 133 | "8 [datetime.datetime(2021, 8, 14, 1, 22, 27, 92314), 7.1857312]\n", 134 | "9 [datetime.datetime(2021, 8, 14, 1, 22, 31, 131778), 7.1857293]\n" 135 | ] 136 | } 137 | ], 138 | "source": [ 139 | "for i in range(0, 10): #we want to take 10 readings\n", 140 | " value = dmm.get_reading()\n", 141 | " data = [datetime.datetime.today(), value]\n", 142 | " print(i, data) #show our data\n", 143 | " ws.append(data) #store our data\n", 144 | " wb.save(filename) #write Excel file" 145 | ] 146 | }, 147 | { 148 | "cell_type": "code", 149 | "execution_count": null, 150 | "id": "ba54f751-3151-44cf-907f-e9b5f9ee0e41", 151 | "metadata": {}, 152 | "outputs": [], 153 | "source": [] 154 | } 155 | ], 156 | "metadata": { 157 | "kernelspec": { 158 | "display_name": "Python 3", 159 | "language": "python", 160 | "name": "python3" 161 | }, 162 | "language_info": { 163 | "codemirror_mode": { 164 | "name": "ipython", 165 | "version": 3 166 | }, 167 | "file_extension": ".py", 168 | "mimetype": "text/x-python", 169 | "name": "python", 170 | "nbconvert_exporter": "python", 171 | "pygments_lexer": "ipython3", 172 | "version": "3.8.10" 173 | } 174 | }, 175 | "nbformat": 4, 176 | "nbformat_minor": 5 177 | } 178 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | # Setup GPIB on Raspberry Pi 2 | # 3 | # steps are based on MiDis description: https://www.eevblog.com/forum/metrology/raspberry-pi23-logging-platform-for-voltnuts/msg2008349/#msg2008349 4 | # 5 | 6 | 7 | echo 8 | echo 9 | echo "#################################################" 10 | echo "# install neccessary packets.. #" 11 | echo "#################################################" 12 | echo 13 | echo 14 | 15 | sudo apt-get -y autoremove 16 | 17 | #install build tools 18 | sudo apt -y install subversion 19 | sudo apt -y install build-essential 20 | sudo apt -y install bison flex 21 | sudo apt -y install automake libtool 22 | sudo apt -y install python3-setuptools 23 | 24 | #sudo apt-get -y install libpython3-dev 25 | sudo apt -y install libopenblas-dev liblapack-dev 26 | sudo apt -y install libopenjp2-7 27 | 28 | #install some common tools 29 | sudo apt-get -y install tmux mc 30 | 31 | 32 | #before we go on: check if subversion is really installed. That was sometimes a problem in the past 33 | if ! command -v svn &> /dev/null 34 | then 35 | echo "subversion failed to install!" 36 | exit 37 | fi 38 | 39 | #install python GPIB before linux-gpib! 40 | sudo apt -y install python3 python3-pip python3-venv nodejs 41 | sudo apt-get -y install python3-smbus 42 | 43 | 44 | echo 45 | echo 46 | echo "#################################################" 47 | echo "# create Python venv.. #" 48 | echo "#################################################" 49 | echo 50 | echo 51 | 52 | 53 | cd ~ 54 | python3 -m venv venv 55 | ~/venv/bin/python3 -m pip install jupyter 56 | ~/venv/bin/python3 -m pip install pyvisa pyvisa-py scipy openpyxl pandas xlrd pyserial pyusb 57 | ~/venv/bin/python3 -m pip install matplotlib ipympl 58 | 59 | 60 | echo 61 | echo 62 | echo "#################################################" 63 | echo "# install Jupyter Lab Service.. #" 64 | echo "#################################################" 65 | echo 66 | echo 67 | 68 | #install Jupyter Lab as a service 69 | #create directory for Jupyter Notebooks 70 | mkdir ~/notebooks 71 | sudo cp ~/repos/meas_rpi/jupyter/jupyter.service /etc/systemd/system/ 72 | sudo systemctl enable jupyter.service 73 | sudo systemctl daemon-reload 74 | sudo systemctl start jupyter.service 75 | #jupyter notebook --generate-config 76 | ## set password later with: jupyter notebook password 77 | ln -s ~/repos/meas_rpi/jupyter/examples ~/notebooks/examples 78 | ln -s ~/repos/meas_rpi/jupyter/maintenance ~/notebooks/maintenance 79 | mkdir ~/notebooks/maintenance/backups 80 | 81 | 82 | echo 83 | echo 84 | echo "#################################################" 85 | echo "# install Linux GPIB.. #" 86 | echo "#################################################" 87 | echo 88 | echo 89 | 90 | #check out linux-gpib 91 | sudo svn checkout http://svn.code.sf.net/p/linux-gpib/code/trunk /usr/local/src/linux-gpib-code 92 | 93 | #install Kernel Module 94 | cd /usr/local/src/linux-gpib-code/linux-gpib-kernel/ 95 | sudo make clean 96 | sudo sed -i 's/GPIOF_DIR_IN/GPIOD_IN/g' drivers/gpib/gpio/gpib_bitbang.c 97 | sudo make 98 | sudo make install 99 | 100 | #install User Module 101 | cd /usr/local/src/linux-gpib-code/linux-gpib-user/ 102 | sudo ./bootstrap 103 | sudo ./configure 104 | sudo make 105 | sudo make install 106 | 107 | #install gpib in venv 108 | sudo ~/venv/bin/python3 -m pip install -e /usr/local/src/linux-gpib-code/linux-gpib-user/language/python/ 109 | 110 | echo 111 | echo 112 | echo "#################################################" 113 | echo "# install Agilent 82357A Support.. #" 114 | echo "#################################################" 115 | echo 116 | echo 117 | 118 | #Install Agilent 82357a 119 | cd /usr/local/src/linux-gpib-code/ 120 | sudo apt-get -y install fxload 121 | sudo wget http://linux-gpib.sourceforge.net/firmware/gpib_firmware-2008-08-10.tar.gz 122 | sudo tar xvzf gpib_firmware-2008-08-10.tar.gz 123 | 124 | #backup original gpib.conf 125 | sudo mv /usr/local/etc/gpib.conf /usr/local/etc/gpib.conf.backup 126 | 127 | #replace gpib.conf with modified one 128 | sudo cp ~/repos/meas_rpi/gpib/gpib.conf /usr/local/etc/ 129 | 130 | #auto download firmware 131 | sudo cp /usr/local/src/linux-gpib-code/gpib_firmware-2008-08-10/agilent_82357a/measat_releaseX1.8.hex $(sudo find / -type d -name 'agilent_82357a' | grep usb | grep -v gpib) 132 | 133 | sudo cp /usr/local/etc/udev/rules.d/* /etc/udev/rules.d/ 134 | 135 | #create gpib group 136 | sudo groupadd gpib 137 | sudo adduser $(whoami) gpib 138 | 139 | #allow access to USB devices 140 | echo 'SUBSYSTEM=="usb", MODE="0666", GROUP="gpib"' | sudo tee -a /etc/udev/rules.d/99-com.rules 141 | 142 | sudo ldconfig 143 | sudo gpib_config 144 | 145 | echo 146 | echo 147 | echo "#################################################" 148 | echo "# install TestGear Lib.. #" 149 | echo "#################################################" 150 | echo 151 | echo 152 | 153 | 154 | #install testgear lib 155 | cd ~/repos 156 | git clone https://github.com/PhilippCo/testgear.git 157 | cd testgear 158 | sudo ~/venv/bin/pip3 install -e ./ 159 | 160 | echo 161 | echo 162 | echo "#################################################" 163 | echo "# creat SSH-key.. #" 164 | echo "#################################################" 165 | echo 166 | echo 167 | 168 | echo "generate SSH key" 169 | ssh-keygen -b 4096 -t rsa -f ~/.ssh/id_rsa -q -N "" 170 | 171 | echo 172 | echo 173 | echo "#################################################" 174 | echo "# add Cron Jobs.. #" 175 | echo "#################################################" 176 | echo 177 | echo 178 | 179 | #add Cron Jobs 180 | mkdir ~/notebooks/cron 181 | mkdir ~/notebooks/cron/nightly 182 | mkdir ~/notebooks/cron/hourly 183 | chmod 777 ~/repos/meas_rpi/scripts/cron_nightly.sh 184 | chmod 777 ~/repos/meas_rpi/scripts/cron_hourly.sh 185 | (crontab -l 2>/dev/null; echo "30 2 * * * /home/$USER/repos/meas_rpi/scripts/cron_nightly.sh") | crontab - 186 | (crontab -l 2>/dev/null; echo "0 * * * * /home/$USER/repos/meas_rpi/scripts/cron_hourly.sh") | crontab - 187 | 188 | echo 189 | echo 190 | echo "#################################################" 191 | echo "# installation done.. #" 192 | echo "# please reboot (type: sudo reboot) #" 193 | echo "#################################################" 194 | 195 | -------------------------------------------------------------------------------- /jupyter/examples/analysis/plot_log.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "01c99c0f-c7c0-4d8d-9b0f-2434e6a94722", 6 | "metadata": {}, 7 | "source": [ 8 | "# Plot the simple log" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": 1, 14 | "id": "contained-reduction", 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "%matplotlib widget\n", 19 | "import matplotlib.pyplot as plt\n", 20 | "import pandas as pd\n", 21 | "import numpy as np\n", 22 | "from scipy import stats" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": 2, 28 | "id": "fabulous-charge", 29 | "metadata": {}, 30 | "outputs": [ 31 | { 32 | "data": { 33 | "text/html": [ 34 | "
\n", 35 | "\n", 48 | "\n", 49 | " \n", 50 | " \n", 51 | " \n", 52 | " \n", 53 | " \n", 54 | " \n", 55 | " \n", 56 | " \n", 57 | " \n", 58 | " \n", 59 | " \n", 60 | " \n", 61 | " \n", 62 | " \n", 63 | " \n", 64 | " \n", 65 | " \n", 66 | " \n", 67 | " \n", 68 | " \n", 69 | " \n", 70 | " \n", 71 | " \n", 72 | " \n", 73 | " \n", 74 | " \n", 75 | " \n", 76 | " \n", 77 | " \n", 78 | " \n", 79 | " \n", 80 | " \n", 81 | " \n", 82 | " \n", 83 | " \n", 84 | " \n", 85 | " \n", 86 | " \n", 87 | " \n", 88 | " \n", 89 | " \n", 90 | " \n", 91 | " \n", 92 | " \n", 93 | " \n", 94 | " \n", 95 | " \n", 96 | " \n", 97 | " \n", 98 | " \n", 99 | " \n", 100 | " \n", 101 | " \n", 102 | " \n", 103 | " \n", 104 | " \n", 105 | " \n", 106 | " \n", 107 | " \n", 108 | "
timestampvalue
02021-08-14 01:03:45.6567.185730
12021-08-14 01:03:49.7347.185730
22021-08-14 01:03:53.7737.185730
32021-08-14 01:03:57.8137.185730
42021-08-14 01:04:01.8497.185730
52021-08-14 01:04:05.9117.185731
62021-08-14 01:04:09.9517.185730
72021-08-14 01:04:14.0397.185730
82021-08-14 01:04:18.0767.185731
92021-08-14 01:04:22.1197.185731
\n", 109 | "
" 110 | ], 111 | "text/plain": [ 112 | " timestamp value\n", 113 | "0 2021-08-14 01:03:45.656 7.185730\n", 114 | "1 2021-08-14 01:03:49.734 7.185730\n", 115 | "2 2021-08-14 01:03:53.773 7.185730\n", 116 | "3 2021-08-14 01:03:57.813 7.185730\n", 117 | "4 2021-08-14 01:04:01.849 7.185730\n", 118 | "5 2021-08-14 01:04:05.911 7.185731\n", 119 | "6 2021-08-14 01:04:09.951 7.185730\n", 120 | "7 2021-08-14 01:04:14.039 7.185730\n", 121 | "8 2021-08-14 01:04:18.076 7.185731\n", 122 | "9 2021-08-14 01:04:22.119 7.185731" 123 | ] 124 | }, 125 | "execution_count": 2, 126 | "metadata": {}, 127 | "output_type": "execute_result" 128 | } 129 | ], 130 | "source": [ 131 | "data = pd.read_excel(\"../data/2021-08-14--01-03-41_10V_log.xlsx\")\n", 132 | "data" 133 | ] 134 | }, 135 | { 136 | "cell_type": "code", 137 | "execution_count": 3, 138 | "id": "4b37c4d6-6f48-4acc-8daf-9f43c2e5be7f", 139 | "metadata": {}, 140 | "outputs": [], 141 | "source": [ 142 | "#lets write a litle helper function to calculate the deviation in ppm referenced to the mean\n", 143 | "def ppm(arr):\n", 144 | " return (arr - np.mean(arr))/np.mean(arr) * 1e6" 145 | ] 146 | }, 147 | { 148 | "cell_type": "code", 149 | "execution_count": 4, 150 | "id": "indirect-reception", 151 | "metadata": {}, 152 | "outputs": [ 153 | { 154 | "data": { 155 | "application/vnd.jupyter.widget-view+json": { 156 | "model_id": "861cb0f6195347b4a047914b1111d5c3", 157 | "version_major": 2, 158 | "version_minor": 0 159 | }, 160 | "text/plain": [ 161 | "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" 162 | ] 163 | }, 164 | "metadata": {}, 165 | "output_type": "display_data" 166 | } 167 | ], 168 | "source": [ 169 | "plt.figure()\n", 170 | "plt.title(\"Simple Voltage Log\")\n", 171 | "plt.plot(ppm(data[\"value\"]))\n", 172 | "\n", 173 | "plt.ylabel(\"Deviation in ppm\")\n", 174 | "plt.xlabel(\"Numer of Measurement\")\n", 175 | "plt.grid()\n", 176 | "plt.tight_layout()\n", 177 | "plt.show()" 178 | ] 179 | }, 180 | { 181 | "cell_type": "code", 182 | "execution_count": null, 183 | "id": "hairy-realtor", 184 | "metadata": {}, 185 | "outputs": [], 186 | "source": [] 187 | } 188 | ], 189 | "metadata": { 190 | "kernelspec": { 191 | "display_name": "Python 3", 192 | "language": "python", 193 | "name": "python3" 194 | }, 195 | "language_info": { 196 | "codemirror_mode": { 197 | "name": "ipython", 198 | "version": 3 199 | }, 200 | "file_extension": ".py", 201 | "mimetype": "text/x-python", 202 | "name": "python", 203 | "nbconvert_exporter": "python", 204 | "pygments_lexer": "ipython3", 205 | "version": "3.8.10" 206 | } 207 | }, 208 | "nbformat": 4, 209 | "nbformat_minor": 5 210 | } 211 | -------------------------------------------------------------------------------- /jupyter/examples/analysis/INL_example.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "01c99c0f-c7c0-4d8d-9b0f-2434e6a94722", 6 | "metadata": {}, 7 | "source": [ 8 | "# Example of INL calculation" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": 1, 14 | "id": "contained-reduction", 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "%matplotlib widget\n", 19 | "import matplotlib.pyplot as plt\n", 20 | "import pandas as pd\n", 21 | "import numpy as np\n", 22 | "from scipy import stats" 23 | ] 24 | }, 25 | { 26 | "cell_type": "markdown", 27 | "id": "5b94ef3b-b5df-44cb-878a-0f503160394f", 28 | "metadata": {}, 29 | "source": [ 30 | "create variable to select the reference source" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": 2, 36 | "id": "super-cattle", 37 | "metadata": {}, 38 | "outputs": [], 39 | "source": [ 40 | "# source = Fluke 5720A\n", 41 | "# dutb = HP3458A\n", 42 | "ref = \"source\"" 43 | ] 44 | }, 45 | { 46 | "cell_type": "markdown", 47 | "id": "a54e674f-7063-48ff-85c8-7b6fd9f7a364", 48 | "metadata": {}, 49 | "source": [ 50 | "load Transmille measurement from xdevs server\n", 51 | "\n", 52 | "it doesn't matter if the source is your local file system or a web address" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": 3, 58 | "id": "fabulous-charge", 59 | "metadata": {}, 60 | "outputs": [ 61 | { 62 | "data": { 63 | "text/html": [ 64 | "
\n", 65 | "\n", 78 | "\n", 79 | " \n", 80 | " \n", 81 | " \n", 82 | " \n", 83 | " \n", 84 | " \n", 85 | " \n", 86 | " \n", 87 | " \n", 88 | " \n", 89 | " \n", 90 | " \n", 91 | " \n", 92 | " \n", 93 | " \n", 94 | " \n", 95 | " \n", 96 | " \n", 97 | " \n", 98 | " \n", 99 | " \n", 100 | " \n", 101 | " \n", 102 | " \n", 103 | " \n", 104 | " \n", 105 | " \n", 106 | " \n", 107 | " \n", 108 | " \n", 109 | " \n", 110 | " \n", 111 | " \n", 112 | " \n", 113 | " \n", 114 | " \n", 115 | " \n", 116 | " \n", 117 | " \n", 118 | " \n", 119 | " \n", 120 | " \n", 121 | " \n", 122 | " \n", 123 | " \n", 124 | " \n", 125 | " \n", 126 | " \n", 127 | " \n", 128 | " \n", 129 | " \n", 130 | " \n", 131 | " \n", 132 | " \n", 133 | " \n", 134 | " \n", 135 | " \n", 136 | " \n", 137 | " \n", 138 | " \n", 139 | " \n", 140 | " \n", 141 | " \n", 142 | " \n", 143 | " \n", 144 | " \n", 145 | " \n", 146 | " \n", 147 | " \n", 148 | " \n", 149 | " \n", 150 | " \n", 151 | " \n", 152 | " \n", 153 | " \n", 154 | " \n", 155 | " \n", 156 | " \n", 157 | " \n", 158 | " \n", 159 | " \n", 160 | " \n", 161 | " \n", 162 | " \n", 163 | " \n", 164 | " \n", 165 | " \n", 166 | " \n", 167 | " \n", 168 | " \n", 169 | " \n", 170 | " \n", 171 | " \n", 172 | " \n", 173 | " \n", 174 | " \n", 175 | " \n", 176 | " \n", 177 | " \n", 178 | " \n", 179 | " \n", 180 | " \n", 181 | " \n", 182 | " \n", 183 | " \n", 184 | " \n", 185 | " \n", 186 | " \n", 187 | " \n", 188 | " \n", 189 | " \n", 190 | " \n", 191 | " \n", 192 | " \n", 193 | " \n", 194 | " \n", 195 | " \n", 196 | " \n", 197 | " \n", 198 | " \n", 199 | " \n", 200 | " \n", 201 | " \n", 202 | " \n", 203 | " \n", 204 | " \n", 205 | " \n", 206 | " \n", 207 | " \n", 208 | " \n", 209 | " \n", 210 | " \n", 211 | " \n", 212 | " \n", 213 | " \n", 214 | " \n", 215 | " \n", 216 | " \n", 217 | " \n", 218 | " \n", 219 | " \n", 220 | " \n", 221 | " \n", 222 | " \n", 223 | " \n", 224 | " \n", 225 | " \n", 226 | " \n", 227 | " \n", 228 | " \n", 229 | " \n", 230 | " \n", 231 | " \n", 232 | " \n", 233 | " \n", 234 | " \n", 235 | " \n", 236 | " \n", 237 | " \n", 238 | " \n", 239 | " \n", 240 | " \n", 241 | " \n", 242 | " \n", 243 | " \n", 244 | " \n", 245 | " \n", 246 | " \n", 247 | " \n", 248 | " \n", 249 | " \n", 250 | " \n", 251 | " \n", 252 | " \n", 253 | " \n", 254 | " \n", 255 | " \n", 256 | " \n", 257 | " \n", 258 | " \n", 259 | " \n", 260 | " \n", 261 | " \n", 262 | " \n", 263 | " \n", 264 | " \n", 265 | " \n", 266 | " \n", 267 | " \n", 268 | " \n", 269 | " \n", 270 | " \n", 271 | " \n", 272 | " \n", 273 | " \n", 274 | " \n", 275 | " \n", 276 | " \n", 277 | " \n", 278 | " \n", 279 | " \n", 280 | " \n", 281 | " \n", 282 | " \n", 283 | " \n", 284 | " \n", 285 | " \n", 286 | " \n", 287 | " \n", 288 | " \n", 289 | " \n", 290 | " \n", 291 | " \n", 292 | " \n", 293 | " \n", 294 | " \n", 295 | " \n", 296 | " \n", 297 | " \n", 298 | " \n", 299 | " \n", 300 | " \n", 301 | " \n", 302 | " \n", 303 | " \n", 304 | " \n", 305 | " \n", 306 | " \n", 307 | " \n", 308 | " \n", 309 | " \n", 310 | " \n", 311 | "
datesourcedutadutbdutcdutdsdevsdev2sdev3sdev4temptemp2ambtrhpressureUnnamed: 15
008042021-00:54:11-10.9-10.899970-10.900027-10.90.00.000000e+006.500000e-080.000000e+00035.023.023.01759.64,992.47NaNNaN
108042021-00:54:18-10.9-10.899968-10.900027-10.90.08.956690e-071.710750e-070.000000e+00035.023.023.01159.66,992.46NaNNaN
208042021-00:54:25-10.9-10.899968-10.900027-10.90.09.500000e-071.491640e-070.000000e+00035.023.023.00159.70,992.45NaNNaN
308042021-00:54:32-10.9-10.899970-10.900027-10.90.09.308060e-071.905150e-070.000000e+00035.023.022.99259.70,992.49NaNNaN
408042021-00:54:39-10.9-10.899970-10.900027-10.90.08.517950e-072.447280e-070.000000e+00035.023.022.98259.74,992.44NaNNaN
...................................................
130908042021-06:35:1310.910.89997510.90002910.90.05.312460e-071.790720e-070.000000e+00035.023.022.68062.52,993.31NaNNaN
131008042021-06:35:2010.910.89997610.90002910.90.05.356070e-071.649810e-070.000000e+00035.023.022.68062.49,993.29NaNNaN
131108042021-06:35:2710.910.89997610.90002910.90.06.437390e-072.198730e-070.000000e+00035.023.022.67962.49,993.29NaNNaN
131208042021-06:35:3510.910.89997610.90002910.90.05.955860e-072.123480e-070.000000e+00035.023.022.68562.48,993.32NaNNaN
131308042021-06:35:4210.910.89997410.90002910.90.06.691450e-072.105000e-071.776360e-15035.023.022.68362.46,993.34NaNNaN
\n", 312 | "

1314 rows × 16 columns

\n", 313 | "
" 314 | ], 315 | "text/plain": [ 316 | " date source duta dutb dutc dutd \\\n", 317 | "0 08042021-00:54:11 -10.9 -10.899970 -10.900027 -10.9 0.0 \n", 318 | "1 08042021-00:54:18 -10.9 -10.899968 -10.900027 -10.9 0.0 \n", 319 | "2 08042021-00:54:25 -10.9 -10.899968 -10.900027 -10.9 0.0 \n", 320 | "3 08042021-00:54:32 -10.9 -10.899970 -10.900027 -10.9 0.0 \n", 321 | "4 08042021-00:54:39 -10.9 -10.899970 -10.900027 -10.9 0.0 \n", 322 | "... ... ... ... ... ... ... \n", 323 | "1309 08042021-06:35:13 10.9 10.899975 10.900029 10.9 0.0 \n", 324 | "1310 08042021-06:35:20 10.9 10.899976 10.900029 10.9 0.0 \n", 325 | "1311 08042021-06:35:27 10.9 10.899976 10.900029 10.9 0.0 \n", 326 | "1312 08042021-06:35:35 10.9 10.899976 10.900029 10.9 0.0 \n", 327 | "1313 08042021-06:35:42 10.9 10.899974 10.900029 10.9 0.0 \n", 328 | "\n", 329 | " sdev sdev2 sdev3 sdev4 temp temp2 ambt \\\n", 330 | "0 0.000000e+00 6.500000e-08 0.000000e+00 0 35.0 23.0 23.017 \n", 331 | "1 8.956690e-07 1.710750e-07 0.000000e+00 0 35.0 23.0 23.011 \n", 332 | "2 9.500000e-07 1.491640e-07 0.000000e+00 0 35.0 23.0 23.001 \n", 333 | "3 9.308060e-07 1.905150e-07 0.000000e+00 0 35.0 23.0 22.992 \n", 334 | "4 8.517950e-07 2.447280e-07 0.000000e+00 0 35.0 23.0 22.982 \n", 335 | "... ... ... ... ... ... ... ... \n", 336 | "1309 5.312460e-07 1.790720e-07 0.000000e+00 0 35.0 23.0 22.680 \n", 337 | "1310 5.356070e-07 1.649810e-07 0.000000e+00 0 35.0 23.0 22.680 \n", 338 | "1311 6.437390e-07 2.198730e-07 0.000000e+00 0 35.0 23.0 22.679 \n", 339 | "1312 5.955860e-07 2.123480e-07 0.000000e+00 0 35.0 23.0 22.685 \n", 340 | "1313 6.691450e-07 2.105000e-07 1.776360e-15 0 35.0 23.0 22.683 \n", 341 | "\n", 342 | " rh pressure Unnamed: 15 \n", 343 | "0 59.64,992.47 NaN NaN \n", 344 | "1 59.66,992.46 NaN NaN \n", 345 | "2 59.70,992.45 NaN NaN \n", 346 | "3 59.70,992.49 NaN NaN \n", 347 | "4 59.74,992.44 NaN NaN \n", 348 | "... ... ... ... \n", 349 | "1309 62.52,993.31 NaN NaN \n", 350 | "1310 62.49,993.29 NaN NaN \n", 351 | "1311 62.49,993.29 NaN NaN \n", 352 | "1312 62.48,993.32 NaN NaN \n", 353 | "1313 62.46,993.34 NaN NaN \n", 354 | "\n", 355 | "[1314 rows x 16 columns]" 356 | ] 357 | }, 358 | "execution_count": 3, 359 | "metadata": {}, 360 | "output_type": "execute_result" 361 | } 362 | ], 363 | "source": [ 364 | "data = pd.read_csv(\"https://xdevs.com/doc/Transmille/8104/3458_vs_8104/dcl_10vdc_5720_8104r_3458a_nlpc100_raw_jul2021.csv\", sep=\";\")\n", 365 | "data" 366 | ] 367 | }, 368 | { 369 | "cell_type": "markdown", 370 | "id": "e0e7b2fc-2776-4486-b6e6-b4d5a1d40b1c", 371 | "metadata": {}, 372 | "source": [ 373 | "There are multiple measurements for each voltage point. Therefore, we group them and calculate the mean for every group" 374 | ] 375 | }, 376 | { 377 | "cell_type": "code", 378 | "execution_count": 4, 379 | "id": "quiet-passenger", 380 | "metadata": {}, 381 | "outputs": [], 382 | "source": [ 383 | "data = data.groupby(['source']).apply(np.mean)" 384 | ] 385 | }, 386 | { 387 | "cell_type": "markdown", 388 | "id": "5013c1f8-9d1c-429f-9b7c-5269cc0f4bc9", 389 | "metadata": {}, 390 | "source": [ 391 | "Now we can calculate a least square fit" 392 | ] 393 | }, 394 | { 395 | "cell_type": "code", 396 | "execution_count": 5, 397 | "id": "stopped-naples", 398 | "metadata": {}, 399 | "outputs": [], 400 | "source": [ 401 | "slope, intercept, rvalue, pvalue, stderr = stats.linregress(data[\"duta\"], data[ref])" 402 | ] 403 | }, 404 | { 405 | "cell_type": "code", 406 | "execution_count": 7, 407 | "id": "indirect-reception", 408 | "metadata": {}, 409 | "outputs": [ 410 | { 411 | "data": { 412 | "application/vnd.jupyter.widget-view+json": { 413 | "model_id": "988e8849d7f945618ff63147757bad28", 414 | "version_major": 2, 415 | "version_minor": 0 416 | }, 417 | "text/plain": [ 418 | "Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …" 419 | ] 420 | }, 421 | "metadata": {}, 422 | "output_type": "display_data" 423 | } 424 | ], 425 | "source": [ 426 | "corr = data[\"duta\"] * slope - intercept\n", 427 | "error = corr - data[ref]\n", 428 | "\n", 429 | "plt.figure()\n", 430 | "plt.title(\"Transmille INL\")\n", 431 | "plt.plot(data[ref], error, '.', label=\"measured error\")\n", 432 | "\n", 433 | "plt.ylabel(\"Deviation in V\")\n", 434 | "plt.xlabel(\"Input in V\")\n", 435 | "plt.grid()" 436 | ] 437 | }, 438 | { 439 | "cell_type": "code", 440 | "execution_count": null, 441 | "id": "hairy-realtor", 442 | "metadata": {}, 443 | "outputs": [], 444 | "source": [] 445 | } 446 | ], 447 | "metadata": { 448 | "kernelspec": { 449 | "display_name": "Python 3", 450 | "language": "python", 451 | "name": "python3" 452 | }, 453 | "language_info": { 454 | "codemirror_mode": { 455 | "name": "ipython", 456 | "version": 3 457 | }, 458 | "file_extension": ".py", 459 | "mimetype": "text/x-python", 460 | "name": "python", 461 | "nbconvert_exporter": "python", 462 | "pygments_lexer": "ipython3", 463 | "version": "3.8.10" 464 | } 465 | }, 466 | "nbformat": 4, 467 | "nbformat_minor": 5 468 | } 469 | -------------------------------------------------------------------------------- /jupyter/examples/tutorial/00_Jupyter Lab/basics.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "agricultural-security", 6 | "metadata": {}, 7 | "source": [ 8 | "# very first steps in Jupyter Lab\n", 9 | "\n", 10 | "In Jupyter there are at least two different field: Markdown and Code" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": 1, 16 | "id": "entire-lotus", 17 | "metadata": {}, 18 | "outputs": [ 19 | { 20 | "name": "stdout", 21 | "output_type": "stream", 22 | "text": [ 23 | "Hello World!\n" 24 | ] 25 | } 26 | ], 27 | "source": [ 28 | "#this is a code cell which can be executed\n", 29 | "print(\"Hello World!\")" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "id": "dated-encoding", 35 | "metadata": {}, 36 | "source": [ 37 | "One can do all the documentation within a Jupyter Notebook. It is also possible to use LaTex for formating $\\frac{1}{2}=0.5$ " 38 | ] 39 | }, 40 | { 41 | "attachments": { 42 | "e13370bd-811d-4e3e-a5a1-0b930e55dd31.png": { 43 | "image/png": "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" 44 | } 45 | }, 46 | "cell_type": "markdown", 47 | "id": "answering-greek", 48 | "metadata": {}, 49 | "source": [ 50 | "![image.png](attachment:e13370bd-811d-4e3e-a5a1-0b930e55dd31.png)\n", 51 | "Or paste some images" 52 | ] 53 | }, 54 | { 55 | "cell_type": "markdown", 56 | "id": "novel-representative", 57 | "metadata": {}, 58 | "source": [ 59 | "The images will be stores within the .ipynb file" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": null, 65 | "id": "entertaining-abortion", 66 | "metadata": {}, 67 | "outputs": [], 68 | "source": [] 69 | } 70 | ], 71 | "metadata": { 72 | "kernelspec": { 73 | "display_name": "Python 3", 74 | "language": "python", 75 | "name": "python3" 76 | }, 77 | "language_info": { 78 | "codemirror_mode": { 79 | "name": "ipython", 80 | "version": 3 81 | }, 82 | "file_extension": ".py", 83 | "mimetype": "text/x-python", 84 | "name": "python", 85 | "nbconvert_exporter": "python", 86 | "pygments_lexer": "ipython3", 87 | "version": "3.8.10" 88 | } 89 | }, 90 | "nbformat": 4, 91 | "nbformat_minor": 5 92 | } 93 | --------------------------------------------------------------------------------