# Output devices

## Brushless motors
For this week I am going to focus on brushless motors and electronic speed controllers. I need to control 4 of them at the same time for my final project. For the group assignment I wanted to get my brushless motor working quickly so we could measure it for the group assignment. I already got it working one time but I had trouble getting it working again because it was a long time ago.

![alt text](image-4.jpg)

During that time I used this code

??? Code
        ```cpp
        const int escpin = 21;
        const int potPin = 4;
        // LEDC channel and timer configuration
        const int ledcChannel = 0;
        const int ledcTimer = 0;
        const int pwmFreq = 50;        // 50Hz frequency (20ms period)
        const int pwmResolution = 16;  // 16-bit resolution

        // Pulse widths (in microseconds) for min and max throttle
        const int minPulseWidth = 1100;  // 1ms for min throttle
        const int maxPulseWidth = 1940;  // 2ms for max throttle

        int incomingByte = 0;

        // Function to convert pulse width to LEDC duty cycle
        int pulseWidthToDutyCycle(int pulseWidth) {
        int maxDuty = (1 << pwmResolution) - 1;
        return (pulseWidth * maxDuty) / 20000;  // Convert to 16-bit duty cycle
        }

        void setup() {
        Serial.begin(115200);

        // Set up the PWM signal on the ledcChannel
        ledcAttach(ledcChannel, pwmFreq, pwmResolution);

        // Start the ESC calibration sequence
        Serial.println("Starting ESC...");

        // Step 2: Send minimum throttle (1ms pulse width)
        Serial.println("Setting min throttle...");
        ledcWrite(ledcChannel, pulseWidthToDutyCycle(minPulseWidth));

        // At this point, the ESC should be calibrated
        Serial.println("ESC calibration complete.");
        delay(2000);
        }

        void loop() {
        int potVal = analogRead(potPin);
        int throttle = map(potVal, 0, 4095, minPulseWidth, maxPulseWidth);

        if (Serial.available() > 0) {
            // read the incoming byte:
            incomingByte = Serial.read();
        }
        //min 1100, max 1940
        if (incomingByte == 48) {
            ledcWrite(ledcChannel, pulseWidthToDutyCycle(1100));
            Serial.println("low");
        } else if (incomingByte == 49) {
            ledcWrite(ledcChannel, pulseWidthToDutyCycle(1940));
            Serial.println("high");
        }

        // Reset incomingByte after processing

        // Small delay to allow for serial input processing
        }
        ```
It has an automatic arming sequence when the MCU starts with the esc and motor. But there is one small problem. I couldn't get the motor armed using this script even though I set the escpin to the correct pin. After inspecting the code a bit more I realized that escpin wasn't used anywhere and ledcChannel was the actual pin where the PWM signal would get generated. After I changed ledcChannel to the correct pin the motor armed and I could start if by sending the MCU "1".

??? Correct code
        ```cpp
        const int potPin = 4;
        // LEDC channel and timer configuration
        const int ledcChannel = D2;
        const int ledcTimer = 0;
        const int pwmFreq = 50;        // 50Hz frequency (20ms period)
        const int pwmResolution = 16;  // 16-bit resolution

        // Pulse widths (in microseconds) for min and max throttle
        const int minPulseWidth = 1200;  // 1ms for min throttle
        const int maxPulseWidth = 1940;  // 2ms for max throttle

        int incomingByte = 0;

        // Function to convert pulse width to LEDC duty cycle
        int pulseWidthToDutyCycle(int pulseWidth) {
        int maxDuty = (1 << pwmResolution) - 1;
        return (pulseWidth * maxDuty) / 20000;  // Convert to 16-bit duty cycle
        }

        void setup() {
        Serial.begin(115200);
        // Set up the PWM signal on the escPin
        ledcAttach(ledcChannel, pwmFreq, pwmResolution);

        // Start the ESC calibration sequence
        Serial.println("Starting ESC...");

        // Step 2: Send minimum throttle (1ms pulse width)
        Serial.println("Setting min throttle...");
        ledcWrite(ledcChannel, pulseWidthToDutyCycle(minPulseWidth));

        // At this point, the ESC should be calibrated
        Serial.println("ESC calibration complete.");
        delay(2000);
        }

        void loop() {

        if (Serial.available() > 0) {
            // read the incoming byte:
            incomingByte = Serial.read();
        }
        //min 1100, max 1940
        if (incomingByte == 48) {
            ledcWrite(ledcChannel, pulseWidthToDutyCycle(1100));
            Serial.println("low");
        } else if (incomingByte == 49) {
            ledcWrite(ledcChannel, pulseWidthToDutyCycle(1940));
            Serial.println("high");
        }

        // Reset incomingByte after processing

        // Small delay to allow for serial input processing
        }
        ```

<video controls src="../../../Assignments/week_10_output_devices/video1.mp4" title="Title"></video>

In the loop section of the code is a method where it accepts serial communication back. Byte 49 represents ascii character 1 and byte 48 represents 0.

![alt text](image-5.jpg)
Source: https://commons.wikimedia.org/wiki/File:ASCII-Table-wide.svg

With the LedC library I can easily generate PWM signals that the electronic speed controllers can understand.

I also milled a pcb to test the motors with because signals on breadboards are super unreliable. It is super simple 4 pin headers for each motor and a header for the Inertial measurement unit (IMU).

![alt text](image-10.jpg)

![alt text](image-11.jpg)

## Group assignment
### BLDC motors
For this group assignment we needed to connect and measure an output device. We used my brushless motor as an example. We connected it to my power supply because it had an XT-60 connecter and the drone esc also had a XT-60 connector.

![alt text](image-6.jpg)

The motors and esc are rated up to 4S. What is 4S? 4S means the amount of li-po cells connected in series. When connecting them in series the voltage adds up. So 1S = 4.2V, 2S 8.4V, 3S 12.6V and 4S 16,8V. So they can take a maximum of 16,8 volts. We started off with 12 volts. When the motor needed to start it surged a lot of power and stabilized later on.
![alt text](image-7.jpg)
![alt text](image-8.jpg)
When touching the motor I created friction and thus it needs more current.
![alt text](image-9.jpg)
Here you can see it hit the maximum of the power supply (60watts). If it goes any higher than this the power supply will go into surge protection mode and shut down. But when running the motor it stays between 30 to 40 watts. So if I wanted to run all motors I needed about 120 watts. But I also need to be able to surge power so the motors can start so that will add an additional 40 watts. So I will need about 160 watts to power 4 motors. 

### Led strip
Henk also showed us the ledstrip with a program where the leds turn on one by one and the colors change.

![alt text](image-12.jpg)
![alt text](image-13.jpg)
Henk also changed the light to blue and there we could instantly see that the amount of current needed went up. So depending on the color light you may need more or less current.

### Power supply
Here are the files to build the PSU yourself. I don't recommend building it without making a top lid. Otherwise you will have a very hard time assembling it.
Link to PSU: https://git.smikkelbakje.nl/Smikkelbakje/Labvoeding


## Power
Right now I'm facing the issue of powering the motors. My power supply can't handle the current draw from my motors. So I needed something that could output a lot of power while staying stable. That's where li-po batteries luckily come in. I have a bit of experience with handling them. The maximum amount of voltage I can put on my motors is 6S but the Electronic speed controllers can only go up to 4S. So that's what I'm going for. For now I will keep trying to test with my current power supply.

