# Embedded

# Getting Started

***This page:** *structure of this subsystem**

##### `<span class="editor-theme-code">components/driving_board</span>`<span style="white-space: pre-wrap;"> folder contains 4 libraries:</span>

- firmware
- motor
- parser
- simulink

**Firmware** <span style="color: rgb(68, 68, 68); background-color: rgb(255, 255, 255); white-space: pre-wrap;">contains the generated CubeMX code. </span><span style="color: rgb(68, 68, 68); background-color: rgb(251, 238, 184);">Don't edit this after generating, it will be rewritten after you generate again</span><span style="color: rgb(68, 68, 68); background-color: rgb(255, 255, 255);">.</span>

<p class="callout info"><span style="color: rgb(68, 68, 68);">NOTE: do make sure that after generating your code in CubeMX, you run the post generation script. You can set a post generation script in CubeMX itself. However, if you use Windows run: scripts/post\_code\_generation.bash, if you use Mac run: scripts/post\_code\_generation\_mac.bash</span></p>

<span style="color: rgb(68, 68, 68); white-space: pre-wrap;">The </span>**Simulink**<span style="color: rgb(68, 68, 68); white-space: pre-wrap;"> folder contains code generated by the control team, and it </span><span style="color: rgb(68, 68, 68); background-color: rgb(251, 238, 184); white-space: pre-wrap;">shouldn't be modified by embedded. </span><span style="color: rgb(68, 68, 68);">This code is not used on the embedded side, but it provides a clear reference for the type of input we give to control algorithm and the output we receive from it.</span>

<span style="color: rgb(68, 68, 68); white-space: pre-wrap;">In </span>`<span class="editor-theme-code">control.h</span>`<span style="color: rgb(68, 68, 68); white-space: pre-wrap;">, struct </span>`<span class="editor-theme-code">ExtY</span>`<span style="color: rgb(68, 68, 68); white-space: pre-wrap;"> gives the external outputs and </span>`<span class="editor-theme-code">ExtU</span>`<span style="color: rgb(68, 68, 68); white-space: pre-wrap;"> is the struct for external inputs. </span>

---

##### `<span class="editor-theme-code">src/driving_board</span>`<span style="white-space: pre-wrap;"> contains </span>`<span class="editor-theme-code">main.c</span>`

This is the code that runs when we build and update to the board by pio. Main includes multiple threads for some tasks that need to run concurrently.

---

##### `<span class="editor-theme-code">ERC-Protobufs/components/driving_board</span>`<span style="white-space: pre-wrap;"> contains protobuffers for this subsystem</span>

Protobuffers are used to send information to software and debugging board and receiving information from software.

# Motor Folder

##### `<span class="editor-theme-code">components/driving_board/motor</span>`<span style="white-space: pre-wrap;"> </span>

