---
# System prepended metadata

title: Week2_HW (4th July ~ 8th July)
tags: [2022 Summer, UCLA Biomimetic Research Lab]

---

Week2_HW (4th July ~ 8th July)
===
###### tags: `UCLA Biomimetic Research Lab`, `2022 Summer`
## Table of Contents

[TOC]

## DAY 1     
**1. What’s the original frequency of the sine wave in the example code?  Modify the code and change the sine wave to 1Hz. Please connect the DAC pin to the red LED to observe the change. (hint: you need to change the gptimer to 32bit mode)**
    

the original time base rate is 7680 and the buffer size is 128, so we get $$
    Frequency  = (7680 / 128) = 60 Hz
    $$Thus, if we modify time base rate to 128, we will get 1Hz. The LED flickers in 1 Hz. (Because of the bit extension, we dont even have to adjust gptimer to 32bit mode)
> PS : LED is not as bright as expected when using DAC control.
    
**2. Can you make the magnitude of the sine wave 2-times greater or 2-times smaller than the original output in the example code? There are multiple ways to do this. Briefly explain (or just realize this task in multiple ways if you wish).**

we write a funciton to magnitude the sine wave
```c++
uint8_t magnitude(uint8_t a){
    int32_t tmp = (a-128)*2 + 128;
    if(tmp > 0xFF){
        return 0xFF;
    }
    if(tmp < 0){
        return 0;
    }
    return tmp;
}
```
First use a 32bit signed integer `tmp` to compute 2-times of the sine value.  And make sure all the values are between 0 and 0xFF, which is the boundary of uint8. Via the observation of oscilloscope we know that the signal is like a square wave after adjustment.  However, LED is still not very bright.

**3. What kind of interrupt is registered to GPtimer? (hwi, swi, or task)**
hwi.
**4. Which GPIOs can operate as DAC pin?**
DIO25.
<br></br>
## DAY 2
**1.	In the example code, the LED blinks at a rate of once every 2 seconds. Can you make it blink at a rate of once every 1 seconds and every 4 seconds?**
```C++
/*
 * Setting up the timer in continuous callback mode that calls the callback
 * function every 1,000,000 microseconds, or 1 second.
 */
Timer_Params_init(&params);
params.period = 1000000;
params.periodUnits = Timer_PERIOD_US;
params.timerMode = Timer_CONTINUOUS_CALLBACK;
params.timerCallback = timerCallback;
```
Refer to the example code above, I think the LED blinks at a rate of once every second. We can adjust the frequency to `once every 2 seconds` and `once every 4 seconds` by modifying `parms.period` to `2000000`and `4000000`respectively.

