Main project in collaboration with John Deere for the undergrad course "System Design on Chip", which delves mainly into SoCs, Computer Architecture and Organization, Bare Metal Programming, Real-Time Operating Systems, and Embedded Linux.
It consists of a John Deere tractor driving simulator. The project uses SoCs to prototype the technologies integrated into a John Deere agricultural tractor. A matrix keypad represents the Steering and Braking of the vehicle, and a potentiometer represents the Throttle. The NUCLEO-F103RB development board with STM32F103RB MCU operates those values with a tractor engine automatic transmission controller model and displays the output on an LCD. Also, through the UART protocol, it is sent to a Raspberry Pi 3 Model B (with Raspberry Pi OS 64-bit, based on Debian), which carries out its graphing on a screen.
John Deere provided the files for a model of a tractor engine automatic transmission controller. This receives two input values, vehicle Throttle and Brake, and returns three output values, Engine speed, Vehicle Speed and Gear. Since a potentiometer represents the Throttle, the ADC on the NUCLEO-F103RB board is used to sense a variable voltage value which is then normalized to a range of 0 to 100 and fed to the model.
On the other hand, the matrix keypad is read by declaring the rows pins as outputs and the columns pins as pull-up inputs. Then, the row to be read is selected by setting the corresponding pin to ground and turning on the remaining pins. Thus, if a button in this row is pressed, an input will detect a logic 0 while the others remain at logic 1, so it is necessary to detect which of these has such a value to determine the column, and thus, the pressed button. If the pressed button is not found in such a row, then the procedure is repeated with the next row. In other words, it is a constant process of sweeping through rows and columns.
Once the model has processed this information, the output data is sent via the USART internal peripheral to the UART TX pin of the NUCLEO-F103RB board, which, like it will be reviewed later, is connected to the UART RX pin of the Raspberry Pi. It is also string formatted and written to the LCD. It is important to note that the TIM internal peripheral is programmed to provide the required delays to both the model and the LCD.
It should be noted that there are two modes of operation: manual and simulation. In the first one, the Throttle is determined by the potentiometer, and in the second one, with a value sent through the serial port by the Raspberry Pi. Button A on the matrix keyboard chooses the manual mode, while button B selects the simulation mode. In the latter, the input data is read via the UART RX pin of the NUCLEO-F103RB board which is connected to the UART TX pin of the Raspberry Pi.
The Raspberry Pi receives the output data from the model (engine speed, vehicle speed and gear) through the UART RX pin. Thus, using the serial library, the serial port containing the real-time values is read. These are written to a CSV file with the csv library and plotted with the Matplotlib library. A graphical interface was also realized via the Pygame library, which receives the graphs from Matplotlib in raw data format, converts them to surfaces, and can then draw them within the same game window.
To use the graphical interface, run game.py. It is possible to select between randomly generated or serially read data by uncommenting the desired functionality line and commenting the remaining one at the top of the file in the code imports section. To plot without a Pygame graphical interface, run plot_RPi.py, which uses serially read data.
In addition, a widget was created with the Tkinter library in which the user can stipulate a Throttle value by means of a slider. If the button corresponding to the simulation is pressed, the Throttle is transmitted over the UART TX pin with the help of the same library used to receive. To use it run widget.py.
In all serial interaction cases, modify plot_serial_settings.py to specify the serial port depending on your test environment, i.e, COMX for Windows or /dev/ttySX for Linux. The CSV files with the data (random or serial) will be stored in the Data folder. A script for testing a serial connection is uploaded. Once more, the serial port is modifiable within the plot_serial_settings.py, alongside the baud rate, which is by default 115200 to ensure compatibility with the NUCLEO-F103RB intern USART peripheral which operates at the same rate.
Finally, bash scripts were written to simplify the process of running the plotting and widget files. It ensures the current user has access to the serial interface and port, creates and activates a Python virtual environment, installs (if necessary) the required packages (Pygame, Matplotlib, Numpy, Pyserial), changes the directory to the location of the file, executes it and deactivates the virtual environment. Don't forget to run sudo raspi-config to enable the serial port.
To conclude the project, the Bare Metal code was refactored to add a Real-Time Operating System (RTOS), in this case, using the CMSIS_V1 API for FreeRTOS. The program was divided into tasks, for which an approximate execution time was measured. Then, based on the rate-monotonic scheduling (RMS) priority assignment algorithm, the priority of each task was determined and a feasibility analysis for such selection was performed.
The I2C internal peripheral was configured to communicate with a 128x64 OLED screen (although it is possible to use a 128x32 screen). Then, functions were developed so it would be possible to display images sending commands and data in the format of a buffer.
A TIM internal peripheral was used to generate a PWM signal and control a Micro Servo, simulating the movement of the tractor's steering wheel.














