diff --git a/README.md b/README.md index 7620ed9..ec47111 100755 --- a/README.md +++ b/README.md @@ -4,11 +4,13 @@ ## Magnetic Environment Simulator for CubeSats -SOP can be found [here](http://psu-epl.github.io/doc/equip/testing/ETL/) at the Electronics Prototyping Lab website +![helmholtz_cage](https://github.com/user-attachments/assets/6658f6dd-697b-4fe9-8dbe-10519ecca47b) -![alt text](https://user-images.githubusercontent.com/33878769/48651456-dfe9f300-e9af-11e8-9a90-02227cccc314.jpg) -MCECS BETA Project 2018 +Oresat Helmholtz is an open-source and DIY Helmholtz cage controller for magnetic +field simulations. Developed for the Oresat project, this repo hosts a software designed to +facilite the operation of the Helmholtz cage and execute dynamics testing for B-Field related +CubeSat attitude controls. ## To Set Up Run: `python -m venv .venv` @@ -19,6 +21,23 @@ MCECS BETA Project 2018 `source .venv/bin/activate` `python3 main.py -l '1-1.2.2' -s '1-1.2.3'` +## Sphinx Documenation +A convienient way to view the documentation for this project is provided through the Sphinx +documentation framework. In order to use the Sphinx documentation you must first install the +library as well as the markdown extension, `myst-parser`. See installation instructions [here](https://www.sphinx-doc.org/en/master/usage/installation.html). +Once installed, you may compile and view the docs using the prodecure below, +1. Enter the docs location and build the HTML file. +``` +$ cd docs +$ make html +``` +If you get errors from `myst-parser`, just run `make html` twice. + +2. Open the index page using your browser of choice. Either navigate to `docs/_build/html/index.html` graphically and open the file, or via the command line. eg. with firefox +``` +$ firefox file:./_build/html/index.html +``` + ## Detecting ports for the buck converters and arduino on linux 1. ls -la /sys/bus/usb/devices (to view all ports) 2. Crosscheck what comes up before and after plugging in the cagebox diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..d4bb2cb --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/SOP.md b/docs/SOP.md index ce9ae1d..baa0336 100755 --- a/docs/SOP.md +++ b/docs/SOP.md @@ -2,9 +2,23 @@ # OreSat Helmholtz Cage: Standard Operating Procedure +This Standard Operating Procedure contains information about safely operating the cage to avoid +potential injuries to the operator, and to avoid damaging the Helmholtz cage components. This is +the place to start if you're hoping to run some simulations, test the cage operation, or simply +learn about how the cage is operated. + + ## General Notes: -* Operate the cage with 4.92 max amps and 15.20 max volts to output the largest magnetic field vector. +### Maximum Operating Range! +In order to maintain operation of coil components, the Helmholtz cage operator must ensure +that commands they issue to the cage do not exceed these limits. +* Maximum Voltage across a single coil must not exceed 10V +* Maximum current through a single coil must not exceed 1 Amp at 10V for a 10W maximum. +* Hardware components must not exceed their maximum operating temperatures. See Safety for details. + + +### Analytical Field Control Model * Theoretical magnetic field vector equation: ![alt text](https://user-images.githubusercontent.com/33878769/50580148-2381aa80-0e00-11e9-8fdd-0a406a66f1ba.png) * Bz is the total field produced by both square coils as a function of the axial distance z from the center of the coils @@ -13,52 +27,88 @@ * I is the current of the wire being analyzed: user input * h is the distance between the coils: * a is one half the side length of the structure: - -**Do not operate the Helmholtz Cage if the vacuum chamber is on!** --- ## Safety: * The red coils will get hot if operated for an extended period of time at high currents. Do not touch or hold the coils when operating the cage. -* Monitor the temperature of the wires to maintain a safe operating temperature below 140°C. +* Monitor the temperature of the H-Bridges and wires to maintain a safe operating temperature below 140°C. * Monitor the temperature of the main power supply to operate between -25°C to 70°C. * If the temperature begins to approach the operating limits, turn off the power supply and let the cage cool down before resuming testing. -**Do not operate the Helmholtz Cage if the vacuum chamber is on!** - --- ## Prepping the Cage: -1. It is safe to put electronic devices inside and around the cage. However, they may disrupt the magnetic field and cause discrepancies in testing data. Be mindful of this and be aware of the testing space surroundings. -2. Verify that the vacuum chamber is NOT on. -3. Verify that the coils are secured in the terminal blocks and make sure they are connected to the correct terminals/power supply. No exposed or crossing wires! -4. Turn on the surge protector. This will power the raspberry pi, monitor, power supplies, and cage. -5. Let the raspberry pi boot up. -6. Turn the keyboard and the mouse on. There are spare batteries in the tote just in case. +1. It is *generally* safe to put electronic devices inside and around the cage. However, they may disrupt the magnetic field or magnetometer readings and cause discrepancies in testing data. Be mindful of this and be aware of the testing space surroundings. +2. Verify that the coils are secured in the terminal blocks and make sure they are connected to the correct terminals/power supply, see labels. No exposed or crossing wires! +3. Turn on the surge protector. This will power the raspberry pi, monitor, power supplies, magnetometer, and Arduino. +4. Turn on the Magnetometer by rotating the power knob to the 'On' position. +5. Let the Raspberry Pi boot up and power on the keyboard to operate the command line. --- ## Operating the Cage Program: -TBD +The Helmholtz command line program boots into a manual control mode in which you have complete +control of the power supply, H-Bridges, and Magnetometer data. It is your responsibility as an +operator to comply with the safety protocols and ensure that the maximum operating range is +NOT EXCEEDED. Broken components are a total bummer and you don't want to have to be that guy. +Refer to the General Notes and Safety sections of the SOP to get familiar. + +### Starting the Program +Now if you've just booted up the Rasberry Pi you'll have to launch the command line utility +using the python compiler. Here is how you do that: +1. Enter the oresat-helmholtz directory where the program is stored +``` +$ cd ~/oresat-helmholtz +``` +2. Run the python script which initializes the cage control modules. This requires that we provide +the USB bus locations of the Arduino nano and the Magnetometer. If nothing has been tampered with +these should be `1-1.2.2` and `1-1.2.3` for the Arduino and Magnetometer respectively. +The command for starting the program would then be: +``` +$ python3 main.py -l '1-1.2.2' -s '1-1.2.3' +``` +**Note: If you are using your own laptop to control the cage, or these bus locations provoke an +error, please see "Connecting to the Cage Manually"** + +Once the script has started you can view the various commands available using the `help` command. +![helmholtz_help](https://github.com/user-attachments/assets/d9d7023a-c39e-4fea-ba2e-20a3f53f1c34) + +### Using the `set_field` command + +For a quick test to see that things are operational you might begin with the `set_field` command. +This allows you to provide a target vector which the cage will attempt to produce approximately. +For instance, try: +``` +> set_field 0 0 0 +Setting magnetic field to target vector : 0, 0, 0 +``` +This will attempt to produce zero field at the location of the magnetometer by cancelling out the +earths magnetic field in the cage. Without calibration this result will be quite inaccurate, but +you should see a change in the magnetometer readings. + +**Important: In order to exit the program please use the `exit` command as this will disable the cage for you. Otherwise, some power supplies may remain active!** --- ## Testing & Analyzing Data: -TBD +This feature is yet to be implemented, but is intended to describe the open loop control of the +cage which allow for dynamic orbital simulations to be run, as well as the calibration features +of the cage control program. --- ## While the Helmholtz Cage is Running: * Do not leave the cage unattended. You must monitor it constantly in case of a fire, to maintain safe temperatures for components, and to ensure accurate data collection. * When the cage is running, do not touch or hold the red coils! They get hot and can cause injury/burns. -* Turn off the surge protector to turn the cage of for any reason. +* Turn off the surge protector to turn the cage off for any reason. --- ## Finishing Up: -1. Once testing is completed, turn off the raspberry pi using the desktop menu. +1. Once testing is completed, turn off the Raspberry Pi by issueing the `shutdown` through the console 2. Wait for the raspberry pi to shutdown completely. -3. Turn off the keyboard and mouse!! Don’t waste the batteries! +3. Turn off the keyboard!! Don’t waste the batteries! 4. Flip off the surge protector to power down the power supplies, monitor, and cage. 5. If you adjusted the coil placement, wait until the red wire is cool to the touch before returning the coils to their originally labelled terminals. 6. Clean up after yourself and keep the workstation organized! diff --git a/docs/arduino.md b/docs/arduino.md new file mode 100644 index 0000000..42daecb --- /dev/null +++ b/docs/arduino.md @@ -0,0 +1,126 @@ +# Arduino Module + +The Helmholtz Cage uses an Arduino Nano to control and monitor a set of three H-Bridge drivers +which determine the direction of current through each Helmholtz coil. These functions issue +commands which are sent to a script stored on the Arudino Nano over the serial bus. + + +--- +## `set_positive_X() -> str` +Arguments: None + +Return: +* `msg` : response from the Arduino over the serial bus + +Sends a char `'x'` over the serial bus to the Arduino, setting the X-Axis to +the positive polarity. + +--- +## `set_positive_Y() -> str` +Arguments: None + +Return: +* `msg` : response from the Arduino over the serial bus + +Sends a char `'y'` over the serial bus to the Arduino, setting the Y-Axis to +the positive polarity. + +--- +## `set_positive_Z() -> str` +Arguments: None + +Return: +* `msg` : response from the Arduino over the serial bus + +Sends a char `'z'` over the serial bus to the Arduino, setting the Z-Axis to +the positive polarity. + +--- +## `set_negative_X() -> str` +Arguments: None + +Return: +* `msg` : response from the Arduino over the serial bus + +Sends a char `'X'` over the serial bus to the Arduino, setting the X-Axis to +the negative polarity. + +--- +## `set_negative_Y() -> str` +Arguments: None + +Return: +* `msg` : response from the Arduino over the serial bus + +Sends a char `'Y'` over the serial bus to the Arduino, setting the Y-Axis to +the negative polarity. + +--- +## `set_negative_Z() -> str` +Arguments: None + +Return: +* `msg` : response from the Arduino over the serial bus + +Sends a char `'Z'` over the serial bus to the Arduino, setting the Z-Axis to +the negative polarity. + +--- +## `deactivate_X() -> str` +Arguments: None + +Return: +* `msg` : response from the Arduino over the serial bus + +Sends a char `'b'` over the serial bus to the Arduino, setting the X-Axis to +a high-impedence or 'off' state. + +--- +## `deactivate_Y() -> str` +Arguments: None + +Return: +* `msg` : response from the Arduino over the serial bus + +Sends a char `'c'` over the serial bus to the Arduino, setting the Y-Axis to +a high-impedence or 'off' state. + +--- +## `deactivate_Z() -> str` +Arguments: None + +Return: +* `msg` : response from the Arduino over the serial bus + +Sends a char `'d'` over the serial bus to the Arduino, setting the Z-Axis to +a high-impedence or 'off' state. + +--- +## `deactivate_all() -> str` +Arguments: None + +Return: +* `msg` : response from the Arduino over the serial bus + +Sends a char `'a'` over the serial bus to the Arduino, setting all axes to +a high-impedence or 'off' state. + +--- +## `get_bridge_status() -> str` +Arguments: None + +Return: +* string formatted `"XYZ"` : each position can be {0, 1, 2} see table and example below. + +| Value | Status | +| ----- | ------ | +| 0 | `OFF` | +| 1 | `+` | +| 2 | `-` | + +Example string : "012" \ +This indicates that X is deactivated, Y is in positive polarity, and Z is negative polarity. + + +Sends a char `'s'` over the serial bus to the Arduino, prompting the Arduino to send the +H-Bridge status signal. diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..a6b2141 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,27 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = 'Oresat Helmholtz' +copyright = '2024, Oresat' +author = 'Oresat' + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = ["myst_parser"] + +templates_path = ['_templates'] +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + + + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = 'alabaster' +html_static_path = ['_static'] diff --git a/docs/hshell.md b/docs/hshell.md new file mode 100644 index 0000000..8bfd999 --- /dev/null +++ b/docs/hshell.md @@ -0,0 +1,299 @@ +# Helmholtz Shell + +The Helmholtz Shell acts as an interface for the Helmholtz cage operator to issue commands +and control the system through the command line. This facilitates the interactive command line +environment using Python's cmd module. See their docs for more. The operator may manually control +the cage via calls to the Arduino, Magnetometer, and Power supplies, or by initiating simulations +and calibration methods using the various tools provided in the utilites module. + +--- +## Power supply controls: + +--- +### `do_model(arg)` +Arguments: +* `device_name` : char `'X'`, `'Y'`, or `'Z'` indicating axis + +Return: None + +Provides a command to call 'model()' from the ZXY6005s module + +--- +### `do_firmware(arg)` +Arguments: +* `device_name` : char `'X'`, `'Y'`, or `'Z'` indicating axis + +Return: None + +Provides a command to call 'firmware_version()' from the ZXY6005s module + +--- +### `do_power(arg)` +Arguments: +* `device_name` : char `'X'`, `'Y'`, or `'Z'` indicating axis +* `value` : integer `0` or `1` for `OFF` or `ON` respectively + +Return: None + +Provides a command to call 'set_output()' from the ZXY6005s module + +--- +### `do_amp_hour(arg)` +Arguments: +* `device_name` : char `'X'`, `'Y'`, or `'Z'` indicating axis +* `value` : unsigned integer value in mAh + +Return: None + +Provides a command to call 'set_amp_hour()' from the ZXY6005s module + +--- +### `do_return_amp_hour(arg)` +Arguments: +* `device_name` : char `'X'`, `'Y'`, or `'Z'` indicating axis + +Return: None + +Provides a command to call 'return_amp_hour()' from the ZXY6005s module + +--- +### `do_voltage(arg)` +Arguments: +* `device_name` : char `'X'`, `'Y'`, or `'Z'` indicating axis +* `value` : unsigned integer value in mV + +Return: None + +Provides a command to call 'set_voltage()' from the ZXY6005s module + +--- +### `do_return_voltage(arg)` +Arguments: +* `device_name` : char `'X'`, `'Y'`, or `'Z'` indicating axis + +Return: None + +Provides a command to call 'return_voltage()' from the ZXY6005s module + +--- +### `do_current_limit(arg)` +Arguments: +* `device_name` : char `'X'`, `'Y'`, or `'Z'` indicating axis +* `value` : unsigned integer value in mA + +Return: None + +Provides a command to call 'set_current_limit()' from the ZXY6005s module + +--- +### `do_return_current(arg)` +Arguments: +* `device_name` : char `'X'`, `'Y'`, or `'Z'` indicating axis + +Return: None + +Provides a command to call 'return_current_limit()' from the ZXY6005s module + +--- +### `do_return_mode(arg)` +Arguments: +* `device_name` : char `'X'`, `'Y'`, or `'Z'` indicating axis + +Return: None + +Provides a command to call 'return_mode()' from the ZXY6005s module + +--- +### `do_return_temp(arg)` +Arguments: +* `device_name` : char `'X'`, `'Y'`, or `'Z'` indicating axis + +Return: None + +Provides a command to call 'return_temp()' from the ZXY6005s module + +--- +## Arduino (H-Bridge) controls: + +--- +### `do_set_positive_X(arg)` +Arguments: None + +Return: None + +Provides a command to call `set_positive_X()` from the Arduino module. Response from the +Arduino is printed to the command line. + +--- +### `do_set_positive_Y(arg)` +Arguments: None + +Return: None + +Provides a command to call `set_positive_Y()` from the Arduino module. Response from the +Arduino is printed to the command line. + +--- +### `do_set_positive_Z(arg)` +Arguments: None + +Return: None + +Provides a command to call `set_positive_Z()` from the Arduino module. Response from the +Arduino is printed to the command line. + +--- +### `do_set_negative_X(arg)` +Arguments: None + +Return: None + +Provides a command to call `set_negative_X()` from the Arduino module. Response from the +Arduino is printed to the command line. + +--- +### `do_set_negative_Y(arg)` +Arguments: None + +Return: None + +Provides a command to call `set_negative_Y()` from the Arduino module. Response from the +Arduino is printed to the command line. + +--- +### `do_set_negative_Z(arg)` +Arguments: None + +Return: None + +Provides a command to call `set_negative_Z()` from the Arduino module. Response from the +Arduino is printed to the command line. + +--- +### `do_deactivate_X(arg)` +Arguments: None + +Return: None + +Provides a command to call `deactivate_X()` from the Arduino module. Response from the +Arduino is printed to the command line. + +--- +### `do_deactivate_Y(arg)` +Arguments: None + +Return: None + +Provides a command to call `deactivate_Y()` from the Arduino module. Response from the +Arduino is printed to the command line. + +--- +### `do_deactivate_Z(arg)` +Arguments: None + +Return: None + +Provides a command to call `deactivate_Z()` from the Arduino module. Response from the +Arduino is printed to the command line. + +--- +### `do_deactivate_all(arg)` +Arguments: None + +Return: None + +Provides a command to call `deactivate_all()` from the Arduino module. Response from the +Arduino is printed to the command line. + +--- +### `do_bridge_status(arg)` +Arguments: None + +Return: None + +Provides a command to call `get_bridge_status()` from the Arduino module. Response from the +Arduino is printed to the command line. + +--- +## Magnetometer Commands + +--- +### `do_meter_properties(arg)` +Arguments: None + +Return: None + +Provides a command to call `meter_properties()` from the Magnetometer module. Response from the +Arduino is printed to the command line. + +--- +### `do_meter_values(arg)` +Arguments: None + +Return: None + +Provides a command to call `meter_value_settings()` from the Magnetometer module. Response from the +Arduino is printed to the command line. + +--- +### `do_var_tag(arg)` +Arguments: None + +Return: None + +Provides a command to call `var_adc_settings()` from the Magnetometer module. Response from the +Arduino is printed to the command line. + +--- +### `do_stream(arg)` +Arguments: None + +Return: None + +Provides a command to call `stream_data()` from the Magnetometer module. Response from the +Arduino is printed to the command line. + +--- +## Utilites Commands: + +--- +### `do_calibration(arg)` +Arguments: None + +Return: None + +Provides a command to call `calibration()` from the Utilities module. + +--- +### `do_average(arg)` +Arguments: None + +Return: None + +Provides a command to call `reading_average()` from the Utilities module. + +--- +### `do_set_field(arg)` +Arguments: +* `X_mag` : desired magnetic field component in the X-axis coil +* `Y_mag` : desired magnetic field component in the Y-axis coil +* `Z_mag` : desired magnetic field component in the Z-axis coil +Must provide 3 arguments separated by spaces, e.g: set_field 10 10 10 + +Return: None + +Provides a command to call 'set_field_vector()` from the Utilities module, and parses +command line arguments which are sent as a list. + +Return: None + +Provides a command to call `calibration()` from the Utilities module. + +--- +### `do_exit(arg)` +Arguments: None + +Return: None + +Powers off all power supply units and terminates the program. + diff --git a/docs/index.md b/docs/index.md deleted file mode 100755 index 8b13789..0000000 --- a/docs/index.md +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..6dc290a --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,19 @@ +.. Oresat Helmholtz documentation master file, created by + sphinx-quickstart on Fri Sep 20 14:10:44 2024. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Oresat Helmholtz documentation +============================== +Oresat Helmholtz is magnetic field environment simulator used for testing Oresat's attitude control systems! These documents serve as a manpage for those working on the Helmholtz Cage and as a reference guide for those using the device for dynamic orbit simulation. +For detailed information about operation and safety procedures please refer to the Standard Operating Procedure section. +If you're a developer looking for details of the Helmholtz cage command line refer to the manpages. + + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + Standard Operating Procedure + Manpages + diff --git a/docs/magmeter.md b/docs/magmeter.md new file mode 100644 index 0000000..8007770 --- /dev/null +++ b/docs/magmeter.md @@ -0,0 +1,126 @@ +# Magnetometer Module +The magnetometer module facilitates serial communication between the Raspberry Pi and the +magnetometer. This module includes functions which can be used to request, read, and parse +magnetometer readings and settings. + +--- +## `proto_read_chunk()` +Arguments: None + +Return: +* `data` : bytearray of 20 bytes + +Reads a single chunk (20 bytes) from the serial port. + +--- +## `send_command(command, extra_bytes = None)` +Arguments: +* `command` : a predefined command byte according to the magnetometer documentation +* `extra_bytes` : optional bytes to provide a buffer at the end of the command signal + +Return: None + +This is a helper function used to communicate with the magnetometer. + +--- +## `acknowledgement()` +Arguments: None + +Return: None + +Sends an `ack` command to the magnetometer. This is a helper function to be called at the end +of a transmission to the magnetometer. + +--- +## `handle_meter_response()` +Arguments: None + +Return: None + +This function reads a response from the magnetometer and prints the decoded message to the +console. + +--- +## `parse_meter_response(response)` +Arguments: None + +Return: None + +Reads a response from the meter as a string and creates a list of data points, which is +printed to the console. + +--- +## `read_stream_data()` +Arguments: None + +Return: +* `chunk` : list of four data points returned by the magnetometer, stored in a dictionary +Each element in the return chunk has a dictionary structure returned by `parse_data_point()`. +See the `parse_data_point()` section of this document for more details. + +Each chunk is gathered during a single transmission provided by the magnetometer, typically of the +form `[