AeroShield
Before we start, it should be noted that you won’t need to use the AeroShield class directly for most purposes. Often, it will be more convenient to use the AeroController class. AeroShield takes care of communication with the Arduino, but doesn’t implement anything else that would be needed for a controller, e.g. a configurable time step, logging the data, … All of this is available in the AeroController (See the AeroController example). If you’re sure you need to use the AeroShield class, read on.
First, we import the AeroShield class from the aeroshield package.
1from aeroshield import AeroShield
Using the with Context Manager
AeroShield supports the with context manager, which takes care of opening and closing the serial connection, calibrating the angle reading at the start and making sure the fan is stopped at the end. Using the context manager is preferred, since it guarantees the fan will stop, even if an error occurs at some point. In the code block below, the motor power is controlled by the value of the potentiometer on the shield.
1with AeroShield() as aero_shield:
2 # make an initial write to the arduino so it will send something back we can act on.
3 aero_shield.write(flag=aero_shield.RUN, motor=0)
4
5 for _ in range(1000):
6 # read state
7 pot, angle = aero_shield.read()
8
9 # act on state
10 motor = pot
11
12 # write motor input
13 aero_shield.write(flag=aero_shield.RUN, motor=motor)
Let’s break down what happens here:
We create an instance of
AeroShield, which we callaero_shield. The context manager will also calibrate the angle measurement. Calibration is done by reading and storing the measurement value at the start of the experiment. This means the pendulum should be at rest before starting an experiment.We write to the shield once before we enter the
forloop. Why do we do this? The communication with the Arduino is set up such that when it gets an input from the computer, it will return the state of the device once, and wait for a new input before it sends the state again. That initial write to the Arduino ensures that we can read the state at the start of our loop.We loop 1000 times through reading the Aeroshield and writing a command to the Aeroshield. It’s important to note that the frequency of the loop is not in any way controlled in this script. If you need a fixed time step, you need to implement that yourself, or use the
AeroController, which does that for you.We read the state of the Aeroshield. The return of
readis the potentiomenter value [%] and the angle measurement [°].We do something with the state. This is where you would implement any control algorithm. In the example, we simply set the motor value equal to the potentiometer.
We write the motor value to the Arduino. The
flagparameter takes eitherAeroShield.RUN, as is the case here, orAeroShield.STOP. UseRUNduring your experiment. TheSTOPflag will stop the fan, regardless of the motor value given.When the for loop is finished, the context manager exits, ensuring that the fan is stopped and the serial connection is closed.
The runtime of this script is dependent on your system and the specific Arduino, but the frequency has been recorded to get close to 1 kHz.
AeroShield without the Context Manager
If you don’t want to or can’t use the context manager, the script below does the same thing as the one above, without the context manager. The first three commands create an AeroShield instance, open the connection and calibrate the angle measurement. This was all done by the context manager in the above example. The loop is identical. At the end, the stop method sends the AeroShield.STOP flag to the Arduino, stopping the fan. The close method closes the serial connection.
1aero_shield = AeroShield()
2
3# Open the serial connection
4aero_shield.open()
5# Calibrate the pendulum angle at rest
6aero_shield.calibrate()
7
8aero_shield.write(flag=aero_shield.RUN, motor=0)
9
10for _ in range(1000):
11 # read state
12 pot, angle = aero_shield.read()
13
14 # act on state
15 motor = pot
16
17 # write motor input
18 aero_shield.write(flag=aero_shield.RUN, motor=motor)
19
20# Tell the Arduino to stop the fan
21aero_shield.stop()
22# Close the serial connection
23aero_shield.close()
Manually Setting the Port
In most cases, the AeroShield class will find which port the Arduino is connected to. It will raise an exception when it fails to do so. When that happens, you need to find out the port using your operating system’s tools and provide like so:
1aero_shield = AeroShield(port="COM1")