Software Development
Using Rust
Nicholas helped our group handle the software for our project as he is the strongest coder out of all of us. He chose to use Rust as the programming language. Rust’s hardware abstraction layer (HAL) made it easier to work with the board by reducing the need to manipulate raw bits in the microcontroller’s registers, which would have been challenging and time-consuming otherwise.
Using Rust with the Arduino Mega brought its own set of challenges since we couldn’t access the standard Arduino libraries written in C++. The HAL provided only some essential features, so he had to develop many of the basic functionalities himself. For example, the HAL allowed for standard operations like setting pin modes and reading or writing pin data. It also supported advanced features like Universal Synchronous/Asynchronous Receiver/Transmitter (USART). USART was essential for our project, as Nicholas relied on it for serial communication with between the microcontroller, computer and Bluetooth module.
The HAL included a simple version of Arduino’s analogWrite
function, called simple_pwm
(simple pulse-width modulation), but it lacked many essential abstractions, such as Arduino’s Serial
library and the millis
function for timers. Although Nicholas had access to a delay
function, he still had to implement other timers, including custom versions of the millis
, micros
, and Serial
functions. Without the Serial
library, he wouldn’t have been able to print output to the computer for debugging.
Finally, the stepper motor driver library typically available through the Arduino IDE wasn’t accessible in Rust, so Nicholas rewrote it from scratch. This process required a deep dive into the Rust language and the board-specific constraints, which was challenging yet rewarding as it improved his proficiency in Rust.
Programming acceleration for the stepper motors
Acceleration for stepper motors is calculated using a stepping mathematical function, where the graph of this function rises in distinct steps, mirroring the way stepper motors operate. The mathematics involved in this calculation includes various equations that detail how the acceleration is applied. The math details can be found here: https://web.archive.org/web/20140705143928/http://fab.cba.mit.edu/classes/MIT/961.09/projects/i0/Stepper_Motor_Speed_Profile.pdf
The process essentially involves converting constant acceleration into speed ramps that the stepper motor can utilize. This transformation is necessary because adjusting the input current to a stepper motor does not directly change its speed; the motor operates based on a pin and a delay to move one step at a time. Therefore, to achieve an increase in speed, the stepping frequency must be increased, allowing the motor to step faster.
Joystick app
The joystick functions by taking a coordinate from its x and y axes, starting from the origin point (0, 0). The maximum values for both axes are set at 300. The code for handling the joystick identifies its center position, which is where it remains inactive. For this joystick, the center is defined as (150, 150).
When a user moves the joystick, the system captures the new x and y coordinates, performing a calculation by subtracting the center coordinates from the current position. For instance, if the new coordinates are (200, 200), the calculation results in (50, 50).
Here, the x-coordinate indicates the difference in motor speed between the left and right sides, while the y-coordinate represents the raw motor speed. Positive or negative values determine the direction: a positive x value signals a turn to the right since standard coordinates have positive values extending to the right, and a positive y value indicates forward movement.
To turn right, the left motor’s speed must be higher than that of the right motor. This relates to fixed angular velocity and varying distances from the circle’s center, leading to different velocities. For example, if the right motor speed calculation yields 50 – 50 = 0, the right motor remains inactive while the left motor runs to facilitate the turn.
The motors will be operated for a set time, approximately 0.5 seconds, to ensure movement at the desired speed. Since stepper motors do not run continuously, they require a specified number of steps to execute movement. The formula used to calculate this is speed multiplied by time, providing the total number of steps needed for the movement.
While we were successful in implementing this code, it unfortunately did not work for our setup. Our car is excessively long and heavy, making it impractical to utilize this steering method. We could experiment using servo motors in the future, to allow our car to turn. Nonetheless, we still achieved our primary objective to lay cones in a straight line.
Cone Laying
Laying the cones involves straightforward calculations. First, the user inputs the number of cones needed and the distance between cone. Next, the code calculates the total distance, including a buffer, and converts this distance into the number of steps required for the stepper motor to move.
A loop is used to move the cone layer forward, pausing to lay each cone before continuing. As long as there are cones to be laid, the steps are as follows:
1. Move the cone layer forward by the specified distance between cones.
2. Stop the wheel motors.
3. Drop the cone by turning the dispenser motor by 1 revolution
4. Repeat the process.
The phone app is designed with simplicity in mind, focusing solely on functionality. Its primary role is to send commands to the Arduino, which handles all the complex processing. The app incorporates the Bluetooth library to establish a connection with the Bluetooth module on the Arduino, while the remainder consists of the user interface.
Creating the user interface involved adding buttons and a joystick for controlling the cone layer. In fact, 90% of the app’s development was dedicated to the UI, which was crafted entirely by Nicholas without the use of any external UI libraries.
For the joystick component, he utilized and modified a reference from KorSoftwareSolutions’ React Native Joystick to meet specific requirements. The entire interface was custom-built using React Native, ensuring cross-platform compatibility for both iOS and Android devices.