**2. Can you make 2 LEDs blink at the same rate together?**
In the example code, it only control the red LED light. So, i add some code regarding GPIO settings to control the green LED light. 
```c
GPIO_setConfig(CONFIG_GPIO_LED_1, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
GPIO_write(CONFIG_GPIO_LED_1, CONFIG_GPIO_LED_OFF);
```
![](https://i.imgur.com/6X42S6S.png)

Then toggle the LED light at TimerCallBack function, and it worked as expected.

**3.	What kind of interrupt is registered to timer? (hwi, swi, or task)**
hwi.
<br></br>
## DAY 3
**RTOS Task 1**
Blinky
<div style="padding:75% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/728335459?h=ebcd35eb67&amp;badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen style="position:absolute;top:0;left:0;width:100%;height:100%;" title="video-1657343622.mp4"></iframe></div><script src="https://player.vimeo.com/api/player.js"></script>


**RTOS Task 2**
![](https://i.imgur.com/zFSAS1m.png)
Cause the stack peak is 124/1024, so the task is no risk of stack overflow.

**RTOS Task 3**
![](https://i.imgur.com/qLk51GY.png)

**RTOS Task 4**
![](https://i.imgur.com/RQC7Zvs.png)
<div style="padding:75% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/728343598?h=2be228cb97&amp;badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen style="position:absolute;top:0;left:0;width:100%;height:100%;" title="a.mp4"></iframe></div><script src="https://player.vimeo.com/api/player.js"></script>

It seems like red LED light`(workTaskFunc)`has higher priority then green LED light`(urgentWorkTaskFunc)`, so the green LED light is not running at the desired rate.

<br></br>
## DAY 4
This task shows how to initialize the ADCBuf driver in continuous mode.
the example code performs at 200Hz.
<div style="padding:75% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/728929806?h=e86cfdebda&amp;badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen style="position:absolute;top:0;left:0;width:100%;height:100%;" title="200hz.mp4"></iframe></div><script src="https://player.vimeo.com/api/player.js"></script>

**1.	Can you adjust the sampling frequency to 50 Hz and 100 Hz? Verify the output frequency in the terminal.**
50Hz:
<div style="padding:75% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/728930245?h=42845ecb4d&amp;badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen style="position:absolute;top:0;left:0;width:100%;height:100%;" title="50hz.mp4"></iframe></div><script src="https://player.vimeo.com/api/player.js"></script>

100Hz:
<div style="padding:75% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/728931103?h=379f7bb107&amp;badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen style="position:absolute;top:0;left:0;width:100%;height:100%;" title="100hz.mp4"></iframe></div><script src="https://player.vimeo.com/api/player.js"></script>

<br></br>
## DAY 5
**PWMLED control**
Code below is the core of controling LED brightness.
The more duty, the more brightness.
We can find that the sleeping time is fixed in each iteration, so the change of the brightness is uniform.

```c
while (1) {
    PWM_setDuty(pwm1, duty);

    PWM_setDuty(pwm2, duty);

    duty = (duty + dutyInc);

    if (duty == pwmPeriod || (!duty)) {
        dutyInc = - dutyInc;
    }

    usleep(time);
}
```
DEMO:
<div style="padding:177.78% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/728995793?h=dc417bdfea&amp;badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen style="position:absolute;top:0;left:0;width:100%;height:100%;" title="original.mp4"></iframe></div><script src="https://player.vimeo.com/api/player.js"></script>

**1. Can you adjust the rate by which the intensity of LED changes? There are multiple ways to do this. Implement at least 2 ways using your microcontroller.**
>I think misunderstood the problem when I worked on it, so I not only change the frequency but also make the high-duty part longer and low-duty part shorter :cry: [name=陳奕帆]
#### Method 1:
we can change rate by **adjusting sleeping time** in high-duty part and low-duty part.
I want to let the sleeping time in high-duty part longer and the time in slow-duty part shorter.
So, I utilize the variable `dutyInc` which has a perfect feature of being positive at high-duty part and being negative at low-duty part.
```c
while (1) {
    PWM_setDuty(pwm1, duty);

    PWM_setDuty(pwm2, duty);

    duty = (duty + dutyInc);

    if (duty == pwmPeriod || (!duty)) {
        dutyInc = - dutyInc;
        time = 50000 + dutyInc * 200;
    }
    usleep(time);
}
```
and it works as expected.
DEMO:
<div style="padding:177.78% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/728995804?h=bfff407a81&amp;badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen style="position:absolute;top:0;left:0;width:100%;height:100%;" title="method 1"></iframe></div><script src="https://player.vimeo.com/api/player.js"></script>

#### Method 2:
we can also change rate by **adjusting the speed of changing** which is `dutyInc`.
Similarly, I want to let the high-duty part longer and slow-duty part shorter.
So, I set different `dutyInc` in high-duty part and low-duty part like below.
```c
while (1) {
    PWM_setDuty(pwm1, duty);

    PWM_setDuty(pwm2, duty);

    duty = (duty + dutyInc);

    if (duty == pwmPeriod || (!duty)) {
        if(dutyInc == 100){
            dutyInc = -30;
        }
        else{
            dutyInc = 100;
        }
    }
    usleep(time);
}
```
and it works as expected.
DEMO:
<div style="padding:177.78% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/728995825?h=0637dc5f12&amp;badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen style="position:absolute;top:0;left:0;width:100%;height:100%;" title="method 2"></iframe></div><script src="https://player.vimeo.com/api/player.js"></script>

---
## Assigned Project
#### PWM part (Green light)
we have to change duty cycle in order of 0 -> 0.25 -> 0.5 -> 0.75 -> 1 then back to 0 and repeat again.
hence, I set `PWM_period` to 3000, and increase 750 (1/4) in each step.
To make the change of brightness at a rate of once second, the sleeping time in each iteration is 1 second.
```c
int32_t   pwmPeriod = 3000;
int32_t   duty = 0;
int32_t   dutyInc = 750;
```
#### DAC part (Red light)
I use DIO25 as DAC control.
And I create a table includes 0, 0.25, 0.5, 0.75, 1 V<sub>DD</sub> for DAC control.
Because voltage is ranging from 0 to 255, the table is 0, 63, 127, 191, 255
```c
static uint32_t TableCounter = 0;
static uint8_t myTable[BUFFER_SIZE]={0, 63, 127, 191, 255};
void DACControl(void)
{
    if (TableCounter < (BUFFER_SIZE - 1) ) {
        DAC_setCode(dacHandle0, myTable[TableCounter]);
        TableCounter ++;
    }
    else {
        DAC_setCode(dacHandle0, myTable[TableCounter]);
        TableCounter = 0;
        repCounter++;
    }
}
```
#### Integrate 2 parts
```c
uint32_t time = 500000;  /* Sleep time in microseconds */
while (1) {
    PWM_setDuty(pwm2, duty);
    duty = (duty + dutyInc);
    if (duty == pwmPeriod) {
        duty = -dutyInc;
    }
    
    DACControl();
    
    usleep(time);
    usleep(time);
}
```
> PS: It does not work when I use `usleep()` for 1 second. However, when I `usleep()` for 0.5 second twice, it works. Something weird is happening, but I don't know why.

DEMO:

<div style="padding:75% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/729655110?h=705306fad3&amp;badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen style="position:absolute;top:0;left:0;width:100%;height:100%;" title="project.avi"></iframe></div><script src="https://player.vimeo.com/api/player.js"></script>

PWM control is way brighter than DAC control obviously.
In my opinion, DAC is more linear.
