|
1 | 1 | ---
|
2 |
| -title: Chirp |
| 2 | +title: Chirp Signal Generation |
3 | 3 | layout: default
|
4 | 4 | math: mathjax
|
5 | 5 | parent: Projects
|
6 | 6 | nav_order: 2
|
7 | 7 | ---
|
8 | 8 |
|
9 |
| -# PCB |
10 |
| -{: .fs-8 .fw-500} |
| 9 | +# Chirp Signal Generation |
| 10 | +{: .no_toc .fs-8 .fw-500} |
11 | 11 | ---
|
12 | 12 |
|
13 |
| -very cool pcb for sensedu shield for arduino giga r1... (short description) |
| 13 | +The **chirp signal generation project** aims at proviving basic code to generate **frequency modulated continuous waves (FMCW)** on the **SensEdu Shield** using the **Arduino Giga R1**. The projects provides two types of frequency modulation : **sawtooth** and **triangular**. |
| 14 | + |
| 15 | +Chirp signals are encountered in numerous fields like radar & sonar systems, telecommunications, signal processing and more. You will find more information on the potential applications from our upcoming FMCW radar project. |
| 16 | + |
| 17 | +<img src="{{site.baseurl}}/assets/images/Chirp_signal.png" alt="drawing" width="500"/> |
| 18 | +{: .text-center} |
| 19 | + |
| 20 | +Chirp signal sweeping from 100 Hz to 10 kHz |
| 21 | +{: .text-center} |
| 22 | + |
| 23 | +<img src="{{site.baseurl}}/assets/images/Chirp_spectro.png" alt="drawing" width="499"/> |
| 24 | +{: .text-center} |
| 25 | + |
| 26 | +Spectrogram of chirp sweeping from 100 Hz to 10 kHz |
| 27 | +{: .text-center} |
| 28 | + |
| 29 | + |
14 | 30 | {: .fw-500}
|
15 | 31 |
|
16 |
| -- TOC |
| 32 | +## Table of contents |
| 33 | +{: .no_toc .text-delta } |
| 34 | +1. TOC |
17 | 35 | {:toc}
|
18 | 36 |
|
19 |
| -## Chapter 1 |
| 37 | +## Chirp Generation Function |
| 38 | +Arduino does not provide any built-in chirp signal function. There are workarounds using MATLAB's built-in chirp function but our idea was to create this signal directly in Arduino with the SensEdu library. |
20 | 39 |
|
21 |
| -TODO: exaplanations about component specifics, voltages, range |
| 40 | +The `generateSawtoothChirp` and `generateTriangularChirp` functions both calculate the values to generate a sawtooth chirp and triangular chirp respectively and copy these values to the DAC's buffer. |
22 | 41 |
|
23 |
| -TODO: voltage for DC jack |
| 42 | +```c |
| 43 | +void generateSawtoothChirp(uint16_t* array) |
| 44 | +void generateTriangularChirp(uint16_t* array) |
| 45 | +``` |
24 | 46 |
|
25 |
| -TODO: aplifiers gain |
| 47 | +### Parameters |
| 48 | +* `uint16_t* array` : A pointer to an array where the generated chirp signal will be stored. |
26 | 49 |
|
27 |
| -TODO: screenshots of specific parts of schematics for better understanding |
28 | 50 |
|
29 |
| -TODO: eveything needed for board modifications, pitfalls and problems |
30 | 51 |
|
31 |
| -TODO: guide, how to order the board |
| 52 | +### Description |
| 53 | +The generate chirp functions use two arrays `lut_sine` and `vChirp` to calculate the chirp values : |
32 | 54 |
|
| 55 | +* `lut_sine` is a LUT containing the values of a quarter sine wave. The `x` variable defines the resolution of `lut_sine`. A larger `x` will result in a more detailed LUT with more values which in turn increases the precision of the chirp values which will be calculated. |
| 56 | +* `vChirp` is the array in which the chirp values are calculated. |
33 | 57 |
|
34 |
| -styling examples: |
35 |
| -* check library documentation code |
36 |
| -* [link1] |
37 |
| -* [link2] |
38 | 58 |
|
39 |
| ---- |
| 59 | +The following steps describe how the function was implemented : |
40 | 60 |
|
41 |
| -example text |
| 61 | +**Step 1**{: .text-blue-000} : Generate the quarter-wave LUT |
42 | 62 |
|
43 |
| -[example link] |
| 63 | +```c |
| 64 | +// Generate the quarter-wave sine LUT |
| 65 | + for (int i = 0; i < 90 * x; i++) { |
| 66 | + float phase_deg = (float)i * 90.0 / (90 * x); // Phase angle in degrees |
| 67 | + float phase_rad = phase_deg * Pi / 180.0; // Phase angle to radians |
| 68 | + lut_sine[i] = sin(phase_rad-Pi/2); // Store sine value in the LUT |
| 69 | + } |
| 70 | +``` |
| 71 | + |
| 72 | +**Step 2**{: .text-blue-000} : Calculate the instantaneous phase of the chirp signal and wrap between 0-360 degrees |
44 | 73 |
|
45 |
| -example list: |
46 |
| -* sdsd |
47 |
| -* sdsds |
48 |
| -* sdsds |
| 74 | +```c |
| 75 | +for (int i = 1; i < samples_int + 1; i++) { |
| 76 | + float phase_rad = 2.0 * Pi * (0.5 * sK * (i - 1) / fs + START_FREQUENCY) * (i - 1) / fs; // Phase angle in radians |
| 77 | + float phase_deg = phase_rad * 180.0 / Pi; // Phase angle to degrees |
| 78 | + float phase_deg_wrapped = fmod(phase_deg, 360.0); // Wrap phase angle to 0-360 degrees |
| 79 | +``` |
49 | 80 |
|
50 |
| -example list 2: |
51 |
| -1. sdsd |
52 |
| -2. sdsds |
53 |
| -3. sdsds |
| 81 | +**Step 3**{: .text-blue-000} : Calculate the value of the chirp using a quadrant-based approach. Scale and offset values to get 12 bit values. |
54 | 82 |
|
55 |
| -`marked text` |
| 83 | +```c |
| 84 | +if (phase_deg_wrapped <= 90) { |
| 85 | + vChirp[i - 1] = lut_sine[(int)(phase_deg_wrapped / 90.0 * (90 * x - 1))] * 2047.5 + 2047.5; |
| 86 | + } else if (phase_deg_wrapped <= 180) { |
| 87 | + vChirp[i - 1] = -lut_sine[(int)((180.0 - phase_deg_wrapped) / 90.0 * (90 * x - 1))] * 2047.5 + 2047.5; |
| 88 | + } else if (phase_deg_wrapped <= 270) { |
| 89 | + vChirp[i - 1] = -lut_sine[(int)((phase_deg_wrapped - 180.0) / 90.0 * (90 * x - 1))] * 2047.5 + 2047.5; |
| 90 | + } else { |
| 91 | + vChirp[i - 1] = lut_sine[(int)((360.0 - phase_deg_wrapped) / 90.0 * (90 * x - 1))] * 2047.5 + 2047.5; |
| 92 | + } |
| 93 | +``` |
56 | 94 |
|
57 |
| -**Bold text** |
| 95 | +{: .warning } |
| 96 | +In this configuration, the first value of the chirp signal array is 0 (or 0 V in amplitude at DAC output). This initial value can be changed by modifying `sine_lut`. |
58 | 97 |
|
59 |
| -*Italics* |
| 98 | +**Step 4**{: .text-blue-000} : Copy the chirp signal's values to the DAC buffer |
60 | 99 |
|
61 |
| -### subchapter 1 |
62 | 100 | ```c
|
63 |
| -// cool code |
| 101 | +// Copy the chirp signal to the DAC buffer |
| 102 | + for (int i = 0; i < samples_int; i++) { |
| 103 | + array[i] = (uint16_t)vChirp[i]; |
| 104 | + } |
64 | 105 | ```
|
65 | 106 |
|
66 |
| -## Chapter 2 |
| 107 | +--- |
| 108 | +
|
| 109 | +## Main code |
| 110 | +Check out the [DAC]({% link Library/DAC.md %}) section for more information on the DAC library and different DAC related functions. |
| 111 | +
|
| 112 | +The `Chirp_SawtoothMod.ino` and `Chirp_TriangularMod.ino` files contain the main code to generate the chirp signal, send the chirp signal to the DAC and enable the DAC. |
| 113 | +
|
| 114 | +The code contains the following user settings to adjust the chirp signal : |
67 | 115 |
|
68 |
| -{. :warning} |
69 |
| -callout #1 |
| 116 | +* `CHIRP_DURATION`{: .text-green-000} : The period of the chirp signal in seconds |
| 117 | +* `START_FREQUENCY`{: .text-green-000} : The start frequency of the chirp signal in Hz |
| 118 | +* `END_FREQUENCY`{: .text-green-000} : The end frequency of the chirp signal in Hz |
| 119 | +
|
| 120 | +A very important variable in the main code is the sampling frequency `fs`. Based on the Nyquist-Shannon sampling theorem, `fs` needs to be at least double the maximum frequency (or end frequency) of the chirp signal. |
| 121 | +Keep in mind this sampling frequency will also be the DAC's output frequency in the `SensEdu_DAC_Settings` function. |
| 122 | +
|
| 123 | +{: .warning } |
| 124 | +`fs` needs to be at least 2*END_FREQUENCY in order for the chirp signal to be generated properly. |
| 125 | +
|
| 126 | +The `samples_int` is an integer representing the amount of samples for one period of the chirp signal. This value also represents the memory size in the `SENSEDU_DAC_BUFFER` and `SensEdu_DAC_Settings` functions. |
| 127 | +
|
| 128 | +{: .warning } |
| 129 | +In this implementation, `samples_int` cannot exceed 7688. |
| 130 | +
|
| 131 | +The values of the chirp are printed in the serial monitor. |
| 132 | +```c |
| 133 | +// Print the chirp signal LUT |
| 134 | + Serial.println("start of the Chirp LUT"); |
| 135 | + for (int i = 0 ; i < samples_int; i++) { // loop for the LUT size |
| 136 | + Serial.print("value "); |
| 137 | + Serial.print(i+1); |
| 138 | + Serial.print(" of the Chirp LUT: "); |
| 139 | + Serial.println(lut[i]); |
| 140 | + } |
| 141 | +``` |
70 | 142 |
|
71 |
| -{. :note} |
72 |
| -callout #1 |
73 | 143 |
|
74 | 144 |
|
75 | 145 | [example link]: https://github.com/ShiegeChan/SensEdu
|
|
0 commit comments