<span style="white-space: pre-wrap;">All of the motor functions in this folder are called in </span>[Main](https://bookstack.roboteamtwente.nl/books/drive-system/page/main "Main")

#### BLDC Motors:

They are used to control the speed of the rover.

##### `<span class="editor-theme-code">bldc.c</span>`<span style="white-space: pre-wrap;"> contains:</span>

<span style="white-space: pre-wrap;">The set\_bldc\_pwm() method. This methods scales the control signal value calculated from control code and adjust the pwm </span>**duty cycle**<span style="white-space: pre-wrap;"> outputted by the STM32 accordingly.</span>

#### Stepper Motors:

##### `<span class="editor-theme-code">stepper.c</span>`<span style="white-space: pre-wrap;"> contains:</span>

<span style="white-space: pre-wrap;">The set\_stepper\_pwm() method. This methods scales the control signal value calculated from control code and adjust the pwm </span>**frequency**<span style="white-space: pre-wrap;"> outputted by the STM32 accordingly.</span>

#### Encoders:

##### `<span class="editor-theme-code">read_encoder.c</span>`<span style="white-space: pre-wrap;"> contains:</span>

The read encoders() method. This method reads encoder values of **encoder angle, voltage generated** and **rpm.**

# Parser Folder

##### `<span class="editor-theme-code">components/driving_board/parser</span>`<span style="white-space: pre-wrap;"> </span>

**This page:**<span style="white-space: pre-wrap;"> structure of message encoding in parser.c </span>

#### <span style="white-space: pre-wrap;">The encoding logic includes: </span>

##### **copy\_motor\_to\_pb():**<span style="white-space: pre-wrap;"> </span>

<span style="white-space: pre-wrap;">Copies each motor from internal MotorDiagnostic struct into protobuf MotorInformation. </span>

##### **DBMDiagnosticsEncode():**<span style="white-space: pre-wrap;"> </span>

<span style="white-space: pre-wrap;">Encodes full diagnostics data into a protobuf message. </span>

<span style="white-space: pre-wrap;">This function: Initializes the protobuf message Copies board state Copies all 10 motors into the protobuf structure Calls pb\_message\_encode to serialize data </span>

**The diagnostics message contains 10 motors:**

<span style="white-space: pre-wrap;">front\_left, middle\_left, back\_left, front\_right, middle\_right, back\_right, steering\_front\_left, steering\_back\_left, steering\_front\_right, steering\_back\_right, </span>

<span style="white-space: pre-wrap;">Each motor is copied using a loop into the protobuf message. </span>

##### **message\_add\_envelope():**

<span style="white-space: pre-wrap;">This method wraps a protobuf message into a PBEnvelope using the same pb\_message\_encode function. </span>

It: Takes a populated protobuf message (e.g. DrivingBoardDiagnostics) Initializes a PBEnvelope Sets the correct oneof field (e.g. drive\_diag) Calls pb\_message\_encode on the envelope struct Returns encoded envelope buffer and length

# Main

#### **src/driving\_board/main.c** 

<span style="white-space: pre-wrap;">contains the main firmware entry point and runtime logic for the driving board. The system is built on FreeRTOS (CMSIS-RTOS v2) and runs multiple tasks concurrently. </span>

#### <span style="white-space: pre-wrap;">Initialization </span>

##### init\_board()

<span style="white-space: pre-wrap;">This function initializes the full system before starting the scheduler. </span>

<span style="white-space: pre-wrap;">It: </span>

- <span style="white-space: pre-wrap;">Configures MPU and cache </span>
- <span style="white-space: pre-wrap;">Initializes HAL and system clock </span>
- <span style="white-space: pre-wrap;">Initializes GPIO, timers, and UART logging </span>
- <span style="white-space: pre-wrap;">Initializes control algorithm (control\_initialize) </span>
- <span style="white-space: pre-wrap;">Initializes Ethernet and MAC filtering Creates FreeRTOS tasks Starts PWM and encoder peripherals </span>
- <span style="white-space: pre-wrap;">Starts the RTOS kernel. After this, the scheduler takes over. </span>

#### <span style="white-space: pre-wrap;">Tasks </span>

<span style="white-space: pre-wrap;">The system runs 3 main threads: </span>

##### <span style="white-space: pre-wrap;">MainTask </span>

<span style="white-space: pre-wrap;">This task handles: Ethernet communication Diagnostics message creation and sending Periodic data updates </span>

**Example Flow For Sending A Message:**

- <span style="white-space: pre-wrap;">Initialize UDP Fill DiagnosticsData using FillDiagnostics </span>
- Encode using DBMDiagnostics
- <span style="white-space: pre-wrap;">Encode Send encoded data over Ethernet </span>
- <span style="white-space: pre-wrap;">Free allocated memory after sending Also sends test UDP and raw Ethernet messages. </span>

##### <span style="white-space: pre-wrap;">PwmTask </span>

<span style="white-space: pre-wrap;">This task runs the control loop. </span>

<span style="white-space: pre-wrap;">It: </span>

- <span style="white-space: pre-wrap;">Calls control\_step() from control module(Simulink folder) </span>
- <span style="white-space: pre-wrap;">Reads outputs from rtY </span>
- <span style="white-space: pre-wrap;">Updates motor PWM using set\_bldc\_pwm Runs periodically (1 ms) </span>

##### <span style="white-space: pre-wrap;">DrivingEncoderTask </span>

<span style="white-space: pre-wrap;">This task processes encoder data. </span>

<span style="white-space: pre-wrap;">It: </span>

- <span style="white-space: pre-wrap;">Reads timer counters </span>
- <span style="white-space: pre-wrap;">Calculates: revolutions radians (position) rpm (speed) </span>
- <span style="white-space: pre-wrap;">Populates motor data (rpm, voltage, angle). </span>
- <span style="white-space: pre-wrap;">Updates global variables used in diagnostics </span>
- <span style="white-space: pre-wrap;">Runs every 100 ms </span>