10 |
11 | #define MPU_ADDR 0x68
12 | #define MPU_REG_SIZE 118
13 |
14 | // I2C Registers
15 | #define PWR_MGMT_1 0x6B
16 | #define WHO_AM_I 0x75
17 | #define ACCEL_XOUT_H 0x3B
18 | #define ACCEL_XOUT_L 0x3C
19 | #define ACCEL_YOUT_H 0x3D
20 | #define ACCEL_YOUT_L 0x3E
21 | #define ACCEL_ZOUT_H 0x3F
22 | #define ACCEL_ZOUT_L 0x40
23 | #define ACCEL_CONFIG 0x1C
24 |
25 |
26 | const float BIT_10_ACC = 1023.0;
27 |
28 | int potXPin = A0;
29 | int potYPin = A1;
30 | int potZPin = A2;
31 |
32 | volatile uint8_t data[MPU_REG_SIZE];
33 | volatile uint8_t dat_ptr = 0xFF;
34 |
35 | void setup()
36 | {
37 | Wire.begin(MPU_ADDR); // join i2c bus with address MPU_ADDR
38 |
39 | pinMode(potXPin, INPUT);
40 | pinMode(potYPin, INPUT);
41 | pinMode(potZPin, INPUT);
42 |
43 | for(int i = 0; i < MPU_REG_SIZE; i++) {
44 | data[i] = 0xFF; //initializes everything to FF
45 | }
46 | //Set initial values
47 | data[WHO_AM_I] = (uint8_t)0x68;
48 | data[PWR_MGMT_1] = 0b01000000;
49 | data[ACCEL_CONFIG] = 0b00000000;
50 |
51 | Wire.onReceive(receiveEvent); // register event
52 | Wire.onRequest(requestEvent);
53 |
54 | }
55 |
56 | void loop()
57 | {
58 | bool powerState = (data[PWR_MGMT_1] & 0b01000000) == 0;
59 | //In the sleep state the accelerometers + gyros are not updated
60 | if(powerState)
61 | {
62 | readAxis();
63 | }
64 |
65 | delay(10);
66 | }
67 |
68 | // data pointer is written value.
69 | // further values end up in the place pointed to by dat_ptr
70 | void receiveEvent(int howMany)
71 | {
72 | dat_ptr = Wire.read();
73 | while(Wire.available()) {
74 | data[dat_ptr] = Wire.read();
75 | }
76 | }
77 |
78 | void requestEvent() {
79 | uint8_t response[6];
80 | for(int i = 0; i < 6; i++) {
81 | uint8_t ind = constrain(dat_ptr + i, 13, MPU_REG_SIZE - 1);
82 | uint8_t temp = data[ind];
83 | response[i] = temp;
84 | }
85 | Wire.write(response,sizeof(response));
86 | }
87 |
88 |
89 | // Get full-scale accelerometer range.
90 | // The AFS_SEL parameter allows setting the full-scale range of the accelerometer
91 | // sensors, as described in the table below.
92 | //
93 | //
94 | // 0 = +/- 2g
95 | // 1 = +/- 4g
96 | // 2 = +/- 8g
97 | // 3 = +/- 16g
98 | //
99 | //
100 |
101 | float getFullScaleAccelRange()
102 | {
103 | switch(data[ACCEL_CONFIG] & 0b00011000)
104 | {
105 | case 0:
106 | return 2.0;
107 | case 8:
108 | return 4.0;
109 | case 16:
110 | return 8.0;
111 | case 24:
112 | return 16.0;
113 | }
114 | }
115 |
116 | int getLSBSensitivity()
117 | {
118 | switch(data[ACCEL_CONFIG] & 0b00011000)
119 | {
120 | case 0:
121 | return 16384;
122 | case 8:
123 | return 8192;
124 | case 16:
125 | return 4096;
126 | case 24:
127 | return 2048;
128 | }
129 | }
130 |
131 |
132 | void readAxis()
133 | {
134 | float xTemp = 0.5-((float)(analogRead(potXPin))/BIT_10_ACC);
135 | float yTemp = 0.5-((float)(analogRead(potYPin))/BIT_10_ACC);
136 | float zTemp = 0.5-((float)(analogRead(potZPin))/BIT_10_ACC);
137 |
138 | float currentAccelRange = getFullScaleAccelRange();
139 |
140 | xTemp*= (2*currentAccelRange);
141 | yTemp*= (2*currentAccelRange);
142 | zTemp*= (2*currentAccelRange);
143 |
144 | int currentLSBSen = getLSBSensitivity();
145 |
146 | long x = (long)(currentLSBSen*xTemp);
147 | long y = (long)(currentLSBSen*yTemp);
148 | long z = (long)(currentLSBSen*zTemp);
149 |
150 | // Handle int overflow
151 |
152 | x = constrain(x, -currentAccelRange*currentLSBSen, currentAccelRange*currentLSBSen - 1);
153 | y = constrain(y, -currentAccelRange*currentLSBSen, currentAccelRange*currentLSBSen - 1);
154 | z = constrain(z, -currentAccelRange*currentLSBSen, currentAccelRange*currentLSBSen - 1);
155 |
156 | data[ACCEL_XOUT_H] = (uint8_t)(x >> 8);
157 | data[ACCEL_XOUT_L] = (uint8_t)(x);
158 | data[ACCEL_YOUT_H] = (uint8_t)(y >> 8);
159 | data[ACCEL_YOUT_L] = (uint8_t)(y);
160 | data[ACCEL_ZOUT_H] = (uint8_t)(z >> 8);
161 | data[ACCEL_ZOUT_L] = (uint8_t)(z);
162 | }
163 |
--------------------------------------------------------------------------------
/code/Week4/Week_4_Solution/Week_4_Solution.ino:
--------------------------------------------------------------------------------
1 | // Firmware Training Week 4
2 | // User Code Example
3 | // Joe Spall, Varun Madabushi
4 |
5 | #include
6 | #include
7 |
8 | #define MPU_ADDR 0x68
9 |
10 | // I2C Registers
11 | #define PWR_MGMT_1 0x6B
12 | #define WHO_AM_I 0x75
13 | #define ACCEL_XOUT_H 0x3B
14 | #define ACCEL_XOUT_L 0x3C
15 | #define ACCEL_YOUT_H 0x3D
16 | #define ACCEL_YOUT_L 0x3E
17 | #define ACCEL_ZOUT_H 0x3F
18 | #define ACCEL_ZOUT_L 0x40
19 | #define ACCEL_CONFIG 0x1C
20 |
21 | #define D1_PIN 11
22 | #define D2_PIN 10
23 | #define D3_PIN 9
24 | #define D4_PIN 6
25 | #define D5_PIN 5
26 |
27 | #define ANG_RANGE_1 -1.0
28 | #define ANG_RANGE_2 -0.5
29 | #define ANG_RANGE_3 0.5
30 | #define ANG_RANGE_4 1.0
31 |
32 | #define SCALE_FACTOR_2G 16384.0
33 |
34 |
35 | namespace tb
36 | {
37 |
38 | // Stores the LED pins
39 | int pinArray[5] = {D1_PIN,D2_PIN,D3_PIN,D4_PIN,D5_PIN};
40 |
41 | struct Vector3D
42 | {
43 | float x_g;
44 | float y_g;
45 | float z_g;
46 | };
47 |
48 | void setBubbleIndicator(tb::Vector3D vector)
49 | {
50 | float angle = atan2f(vector.y_g, vector.z_g);
51 | int pinPos = -1;
52 |
53 | // Checks if angle of vector is in valid range
54 | if(angle <= ANG_RANGE_1)
55 | {
56 | pinPos = 0;
57 | }
58 | else if(angle > ANG_RANGE_1 && angle <= ANG_RANGE_2)
59 | {
60 | pinPos = 1;
61 | }
62 | else if(angle > ANG_RANGE_2 && angle <= ANG_RANGE_3)
63 | {
64 | pinPos = 2;
65 | }
66 | else if(angle > ANG_RANGE_3 && angle <= ANG_RANGE_4)
67 | {
68 | pinPos = 3;
69 | }
70 | else
71 | {
72 | pinPos = 4;
73 | }
74 | // Loop through pin array
75 | for(int i = 0; i <= 4; i++)
76 | {
77 | if(i == pinPos)
78 | {
79 | digitalWrite(pinArray[i], HIGH);
80 | }
81 | else
82 | {
83 | digitalWrite(pinArray[i], LOW);
84 | }
85 | }
86 | }
87 | }
88 |
89 | void setup()
90 | {
91 | Wire.begin(); // join i2c bus (address optional for master)
92 | Serial.begin(9600);
93 |
94 | // Set direction of all of the LED pins
95 | pinMode(D1_PIN, OUTPUT);
96 | pinMode(D2_PIN, OUTPUT);
97 | pinMode(D3_PIN, OUTPUT);
98 | pinMode(D4_PIN, OUTPUT);
99 | pinMode(D5_PIN, OUTPUT);
100 |
101 | digitalWrite(D1_PIN, LOW);
102 | digitalWrite(D2_PIN, LOW);
103 | digitalWrite(D3_PIN, LOW);
104 | digitalWrite(D4_PIN, LOW);
105 | digitalWrite(D5_PIN, LOW);
106 |
107 | // USER CODE - IMPLEMENT FOR LAB
108 |
109 | // POWER ON
110 | // Here set Power Management Register to appropriate value
111 | Wire.beginTransmission(MPU_ADDR);
112 | Wire.write(PWR_MGMT_1);
113 | Wire.write(0);
114 | Wire.endTransmission(true);
115 |
116 | // WHO AM I
117 | // Here conduct a Who Am I test, reading from appropriate register
118 | // The result should be the I2C address of the device (0x68 or 104)
119 | Wire.beginTransmission(MPU_ADDR);
120 | Wire.write(WHO_AM_I);
121 | Wire.endTransmission(true);
122 | Wire.requestFrom(MPU_ADDR, 1, true);
123 | Serial.println(Wire.read());
124 |
125 | // SET AFS_SCALE
126 | // Optionally, change the scale
127 | Wire.beginTransmission(MPU_ADDR);
128 | Wire.write(ACCEL_CONFIG);
129 | Wire.write(0b00000000);
130 | Wire.endTransmission(true);
131 | }
132 |
133 | void loop()
134 | {
135 | // SET START REGISTER
136 | // Send the starting register address to the IMU to set the pointer
137 | // We want to start with register 0x3B (ACCEL_XOUT_H)
138 | Wire.beginTransmission(MPU_ADDR);
139 | Wire.write(ACCEL_XOUT_H);
140 | Wire.endTransmission();
141 |
142 | // READ REGISTERS
143 | // Request a read from 6 registers total
144 | // This corresponds to 2 registers (16 bits) for each axis
145 | Wire.requestFrom(MPU_ADDR, 6, true);
146 |
147 | // PROCESS DATA
148 | // Read in the data and perform bitwise operations to combine
149 | // Make sure to scale by the correct scale factor
150 | float accX = (Wire.read() << 8 | Wire.read()) / SCALE_FACTOR_2G; // X-axis value
151 | float accY = (Wire.read() << 8 | Wire.read()) / SCALE_FACTOR_2G; // Y-axis value
152 | float accZ = (Wire.read() << 8 | Wire.read()) / SCALE_FACTOR_2G; // Z-axis value
153 |
154 | // Print the measured acceleration to the serial monitor
155 | Serial.print("accX ");
156 | Serial.print(accX);
157 | Serial.print(" accY ");
158 | Serial.print(accY);
159 | Serial.print(" accZ ");
160 | Serial.println(accZ);
161 |
162 | // Construct a tb::Vector3D struct instance containing the measured accelerations
163 | tb::Vector3D currentSample{accX,accY,accZ};
164 |
165 | // BUBBLE INDICATOR
166 | // Pass the vector to the tb::setBubbleIndicator function
167 | tb::setBubbleIndicator(currentSample);
168 |
169 | // A delay of 100ms so we do not sample or print too fast
170 | delay(1000);
171 | }
172 |
--------------------------------------------------------------------------------
/code/Week4/Week_4_Template/Week_4_Template.ino:
--------------------------------------------------------------------------------
1 | // Firmware Training Week 4
2 | // User Code
3 |
4 | #include
5 | #include
6 |
7 | #define MPU_ADDR 0x68
8 |
9 | // I2C Registers
10 | #define PWR_MGMT_1 0x6B
11 | #define WHO_AM_I 0x75
12 | #define ACCEL_XOUT_H 0x3B
13 | #define ACCEL_XOUT_L 0x3C
14 | #define ACCEL_YOUT_H 0x3D
15 | #define ACCEL_YOUT_L 0x3E
16 | #define ACCEL_ZOUT_H 0x3F
17 | #define ACCEL_ZOUT_L 0x40
18 | #define ACCEL_CONFIG 0x1C
19 |
20 | #define D1_PIN 11
21 | #define D2_PIN 10
22 | #define D3_PIN 9
23 | #define D4_PIN 6
24 | #define D5_PIN 5
25 |
26 | #define ANG_RANGE_1 -1.0
27 | #define ANG_RANGE_2 -0.5
28 | #define ANG_RANGE_3 0.5
29 | #define ANG_RANGE_4 1.0
30 |
31 | #define SCALE_FACTOR_2G 16384.0
32 |
33 |
34 | namespace tb
35 | {
36 |
37 | // Stores the LED pins
38 | int pinArray[5] = {D1_PIN,D2_PIN,D3_PIN,D4_PIN,D5_PIN};
39 |
40 | struct Vector3D
41 | {
42 | float x_g;
43 | float y_g;
44 | float z_g;
45 | };
46 |
47 | void setBubbleIndicator(tb::Vector3D vector)
48 | {
49 | float angle = atan2f(vector.y_g, vector.z_g);
50 | int pinPos = -1;
51 |
52 | // Checks if angle of vector is in valid range
53 | if(angle <= ANG_RANGE_1)
54 | {
55 | pinPos = 0;
56 | }
57 | else if(angle > ANG_RANGE_1 && angle <= ANG_RANGE_2)
58 | {
59 | pinPos = 1;
60 | }
61 | else if(angle > ANG_RANGE_2 && angle <= ANG_RANGE_3)
62 | {
63 | pinPos = 2;
64 | }
65 | else if(angle > ANG_RANGE_3 && angle <= ANG_RANGE_4)
66 | {
67 | pinPos = 3;
68 | }
69 | else
70 | {
71 | pinPos = 4;
72 | }
73 | // Loop through pin array
74 | for(int i = 0; i <= 4; i++)
75 | {
76 | if(i == pinPos)
77 | {
78 | digitalWrite(pinArray[i], HIGH);
79 | }
80 | else
81 | {
82 | digitalWrite(pinArray[i], LOW);
83 | }
84 | }
85 | }
86 | }
87 |
88 | void setup()
89 | {
90 | Wire.begin(); // join i2c bus (address optional for master)
91 | Serial.begin(9600);
92 |
93 | // Set direction of all of the LED pins
94 | pinMode(D1_PIN, OUTPUT);
95 | pinMode(D2_PIN, OUTPUT);
96 | pinMode(D3_PIN, OUTPUT);
97 | pinMode(D4_PIN, OUTPUT);
98 | pinMode(D5_PIN, OUTPUT);
99 |
100 | digitalWrite(D1_PIN, LOW);
101 | digitalWrite(D2_PIN, LOW);
102 | digitalWrite(D3_PIN, LOW);
103 | digitalWrite(D4_PIN, LOW);
104 | digitalWrite(D5_PIN, LOW);
105 |
106 | // USER CODE - IMPLEMENT FOR LAB
107 |
108 | // POWER ON
109 | // Here set Power Management Register to appropriate value
110 |
111 |
112 | // WHO AM I
113 | // Here conduct a Who Am I test, reading from appropriate register
114 | // The result should be the I2C address of the device (0x68 or 104)
115 |
116 |
117 | // SET AFS_SCALE
118 | // Optionally, change the scale
119 |
120 | }
121 |
122 | void loop()
123 | {
124 | // SET START REGISTER
125 | // Send the starting register address to the IMU to set the pointer
126 | // We want to start with register 0x3B (ACCEL_XOUT_H)
127 |
128 | // READ REGISTERS
129 | // Request a read from 6 registers total
130 | // This corresponds to 2 registers (16 bits) for each axis
131 |
132 | // PROCESS DATA
133 | // Read in the data and perform bitwise operations to combine
134 | // Make sure to scale by the correct scale factor
135 | float accX = 0; // X-axis value
136 | float accY = 0; // Y-axis value
137 | float accZ = 0; // Z-axis value
138 |
139 | // Print the measured acceleration to the serial monitor
140 | Serial.print("accX ");
141 | Serial.print(accX);
142 | Serial.print(" accY ");
143 | Serial.print(accY);
144 | Serial.print(" accZ ");
145 | Serial.println(accZ);
146 |
147 | // Construct a tb::Vector3D struct instance containing the measured accelerations
148 | tb::Vector3D currentSample{accX,accY,accZ};
149 |
150 | // BUBBLE INDICATOR
151 | // Pass the vector to the tb::setBubbleIndicator function
152 |
153 | // A delay of 100ms so we do not sample or print too fast
154 | delay(100);
155 | }
156 |
--------------------------------------------------------------------------------
/demos/Week1/Week_1_Demo_Solution.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "id": "M8AoKc-YofSA"
7 | },
8 | "source": [
9 | "# Week 1"
10 | ]
11 | },
12 | {
13 | "cell_type": "markdown",
14 | "metadata": {
15 | "id": "1lbYclUZn-Eo"
16 | },
17 | "source": [
18 | "## Typing for Coding\n",
19 | "\n",
20 | "* In C / C++, '//' is a comment. The compiler ignores this!\n",
21 | "* CTRL + Left / Right Arrow Key: Jump Forward / Back a word.\n",
22 | "* CTRL + Backspace: Delete previous word (in Linux terminal, its CTRL + w instead)\n",
23 | "* CTRL + /: Comment out current line. If you highlight a larger block of text with your mouse, CTRL + / \n",
24 | "will comment out the whole block!\n",
25 | "\n",
26 | "There are obviously more keyboard shortcuts that these. But if you are obsessed with peak efficiency, \n",
27 | "go be a vimChad in the corner over there. There. I said it."
28 | ]
29 | },
30 | {
31 | "cell_type": "markdown",
32 | "metadata": {
33 | "id": "ujAgFpyLouG3"
34 | },
35 | "source": [
36 | "## How to use this Demo\n",
37 | "\n",
38 | "This is a Jupyter Notebook. Obviously, Jupyter notebooks are meant for Python, not C++. However, Google Colab seamlessly integrates text with a fully functional Linux environment. Therefore, we can still write C++ code, compile it, and execute it!"
39 | ]
40 | },
41 | {
42 | "cell_type": "markdown",
43 | "metadata": {
44 | "id": "iR83YdNPj7Hk"
45 | },
46 | "source": [
47 | "Writing C++ for this demo has 2 parts:\n",
48 | "* creating a file\n",
49 | "* compiling and executing the compiled code\n",
50 | "\n",
51 | "The code block below first writes the file. The `%%writefile hello_world.cpp` command tells Google Colab to create a file called `hello_world.cpp`.\n",
52 | "\n",
53 | "First, run this cell by hitting \"CTRL + Enter\" or by pressing the \"Play\" button. Then, if you click on the file icon on the left, you will see a \"hello_world.cpp\" file there!"
54 | ]
55 | },
56 | {
57 | "cell_type": "code",
58 | "execution_count": null,
59 | "metadata": {
60 | "colab": {
61 | "base_uri": "https://localhost:8080/"
62 | },
63 | "id": "rTjyi-pqp1OA",
64 | "outputId": "f3254ef1-a329-4ca5-cc60-2ff5663744fe"
65 | },
66 | "outputs": [],
67 | "source": [
68 | "%%writefile hello_world.cpp\n",
69 | "\n",
70 | "#include \n",
71 | "\n",
72 | "int main() {\n",
73 | " std::cout << \"Hello World!\" << std::endl;\n",
74 | " return 0;\n",
75 | "}"
76 | ]
77 | },
78 | {
79 | "cell_type": "markdown",
80 | "metadata": {
81 | "id": "qyHMmN4Rj508"
82 | },
83 | "source": [
84 | "The second step is to compile and run your code. There are two places where things can go wrong: compilation and execution.\n",
85 | "\n",
86 | "A compilation error occurs when the compiler is unable to compile your code. Most of the time, a compilation error indicates that you violated a rule of C++. For example, you may have forgotten to end one of your lines in a semicolon or forgot to close a curly brace. You can tell if its a compiler error if the terminal mentions g++, the compiler we are using.\n",
87 | "\n",
88 | "A runtime error occurs when your program does something improper while its being executed. Common infractions are dividing by zero or writing to an unauthorized memory location. You can tell if its a runtime error if the terminal mentions the name of your program."
89 | ]
90 | },
91 | {
92 | "cell_type": "code",
93 | "execution_count": null,
94 | "metadata": {
95 | "colab": {
96 | "base_uri": "https://localhost:8080/"
97 | },
98 | "id": "SiQ-eccnh4lO",
99 | "outputId": "980ce7a9-5e01-4981-c495-82883441d9c2"
100 | },
101 | "outputs": [],
102 | "source": [
103 | "%%bash\n",
104 | "\n",
105 | "g++ hello_world.cpp -o hello_world\n",
106 | "./hello_world"
107 | ]
108 | },
109 | {
110 | "cell_type": "markdown",
111 | "metadata": {
112 | "id": "aqhh_ioameET"
113 | },
114 | "source": [
115 | "## Variable Types\n",
116 | "\n",
117 | "Complete all of the instrucions listed in the comments. Then, try compiling and running you code!"
118 | ]
119 | },
120 | {
121 | "cell_type": "code",
122 | "execution_count": null,
123 | "metadata": {
124 | "colab": {
125 | "base_uri": "https://localhost:8080/"
126 | },
127 | "id": "JklX2ZBBmgyr",
128 | "outputId": "2cdf2699-e083-45c4-d20a-5c107a22a2af"
129 | },
130 | "outputs": [],
131 | "source": [
132 | "%%writefile variables.cpp\n",
133 | "\n",
134 | "#include \n",
135 | "#include \n",
136 | "\n",
137 | "int main() {\n",
138 | " \n",
139 | " // Create an INTEGER named 'myInt', assign it a value '-17'\n",
140 | " int myInt = -17;\n",
141 | " // Create a DOUBLE named 'myDouble', assign it a value '1.23'\n",
142 | " double myDouble = 1.23;\n",
143 | " //Create a CHARACTER named 'myChar', assign it a value 'c'\n",
144 | " char myChar = 'c';\n",
145 | " // Create a std::STRING named 'myString', assign it a value \"Hello World!\" \n",
146 | " std::string myString = \"Hello World!\";\n",
147 | " // Create a BOOLEAN named 'myBool', assign it a value 'false'\n",
148 | " bool myBool = false;\n",
149 | "\n",
150 | " // DO NOT EDIT!\n",
151 | " std::cout << \"This is an integer: \" << myInt << std::endl;\n",
152 | " std::cout << \"This is a double: \" << myDouble << std::endl;\n",
153 | " std::cout << \"This is a character: \" << myChar << std::endl;\n",
154 | " std::cout << \"This is a string: \" << myString << std::endl;\n",
155 | " std::cout << \"This is a bool: \" << myBool << std::endl;\n",
156 | "\n",
157 | " return 0;\n",
158 | "}"
159 | ]
160 | },
161 | {
162 | "cell_type": "code",
163 | "execution_count": null,
164 | "metadata": {
165 | "colab": {
166 | "base_uri": "https://localhost:8080/"
167 | },
168 | "id": "UL7xYQfpnQbz",
169 | "outputId": "2d8b5d26-adba-4fbb-d8c0-5c2f381bfd00"
170 | },
171 | "outputs": [],
172 | "source": [
173 | "%%bash\n",
174 | "\n",
175 | "g++ variables.cpp -o variables\n",
176 | "./variables"
177 | ]
178 | },
179 | {
180 | "cell_type": "markdown",
181 | "metadata": {
182 | "id": "IJ9lWoTSnhqe"
183 | },
184 | "source": [
185 | "## Arithmetic"
186 | ]
187 | },
188 | {
189 | "cell_type": "code",
190 | "execution_count": null,
191 | "metadata": {
192 | "colab": {
193 | "base_uri": "https://localhost:8080/"
194 | },
195 | "id": "77TaPtNvni-r",
196 | "outputId": "4a1e6434-5e30-47a4-f8d9-82e0fe1142c7"
197 | },
198 | "outputs": [],
199 | "source": [
200 | "%%writefile arithmetic.cpp\n",
201 | "\n",
202 | "#include \n",
203 | "#include \n",
204 | "\n",
205 | "int main() {\n",
206 | " \n",
207 | " int a = 8;\n",
208 | " int b = 3;\n",
209 | "\n",
210 | " // Create an INTEGER named 'mySum', assign it to the sum of a and b\n",
211 | " int mySum = a + b;\n",
212 | " // Create an INTEGER named 'myDiff', assign it to the difference of a and b\n",
213 | " int myDiff = a - b;\n",
214 | " // Create an INTEGER named 'myDiff', assign it to the product of a and b\n",
215 | " int myProd = a * b;\n",
216 | " // Create an INTEGER named 'myQuot', assign it to the quotient of a and b\n",
217 | " int myQuot = a / b;\n",
218 | " // Create an INTEGER named 'myMod', assign it to the modulo of a and b\n",
219 | " int myMod = a % b;\n",
220 | "\n",
221 | " // DO NOT EDIT!\n",
222 | "\n",
223 | " std::cout << \"a = \" << a << \", b = \" << b << std::endl;\n",
224 | " std::cout << \"Sum: \" << mySum << std::endl;\n",
225 | " std::cout << \"Difference: \" << myDiff << std::endl;\n",
226 | " std::cout << \"Product: \" << myProd << std::endl;\n",
227 | " std::cout << \"Quotient: \" << myQuot << std::endl;\n",
228 | " std::cout << \"Modulo: \" << myMod << std::endl;\n",
229 | "\n",
230 | " return 0;\n",
231 | "}"
232 | ]
233 | },
234 | {
235 | "cell_type": "code",
236 | "execution_count": null,
237 | "metadata": {
238 | "colab": {
239 | "base_uri": "https://localhost:8080/"
240 | },
241 | "id": "AKQi129SnyG-",
242 | "outputId": "e04cad16-afe2-468f-cc3c-99a7a54e1532"
243 | },
244 | "outputs": [],
245 | "source": [
246 | "%%bash\n",
247 | "\n",
248 | "g++ arithmetic.cpp -o arithmetic\n",
249 | "./arithmetic"
250 | ]
251 | },
252 | {
253 | "cell_type": "markdown",
254 | "metadata": {
255 | "id": "gBdyeDqUn649"
256 | },
257 | "source": [
258 | "## Relational Operators"
259 | ]
260 | },
261 | {
262 | "cell_type": "code",
263 | "execution_count": null,
264 | "metadata": {
265 | "colab": {
266 | "base_uri": "https://localhost:8080/"
267 | },
268 | "id": "OcEjALGin8eO",
269 | "outputId": "cf5d3a69-c906-4192-eb78-664ec73b2a33"
270 | },
271 | "outputs": [],
272 | "source": [
273 | "%%writefile isEqual.cpp\n",
274 | "\n",
275 | "#include \n",
276 | "#include \n",
277 | "\n",
278 | "int main() {\n",
279 | " \n",
280 | " int x = 4;\n",
281 | " int y = 2;\n",
282 | " int z = 0b0100;\n",
283 | "\n",
284 | " //Create a BOOLEAN named 'equals', assign it to the result of x equals y\n",
285 | " bool equals = (x == y);\n",
286 | " //Create a BOOLEAN named 'notEquals', assign it to the result of x not equals y\n",
287 | " bool notEquals = (x != z);\n",
288 | " //Create a BOOLEAN named 'greaterThan', assign it to the result of x greater than y\n",
289 | " bool greaterThan = x > y;\n",
290 | " //Create a BOOLEAN named 'lessThan', assign it to the result of x less than y\n",
291 | " bool lessThan = x < z;\n",
292 | " //Create a BOOLEAN named 'geq', assign it to the result of x greater than or equal to y\n",
293 | " bool geq = x >= y;\n",
294 | " //Create a BOOLEAN named 'leq', assign it to the result of x less than or equal to z\n",
295 | " bool leq = x <= z;\n",
296 | "\n",
297 | " // DO NOT EDIT!\n",
298 | " std::cout << \"x = \" << x << \", y = \" << y << \", z = \" << z << std::endl;\n",
299 | " std::cout << \"x equal to y? \" << equals << std::endl;\n",
300 | " std::cout << \"x not equal to z? \" << notEquals << std::endl;\n",
301 | " std::cout << \"x greater than y? \" << greaterThan << std::endl;\n",
302 | " std::cout << \"x less than z? \" << lessThan << std::endl;\n",
303 | " std::cout << \"x greater than or equal to y? \" << geq << std::endl;\n",
304 | " std::cout << \"x less than or equal to z? \" << leq << std::endl;\n",
305 | "\n",
306 | " return 0;\n",
307 | "}"
308 | ]
309 | },
310 | {
311 | "cell_type": "code",
312 | "execution_count": null,
313 | "metadata": {
314 | "colab": {
315 | "base_uri": "https://localhost:8080/"
316 | },
317 | "id": "LoAn6IJVoIBt",
318 | "outputId": "c066b5a1-8ac0-47c4-e7ea-3f60844372c4"
319 | },
320 | "outputs": [],
321 | "source": [
322 | "%%bash\n",
323 | "\n",
324 | "g++ isEqual.cpp -o isEqual\n",
325 | "./isEqual"
326 | ]
327 | },
328 | {
329 | "cell_type": "markdown",
330 | "metadata": {
331 | "id": "jJXxw62YpK45"
332 | },
333 | "source": [
334 | "## Conditionals (If / Else)"
335 | ]
336 | },
337 | {
338 | "cell_type": "code",
339 | "execution_count": null,
340 | "metadata": {
341 | "colab": {
342 | "base_uri": "https://localhost:8080/"
343 | },
344 | "id": "R6Mspz9ApPi0",
345 | "outputId": "8e0a9a0b-afc9-4dd6-8e25-a90e440deb8e"
346 | },
347 | "outputs": [],
348 | "source": [
349 | "%%writefile potato.cpp\n",
350 | "\n",
351 | "#include \n",
352 | "#include \n",
353 | "\n",
354 | "int main() {\n",
355 | " \n",
356 | " bool potato = true;\n",
357 | " double myGrade = 0;\n",
358 | "\n",
359 | " // If potato is true, then set myGrade to 76. \n",
360 | " // Otherwise, set myGrade to 95.\n",
361 | " if (potato) {\n",
362 | " myGrade = 76;\n",
363 | " } else {\n",
364 | " myGrade = 95;\n",
365 | " }\n",
366 | "\n",
367 | " std::cout << \"potato = \" << potato << \", myGrade = \" << myGrade << std::endl;\n",
368 | "\n",
369 | " // If myGrade is at least 90, print out \"A\"\n",
370 | " // If myGrade is at least 80, print out \"B\"\n",
371 | " // Otherwise, print out \"I didn't even know grades went this low!\"\n",
372 | " if (myGrade >= 90) {\n",
373 | " std::cout << \"A\" << std::endl;\n",
374 | " } else if (myGrade >= 80) {\n",
375 | " std::cout << \"B\" << std:: endl;\n",
376 | " } else {\n",
377 | " std::cout << \"I didn't even know grades went this low!\" << std::endl;\n",
378 | " }\n",
379 | "\n",
380 | " return 0;\n",
381 | "}"
382 | ]
383 | },
384 | {
385 | "cell_type": "code",
386 | "execution_count": null,
387 | "metadata": {
388 | "colab": {
389 | "base_uri": "https://localhost:8080/"
390 | },
391 | "id": "PmdJeVSjpZaQ",
392 | "outputId": "0a9e1f2a-bafa-457b-8507-24f98ab2868d"
393 | },
394 | "outputs": [],
395 | "source": [
396 | "%%bash\n",
397 | "\n",
398 | "g++ potato.cpp -o potato\n",
399 | "./potato"
400 | ]
401 | }
402 | ],
403 | "metadata": {
404 | "colab": {
405 | "provenance": []
406 | },
407 | "kernelspec": {
408 | "display_name": "Python 3.10.4 64-bit",
409 | "language": "python",
410 | "name": "python3"
411 | },
412 | "language_info": {
413 | "name": "python",
414 | "version": "3.10.4"
415 | },
416 | "vscode": {
417 | "interpreter": {
418 | "hash": "916dbcbb3f70747c44a77c7bcd40155683ae19c65e1c03b4aa3499c5328201f1"
419 | }
420 | }
421 | },
422 | "nbformat": 4,
423 | "nbformat_minor": 0
424 | }
425 |
--------------------------------------------------------------------------------
/demos/Week1/Week_1_Demo_Template.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "id": "M8AoKc-YofSA"
7 | },
8 | "source": [
9 | "# Week 1"
10 | ]
11 | },
12 | {
13 | "cell_type": "markdown",
14 | "metadata": {
15 | "id": "1lbYclUZn-Eo"
16 | },
17 | "source": [
18 | "## Typing for Coding\n",
19 | "\n",
20 | "* In C / C++, '//' is a comment. The compiler ignores this!\n",
21 | "* CTRL + Left / Right Arrow Key: Jump Forward / Back a word.\n",
22 | "* CTRL + Backspace: Delete previous word (in Linux terminal, its CTRL + w instead)\n",
23 | "* CTRL + /: Comment out current line. If you highlight a larger block of text with your mouse, CTRL + / \n",
24 | "will comment out the whole block!\n",
25 | "\n",
26 | "There are obviously more keyboard shortcuts that these. But if you are obsessed with peak efficiency, \n",
27 | "go be a vimChad in the corner over there. There. I said it."
28 | ]
29 | },
30 | {
31 | "cell_type": "markdown",
32 | "metadata": {
33 | "id": "ujAgFpyLouG3"
34 | },
35 | "source": [
36 | "## How to use this Demo\n",
37 | "\n",
38 | "This is a Jupyter Notebook. Obviously, Jupyter notebooks are meant for Python, not C++. However, Google Colab seamlessly integrates text with a fully functional Linux environment. Therefore, we can still write C++ code, compile it, and execute it!"
39 | ]
40 | },
41 | {
42 | "cell_type": "markdown",
43 | "metadata": {
44 | "id": "iR83YdNPj7Hk"
45 | },
46 | "source": [
47 | "Writing C++ for this demo has 2 parts:\n",
48 | "* creating a file\n",
49 | "* compiling and executing the compiled code\n",
50 | "\n",
51 | "The code block below first writes the file. The `%%writefile hello_world.cpp` command tells Google Colab to create a file called `hello_world.cpp`.\n",
52 | "\n",
53 | "First, run this cell by hitting \"CTRL + Enter\" or by pressing the \"Play\" button. Then, if you click on the file icon on the left, you will see a \"hello_world.cpp\" file there!"
54 | ]
55 | },
56 | {
57 | "cell_type": "code",
58 | "execution_count": null,
59 | "metadata": {
60 | "colab": {
61 | "base_uri": "https://localhost:8080/"
62 | },
63 | "id": "rTjyi-pqp1OA",
64 | "outputId": "f3254ef1-a329-4ca5-cc60-2ff5663744fe"
65 | },
66 | "outputs": [],
67 | "source": [
68 | "%%writefile hello_world.cpp\n",
69 | "\n",
70 | "#include \n",
71 | "\n",
72 | "int main() {\n",
73 | " std::cout << \"Hello World!\" << std::endl;\n",
74 | " return 0;\n",
75 | "}"
76 | ]
77 | },
78 | {
79 | "cell_type": "markdown",
80 | "metadata": {
81 | "id": "qyHMmN4Rj508"
82 | },
83 | "source": [
84 | "The second step is to compile and run your code. There are two places where things can go wrong: compilation and execution.\n",
85 | "\n",
86 | "A compilation error occurs when the compiler is unable to compile your code. Most of the time, a compilation error indicates that you violated a rule of C++. For example, you may have forgotten to end one of your lines in a semicolon or forgot to close a curly brace. You can tell if its a compiler error if the terminal mentions g++, the compiler we are using.\n",
87 | "\n",
88 | "A runtime error occurs when your program does something improper while its being executed. Common infractions are dividing by zero or writing to an unauthorized memory location. You can tell if its a runtime error if the terminal mentions the name of your program."
89 | ]
90 | },
91 | {
92 | "cell_type": "code",
93 | "execution_count": null,
94 | "metadata": {
95 | "colab": {
96 | "base_uri": "https://localhost:8080/"
97 | },
98 | "id": "SiQ-eccnh4lO",
99 | "outputId": "980ce7a9-5e01-4981-c495-82883441d9c2"
100 | },
101 | "outputs": [],
102 | "source": [
103 | "%%bash\n",
104 | "\n",
105 | "g++ hello_world.cpp -o hello_world\n",
106 | "./hello_world"
107 | ]
108 | },
109 | {
110 | "cell_type": "markdown",
111 | "metadata": {
112 | "id": "aqhh_ioameET"
113 | },
114 | "source": [
115 | "## Variable Types\n",
116 | "\n",
117 | "Complete all of the instrucions listed in the comments. Then, try compiling and running you code!"
118 | ]
119 | },
120 | {
121 | "cell_type": "code",
122 | "execution_count": null,
123 | "metadata": {
124 | "colab": {
125 | "base_uri": "https://localhost:8080/"
126 | },
127 | "id": "JklX2ZBBmgyr",
128 | "outputId": "2cdf2699-e083-45c4-d20a-5c107a22a2af"
129 | },
130 | "outputs": [],
131 | "source": [
132 | "%%writefile variables.cpp\n",
133 | "\n",
134 | "#include \n",
135 | "#include \n",
136 | "\n",
137 | "int main() {\n",
138 | " \n",
139 | " // Create an INTEGER named 'myInt', assign it a value '-17'\n",
140 | "\n",
141 | " // Create a DOUBLE named 'myDouble', assign it a value '1.23'\n",
142 | " \n",
143 | " //Create a CHARACTER named 'myChar', assign it a value 'c'\n",
144 | " \n",
145 | " // Create a std::STRING named 'myString', assign it a value \"Hello World!\" \n",
146 | " \n",
147 | " // Create a BOOLEAN named 'myBool', assign it a value 'false'\n",
148 | " \n",
149 | "\n",
150 | " // DO NOT EDIT!\n",
151 | " std::cout << \"This is an integer: \" << myInt << std::endl;\n",
152 | " std::cout << \"This is a double: \" << myDouble << std::endl;\n",
153 | " std::cout << \"This is a character: \" << myChar << std::endl;\n",
154 | " std::cout << \"This is a string: \" << myString << std::endl;\n",
155 | " std::cout << \"This is a bool: \" << myBool << std::endl;\n",
156 | "\n",
157 | " return 0;\n",
158 | "}"
159 | ]
160 | },
161 | {
162 | "cell_type": "code",
163 | "execution_count": null,
164 | "metadata": {
165 | "colab": {
166 | "base_uri": "https://localhost:8080/"
167 | },
168 | "id": "UL7xYQfpnQbz",
169 | "outputId": "2d8b5d26-adba-4fbb-d8c0-5c2f381bfd00"
170 | },
171 | "outputs": [],
172 | "source": [
173 | "%%bash\n",
174 | "\n",
175 | "g++ variables.cpp -o variables\n",
176 | "./variables"
177 | ]
178 | },
179 | {
180 | "cell_type": "markdown",
181 | "metadata": {
182 | "id": "IJ9lWoTSnhqe"
183 | },
184 | "source": [
185 | "## Arithmetic"
186 | ]
187 | },
188 | {
189 | "cell_type": "code",
190 | "execution_count": null,
191 | "metadata": {
192 | "colab": {
193 | "base_uri": "https://localhost:8080/"
194 | },
195 | "id": "77TaPtNvni-r",
196 | "outputId": "4a1e6434-5e30-47a4-f8d9-82e0fe1142c7"
197 | },
198 | "outputs": [],
199 | "source": [
200 | "%%writefile arithmetic.cpp\n",
201 | "\n",
202 | "#include \n",
203 | "#include \n",
204 | "\n",
205 | "int main() {\n",
206 | " \n",
207 | " int a = 8;\n",
208 | " int b = 3;\n",
209 | "\n",
210 | " // Create an INTEGER named 'mySum', assign it to the sum of a and b\n",
211 | " \n",
212 | " // Create an INTEGER named 'myDiff', assign it to the difference of a and b\n",
213 | " \n",
214 | " // Create an INTEGER named 'myDiff', assign it to the product of a and b\n",
215 | " \n",
216 | " // Create an INTEGER named 'myQuot', assign it to the quotient of a and b\n",
217 | " \n",
218 | " // Create an INTEGER named 'myMod', assign it to the modulo of a and b\n",
219 | " \n",
220 | "\n",
221 | " // DO NOT EDIT!\n",
222 | "\n",
223 | " std::cout << \"a = \" << a << \", b = \" << b << std::endl;\n",
224 | " std::cout << \"Sum: \" << mySum << std::endl;\n",
225 | " std::cout << \"Difference: \" << myDiff << std::endl;\n",
226 | " std::cout << \"Product: \" << myProd << std::endl;\n",
227 | " std::cout << \"Quotient: \" << myQuot << std::endl;\n",
228 | " std::cout << \"Modulo: \" << myMod << std::endl;\n",
229 | "\n",
230 | " return 0;\n",
231 | "}"
232 | ]
233 | },
234 | {
235 | "cell_type": "code",
236 | "execution_count": null,
237 | "metadata": {
238 | "colab": {
239 | "base_uri": "https://localhost:8080/"
240 | },
241 | "id": "AKQi129SnyG-",
242 | "outputId": "e04cad16-afe2-468f-cc3c-99a7a54e1532"
243 | },
244 | "outputs": [],
245 | "source": [
246 | "%%bash\n",
247 | "\n",
248 | "g++ arithmetic.cpp -o arithmetic\n",
249 | "./arithmetic"
250 | ]
251 | },
252 | {
253 | "cell_type": "markdown",
254 | "metadata": {
255 | "id": "gBdyeDqUn649"
256 | },
257 | "source": [
258 | "## Relational Operators"
259 | ]
260 | },
261 | {
262 | "cell_type": "code",
263 | "execution_count": null,
264 | "metadata": {
265 | "colab": {
266 | "base_uri": "https://localhost:8080/"
267 | },
268 | "id": "OcEjALGin8eO",
269 | "outputId": "cf5d3a69-c906-4192-eb78-664ec73b2a33"
270 | },
271 | "outputs": [],
272 | "source": [
273 | "%%writefile isEqual.cpp\n",
274 | "\n",
275 | "#include \n",
276 | "#include \n",
277 | "\n",
278 | "int main() {\n",
279 | " \n",
280 | " int x = 4;\n",
281 | " int y = 2;\n",
282 | " int z = 0b0100;\n",
283 | "\n",
284 | " //Create a BOOLEAN named 'equals', assign it to the result of x equals y\n",
285 | " \n",
286 | " //Create a BOOLEAN named 'notEquals', assign it to the result of x not equals y\n",
287 | " \n",
288 | " //Create a BOOLEAN named 'greaterThan', assign it to the result of x greater than y\n",
289 | " \n",
290 | " //Create a BOOLEAN named 'lessThan', assign it to the result of x less than y\n",
291 | " \n",
292 | " //Create a BOOLEAN named 'geq', assign it to the result of x greater than or equal to y\n",
293 | " \n",
294 | " //Create a BOOLEAN named 'leq', assign it to the result of x less than or equal to z\n",
295 | " \n",
296 | "\n",
297 | " // DO NOT EDIT!\n",
298 | " std::cout << \"x = \" << x << \", y = \" << y << \", z = \" << z << std::endl;\n",
299 | " std::cout << \"x equal to y? \" << equals << std::endl;\n",
300 | " std::cout << \"x not equal to z? \" << notEquals << std::endl;\n",
301 | " std::cout << \"x greater than y? \" << greaterThan << std::endl;\n",
302 | " std::cout << \"x less than z? \" << lessThan << std::endl;\n",
303 | " std::cout << \"x greater than or equal to y? \" << geq << std::endl;\n",
304 | " std::cout << \"x less than or equal to z? \" << leq << std::endl;\n",
305 | "\n",
306 | " return 0;\n",
307 | "}"
308 | ]
309 | },
310 | {
311 | "cell_type": "code",
312 | "execution_count": null,
313 | "metadata": {
314 | "colab": {
315 | "base_uri": "https://localhost:8080/"
316 | },
317 | "id": "LoAn6IJVoIBt",
318 | "outputId": "c066b5a1-8ac0-47c4-e7ea-3f60844372c4"
319 | },
320 | "outputs": [],
321 | "source": [
322 | "%%bash\n",
323 | "\n",
324 | "g++ isEqual.cpp -o isEqual\n",
325 | "./isEqual"
326 | ]
327 | },
328 | {
329 | "cell_type": "markdown",
330 | "metadata": {
331 | "id": "jJXxw62YpK45"
332 | },
333 | "source": [
334 | "## Conditionals (If / Else)"
335 | ]
336 | },
337 | {
338 | "cell_type": "code",
339 | "execution_count": null,
340 | "metadata": {
341 | "colab": {
342 | "base_uri": "https://localhost:8080/"
343 | },
344 | "id": "R6Mspz9ApPi0",
345 | "outputId": "8e0a9a0b-afc9-4dd6-8e25-a90e440deb8e"
346 | },
347 | "outputs": [],
348 | "source": [
349 | "%%writefile potato.cpp\n",
350 | "\n",
351 | "#include \n",
352 | "#include \n",
353 | "\n",
354 | "int main() {\n",
355 | " \n",
356 | " bool potato = true;\n",
357 | " double myGrade = 0;\n",
358 | "\n",
359 | " // If potato is true, then set myGrade to 76. \n",
360 | " // Otherwise, set myGrade to 95.\n",
361 | "\n",
362 | " std::cout << \"potato = \" << potato << \", myGrade = \" << myGrade << std::endl;\n",
363 | "\n",
364 | " // If myGrade is at least 90, print out \"A\"\n",
365 | " // If myGrade is at least 80, print out \"B\"\n",
366 | " // Otherwise, print out \"I didn't even know grades went this low!\"\n",
367 | "\n",
368 | " return 0;\n",
369 | "}"
370 | ]
371 | },
372 | {
373 | "cell_type": "code",
374 | "execution_count": null,
375 | "metadata": {
376 | "colab": {
377 | "base_uri": "https://localhost:8080/"
378 | },
379 | "id": "PmdJeVSjpZaQ",
380 | "outputId": "0a9e1f2a-bafa-457b-8507-24f98ab2868d"
381 | },
382 | "outputs": [],
383 | "source": [
384 | "%%bash\n",
385 | "\n",
386 | "g++ potato.cpp -o potato\n",
387 | "./potato"
388 | ]
389 | }
390 | ],
391 | "metadata": {
392 | "colab": {
393 | "provenance": []
394 | },
395 | "kernelspec": {
396 | "display_name": "Python 3",
397 | "name": "python3"
398 | },
399 | "language_info": {
400 | "name": "python"
401 | }
402 | },
403 | "nbformat": 4,
404 | "nbformat_minor": 0
405 | }
406 |
--------------------------------------------------------------------------------
/demos/Week2/Week_2_Demo_Solution.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "id": "gjT7QCBsrIxk"
7 | },
8 | "source": [
9 | "# Week 2"
10 | ]
11 | },
12 | {
13 | "cell_type": "markdown",
14 | "metadata": {
15 | "id": "ExUggTKIrc-U"
16 | },
17 | "source": [
18 | "## Functions in C++"
19 | ]
20 | },
21 | {
22 | "cell_type": "markdown",
23 | "metadata": {
24 | "id": "4jpE1RaN1Hsh"
25 | },
26 | "source": [
27 | "### Declaring, Defining, and Calling Functions"
28 | ]
29 | },
30 | {
31 | "cell_type": "markdown",
32 | "metadata": {
33 | "id": "6tufB2RGwlSG"
34 | },
35 | "source": [
36 | "**Declare** a function `mult` which multiplies two integers `a` and `b` and returns the result:\n",
37 | "```\n",
38 | "int mult(int a, int b);\n",
39 | "```\n",
40 | "\n",
41 | "**Define** mult:\n",
42 | "\n",
43 | "```\n",
44 | "int mult(int a, int b) {\n",
45 | " return a * b;\n",
46 | "}\n",
47 | "```\n",
48 | "\n",
49 | "Call **mult** to calculate the product of `3` and `9`:\n",
50 | "\n",
51 | "```\n",
52 | "int main() {\n",
53 | " int result = mult(3, 9);\n",
54 | " return 0;\n",
55 | "}\n",
56 | "```\n"
57 | ]
58 | },
59 | {
60 | "cell_type": "markdown",
61 | "metadata": {
62 | "id": "c4MKN1jg1M5a"
63 | },
64 | "source": [
65 | "### Demo, Part 1"
66 | ]
67 | },
68 | {
69 | "cell_type": "code",
70 | "execution_count": null,
71 | "metadata": {
72 | "colab": {
73 | "base_uri": "https://localhost:8080/"
74 | },
75 | "id": "FA1383het0_5",
76 | "outputId": "a50c288e-f14e-45a0-8d4a-caf83159f575"
77 | },
78 | "outputs": [
79 | {
80 | "name": "stdout",
81 | "output_type": "stream",
82 | "text": [
83 | "Overwriting functions.cpp\n"
84 | ]
85 | }
86 | ],
87 | "source": [
88 | "%%writefile functions.cpp\n",
89 | "\n",
90 | "// TODO: Include the iostream library here\n",
91 | "#include \n",
92 | "\n",
93 | "// TODO: Declare a function named \"add\", which takes two integers \"a\" and \"b\" \n",
94 | "// as arguments and returns an integer.\n",
95 | "\n",
96 | "int add(int a, int b);\n",
97 | "\n",
98 | "// TODO: Declare a function named \"fib\", which takes one integer \"n\" as an\n",
99 | "// argument and returns an integer.\n",
100 | "\n",
101 | "int fib(int n);\n",
102 | "\n",
103 | "// TODO: Define the \"add\" function here, which returns the sum of \"a\" and \"b\"\n",
104 | "\n",
105 | "int add(int a, int b) {\n",
106 | " return a + b;\n",
107 | "}\n",
108 | "\n",
109 | "// TODO: Define the \"fib\" function here, which returns the nth fibonacci\n",
110 | "// number.\n",
111 | "// NOTE: f0 = 0, f1 = 1, fn = f_{n-1} + f_{n-2}\n",
112 | "\n",
113 | "int fib(int n) {\n",
114 | " if (n == 0) {\n",
115 | " return 0;\n",
116 | " } else if (n == 1) {\n",
117 | " return 1;\n",
118 | " } else {\n",
119 | " int f_n1 = fib(n - 1);\n",
120 | " int f_n2 = fib(n - 2);\n",
121 | " return f_n1 + f_n2;\n",
122 | " }\n",
123 | "}\n",
124 | "\n",
125 | "\n",
126 | "// DO NOT EDIT!\n",
127 | "int main() {\n",
128 | " \n",
129 | " for (int i = 0; i <= 7; i++) {\n",
130 | " std::cout << i << \": \" << fib(i) << std::endl;\n",
131 | " }\n",
132 | " \n",
133 | " return 0;\n",
134 | "}"
135 | ]
136 | },
137 | {
138 | "cell_type": "code",
139 | "execution_count": null,
140 | "metadata": {
141 | "colab": {
142 | "base_uri": "https://localhost:8080/"
143 | },
144 | "id": "XsdnKQLAv4Ua",
145 | "outputId": "031f5242-9b73-4b4f-ce22-a7b6117b6845"
146 | },
147 | "outputs": [
148 | {
149 | "name": "stdout",
150 | "output_type": "stream",
151 | "text": [
152 | "0: 0\n",
153 | "1: 1\n",
154 | "2: 1\n",
155 | "3: 2\n",
156 | "4: 3\n",
157 | "5: 5\n",
158 | "6: 8\n",
159 | "7: 13\n"
160 | ]
161 | }
162 | ],
163 | "source": [
164 | "%%bash\n",
165 | "\n",
166 | "g++ functions.cpp -o functions\n",
167 | "./functions"
168 | ]
169 | },
170 | {
171 | "cell_type": "markdown",
172 | "metadata": {
173 | "id": "7EYkKJ_Kwe7n"
174 | },
175 | "source": [
176 | "## Variable Scope, For Loops, While Loops"
177 | ]
178 | },
179 | {
180 | "cell_type": "markdown",
181 | "metadata": {
182 | "id": "MsBEZuRm0CT7"
183 | },
184 | "source": [
185 | "### Variable Scope"
186 | ]
187 | },
188 | {
189 | "cell_type": "markdown",
190 | "metadata": {
191 | "id": "d5wXOHU9wru2"
192 | },
193 | "source": [
194 | "A variable can only be used within the scope it is defined for. \n",
195 | "* A variable with **global** scope can be used anywhere in the program. You can make a global variable by declaring it outside of `main()`.\n",
196 | "* A variable with **local** scope means the variable is enclosed in some curly braces. You can only use the variable inside those curly braces. After that, you cannot use the local variable. Function arguments and loop counter variables count as local variables."
197 | ]
198 | },
199 | {
200 | "cell_type": "markdown",
201 | "metadata": {
202 | "id": "OqzD0EnY0LKV"
203 | },
204 | "source": [
205 | "### For Loop"
206 | ]
207 | },
208 | {
209 | "cell_type": "markdown",
210 | "metadata": {
211 | "id": "c2wVnq3T0SqX"
212 | },
213 | "source": [
214 | "Examples of `for` loops:\n",
215 | "```\n",
216 | "for (int i = 0; i < 10; i++) {}\n",
217 | "for (int j = 5; j >= 0; j--) {}\n",
218 | "for (int k = 0; k < 20; k += 2) {}\n",
219 | "```"
220 | ]
221 | },
222 | {
223 | "cell_type": "markdown",
224 | "metadata": {
225 | "id": "_HRmKezG0eb7"
226 | },
227 | "source": [
228 | "### While Loop"
229 | ]
230 | },
231 | {
232 | "cell_type": "markdown",
233 | "metadata": {
234 | "id": "XsY9dLWq0gfU"
235 | },
236 | "source": [
237 | "Example of a 'while` loop:\n",
238 | "```\n",
239 | "int count = 1;\n",
240 | "\n",
241 | "while (count <= 10 and count >= -10) {\n",
242 | " count *= -2;\n",
243 | "} \n",
244 | "```\n"
245 | ]
246 | },
247 | {
248 | "cell_type": "markdown",
249 | "metadata": {
250 | "id": "zfOk7OMw0n4W"
251 | },
252 | "source": [
253 | "### Infinite Loop"
254 | ]
255 | },
256 | {
257 | "cell_type": "markdown",
258 | "metadata": {
259 | "id": "F-1HpCzG0wFT"
260 | },
261 | "source": [
262 | "Examples of infinite loops:\n",
263 | "\n",
264 | "```\n",
265 | "while (true) {}\n",
266 | "for (;;) {}\n",
267 | "```\n"
268 | ]
269 | },
270 | {
271 | "cell_type": "markdown",
272 | "metadata": {
273 | "id": "9KLiJZ_-1Aj1"
274 | },
275 | "source": [
276 | "### Demo, Part 2"
277 | ]
278 | },
279 | {
280 | "cell_type": "code",
281 | "execution_count": null,
282 | "metadata": {
283 | "colab": {
284 | "base_uri": "https://localhost:8080/"
285 | },
286 | "id": "7tHFsAgz0_H0",
287 | "outputId": "38ca3645-583c-443b-8e30-8a0af6bac7bd"
288 | },
289 | "outputs": [
290 | {
291 | "name": "stdout",
292 | "output_type": "stream",
293 | "text": [
294 | "Overwriting looping.cpp\n"
295 | ]
296 | }
297 | ],
298 | "source": [
299 | "%%writefile looping.cpp\n",
300 | "\n",
301 | "#include \n",
302 | "\n",
303 | "int i = 5; // Global variable i\n",
304 | "\n",
305 | "int main() {\n",
306 | "\n",
307 | " std::cout << \"The value of 'i' before is: \" << i << std::endl;\n",
308 | " std::cout << \"For Loop\" << std::endl; \n",
309 | "\n",
310 | " // TODO: Write a for loop that \n",
311 | " // * declares a LOCAL variable i\n",
312 | " // * prints out the numbers from 0 to 9 using local variable i\n",
313 | "\n",
314 | " for (int i = 0; i < 10; i++) {\n",
315 | " std::cout << i;\n",
316 | " }\n",
317 | "\n",
318 | " std::cout << std::endl;\n",
319 | " std::cout << \"While Loop\" << std::endl; \n",
320 | "\n",
321 | " // TODO: Write a while loop that \n",
322 | " // * prints out the value of GLOBAL variable i, \n",
323 | " // * increments i by 2, and \n",
324 | " // * stops when i >= 7\n",
325 | "\n",
326 | " while (i < 7) {\n",
327 | " std::cout << i;\n",
328 | " i += 2;\n",
329 | " }\n",
330 | "\n",
331 | " std::cout << std::endl;\n",
332 | " std::cout << \"The value of 'i' after is: \" << i << std::endl;\n",
333 | "\n",
334 | " return 0;\n",
335 | "}"
336 | ]
337 | },
338 | {
339 | "cell_type": "code",
340 | "execution_count": null,
341 | "metadata": {
342 | "colab": {
343 | "base_uri": "https://localhost:8080/"
344 | },
345 | "id": "EAmyYL5M2LcR",
346 | "outputId": "7a781e25-8566-4db7-9577-64e42aed87bf"
347 | },
348 | "outputs": [
349 | {
350 | "name": "stdout",
351 | "output_type": "stream",
352 | "text": [
353 | "The value of 'i' before is: 5\n",
354 | "For Loop\n",
355 | "0123456789\n",
356 | "While Loop\n",
357 | "5\n",
358 | "The value of 'i' after is: 7\n"
359 | ]
360 | }
361 | ],
362 | "source": [
363 | "%%bash\n",
364 | "\n",
365 | "g++ looping.cpp -o looping\n",
366 | "./looping"
367 | ]
368 | },
369 | {
370 | "cell_type": "markdown",
371 | "metadata": {
372 | "id": "G5oNRbiL2eS3"
373 | },
374 | "source": [
375 | "## Arrays"
376 | ]
377 | },
378 | {
379 | "cell_type": "markdown",
380 | "metadata": {
381 | "id": "flYPq1gY2kEd"
382 | },
383 | "source": [
384 | "### Array Examples"
385 | ]
386 | },
387 | {
388 | "cell_type": "markdown",
389 | "metadata": {
390 | "id": "cuhbB35n21t0"
391 | },
392 | "source": [
393 | "Example 1:\n",
394 | "```\n",
395 | "int countMe[5];\n",
396 | "countMe = {1, 2, 3, 4, 5};\n",
397 | "```\n",
398 | "\n",
399 | "Example 2:\n",
400 | "\n",
401 | "```\n",
402 | "double magicNumbers[] = {0.94, 0.91, 0.15, 0.51};\n",
403 | "```\n",
404 | "\n",
405 | "Example 3:\n",
406 | "```\n",
407 | "char wrongColor[7];\n",
408 | "wrongColor[0] = 'c';\n",
409 | "wrongColor[1] = 'o';\n",
410 | "wrongColor[2] = 'l';\n",
411 | "wrongColor[3] = 'o';\n",
412 | "wrongColor[4] = 'u';\n",
413 | "wrongColor[5] = 'r';\n",
414 | "wrongColor[6] = '\\0';\n",
415 | "```\n",
416 | "\n",
417 | "Example 4:\n",
418 | "```\n",
419 | "char wrongColor[] = \"colour\";\n",
420 | "```"
421 | ]
422 | },
423 | {
424 | "cell_type": "markdown",
425 | "metadata": {
426 | "id": "r5cNdGkO5Bl2"
427 | },
428 | "source": [
429 | "### Demo, Part 3"
430 | ]
431 | },
432 | {
433 | "cell_type": "code",
434 | "execution_count": null,
435 | "metadata": {
436 | "colab": {
437 | "base_uri": "https://localhost:8080/"
438 | },
439 | "id": "sXSKlQgr5C5-",
440 | "outputId": "abac6037-e120-4d93-ecd8-69c96b09aadc"
441 | },
442 | "outputs": [
443 | {
444 | "name": "stdout",
445 | "output_type": "stream",
446 | "text": [
447 | "Writing betterFib.cpp\n"
448 | ]
449 | }
450 | ],
451 | "source": [
452 | "%%writefile betterFib.cpp\n",
453 | "\n",
454 | "#include \n",
455 | "\n",
456 | "int betterFib(int n);\n",
457 | "\n",
458 | "// TODO: Complete the function betterFib. Use an array instead of recursion!\n",
459 | "// * If n is 0 or 1, return the answer\n",
460 | "// * Otherwise, declare an array fibArr.\n",
461 | "// Determine the ith Fibonacci number using fibArr[i-1] and fibArr[i-2]\n",
462 | "// The last element in fibArr should be the answer!\n",
463 | "// NOTE: f0 = 0, f1 = 1, fn = f_{n-1} + f_{n-2}\n",
464 | "\n",
465 | "int betterFib(int n) {\n",
466 | " \n",
467 | " if (n == 0 or n == 1) \n",
468 | " return n;\n",
469 | " else {\n",
470 | " int fibArr[n+1];\n",
471 | " fibArr[0] = 0;\n",
472 | " fibArr[1] = 1;\n",
473 | " \n",
474 | " for (int i = 2; i <= n; i++)\n",
475 | " fibArr[i] = fibArr[i-1] + fibArr[i-2];\n",
476 | " \n",
477 | " return fibArr[n];\n",
478 | " }\n",
479 | "}\n",
480 | "\n",
481 | "int main() {\n",
482 | "\n",
483 | " // Test #1 for betterFib\n",
484 | " std::cout << \"Test: n = 0. \\n\\tExpected: 0 \\n\\tActual: \" << betterFib(0) << std::endl;\n",
485 | " std::cout << \"Test: n = 1. \\n\\tExpected: 1 \\n\\tActual: \" << betterFib(1) << std::endl;\n",
486 | "\n",
487 | " // Test #2 for betterFib\n",
488 | " std::cout << \"Test: n = 7. \\n\\tExpected: 13 \\n\\tActual: \" << betterFib(7) << std::endl;\n",
489 | " std::cout << \"Test: n = 45. \\n\\tExpected: 1134903170 \\n\\tActual: \" << betterFib(45) << std::endl;\n",
490 | "\n",
491 | " return 0;\n",
492 | "}"
493 | ]
494 | },
495 | {
496 | "cell_type": "code",
497 | "execution_count": null,
498 | "metadata": {
499 | "colab": {
500 | "base_uri": "https://localhost:8080/"
501 | },
502 | "id": "GFdSMuaT5w0-",
503 | "outputId": "6ceba22b-3824-4cad-a8c5-e028094fd046"
504 | },
505 | "outputs": [
506 | {
507 | "name": "stdout",
508 | "output_type": "stream",
509 | "text": [
510 | "Test: n = 0. \n",
511 | "\tExpected: 0 \n",
512 | "\tActual: 0\n",
513 | "Test: n = 1. \n",
514 | "\tExpected: 1 \n",
515 | "\tActual: 1\n",
516 | "Test: n = 7. \n",
517 | "\tExpected: 13 \n",
518 | "\tActual: 13\n",
519 | "Test: n = 45. \n",
520 | "\tExpected: 1134903170 \n",
521 | "\tActual: 1134903170\n"
522 | ]
523 | }
524 | ],
525 | "source": [
526 | "%%bash\n",
527 | "\n",
528 | "g++ betterFib.cpp -o betterFib\n",
529 | "./betterFib"
530 | ]
531 | },
532 | {
533 | "cell_type": "markdown",
534 | "metadata": {
535 | "id": "xCXwvXuc6Q6f"
536 | },
537 | "source": [
538 | "## Structs and C-strings"
539 | ]
540 | },
541 | {
542 | "cell_type": "markdown",
543 | "metadata": {
544 | "id": "pgYIcsL66Tqd"
545 | },
546 | "source": [
547 | "### Structs"
548 | ]
549 | },
550 | {
551 | "cell_type": "markdown",
552 | "metadata": {
553 | "id": "nubn2xXO6jt2"
554 | },
555 | "source": [
556 | "Example of a struct:\n",
557 | "\n",
558 | "```\n",
559 | "// Declaring & Defining a Struct\n",
560 | "struct {\n",
561 | " char cardSuite;\n",
562 | " int cardValue;\n",
563 | " bool deckHasCard;\n",
564 | "} CardInfo;\n",
565 | "\n",
566 | "// Initalizing a Struct\n",
567 | "struct CardInfo myCardInfo;\n",
568 | "myCardInfo.cardSuite = 'H';\n",
569 | "myCardInfo.cardValue = 5;\n",
570 | "myCardInfo.deckHasCard = false;\n",
571 | "```\n",
572 | "\n",
573 | "Typedef struct: \n",
574 | "```\n",
575 | "// Declaring & Defining a Struct\n",
576 | "typedef struct {\n",
577 | " char cardSuite;\n",
578 | " int cardValue;\n",
579 | " bool deckHasCard;\n",
580 | "} CardInfo;\n",
581 | "\n",
582 | "// Initalizing a Struct\n",
583 | "CardInfo myCardInfo ={.cardSuite = 'H', .cardValue = 5, .deckHasCard = false};\n",
584 | "```"
585 | ]
586 | },
587 | {
588 | "cell_type": "markdown",
589 | "metadata": {
590 | "id": "KG_jm5067-O0"
591 | },
592 | "source": [
593 | "### C strings"
594 | ]
595 | },
596 | {
597 | "cell_type": "markdown",
598 | "metadata": {
599 | "id": "Nr9Tom1A8PV-"
600 | },
601 | "source": [
602 | "How long is the string (really?)"
603 | ]
604 | },
605 | {
606 | "cell_type": "code",
607 | "execution_count": null,
608 | "metadata": {
609 | "colab": {
610 | "base_uri": "https://localhost:8080/"
611 | },
612 | "id": "qldb6ySk8V4_",
613 | "outputId": "9546aa61-471e-4ebf-9a3d-e5f3abd25776"
614 | },
615 | "outputs": [
616 | {
617 | "name": "stdout",
618 | "output_type": "stream",
619 | "text": [
620 | "Writing cStr.cpp\n"
621 | ]
622 | }
623 | ],
624 | "source": [
625 | "%%writefile cStr.cpp\n",
626 | "\n",
627 | "// The C standard library\n",
628 | "#include \n",
629 | "#include \n",
630 | "\n",
631 | "int main() {\n",
632 | "\n",
633 | " const char mystery[] = {'h', 'e', 'l', 'l', '0', '\\0', 'N', 'Y', 'C'};\n",
634 | " int mysteryLen = strlen(mystery);\n",
635 | "\n",
636 | " printf(\"Length of %s is %d.\", mystery, mysteryLen);\n",
637 | "\n",
638 | " return 0;\n",
639 | "}"
640 | ]
641 | },
642 | {
643 | "cell_type": "code",
644 | "execution_count": null,
645 | "metadata": {
646 | "colab": {
647 | "base_uri": "https://localhost:8080/"
648 | },
649 | "id": "ZWmGES2r8Cb0",
650 | "outputId": "5f38a491-0161-4307-e56f-2d1d87e2a4f4"
651 | },
652 | "outputs": [
653 | {
654 | "name": "stdout",
655 | "output_type": "stream",
656 | "text": [
657 | "Length of hell0 is 5."
658 | ]
659 | }
660 | ],
661 | "source": [
662 | "%%bash\n",
663 | "\n",
664 | "g++ cStr.cpp -o cStr\n",
665 | "./cStr"
666 | ]
667 | },
668 | {
669 | "cell_type": "markdown",
670 | "metadata": {
671 | "id": "A3o7nt19-SuS"
672 | },
673 | "source": [
674 | "Common C string operations\n",
675 | "```\n",
676 | "size_t strlen ( const char * str );\n",
677 | "char * strncpy ( char * destination, const char * source, size_t num );\n",
678 | "int strcmp ( const char * str1, const char * str2 );\n",
679 | "```"
680 | ]
681 | },
682 | {
683 | "cell_type": "markdown",
684 | "metadata": {
685 | "id": "uIqEn-0s_C_X"
686 | },
687 | "source": [
688 | "Don't willingly use C strings. It makes everyone sad :(\n",
689 | "\n",
690 | "Including you :((((\n",
691 | "\n",
692 | "Instead, use `std::string` from the `string` library.\n",
693 | "\n",
694 | "However, you should remember that strings are just an array of characters terminated by a `\\0` character. Under the hood, `std::string` is just a C string that protects you from doing something stupid.\n",
695 | "\n",
696 | "If you copy a `std::string` using the `=` operator, then something like `strncpy` is still occuring!\n"
697 | ]
698 | },
699 | {
700 | "cell_type": "markdown",
701 | "metadata": {
702 | "id": "AuxpgpUTA-ML"
703 | },
704 | "source": [
705 | "### Demo, Part 4"
706 | ]
707 | },
708 | {
709 | "cell_type": "code",
710 | "execution_count": null,
711 | "metadata": {
712 | "colab": {
713 | "base_uri": "https://localhost:8080/"
714 | },
715 | "id": "3ySbrNBGBCk1",
716 | "outputId": "526ae6e3-fc17-451d-b236-219b19c586df"
717 | },
718 | "outputs": [
719 | {
720 | "name": "stdout",
721 | "output_type": "stream",
722 | "text": [
723 | "Overwriting studentStruct.cpp\n"
724 | ]
725 | }
726 | ],
727 | "source": [
728 | "%%writefile studentStruct.cpp\n",
729 | "\n",
730 | "#include \n",
731 | "#include \n",
732 | "\n",
733 | "// Structs are a good way to organize related information!\n",
734 | "// TODO: Write a struct called \"StudentInfo\" which contains the following info:\n",
735 | "// * char array of size 30 called \"name\"\n",
736 | "// * uint8_t called \"age\"\n",
737 | "// * bool called \"isGoodStudent\"\n",
738 | "// HINT: use \"typedef\" so you can use \"StudentInfo\" instead of \"struct StudentInfo\"\n",
739 | "\n",
740 | "typedef struct{\n",
741 | " char name[30];\n",
742 | " int age;\n",
743 | " bool isGoodStudent;\n",
744 | "} StudentInfo;\n",
745 | "\n",
746 | "void allAboutYou(StudentInfo info);\n",
747 | "\n",
748 | "void allAboutYou(StudentInfo info) {\n",
749 | " printf(\"Hello! My name is %s\\n\", info.name);\n",
750 | " printf(\"I am %d years old!\\n\", info.age);\n",
751 | " printf(\"I am %s a good student!\\n\", (info.isGoodStudent ? \"\" : \"not \"));\n",
752 | "}\n",
753 | "\n",
754 | "int main() {\n",
755 | " StudentInfo info;\n",
756 | "\n",
757 | " // TODO: Now that you have created the StudentInfo struct, fill out the name, age, and isGoodStudent fields!\n",
758 | " // HINT: This is a rude introduction to C strings. Look up strncpy, strlen!\n",
759 | "\n",
760 | " char myName[30] = \"Andrew\";\n",
761 | " strncpy(info.name, myName, strlen(myName));\n",
762 | " info.age = 20;\n",
763 | " info.isGoodStudent = true;\n",
764 | "\n",
765 | " allAboutYou(info);\n",
766 | "\n",
767 | " return 0;\n",
768 | "}"
769 | ]
770 | },
771 | {
772 | "cell_type": "code",
773 | "execution_count": null,
774 | "metadata": {
775 | "colab": {
776 | "base_uri": "https://localhost:8080/"
777 | },
778 | "id": "G1OJegM2Bouw",
779 | "outputId": "31b300d0-d42e-4add-e07b-4edd2ef5007d"
780 | },
781 | "outputs": [
782 | {
783 | "name": "stdout",
784 | "output_type": "stream",
785 | "text": [
786 | "Hello! My name is Andrew\n",
787 | "I am 20 years old!\n",
788 | "I am a good student!\n"
789 | ]
790 | }
791 | ],
792 | "source": [
793 | "%%bash\n",
794 | "\n",
795 | "g++ studentStruct.cpp -o studentStruct\n",
796 | "./studentStruct"
797 | ]
798 | }
799 | ],
800 | "metadata": {
801 | "colab": {
802 | "provenance": []
803 | },
804 | "kernelspec": {
805 | "display_name": "Python 3.10.4 64-bit",
806 | "language": "python",
807 | "name": "python3"
808 | },
809 | "language_info": {
810 | "name": "python",
811 | "version": "3.10.4"
812 | },
813 | "vscode": {
814 | "interpreter": {
815 | "hash": "916dbcbb3f70747c44a77c7bcd40155683ae19c65e1c03b4aa3499c5328201f1"
816 | }
817 | }
818 | },
819 | "nbformat": 4,
820 | "nbformat_minor": 0
821 | }
822 |
--------------------------------------------------------------------------------
/demos/Week2/Week_2_Demo_Template.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "id": "gjT7QCBsrIxk"
7 | },
8 | "source": [
9 | "# Week 2"
10 | ]
11 | },
12 | {
13 | "cell_type": "markdown",
14 | "metadata": {
15 | "id": "ExUggTKIrc-U"
16 | },
17 | "source": [
18 | "## Functions in C++"
19 | ]
20 | },
21 | {
22 | "cell_type": "markdown",
23 | "metadata": {
24 | "id": "4jpE1RaN1Hsh"
25 | },
26 | "source": [
27 | "### Declaring, Defining, and Calling Functions"
28 | ]
29 | },
30 | {
31 | "cell_type": "markdown",
32 | "metadata": {
33 | "id": "6tufB2RGwlSG"
34 | },
35 | "source": [
36 | "**Declare** a function `mult` which multiplies two integers `a` and `b` and returns the result:\n",
37 | "```\n",
38 | "int mult(int a, int b);\n",
39 | "```\n",
40 | "\n",
41 | "**Define** mult:\n",
42 | "\n",
43 | "```\n",
44 | "int mult(int a, int b) {\n",
45 | " return a * b;\n",
46 | "}\n",
47 | "```\n",
48 | "\n",
49 | "Call **mult** to calculate the product of `3` and `9`:\n",
50 | "\n",
51 | "```\n",
52 | "int main() {\n",
53 | " int result = mult(3, 9);\n",
54 | " return 0;\n",
55 | "}\n",
56 | "```\n"
57 | ]
58 | },
59 | {
60 | "cell_type": "markdown",
61 | "metadata": {
62 | "id": "c4MKN1jg1M5a"
63 | },
64 | "source": [
65 | "### Demo, Part 1"
66 | ]
67 | },
68 | {
69 | "cell_type": "code",
70 | "execution_count": null,
71 | "metadata": {
72 | "colab": {
73 | "base_uri": "https://localhost:8080/"
74 | },
75 | "id": "FA1383het0_5",
76 | "outputId": "a50c288e-f14e-45a0-8d4a-caf83159f575"
77 | },
78 | "outputs": [],
79 | "source": [
80 | "%%writefile functions.cpp\n",
81 | "\n",
82 | "// TODO: Include the iostream library here\n",
83 | "\n",
84 | "\n",
85 | "// TODO: Declare a function named \"add\", which takes two integers \"a\" and \"b\" \n",
86 | "// as arguments and returns an integer.\n",
87 | "\n",
88 | "\n",
89 | "// TODO: Declare a function named \"fib\", which takes one integer \"n\" as an\n",
90 | "// argument and returns an integer.\n",
91 | "\n",
92 | "\n",
93 | "// TODO: Define the \"add\" function here, which returns the sum of \"a\" and \"b\"\n",
94 | "\n",
95 | "\n",
96 | "// TODO: Define the \"fib\" function here, which returns the nth fibonacci\n",
97 | "// number.\n",
98 | "// NOTE: f0 = 0, f1 = 1, fn = f_{n-1} + f_{n-2}\n",
99 | "\n",
100 | "\n",
101 | "// DO NOT EDIT!\n",
102 | "int main() {\n",
103 | " \n",
104 | " for (int i = 0; i <= 7; i++) {\n",
105 | " std::cout << i << \": \" << fib(i) << std::endl;\n",
106 | " }\n",
107 | " \n",
108 | " return 0;\n",
109 | "}"
110 | ]
111 | },
112 | {
113 | "cell_type": "code",
114 | "execution_count": null,
115 | "metadata": {
116 | "colab": {
117 | "base_uri": "https://localhost:8080/"
118 | },
119 | "id": "XsdnKQLAv4Ua",
120 | "outputId": "031f5242-9b73-4b4f-ce22-a7b6117b6845"
121 | },
122 | "outputs": [],
123 | "source": [
124 | "%%bash\n",
125 | "\n",
126 | "g++ functions.cpp -o functions\n",
127 | "./functions"
128 | ]
129 | },
130 | {
131 | "cell_type": "markdown",
132 | "metadata": {
133 | "id": "7EYkKJ_Kwe7n"
134 | },
135 | "source": [
136 | "## Variable Scope, For Loops, While Loops"
137 | ]
138 | },
139 | {
140 | "cell_type": "markdown",
141 | "metadata": {
142 | "id": "MsBEZuRm0CT7"
143 | },
144 | "source": [
145 | "### Variable Scope"
146 | ]
147 | },
148 | {
149 | "cell_type": "markdown",
150 | "metadata": {
151 | "id": "d5wXOHU9wru2"
152 | },
153 | "source": [
154 | "A variable can only be used within the scope it is defined for. \n",
155 | "* A variable with **global** scope can be used anywhere in the program. You can make a global variable by declaring it outside of `main()`.\n",
156 | "* A variable with **local** scope means the variable is enclosed in some curly braces. You can only use the variable inside those curly braces. After that, you cannot use the local variable. Function arguments and loop counter variables count as local variables."
157 | ]
158 | },
159 | {
160 | "cell_type": "markdown",
161 | "metadata": {
162 | "id": "OqzD0EnY0LKV"
163 | },
164 | "source": [
165 | "### For Loop"
166 | ]
167 | },
168 | {
169 | "cell_type": "markdown",
170 | "metadata": {
171 | "id": "c2wVnq3T0SqX"
172 | },
173 | "source": [
174 | "Examples of `for` loops:\n",
175 | "```\n",
176 | "for (int i = 0; i < 10; i++) {}\n",
177 | "for (int j = 5; j >= 0; j--) {}\n",
178 | "for (int k = 0; k < 20; k += 2) {}\n",
179 | "```"
180 | ]
181 | },
182 | {
183 | "cell_type": "markdown",
184 | "metadata": {
185 | "id": "_HRmKezG0eb7"
186 | },
187 | "source": [
188 | "### While Loop"
189 | ]
190 | },
191 | {
192 | "cell_type": "markdown",
193 | "metadata": {
194 | "id": "XsY9dLWq0gfU"
195 | },
196 | "source": [
197 | "Example of a 'while` loop:\n",
198 | "```\n",
199 | "int count = 1;\n",
200 | "\n",
201 | "while (count <= 10 and count >= -10) {\n",
202 | " count *= -2;\n",
203 | "} \n",
204 | "```\n"
205 | ]
206 | },
207 | {
208 | "cell_type": "markdown",
209 | "metadata": {
210 | "id": "zfOk7OMw0n4W"
211 | },
212 | "source": [
213 | "### Infinite Loop"
214 | ]
215 | },
216 | {
217 | "cell_type": "markdown",
218 | "metadata": {
219 | "id": "F-1HpCzG0wFT"
220 | },
221 | "source": [
222 | "Examples of infinite loops:\n",
223 | "\n",
224 | "```\n",
225 | "while (true) {}\n",
226 | "for (;;) {}\n",
227 | "```\n"
228 | ]
229 | },
230 | {
231 | "cell_type": "markdown",
232 | "metadata": {
233 | "id": "9KLiJZ_-1Aj1"
234 | },
235 | "source": [
236 | "### Demo, Part 2"
237 | ]
238 | },
239 | {
240 | "cell_type": "code",
241 | "execution_count": null,
242 | "metadata": {
243 | "colab": {
244 | "base_uri": "https://localhost:8080/"
245 | },
246 | "id": "7tHFsAgz0_H0",
247 | "outputId": "38ca3645-583c-443b-8e30-8a0af6bac7bd"
248 | },
249 | "outputs": [],
250 | "source": [
251 | "%%writefile looping.cpp\n",
252 | "\n",
253 | "#include \n",
254 | "\n",
255 | "int i = 5; // Global variable i\n",
256 | "\n",
257 | "int main() {\n",
258 | "\n",
259 | " std::cout << \"The value of 'i' before is: \" << i << std::endl;\n",
260 | " std::cout << \"For Loop\" << std::endl; \n",
261 | "\n",
262 | " // TODO: Write a for loop that \n",
263 | " // * declares a LOCAL variable i\n",
264 | " // * prints out the numbers from 0 to 9 using local variable i\n",
265 | "\n",
266 | "\n",
267 | "\n",
268 | " std::cout << std::endl;\n",
269 | " std::cout << \"While Loop\" << std::endl; \n",
270 | "\n",
271 | " // TODO: Write a while loop that \n",
272 | " // * prints out the value of GLOBAL variable i, \n",
273 | " // * increments i by 2, and \n",
274 | " // * stops when i >= 7\n",
275 | "\n",
276 | "\n",
277 | "\n",
278 | " std::cout << std::endl;\n",
279 | " std::cout << \"The value of 'i' after is: \" << i << std::endl;\n",
280 | "\n",
281 | " return 0;\n",
282 | "}"
283 | ]
284 | },
285 | {
286 | "cell_type": "code",
287 | "execution_count": null,
288 | "metadata": {
289 | "colab": {
290 | "base_uri": "https://localhost:8080/"
291 | },
292 | "id": "EAmyYL5M2LcR",
293 | "outputId": "7a781e25-8566-4db7-9577-64e42aed87bf"
294 | },
295 | "outputs": [],
296 | "source": [
297 | "%%bash\n",
298 | "\n",
299 | "g++ looping.cpp -o looping\n",
300 | "./looping"
301 | ]
302 | },
303 | {
304 | "cell_type": "markdown",
305 | "metadata": {
306 | "id": "G5oNRbiL2eS3"
307 | },
308 | "source": [
309 | "## Arrays"
310 | ]
311 | },
312 | {
313 | "cell_type": "markdown",
314 | "metadata": {
315 | "id": "flYPq1gY2kEd"
316 | },
317 | "source": [
318 | "### Array Examples"
319 | ]
320 | },
321 | {
322 | "cell_type": "markdown",
323 | "metadata": {
324 | "id": "cuhbB35n21t0"
325 | },
326 | "source": [
327 | "Example 1:\n",
328 | "```\n",
329 | "int countMe[5];\n",
330 | "countMe = {1, 2, 3, 4, 5};\n",
331 | "```\n",
332 | "\n",
333 | "Example 2:\n",
334 | "\n",
335 | "```\n",
336 | "double magicNumbers[] = {0.94, 0.91, 0.15, 0.51};\n",
337 | "```\n",
338 | "\n",
339 | "Example 3:\n",
340 | "```\n",
341 | "char wrongColor[7];\n",
342 | "wrongColor[0] = 'c';\n",
343 | "wrongColor[1] = 'o';\n",
344 | "wrongColor[2] = 'l';\n",
345 | "wrongColor[3] = 'o';\n",
346 | "wrongColor[4] = 'u';\n",
347 | "wrongColor[5] = 'r';\n",
348 | "wrongColor[6] = '\\0';\n",
349 | "```\n",
350 | "\n",
351 | "Example 4:\n",
352 | "```\n",
353 | "char wrongColor[] = \"colour\";\n",
354 | "```"
355 | ]
356 | },
357 | {
358 | "cell_type": "markdown",
359 | "metadata": {
360 | "id": "r5cNdGkO5Bl2"
361 | },
362 | "source": [
363 | "### Demo, Part 3"
364 | ]
365 | },
366 | {
367 | "cell_type": "code",
368 | "execution_count": null,
369 | "metadata": {
370 | "colab": {
371 | "base_uri": "https://localhost:8080/"
372 | },
373 | "id": "sXSKlQgr5C5-",
374 | "outputId": "abac6037-e120-4d93-ecd8-69c96b09aadc"
375 | },
376 | "outputs": [],
377 | "source": [
378 | "%%writefile betterFib.cpp\n",
379 | "\n",
380 | "#include \n",
381 | "\n",
382 | "int betterFib(int n);\n",
383 | "\n",
384 | "// TODO: Complete the function betterFib. Use an array instead of recursion!\n",
385 | "// * If n is 0 or 1, return the answer\n",
386 | "// * Otherwise, declare an array fibArr.\n",
387 | "// Determine the ith Fibonacci number using fibArr[i-1] and fibArr[i-2]\n",
388 | "// The last element in fibArr should be the answer!\n",
389 | "// NOTE: f0 = 0, f1 = 1, fn = f_{n-1} + f_{n-2}\n",
390 | "\n",
391 | "int betterFib(int n) {\n",
392 | " \n",
393 | "}\n",
394 | "\n",
395 | "int main() {\n",
396 | "\n",
397 | " // Test #1 for betterFib\n",
398 | " std::cout << \"Test: n = 0. \\n\\tExpected: 0 \\n\\tActual: \" << betterFib(0) << std::endl;\n",
399 | " std::cout << \"Test: n = 1. \\n\\tExpected: 1 \\n\\tActual: \" << betterFib(1) << std::endl;\n",
400 | "\n",
401 | " // Test #2 for betterFib\n",
402 | " std::cout << \"Test: n = 7. \\n\\tExpected: 13 \\n\\tActual: \" << betterFib(7) << std::endl;\n",
403 | " std::cout << \"Test: n = 45. \\n\\tExpected: 1134903170 \\n\\tActual: \" << betterFib(45) << std::endl;\n",
404 | "\n",
405 | " return 0;\n",
406 | "}"
407 | ]
408 | },
409 | {
410 | "cell_type": "code",
411 | "execution_count": null,
412 | "metadata": {
413 | "colab": {
414 | "base_uri": "https://localhost:8080/"
415 | },
416 | "id": "GFdSMuaT5w0-",
417 | "outputId": "6ceba22b-3824-4cad-a8c5-e028094fd046"
418 | },
419 | "outputs": [],
420 | "source": [
421 | "%%bash\n",
422 | "\n",
423 | "g++ betterFib.cpp -o betterFib\n",
424 | "./betterFib"
425 | ]
426 | },
427 | {
428 | "cell_type": "markdown",
429 | "metadata": {
430 | "id": "xCXwvXuc6Q6f"
431 | },
432 | "source": [
433 | "## Structs and C-strings"
434 | ]
435 | },
436 | {
437 | "cell_type": "markdown",
438 | "metadata": {
439 | "id": "pgYIcsL66Tqd"
440 | },
441 | "source": [
442 | "### Structs"
443 | ]
444 | },
445 | {
446 | "cell_type": "markdown",
447 | "metadata": {
448 | "id": "nubn2xXO6jt2"
449 | },
450 | "source": [
451 | "Example of a struct:\n",
452 | "\n",
453 | "```\n",
454 | "// Declaring & Defining a Struct\n",
455 | "struct {\n",
456 | " char cardSuite;\n",
457 | " int cardValue;\n",
458 | " bool deckHasCard;\n",
459 | "} CardInfo;\n",
460 | "\n",
461 | "// Initalizing a Struct\n",
462 | "struct CardInfo myCardInfo;\n",
463 | "myCardInfo.cardSuite = 'H';\n",
464 | "myCardInfo.cardValue = 5;\n",
465 | "myCardInfo.deckHasCard = false;\n",
466 | "```\n",
467 | "\n",
468 | "Typedef struct: \n",
469 | "```\n",
470 | "// Declaring & Defining a Struct\n",
471 | "typedef struct {\n",
472 | " char cardSuite;\n",
473 | " int cardValue;\n",
474 | " bool deckHasCard;\n",
475 | "} CardInfo;\n",
476 | "\n",
477 | "// Initalizing a Struct\n",
478 | "CardInfo myCardInfo ={.cardSuite = 'H', .cardValue = 5, .deckHasCard = false};\n",
479 | "```"
480 | ]
481 | },
482 | {
483 | "cell_type": "markdown",
484 | "metadata": {
485 | "id": "KG_jm5067-O0"
486 | },
487 | "source": [
488 | "### C strings"
489 | ]
490 | },
491 | {
492 | "cell_type": "markdown",
493 | "metadata": {
494 | "id": "Nr9Tom1A8PV-"
495 | },
496 | "source": [
497 | "How long is the string (really?)"
498 | ]
499 | },
500 | {
501 | "cell_type": "code",
502 | "execution_count": null,
503 | "metadata": {
504 | "colab": {
505 | "base_uri": "https://localhost:8080/"
506 | },
507 | "id": "qldb6ySk8V4_",
508 | "outputId": "9546aa61-471e-4ebf-9a3d-e5f3abd25776"
509 | },
510 | "outputs": [],
511 | "source": [
512 | "%%writefile cStr.cpp\n",
513 | "\n",
514 | "// The C standard library\n",
515 | "#include \n",
516 | "#include \n",
517 | "\n",
518 | "int main() {\n",
519 | "\n",
520 | " const char mystery[] = {'h', 'e', 'l', 'l', '0', '\\0', 'N', 'Y', 'C'};\n",
521 | " int mysteryLen = strlen(mystery);\n",
522 | "\n",
523 | " printf(\"Length of %s is %d.\", mystery, mysteryLen);\n",
524 | "\n",
525 | " return 0;\n",
526 | "}"
527 | ]
528 | },
529 | {
530 | "cell_type": "code",
531 | "execution_count": null,
532 | "metadata": {
533 | "colab": {
534 | "base_uri": "https://localhost:8080/"
535 | },
536 | "id": "ZWmGES2r8Cb0",
537 | "outputId": "5f38a491-0161-4307-e56f-2d1d87e2a4f4"
538 | },
539 | "outputs": [],
540 | "source": [
541 | "%%bash\n",
542 | "\n",
543 | "g++ cStr.cpp -o cStr\n",
544 | "./cStr"
545 | ]
546 | },
547 | {
548 | "cell_type": "markdown",
549 | "metadata": {
550 | "id": "A3o7nt19-SuS"
551 | },
552 | "source": [
553 | "Common C string operations\n",
554 | "```\n",
555 | "size_t strlen ( const char * str );\n",
556 | "char * strncpy ( char * destination, const char * source, size_t num );\n",
557 | "int strcmp ( const char * str1, const char * str2 );\n",
558 | "```"
559 | ]
560 | },
561 | {
562 | "cell_type": "markdown",
563 | "metadata": {
564 | "id": "uIqEn-0s_C_X"
565 | },
566 | "source": [
567 | "Don't willingly use C strings. It makes everyone sad :(\n",
568 | "\n",
569 | "Including you :((((\n",
570 | "\n",
571 | "Instead, use `std::string` from the `string` library.\n",
572 | "\n",
573 | "However, you should remember that strings are just an array of characters terminated by a `\\0` character. Under the hood, `std::string` is just a C string that protects you from doing something stupid.\n",
574 | "\n",
575 | "If you copy a `std::string` using the `=` operator, then something like `strncpy` is still occuring!\n"
576 | ]
577 | },
578 | {
579 | "cell_type": "markdown",
580 | "metadata": {
581 | "id": "AuxpgpUTA-ML"
582 | },
583 | "source": [
584 | "### Demo, Part 4"
585 | ]
586 | },
587 | {
588 | "cell_type": "code",
589 | "execution_count": null,
590 | "metadata": {
591 | "colab": {
592 | "base_uri": "https://localhost:8080/"
593 | },
594 | "id": "3ySbrNBGBCk1",
595 | "outputId": "526ae6e3-fc17-451d-b236-219b19c586df"
596 | },
597 | "outputs": [],
598 | "source": [
599 | "%%writefile studentStruct.cpp\n",
600 | "\n",
601 | "#include \n",
602 | "#include \n",
603 | "\n",
604 | "// Structs are a good way to organize related information!\n",
605 | "// TODO: Write a struct called \"StudentInfo\" which contains the following info:\n",
606 | "// * char array of size 30 called \"name\"\n",
607 | "// * uint8_t called \"age\"\n",
608 | "// * bool called \"isGoodStudent\"\n",
609 | "// HINT: use \"typedef\" so you can use \"StudentInfo\" instead of \"struct StudentInfo\"\n",
610 | "\n",
611 | "\n",
612 | "\n",
613 | "void allAboutYou(StudentInfo info);\n",
614 | "\n",
615 | "void allAboutYou(StudentInfo info) {\n",
616 | " printf(\"Hello! My name is %s\\n\", info.name);\n",
617 | " printf(\"I am %d years old!\\n\", info.age);\n",
618 | " printf(\"I am %s a good student!\\n\", (info.isGoodStudent ? \"\" : \"not \"));\n",
619 | "}\n",
620 | "\n",
621 | "int main() {\n",
622 | " StudentInfo info;\n",
623 | "\n",
624 | " // TODO: Now that you have created the StudentInfo struct, fill out the name, age, and isGoodStudent fields!\n",
625 | " // HINT: This is a rude introduction to C strings. Look up strncpy, strlen!\n",
626 | "\n",
627 | "\n",
628 | "\n",
629 | " allAboutYou(info);\n",
630 | "\n",
631 | " return 0;\n",
632 | "}"
633 | ]
634 | },
635 | {
636 | "cell_type": "code",
637 | "execution_count": null,
638 | "metadata": {
639 | "colab": {
640 | "base_uri": "https://localhost:8080/"
641 | },
642 | "id": "G1OJegM2Bouw",
643 | "outputId": "31b300d0-d42e-4add-e07b-4edd2ef5007d"
644 | },
645 | "outputs": [],
646 | "source": [
647 | "%%bash\n",
648 | "\n",
649 | "g++ studentStruct.cpp -o studentStruct\n",
650 | "./studentStruct"
651 | ]
652 | }
653 | ],
654 | "metadata": {
655 | "colab": {
656 | "provenance": []
657 | },
658 | "kernelspec": {
659 | "display_name": "Python 3.10.4 64-bit",
660 | "language": "python",
661 | "name": "python3"
662 | },
663 | "language_info": {
664 | "name": "python",
665 | "version": "3.10.6"
666 | },
667 | "vscode": {
668 | "interpreter": {
669 | "hash": "916dbcbb3f70747c44a77c7bcd40155683ae19c65e1c03b4aa3499c5328201f1"
670 | }
671 | }
672 | },
673 | "nbformat": 4,
674 | "nbformat_minor": 0
675 | }
676 |
--------------------------------------------------------------------------------
/labs/Week 1 Lab (Fall 2023).pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/labs/Week 1 Lab (Fall 2023).pdf
--------------------------------------------------------------------------------
/labs/Week 2 Lab (Fall 2023).pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/labs/Week 2 Lab (Fall 2023).pdf
--------------------------------------------------------------------------------
/labs/Week 3 Lab (2021-2022).pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/labs/Week 3 Lab (2021-2022).pdf
--------------------------------------------------------------------------------
/labs/Week 4 Lab (Fall 2023).pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/labs/Week 4 Lab (Fall 2023).pdf
--------------------------------------------------------------------------------
/latex/RoboJackets Training Firmware Setup Guide/images/Uno_to_Nano_burn_bootloader.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/RoboJackets Training Firmware Setup Guide/images/Uno_to_Nano_burn_bootloader.png
--------------------------------------------------------------------------------
/latex/RoboJackets Training Firmware Setup Guide/images/linux-arduino-ready.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/RoboJackets Training Firmware Setup Guide/images/linux-arduino-ready.png
--------------------------------------------------------------------------------
/latex/RoboJackets Training Firmware Setup Guide/images/linux-module-load-correct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/RoboJackets Training Firmware Setup Guide/images/linux-module-load-correct.png
--------------------------------------------------------------------------------
/latex/RoboJackets Training Firmware Setup Guide/images/linux-module-load-incorrect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/RoboJackets Training Firmware Setup Guide/images/linux-module-load-incorrect.png
--------------------------------------------------------------------------------
/latex/RoboJackets Training Firmware Setup Guide/images/linux-module-present.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/RoboJackets Training Firmware Setup Guide/images/linux-module-present.png
--------------------------------------------------------------------------------
/latex/RoboJackets Training Firmware Setup Guide/images/windows-arduino-ready.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/RoboJackets Training Firmware Setup Guide/images/windows-arduino-ready.png
--------------------------------------------------------------------------------
/latex/RoboJackets Training Firmware Setup Guide/images/windows-driver-setup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/RoboJackets Training Firmware Setup Guide/images/windows-driver-setup.png
--------------------------------------------------------------------------------
/latex/RoboJackets Training Firmware Setup Guide/images/windows-module-load-correct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/RoboJackets Training Firmware Setup Guide/images/windows-module-load-correct.png
--------------------------------------------------------------------------------
/latex/RoboJackets Training Firmware Setup Guide/images/windows-module-present.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/RoboJackets Training Firmware Setup Guide/images/windows-module-present.png
--------------------------------------------------------------------------------
/latex/RoboJackets Training Firmware Setup Guide/main.tex:
--------------------------------------------------------------------------------
1 | \documentclass{article}
2 |
3 | \usepackage{geometry}
4 | \usepackage{flafter}
5 | \usepackage{listings}
6 | \usepackage{graphicx}
7 | \usepackage{tcolorbox}
8 | \usepackage{textcomp}
9 | \usepackage{gensymb}
10 | \usepackage{indentfirst}
11 | \usepackage{romannum}
12 | \usepackage{vhistory}
13 | \usepackage{cprotect}
14 | \usepackage{hyperref}
15 |
16 | % change margins
17 | \geometry{letterpaper, portrait, margin=1in}
18 |
19 | % graphics in images/ folder
20 | \graphicspath{ {images/} }
21 |
22 | % for lstlisting code environment
23 | \lstdefinestyle{bashstyle}{
24 | language=bash,
25 | basicstyle=\ttfamily,
26 | keywordstyle=\color{blue},
27 | commentstyle=\color{green},
28 | numberstyle=\tiny\color{gray},
29 | numbers=left,
30 | breaklines=true
31 | }
32 |
33 | % settings for /href
34 | \hypersetup{
35 | colorlinks=true,
36 | linkcolor=black,
37 | filecolor=magenta,
38 | urlcolor=blue,
39 | }
40 |
41 | \title{RoboJackets Training Firmware Setup Guide}
42 | \author{Andrew Roach}
43 | \date{\today\\v1.1}
44 |
45 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
46 | %% NOTE TO EDITOR: %%
47 | %% 1. Please update the version number and the version history when making changes. %%
48 | %% 2. This is a living document. If the hardware or software requirements change, this document %%
49 | %% should change. %%
50 | %% 3. Keep it simple! Don't include unnecessary or extraneous information. Try to minimize %%
51 | %% linking to external websites; explain everything the reader needs to know clearly and %%
52 | %% concisely. %%
53 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
54 |
55 | \begin{document}
56 | \maketitle{}
57 | \setcounter{tocdepth}{2}
58 | \tableofcontents
59 | \pagebreak
60 |
61 | \begin{versionhistory}
62 | \vhEntry{1.0}{9/22/23}{Andrew Roach}{Created}
63 | \vhEntry{1.1}{10/6/23}{Andrew Roach}{Removed section on Verifying CH340 drivers, added section on updating Arduino Nano bootloader.}
64 | \end{versionhistory}
65 |
66 | \clearpage
67 |
68 | \section{Installing the Arduino IDE}
69 |
70 | We will be using the legacy version of the Arduino IDE (version 1.8.19). Follow the installation instructions based on your platform.
71 |
72 | \subsection{Windows and Mac}
73 |
74 | \begin{enumerate}
75 | \item Go to \url{https://www.arduino.cc/en/software} and scroll down to ``Legacy IDE (1.8.X)''. Download the binary corresponding to your platform.
76 | \item Run the installer. Allow the installer to install everything, including drivers.
77 | \end{enumerate}
78 |
79 | \subsection{Linux}
80 |
81 | \begin{enumerate}
82 | \item Go to \url{https://www.arduino.cc/en/software} and scroll down to the ``Legacy IDE (1.8.X)''. The Linux Arduino IDE should download as a \verb|tar.xz| file.
83 | \item Run the following commands, replacing \verb|| with the name of the downloaded file.
84 | \begin{lstlisting}[style=bashstyle, label=lst:mybashcode]
85 | tar -xJvf .tar.xz -C /home/$(whoami)
86 | cd /home/$(whoami)/
87 | sudo ./install.sh
88 | \end{lstlisting}
89 | \end{enumerate}
90 |
91 | \newpage
92 |
93 | % \section{Verify CH340 Drivers}
94 |
95 | % Our Arduino Nanos are kinda old, so they often don't work out of the box without installing the correct drivers first. Your operating system or the installation of the Arduino IDE might have installed the correct drivers, so it's a good idea to check if you have the driver before reinstalling them.
96 |
97 | % \subsection{Checking CH340 Drivers on Windows}
98 |
99 | % {\bf Checking if driver is present: } type \verb|driverquery| into the command prompt. You should see a driver called \verb|CH341SER|.
100 |
101 | % \begin{figure}[ht]
102 | % \centering
103 | % \includegraphics[width = 0.7\textwidth]{images/windows-module-present.png}
104 | % \cprotect\caption{Output of the command \verb|driverquery| on Windows system. \verb|CH341SER| driver module is present.}
105 | % \end{figure}
106 |
107 | % \vspace{1em}
108 |
109 | % {\bf Checking if driver loads: } Plug the Arduino Nano into your computer. Go to \verb|Device Manager| and look under \verb|Ports|. You should see the Arduino Nano as \verb|USB-SERIAL CH340|, followed by the \verb|COM| port it's associated with.
110 |
111 | % \begin{figure}[ht]
112 | % \centering
113 | % \includegraphics[width = 0.4\textwidth]{images/windows-module-load-correct.png}
114 | % \cprotect\caption{Windows Device Manager displaying Arduino Nano plugged into COM6}
115 | % \end{figure}
116 |
117 | % \begin{figure}[ht]
118 | % \centering
119 | % \includegraphics[width = 0.7\textwidth]{images/windows-arduino-ready.png}
120 | % \cprotect\caption{Arduino IDE on Windows with Arduino Nano plugged in. If the driver has been installed correctly, you should see the Arduino Nano show up in the Arduino IDE under \verb|Tools > Port| which matches the COM port in Device Manager.}
121 | % \end{figure}
122 |
123 | % \newpage
124 |
125 | % \subsection{Checking CH340 Drivers on Linux}
126 |
127 | % {\bf Checking if module is present: } type \verb|modinfo ch341| into your shell. The command should return a bunch of information about the \verb|ch341| kernel module.
128 |
129 | % \begin{figure}[ht]
130 | % \centering
131 | % \includegraphics[width = 0.7\textwidth]{images/linux-module-present.png}
132 | % \cprotect\caption{Output of command \verb|modinfo ch341| on Linux system. \verb|ch341| Linux kernel module is present.}
133 | % \end{figure}
134 |
135 | % \vspace{1em}
136 |
137 | % {\bf Checking if module loads: } Plug the Arduino Nano into your computer. Enter the command \verb|sudo dmesg| into your shell.
138 |
139 | % \begin{itemize}
140 | % \item If you see the following, you need to uninstall \verb|brltty|. After uninstalling \verb|brltty|, unplug and plug in the Arduino Nano and run \verb|sudo dmesg| again.
141 | % \begin{itemize}
142 | % \item Ubuntu: \verb|sudo apt remove brltty|.
143 | % \end{itemize}
144 |
145 | % \begin{figure}[ht]
146 | % \centering
147 | % \includegraphics[width = 0.7\textwidth]{images/linux-module-load-incorrect.png}
148 | % \cprotect\caption{Output of command \verb|sudo dmesg| on Linux system after plugging in Arduino Nano. \verb|brltty| is interfering with the \verb|ch341| kernel module.}
149 | % \end{figure}
150 |
151 | % \item If you see the following, type \verb|ls /dev/tty*|. You should see the Arduino Nano show up as \verb|/dev/ttyUSB[0-9]| or \verb|/dev/ttyACM[0-9]|. This indicates that the kernel module has loaded successfully.
152 |
153 | % \begin{figure}[ht]
154 | % \centering
155 | % \includegraphics[width = 0.7\textwidth]{images/linux-module-load-correct.png}
156 | % \cprotect\caption{Output of command \verb|sudo dmesg| on Linux system after plugging in Arduino Nano. \verb|ch341| Linux kernel module has loaded correctly.}
157 | % \end{figure}
158 |
159 | % \begin{figure}[ht]
160 | % \centering
161 | % \includegraphics[width = 0.7\textwidth]{images/linux-arduino-ready.png}
162 | % \cprotect\caption{Arduino IDE on Linux with Arduino Nano plugged in. If the driver has been installed correctly, you should see the Arduino Nano show up in the Arduino IDE under \verb|Tools > Port| as either \verb|/dev/ttyUSB[0-9]| or \verb|/dev/ttyACM[0-9]|.}
163 | % \end{figure}
164 |
165 | % \end{itemize}
166 |
167 | % \clearpage
168 |
169 | \section{Installing CH340 Drivers}
170 |
171 | MacOS and Linux users should have the correct drivers already, so no further action is needed. However, Windows users have to install an older driver version.
172 |
173 | \subsection{Installing CH340 Drivers on Windows}
174 |
175 | At the time of writing, the most recent version of the USB-SERIAL CH340/CH341 driver is v.3.8.2023.2. {\bf You must install v.3.5.2019.1!} The v.3.8.2023.2 version of the driver is incompatible with the Arduino Nanos we have! Download the driver at:
176 | \begin{center}
177 | \url{https://deviceinbox.com/drivers/1571-winchiphead-usb-serial-ch340-ch341-driver.html}
178 | \end{center}
179 |
180 | Unzip the files and run \verb|Setup.exe|. The windows that pops up should look like {\bf Figure \ref{fig:windows-driver-setup}}. First, hit the ``Uninstall'' button to uninstall the v.3.8.2023.2 drivers, then hit the ``Install'' button to install the v.3.5.2019.1 drivers.
181 |
182 | \begin{figure}[ht]
183 | \centering
184 | \includegraphics[width = 0.7\textwidth]{images/windows-driver-setup.png}
185 | \cprotect\caption{USB-SERIAL CH340/CH341 Installation on Windows 11, version 3.5.2019.1.}
186 | \label{fig:windows-driver-setup}
187 | \end{figure}
188 |
189 | % \subsection{Installing CH340 Drivers on Ubuntu Linux}
190 |
191 | % Open a command prompt and enter the following commands:
192 |
193 | % \begin{lstlisting}[style=bashstyle, label=lst:mybashcode, numbers = none]
194 | % sudo apt install build-essential git
195 | % sudo apt remove brltty
196 | % git clone https://github.com/juliagoda/CH341SER.git CH341SER
197 | % cd CH341SER
198 | % make
199 | % \end{lstlisting}
200 |
201 | % Check if you have SecureBoot enabled by running \verb|mokutil --sb-state|. If SecureBoot is enabled, run the command:
202 |
203 | % \begin{lstlisting}[style=bashstyle, label=lst:mybashcode, numbers = none]
204 | % kmodsign sha512 /var/lib/shim-signed/mok/MOK.priv /var/lib/shim-signed/mok/MOK.der ./ch34x.ko
205 | % \end{lstlisting}
206 |
207 | % Finally, run:
208 |
209 | % \begin{lstlisting}[style=bashstyle, label=lst:mybashcode, numbers = none]
210 | % make load
211 | % \end{lstlisting}
212 |
213 | % After installing the drivers, go to section 2.2 to verify the drivers are present.
214 |
215 | \newpage
216 |
217 | \section{Updating the Arduino Nano's Bootloader}
218 |
219 | {\bf This section is only relevant for RoboJackets trainers. Update the Arduino Nano's bootloaders in advance to avoid issues during Firmware Training.} \par
220 |
221 | \vspace{1em}
222 |
223 | Most offbrand Arduino Nanos have old bootloaders. To maximize compatibility, you should update their bootloaders using an Arduino Uno as a programmer.
224 |
225 | \subsection{Setting up the Arduino Uno as a Programmer}
226 |
227 | The following setups will set up the Arduino Uno with the \verb|ArduinoISP| example program.
228 |
229 | \begin{enumerate}
230 | \item Plug an Arduino Uno R3 into your computer using a USB Type B cable.
231 | \item Open up the \verb|ArduinoISP| example sketch under \verb|File > Examples > ArduinoISP|.
232 | \item Ensure the settings under \verb|Tools| are as follows:
233 | \begin{itemize}
234 | \item Board: \verb|Arduino Uno|
235 | \item Port: select the port the Arduino Uno is plugged into.
236 | \begin{itemize}
237 | \item On Windows, check the “Ports” section in Device Manager.
238 | \item On Linux, check for devices starting with \verb|/dev/ttyACM*| or \verb|/dev/ttyUSB*|.
239 | \end{itemize}
240 | \item Programmer: \verb|AVPISP mk|\Romannum{2}
241 | \end{itemize}
242 | \item Upload the \verb|ArduinoISP| to the Arduino Uno.
243 | \end{enumerate}
244 |
245 | \subsection{Wiring the Arduino Nano to the Arduino Uno Programmer}
246 |
247 | Connect the Arduino Uno to the Arduino Nano as shown in {\bf Figure \ref{fig:wiring-diagram}}. Note that you can also connect to the Arduino Nano's ICSP pins.
248 |
249 | \begin{figure}[ht]
250 | \centering
251 | \includegraphics[width = 0.7\textwidth]{images/Uno_to_Nano_burn_bootloader.png}
252 | \cprotect\caption{Wiring Diagram for an Programming Arduino Nano's Bootloader using an Arduino Uno.}
253 | \label{fig:wiring-diagram}
254 | \end{figure}
255 |
256 | \clearpage
257 |
258 | \subsection{Burning the Arduino Nano's Bootloader}
259 |
260 | Once the Arduino Uno is wired to the Arduino Nano, follow these steps.
261 |
262 | \begin{enumerate}
263 | \item {\bf Plug in the Arduino Uno into your computer}. Do NOT plug in the Arduino Nano!
264 | \item Ensure the settings under \verb|Tools| are as follows:
265 | \begin{itemize}
266 | \item Board: \verb|Arduino Nano|
267 | \item Processor: \verb|ATmega328P|
268 | \begin{itemize}
269 | \item this setting determines which bootloader is burned onto the Arduino Nano
270 | \end{itemize}
271 | \item Port: select the port the Arduino Uno is plugged into.
272 | \begin{itemize}
273 | \item On Windows, check the “Ports” section in Device Manager.
274 | \item On Linux, check for devices starting with \verb|/dev/ttyACM*| or \verb|/dev/ttyUSB*|.
275 | \end{itemize}
276 | \item Programmer: \verb|Arduino as ISP|
277 | \end{itemize}
278 | \item Under \verb|Tools|, click \verb|Burn Bootloader|. Lights on the Arduino Uno and the Arduino Nano should flash to indicate the burning process is underway. Upon completion, the Arduino IDE should say ``Done Burning bootloader''.
279 | \end{enumerate}
280 |
281 | Congratulations! The Arduino Nano now has the updated bootloader. You should be able to program the Arduino Nano by plugging it into the computer normally using the following settings:
282 |
283 | \begin{itemize}
284 | \item Board: \verb|Arduino Nano|
285 | \item Processor: \verb|ATmega328P|
286 | \item Port: select the port the Arduino Uno is plugged into.
287 | \item Programmer: \verb|AVPISP mk|\Romannum{2}
288 | \end{itemize}
289 |
290 | \end{document}
--------------------------------------------------------------------------------
/latex/Week 1 Lab/images/ArduinoNanoPinout.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/Week 1 Lab/images/ArduinoNanoPinout.png
--------------------------------------------------------------------------------
/latex/Week 1 Lab/images/ArduinoReady.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/Week 1 Lab/images/ArduinoReady.png
--------------------------------------------------------------------------------
/latex/Week 1 Lab/images/blinkLEDcircuit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/Week 1 Lab/images/blinkLEDcircuit.png
--------------------------------------------------------------------------------
/latex/Week 1 Lab/images/breadboard_diagram.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/Week 1 Lab/images/breadboard_diagram.jpg
--------------------------------------------------------------------------------
/latex/Week 1 Lab/images/breadboard_example.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/Week 1 Lab/images/breadboard_example.JPG
--------------------------------------------------------------------------------
/latex/Week 1 Lab/images/debouncing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/Week 1 Lab/images/debouncing.png
--------------------------------------------------------------------------------
/latex/Week 1 Lab/images/examples.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/Week 1 Lab/images/examples.png
--------------------------------------------------------------------------------
/latex/Week 1 Lab/images/pullup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/Week 1 Lab/images/pullup.png
--------------------------------------------------------------------------------
/latex/Week 1 Lab/images/verifyupload.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/Week 1 Lab/images/verifyupload.png
--------------------------------------------------------------------------------
/latex/Week 1 Lab/main.tex:
--------------------------------------------------------------------------------
1 | \documentclass{article}
2 | \usepackage{geometry}
3 | \usepackage{flafter}
4 | \geometry{letterpaper, portrait, margin=1in}
5 |
6 | \usepackage{listings}
7 | \lstdefinestyle{bashstyle}{
8 | language=bash,
9 | basicstyle=\ttfamily,
10 | keywordstyle=\color{blue},
11 | commentstyle=\color{green},
12 | numberstyle=\tiny\color{gray},
13 | numbers=left,
14 | breaklines=true
15 | }
16 |
17 | \usepackage{cprotect}
18 | \usepackage{hyperref}
19 | \hypersetup{
20 | colorlinks=true,
21 | linkcolor=black,
22 | filecolor=magenta,
23 | urlcolor=blue,
24 | }
25 |
26 | \usepackage{graphicx}
27 | \graphicspath{ {images/} }
28 |
29 | \usepackage{tcolorbox}
30 | \usepackage{textcomp}
31 | \usepackage{gensymb}
32 | \usepackage{indentfirst}
33 | \usepackage{romannum}
34 |
35 | \newcommand{\ans}{$\rule{1.5cm}{0.15mm}$}
36 |
37 | \title{RoboJackets Electrical / Firmware Training Week 1}
38 | \author{Andrew Roach}
39 | \date{\today\\v1.1}
40 |
41 | \begin{document}
42 | \maketitle{}
43 | \setcounter{tocdepth}{2}
44 | \tableofcontents
45 | \pagebreak
46 |
47 | %Everything below is for you to edit. Code above sets up the general formatting for the document
48 |
49 |
50 | \section{Before You Start}
51 |
52 | \subsection{Prerequisites}
53 |
54 | Before diving into the lab, make sure you have followed the Setup Instructions, which can be found on the RoboJackets Electrical Training GitHub page. After completing the setup instructions, verify that you have the following:
55 |
56 | \begin{itemize}
57 | \item The Legacy Arduino IDE (version 1.8.X, NOT 2.X!).
58 | \item A working Arduino Nano. When you plug the Nano into your computer, the LED labeled ``POW'' should illuminate.
59 | \item The CH340 drivers. If you installed the drivers correctly, the Arduino Nano should appear when you click on Tools $>$ Port in the Arduino IDE.
60 | \end{itemize}
61 |
62 | \subsection{Setup}
63 |
64 | Before you can upload code to the Arduino Nano, you need to tell the Arduino IDE what hardware you are using. To configure this, set the following settings in the {\bf Tools} menu:
65 |
66 | \begin{itemize}
67 | \item Board: {\bf Arduino Nano}
68 | \item Processor: {\bf ATMega328P (Old Bootloader)}
69 | \begin{itemize}
70 | \item If this fails, try {\bf ATMega328P}
71 | \end{itemize}
72 | \item Port: select the port the Arduino Nano is plugged into.
73 | \begin{itemize}
74 | \item On Windows, check the ``Ports'' section in Device Manager
75 | \item On Linux, check for devices starting with \verb|/dev/ttyACM*| or \verb|/dev/ttyUSB*|.
76 | \end{itemize}
77 | \item Programmer: AVPISP mk\Romannum{2}
78 | \end{itemize}
79 |
80 | \begin{figure}[ht]
81 | \centering
82 | \includegraphics[width = 0.4\textwidth]{images/ArduinoReady.png}
83 | \cprotect\caption{A properly configured Arduino IDE. Note that the ``Port'' value will be different.}
84 | \end{figure}
85 |
86 | \newpage
87 |
88 | \section{Background}
89 |
90 | The goal of this lab is to get you acquainted with prototyping with Arduinos. First, you must understand the hardware you are working with. Next, you will learn how to write and upload software onto an Arduino. Finally, we will give a brief introduction into the Arduino programming language. At the end, you will be tasked with implementing some basic circuits involving LEDs, resistors, and pushbuttons.
91 |
92 | \subsection{The Arduino Nano}
93 |
94 | {\bf Figure 2} depicts the pinout diagram for the Arduino Nano. The pinout diagram summarizes the capabilities of the Arduino Nano and depicts the mapping between the physical pins on the microcontroller and the aliases given to the physical pins in software. For example, the digital pin ``D2'' is represented by the integer ``2'' in an Arduino program. \par
95 |
96 | For this lab, we will be primarily focused on the digital pins, D0 - D19. The digital pins operate in a binary fashion; they send and receive signals as a logical HIGH or a logical LOW. Since the Arduino Nano operates on 5V logic, logical HIGH corresponds to 5V, while logical LOW corresponds to 0V. \par
97 |
98 |
99 | \begin{figure}[ht]
100 | \centering
101 | \includegraphics[width = 0.8\textwidth]{images/ArduinoNanoPinout.png}
102 | \cprotect\caption{Pinout for Arduino Nano. The ``Digital Pin'' numbers (D2, D3, etc...)
103 | correspond to the numbers used in functions such as \verb|pinMode| and \verb|digitalWrite|.}
104 | \end{figure}
105 |
106 | \newpage
107 |
108 | {\bf Figure 2} also depicts some pins that can't be interacted with via software, but are useful nonetheless. The +3V3 and +5V pins provide power, while the GND pins provide a ground reference. The VIN pin stands for ``Voltage In'', and it is used to supply 5V externally when you aren't providing the microcontroller power over USB. The ``Reset'' pins are used to restart the program on the Arduino Nano using an external signal. \par
109 |
110 | The Arduino Nano also has some useful features besides its pins. The button in the middle of the Arduino Nano causes the program on the Arduino Nano to restart. The ``Power'' LED illuminates when the Arduino Nano is being powered by 5V. The LED labeled ``LED\_BUILTIN'' is an LED that can be controlled via software. You can address it using the \verb|LED_BUILTIN| macro in your program.
111 |
112 | \subsection{Electrical Hardware}
113 |
114 | The solderless breadboard shown in {\bf Figure 3} is your workspace when prototyping. The power rails labeled with ``+'' and ``-'' are connected horizontally and is ideal for distributing 5V and GND. The terminal strips in the middle of the solderless breadboard are connected vertically. The center divider separates the terminal strips on either side of breadboard from one another. \par
115 |
116 | Jumper wires are useful for carrying electrical signals between different vertical terminal strips or between the power rails and the vertical terminal strips. Resistors are useful in conjunction with LEDs and pushbuttons. LEDs will burn themselves out if they are given too much current. The voltage drop across an LED is constant, so by increasing the resistance of the LED by using a resistor in series with an LED, the current drops. Resistors are also used with buttons to ensure the output of the button is never floating. See the appendix for more details.
117 |
118 |
119 | \begin{figure}[ht]
120 | \centering
121 | \includegraphics[width = 0.5\textwidth]{images/breadboard_diagram.jpg}
122 | \cprotect\caption{Anatomy of a solderless breadboard.}
123 | \end{figure}
124 |
125 | \begin{figure}[ht]
126 | \centering
127 | \includegraphics[width = 0.5\textwidth]{images/breadboard_example.jpg}
128 | \cprotect\caption{An example of how to lay out a circuit on a breadboard. The Arduino Nano straddles the center divider, providing power to the power rails. The resistor, LED, and button are laid out across different terminal strips and are connected using jumper wires.}
129 | \end{figure}
130 |
131 | \clearpage
132 |
133 | \subsection{The Arduino IDE}
134 |
135 | We will summarize a couple of important features for getting started with the Arduino IDE.
136 |
137 | \subsubsection{Sketches and Examples}
138 |
139 | User-created programs in the Arduino IDE are called sketches. The Arduino IDE also provides some built-in example sketches under File $>$ Examples. Some useful examples for this lab are ``Blink'' under ``Basics'' and ``Button'' under ``Digital''. You cannot modify examples, but you can use them as a starting points for your sketches.
140 |
141 | \begin{figure}[ht]
142 | \centering
143 | \includegraphics[width = 0.5\textwidth]{images/examples.png}
144 | \cprotect\caption{Accessing the Arduino IDE's built-in examples under File $>$ Examples.}
145 | \end{figure}
146 |
147 | \subsubsection{Verifying and Uploading Code}
148 |
149 | Once you have written your Arduino program, you have to do two things before your code is running on the Arduino Nano.
150 |
151 | \begin{itemize}
152 | \item {\bf Verify (checkmark button)}: This compiles your code into an executable format for the microcontroller. Compilation will fail if you have made a syntax error in your program. You do not need to be plugged into the microcontroller to Verify your program.
153 | \item {\bf Upload (arrow button)}: This uploads your code onto the microcontroller plugged into your computer. Uploading may fail if your settings in the ``Tools'' menu is incorrect; if you are having issues uploading to the microcontroller, go back to Section 1.2 and verify your settings are correct! The program will begin running immediately after it finishes uploading.
154 | \end{itemize}
155 |
156 | \begin{figure}[ht]
157 | \centering
158 | \includegraphics[width = 0.4\textwidth]{images/verifyupload.png}
159 | \cprotect\caption{The Verify (checkmark) and Upload (rightward-facing arrow) buttons in the Arduino IDE.}
160 | \end{figure}
161 |
162 | \clearpage
163 |
164 | \subsubsection{The Arduino Programming Language}
165 |
166 | The Arduino Programming language is similar to C++. Below, we have listed some useful functions for this lab:
167 |
168 | \begin{itemize}
169 | \item \verb|setup()|: \verb|setup()| is called when the program starts. It will run once when you power on or reset the Arduino. \verb|setup()| is ideal for initializing variables and setting pin modes.
170 | \item \verb|loop()|: This function loops consecutively so the code you place here will constantly run. You can have other functions in your program but they will not run unless they are called in setup() or loop().
171 | \item \verb|pinMode(pin, mode)|: Configures \verb|pin| to behave as input or output.
172 | \begin{itemize}
173 | \item Example 1: \verb|pinMode(2, OUTPUT)| configures pin D2 on the Arduino Nano as an output.
174 | \item Example 2: \verb|pinMode(7, INPUT)| configures pin D7 on the Arduino Nano as an input.
175 | \item Example 3: \verb|pinMode(LED_BUILTIN, OUTPUT)| configures the built-in LED of the Arduino Nano as an output.
176 | \end{itemize}
177 | \item \verb|digitalWrite(pin, value)|: Writes a HIGH or LOW value to a digital \verb|pin|.
178 | \begin{itemize}
179 | \item Example 1: \verb|digitalWrite(2, HIGH)| drives pin D2 to logical high (5V on Arduino Nano)
180 | \item Example 2: \verb|digitalWrite(2, LOW)| drives pin D2 to logical low (0V on Arduino Nano)
181 | \item Example 3: \verb|digitalWrite(2, 1)| drives pin D2 to logical high (5V on Arduino Nano)
182 | \end{itemize}
183 | \item \verb|digitalRead(pin)|: Reads a value (HIGH or LOW) from a digital \verb|pin|.
184 | \begin{itemize}
185 | \item Example 1: \verb|int buttonVal = digitalRead(7)| reads a digital value (\verb|HIGH=1| or \verb|LOW=0|) from pin D7 into the variable $\verb|buttonVal|$.
186 | \end{itemize}
187 | \item \verb|delay(time)|: Pauses the program for a number of milliseconds.
188 | \begin{itemize}
189 | \item Example 1: \verb|delay(500)| pauses the program for 500 milliseconds.
190 | \end{itemize}
191 | \end{itemize}
192 |
193 | {\bf If you need information or examples on how the Arduino programming language works,}
194 | \begin{itemize}
195 | \item Check out the \href{https://www.arduino.cc/reference/en/}{Arduino Language Reference}.
196 | \item Refer to the Arduino IDE's built-in Examples under File $>$ Examples.
197 | \end{itemize}
198 |
199 | \clearpage
200 |
201 | \section{Objective}
202 |
203 | Here are some challenges for you to try out!
204 |
205 | \subsection{Uploading Blink}
206 |
207 | \begin{itemize}
208 | \item Open up the example Blink program under Files $>$ Examples $>$ Basics $>$ Blink.
209 | \item Verify and Upload the Blink program.
210 | \item The Arduino Nano's onboard LED should blink on and off.
211 | \end{itemize}
212 |
213 | \subsection{Blinking an External LED}
214 | \begin{itemize}
215 | \item Create a sketch that will blink an LED on the breadboard.
216 | \begin{itemize}
217 | \item Refer to the Arduino Nano's pinout in section 2.1 to figure out which physical pins map to which numbers in software.
218 | \item You will need to use the \verb|pinMode|, \verb|digitalWrite|, and \verb|delay| functions. Refer to section 2.3.3 to learn how to use these functions.
219 | \end{itemize}
220 | \item You will need to put a resistor and LED in series, as shown in {\bf Figure 7}.
221 | \begin{itemize}
222 | \item LEDs have polarity; current will only flow from the anode (longer, positive leg) to the cathode (shorter, negative leg).
223 | \item Provide power through your software-controlled digital output pin on the Arduino Nano, and connect the LED's cathode (shorter, negative leg) to the Arduino Nano's GND.
224 | \end{itemize}
225 |
226 | \begin{figure}[ht]
227 | \centering
228 | \includegraphics[width = 0.4\textwidth]{images/blinkLEDcircuit.png}
229 | \cprotect\caption{Example circuit diagram for blinking an external LED using an Arduino Uno. The resistor and LED are connected in series. Power is supplied through pin 13, and the LEDs cathode is connected to ground.}
230 | \end{figure}
231 |
232 | \end{itemize}
233 |
234 | \clearpage
235 |
236 | \subsection{Blinking LEDs using a button}
237 |
238 | \begin{itemize}
239 | \item Use the \verb|digitalRead| function to read the value of the button.
240 | \begin{itemize}
241 | \item To figure out how to wire up the button, refer to the Appendix.
242 | \end{itemize}
243 | \item Try controlling two different LEDs using two different digital output pins with the button. For instance, one LED could turn on while the other turns off when the button is pressed.
244 | \end{itemize}
245 |
246 | \subsection{Using button to adjust blink frequency (optional challenge)}
247 |
248 | \begin{itemize}
249 | \item Use a button to control the rate at which an LED blinks.
250 | \item For instance, button unpressed = slow blink, button pressed = fast blink.
251 | \end{itemize}
252 |
253 | \subsection{Binary Counter (optional challenge)}
254 |
255 | \begin{itemize}
256 | \item Create a binary counter using the button as input and the LEDs as output.
257 | \begin{itemize}
258 | \item A button press increments the count by 1
259 | \item Read up on \href{https://www.clivemaxfield.com/coolbeans/masking-and-the-c-c-bitwise-operators/}{Binary number and bit masking} to figure out how to translate a number into the LED output.
260 | \item Read the Appendix section about button debouncing
261 | \end{itemize}
262 | \end{itemize}
263 |
264 | \clearpage
265 |
266 | \section{Appendix}
267 |
268 | \subsection{Pull-up Resistors}
269 |
270 | Pull-up resistors (and pull-down resistors) are used to ensure that a pin is not left floating when a connection is opened (by a button in this case). We connect the output side of the circuit to power through a resistor to accomplish this. Check out the circuit below.
271 |
272 | \begin{figure}[ht]
273 | \centering
274 | \includegraphics[width = 0.4\textwidth]{images/pullup.png}
275 | \cprotect\caption{Circuit diagram of pullup resistor in use with a button. When button is unpressed, resistor ``pulls up'' value of input pin. }
276 | \end{figure}
277 |
278 | Luckily, the Ardunio Nano has built-in pull-up resistors for all its digital pins, but we must activate them in firmware. To do this, we simply change the \verb|pinMode| of the pin. Instead of using \verb|pinMode(pin, INPUT)|, we use \verb|pinMode(pin, INPUT_PULLUP)|. You can read more \href{https://docs.arduino.cc/tutorials/generic/digital-input-pullup}{here}.
279 |
280 | \subsection{Debouncing}
281 |
282 | Due to mechanical/electrical issues, when a button is pressed it may be detected as many button presses.
283 |
284 | \begin{figure}[ht]
285 | \centering
286 | \includegraphics[width = 0.6\textwidth]{images/debouncing.png}
287 | \cprotect\caption{When switch is closed (left), voltage read by the microcontroller can fluctuate for a brief period before stabilizing (right). This can make a single button press look like several button presses.}
288 | \end{figure}
289 |
290 | These fluctuations might be detected by the MCU as many button presses, causing issues in firmware.
291 | To counter this issue, there a few things we can do. For now, we can simply add a delay after we detect the change of state. However you decide to detect a button press to increment the binary counter, you can add a \verb|delay(50)| after so that the MCU doesn’t even look for another change of state until the delay is over. 50 ms is more than enough time to counter this issue.
292 |
293 |
294 | \end{document}
--------------------------------------------------------------------------------
/latex/Week 2 Lab/images/AttachInterrupt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/Week 2 Lab/images/AttachInterrupt.png
--------------------------------------------------------------------------------
/latex/Week 2 Lab/images/StateMachine.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/Week 2 Lab/images/StateMachine.png
--------------------------------------------------------------------------------
/latex/Week 2 Lab/images/TinkerCadCode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/Week 2 Lab/images/TinkerCadCode.png
--------------------------------------------------------------------------------
/latex/Week 2 Lab/images/TinkerCadWires.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/Week 2 Lab/images/TinkerCadWires.png
--------------------------------------------------------------------------------
/latex/Week 2 Lab/main.tex:
--------------------------------------------------------------------------------
1 | \documentclass{article}
2 | \usepackage{geometry}
3 | \usepackage{flafter}
4 | \geometry{letterpaper, portrait, margin=1in}
5 |
6 | \usepackage{hyperref}
7 | \hypersetup{
8 | colorlinks=true,
9 | linkcolor=black,
10 | filecolor=magenta,
11 | urlcolor=blue,
12 | }
13 | \usepackage{listings}
14 | \lstdefinestyle{bashstyle}{
15 | language=bash,
16 | basicstyle=\ttfamily,
17 | keywordstyle=\color{blue},
18 | commentstyle=\color{green},
19 | numberstyle=\tiny\color{gray},
20 | numbers=left,
21 | breaklines=true
22 | }
23 |
24 | \usepackage{tikz} % Import the tikz package
25 | \usetikzlibrary{automata} % Import library for drawing automata
26 | \usetikzlibrary{positioning} % ...positioning nodes
27 | \usetikzlibrary{arrows} % ...customizing arrows
28 | \tikzset{node distance=2.5cm, % Minimum distance between two nodes. Change if necessary.
29 | every state/.style={ % Sets the properties for each state
30 | semithick,
31 | fill=gray!10},
32 | initial text={}, % No label on start arrow
33 | double distance=2pt, % Adjust appearance of accept states
34 | every edge/.style={ % Sets the properties for each transition
35 | draw,
36 | ->,>=stealth', % Makes edges directed with bold arrowheads
37 | auto,
38 | semithick}}
39 | \let\epsilon\varepsilon
40 |
41 | \usepackage{graphicx}
42 | \graphicspath{ {images/} }
43 |
44 | \usepackage{tcolorbox}
45 | \usepackage{textcomp}
46 | \usepackage{gensymb}
47 | \usepackage{indentfirst}
48 |
49 | \newcommand{\ans}{$\rule{1.5cm}{0.15mm}$}
50 |
51 | \title{RoboJackets Firmware Training Week 2 Lab Guide}
52 | \author{Andrew Rocco, Andrew Roach}
53 | \date{\today\\v1.1}
54 |
55 | \begin{document}
56 | \maketitle{}
57 | \setcounter{tocdepth}{2}
58 | \tableofcontents
59 | \pagebreak
60 |
61 | %Everything below is for you to edit. Code above sets up the general formatting for the document
62 |
63 | \section{Background}
64 | \subsection{Topics}
65 | The important topics being discussed this week in lab include state machines, interrupts, and more complex C++.
66 | \subsection{Premise}
67 | The lab premise is to make a state machine that implements a simple counter. At the start of the program, the counter should start at 0 and should be able to count up to 5 and back down to 0. This state machine will change states based on the 2 button inputs and will display state using the 5 controllable LEDs. One button input will be able to increment and the other decrement.
68 | \subsection{Interrupt Service Routines}
69 | Interrupt Service Routines (ISR) are functions that are called when interrupts are activated. These are usually short functions that should be used to update variables in global scope. Remember that interrupts are when your microcontroller gets a signal that makes it stop whats its doing, run the ISR, and then return to the code it was running. Interrupt-based programming is very common for microcontrollers and robots and is usually more efficient that other methods.
70 |
71 | \subsection{Simulation}
72 | If you are using a simulation instead of the hardware, do not worry. The steps are exactly the same. Go to the TinkerCad link and you will see the circuit that is a subset of the the hardware. The Arduino you see will be what you use, with the LEDs and buttons replicated as they would be on the actual board.
73 |
74 | \begin{figure}[ht]
75 | \centering
76 | \includegraphics[width = 0.7\textwidth]{images/TinkerCadWires.png}
77 | \caption{The circuit window of TinkerCAD for this project}
78 | \end{figure}
79 |
80 | \begin{figure}[ht]
81 | \centering
82 | \includegraphics[width = 0.7\textwidth]{images/TinkerCadCode.png}
83 | \caption{The area which you can use to select your target and compile}
84 | \end{figure}
85 |
86 | \subsection{Firmware Training Board}
87 | If you are using the hardware, there are a few steps to complete to ensure that you can program the Arduino Nano on the circuit board. You may need to download the CH340 driver for your operating system which can be found \href{https://learn.sparkfun.com/tutorials/how-to-install-ch340-drivers/all}{here}. If you completed this in Week 1 there is no need to do this again. Remember in Tools$>$Board Type, ensure that you have set the board to Arduino Nano. Also make sure that you have selected the correct COM port in Tools$>$Port. For these Arduino Nanos you also need to select Tools$>$Processor$>$ATmega328P (Old Bootloader).
88 |
89 |
90 |
91 | \section{Materials}
92 | \begin{itemize}
93 | \item If running Simulation: \href{https://www.autodesk.com/education/edu-software/overview}{AutoDesk Education Account} and \href{https://www.tinkercad.com/things/8J1RA4SvqOM}{TinkerCAD}
94 | \item If running on Firmware Training Board: \href{https://github.com/RoboJackets/firmware-training/blob/master/code/Week2/Week_2_Template/Week_2_Template.ino}{Firmware Training Board Template Code} and \href{https://www.arduino.cc/en/software}{Arduino IDE}
95 | \end{itemize}
96 |
97 | \section{Objectives}
98 | \subsection{Task 1 - Create State Machine}
99 | \begin{enumerate}
100 | \item Plan and draw out the full state machine.
101 | \begin{itemize}
102 | \item Make sure you have all the states and transitions marked.
103 | \item As a programming convention, we will number our states from 0 upwards, which you will find more useful in the next step.
104 | \item Don't forget that no LEDs can be on for our counter.
105 | \item A refresher on state machines and a template to get started can be found in Section \ref{statemachine}.
106 | \end{itemize}
107 | \item Write code to display state in \texttt{loop}.
108 | \begin{itemize}
109 | \item You will need to go through every LED to set it state, so use a \texttt{for} loop and the \texttt{pinArray} array.
110 | \item Make sure to use the fact your states are starting counting at 0, which is similar to arrays.
111 | \item You will need to use your state variable to know how to do the update.
112 | \end{itemize}
113 | \end{enumerate}
114 | \subsection{Task 2 - Create Interrupts}
115 | \begin{enumerate}
116 | \item Write an ISR for each button.
117 | \begin{itemize}
118 | \item SW1 is a button that when pressed sends a \texttt{HIGH} value to the Arduino, but is otherwise \texttt{LOW}. You should make sure this button should increase the number of LEDs turned on.
119 | \item SW2 is a button that when pressed sends a \texttt{LOW} value to the Arduino, but is otherwise \texttt{HIGH}. This button should decrease the number of LEDs turned on.
120 | \end{itemize}
121 | \item Write code in \texttt{setup} for the buttons and interrupts.
122 | \begin{itemize}
123 | \item You will also need to setup the buttons as normal digital inputs first.
124 | \item Make sure to understand how each button has a different type of change, which will affect how the interrupt triggers.
125 | \item A refresher on setting up interrupts can be found in Section \ref{attachinterrupt}.
126 | \end{itemize}
127 | \end{enumerate}
128 |
129 |
130 | \section{Relevant Information}
131 | \subsection{State Machines} \label{statemachine}
132 | State machines are tools to organize the behavior of code, based around a number of "states" or points the code can be at. We specifically are looking at state machines that have output behavior depend only on current state, meaning the number of behaviors equals the number of states. The state machine inputs are used to trigger transitions to different states, and there no transitions to an impossible state. A graphical representation is often used with bubbles representing states and labelled arrows representing transitions. In addition, a state-transition table can be used to show what state a finite-state machine will move to based on the input and current state. Templates for both the table and graphical representation are given with the first two transitions filled out.
133 |
134 | \begin{center}
135 | \begin{tabular}{|c|c|c|c|}
136 | \hline
137 | Current State & Input & Next State & LED Output \\
138 | \hline
139 | State 0 & SW2 = 0 & State 0 & 0 \\
140 | State 0 & SW1 = 1 & State 1 & 1 \\
141 | \hline
142 | State 1 & SW2 = 0 & & \\
143 | State 1 & SW1 = 1 & & \\
144 | \hline
145 | State 2 & SW2 = 0 & & \\
146 | State 2 & SW1 = 1 & & \\
147 | \hline
148 | State 3 & SW2 = 0 & & \\
149 | State 3 & SW1 = 1 & & \\
150 | \hline
151 | State 4 & SW2 = 0 & & \\
152 | State 4 & SW1 = 1 & & \\
153 | \hline
154 | State 5 & SW2 = 0 & & \\
155 | State 5 & SW1 = 1 & & \\
156 | \hline
157 | \end{tabular}
158 | \end{center}
159 |
160 | \begin{center}
161 | \begin{tikzpicture}
162 | \node[state, initial] (0) {$\frac{State 0}{0}$};
163 | \node[state, right of = 0, xshift=2cm] (1) {$\frac{State 1}{1}$};
164 | \node[state, below of = 0, yshift=-2cm] (3) {$\frac{State 3}{3}$};
165 | \node[state, right of = 3, xshift=2cm] (2) {$\frac{State 2}{2}$};
166 | \node[state, below of = 3, yshift=-2cm] (4) {$\frac{State 4}{4}$};
167 | \node[state, right of = 4, xshift=2cm] (5) {$\frac{State 5}{5}$};
168 |
169 | \draw (0) edge[loop above] node{$SW2 = 0$} (0)
170 | (0) edge[bend left, above] node{$SW1 = 1$} (1);
171 | \end{tikzpicture}
172 | \end{center}
173 |
174 |
175 | \begin{figure}[ht]
176 | \centering
177 | \includegraphics[width = 0.5\textwidth]{images/StateMachine.png}
178 | \caption{Example State Machine}
179 | \end{figure}
180 |
181 | \subsection{\texttt{attachInterrupt} Function} \label{attachinterrupt}
182 | The function we will be using for setting up interrupts is the \texttt{attachInterrupt} Function. You can refer to the reference page \href{https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt}{here} for understanding it along with examples. Specifically, you need to look into how to convert a pin to a interrupt number and to set the mode that triggers the interrupts. Note that you should use the recommended syntax using the \texttt{digitalPinToInterrupt} function.
183 |
184 | \begin{figure}[ht]
185 | \centering
186 | \includegraphics[width = 0.75\textwidth]{images/AttachInterrupt.png}
187 | \caption{\texttt{attachInterrupt} Function on the Arduino Website}
188 | \end{figure}
189 |
190 |
191 | \section{Troubleshooting}
192 | \subsection{Solutions}
193 | We have included the solutions below if you do not complete the lab during the session or if you want to verify your answer. If you need help during the lab ask an instructor!
194 | \begin{itemize}
195 | \item \href{https://www.tinkercad.com/things/cGKh5f8nkDv}{TinkerCAD Solution}
196 | \item \href{https://github.com/RoboJackets/firmware-training/blob/master/code/Week2/Week_2_Solution/Week_2_Solution.ino}{Firmware Training Board Template Solution}
197 | \item State Machine Solution
198 | \begin{center}
199 | \begin{tabular}{|c|c|c|c|}
200 | \hline
201 | Current State & Input & Next State & LED Output \\
202 | \hline
203 | State 0 & SW2 = 0 & State 0 & 0 \\
204 | State 0 & SW1 = 1 & State 1 & 1 \\
205 | \hline
206 | State 1 & SW2 = 0 & State 0 & 0 \\
207 | State 1 & SW1 = 1 & State 2 & 2 \\
208 | \hline
209 | State 2 & SW2 = 0 & State 1 & 1 \\
210 | State 2 & SW1 = 1 & State 3 & 3 \\
211 | \hline
212 | State 3 & SW2 = 0 & State 2 & 2 \\
213 | State 3 & SW1 = 1 & State 4 & 4 \\
214 | \hline
215 | State 4 & SW2 = 0 & State 3 & 3 \\
216 | State 4 & SW1 = 1 & State 5 & 5 \\
217 | \hline
218 | State 5 & SW2 = 0 & State 4 & 4 \\
219 | State 5 & SW1 = 1 & State 5 & 5 \\
220 | \hline
221 | \end{tabular}
222 | \end{center}
223 |
224 | \begin{center}
225 | \begin{tikzpicture}
226 | \node[state, initial] (0) {$\frac{State 0}{0}$};
227 | \node[state, right of = 0, xshift=2cm] (1) {$\frac{State 1}{1}$};
228 | \node[state, below of = 0, yshift=-2cm] (3) {$\frac{State 3}{3}$};
229 | \node[state, right of = 3, xshift=2cm] (2) {$\frac{State 2}{2}$};
230 | \node[state, below of = 3, yshift=-2cm] (4) {$\frac{State 4}{4}$};
231 | \node[state, right of = 4, xshift=2cm] (5) {$\frac{State 5}{5}$};
232 |
233 | \draw (0) edge[loop above] node{$SW2 = 0$} (0)
234 | (0) edge[bend left, above] node{$SW1 = 1$} (1)
235 | (1) edge[bend left, below] node{$SW2 = 0$} (0)
236 | (1) edge[bend left, right] node{$SW1 = 1$} (2)
237 | (2) edge[bend left, left] node{$SW2 = 0$} (1)
238 | (2) edge[bend left, below] node{$SW1 = 1$} (3)
239 | (3) edge[bend left, above] node{$SW2 = 0$} (2)
240 | (3) edge[bend left, right] node{$SW1 = 1$} (4)
241 | (4) edge[bend left, left] node{$SW2 = 0$} (3)
242 | (4) edge[bend left, above] node{$SW1 = 1$} (5)
243 | (5) edge[bend left, below] node{$SW2 = 0$} (4)
244 | (5) edge[loop right] node{$SW1 = 1$} (5);
245 |
246 |
247 | \end{tikzpicture}
248 | \end{center}
249 |
250 |
251 | \end{itemize}
252 |
253 | \newpage
254 |
255 | \section{Appendix}
256 |
257 | \subsection{Installing the Arduino IDE}
258 |
259 | We will be using the legacy version of the Arduino IDE (version 1.8.19). Follow the installation instructions based on your platform.
260 |
261 | \subsubsection{Windows and Mac}
262 |
263 | \begin{enumerate}
264 | \item Go to the \href{https://www.tinkercad.com/things/cGKh5f8nkDv}{Arduino Software} page and scroll down to the ``Legacy IDE (1.8.X)''. Download the binary corresponding to your platform.
265 | \item Run the installer. Allow the installer to install everything, including drivers.
266 | \end{enumerate}
267 |
268 | \subsubsection{Linux}
269 |
270 | \begin{enumerate}
271 | \item Go to the \href{https://www.tinkercad.com/things/cGKh5f8nkDv}{Arduino Software} page and scroll down to the ``Legacy IDE (1.8.X)''. The Linux Arduino IDE should download as a \verb|tar.xz| file.
272 | \item Run the following commands, replacing \verb|| with the name of the downloaded file.
273 | \begin{lstlisting}[style=bashstyle, label=lst:mybashcode]
274 | tar -xJvf .tar.xz -C /home/$(whoami)
275 | cd /home/$(whoami)/
276 | sudo ./install.sh
277 | \end{lstlisting}
278 | \end{enumerate}
279 |
280 | \subsection{Verify CH340 Drivers}
281 |
282 | Our Arduino Nanos are kinda old, so they often don't work out of the box without installing the correct drivers first. Your operating system or the installation of the Arduino IDE might have installed the correct drivers, so it's a good idea to check if you have the driver before reinstalling them.
283 |
284 | \subsubsection{Windows}
285 |
286 | {\bf Checking if driver is present: } type \verb|driverquery| into the command prompt. You should see a driver called \verb|CH341SER|.
287 |
288 | \vspace{1em}
289 |
290 | {\bf Checking if driver loads: } Plug the Arduino Nano into your computer. Go to \verb|Device Manager| and look under \verb|Ports|. You should see the Arduino Nano as \verb|USB-SERIAL CH340|, followed by the \verb|COM| port it's associated with.
291 |
292 | \subsubsection{Linux}
293 |
294 | {\bf Checking if module is present: } type \verb|modinfo ch341| into your shell. The command should return a bunch of information about the \verb|ch341| kernel module.
295 |
296 | \vspace{1em}
297 |
298 | {\bf Checking if driver is present: } Plug the Arduino Nano into your computer. Enter the command \verb|sudo dmesg| into your shell.
299 |
300 | \begin{itemize}
301 | \item If you see the following, you need to uninstall \verb|br1tty|. After uninstalling \verb|br1tty|, unplug and plug in the Arduino Nano and run \verb|sudo dmesg| again.
302 | \begin{itemize}
303 | \item Ubuntu: \verb|sudo apt remove br1tty|.
304 | \end{itemize}
305 | \item If you see the following, type \verb|ls /dev/tty*|. You should see the Arduino Nano show up as \verb|/dev/ttyUSB[0-9]| or \verb|/dev/ttyACM[0-9]|. This indicates that the kernel module has loaded successfully.
306 |
307 | \end{itemize}
308 |
309 |
310 | \newpage
311 |
312 | \subsection{Install CH340 Drivers}
313 |
314 | If you could not find the \verb|CH340| drivers, you may have to install them manually.
315 |
316 | \subsubsection{Windows and Mac}
317 |
318 | Follow the instructions
319 |
320 |
321 | \end{document}
--------------------------------------------------------------------------------
/latex/Week 4 Lab/TinkerCadCode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/Week 4 Lab/TinkerCadCode.png
--------------------------------------------------------------------------------
/latex/Week 4 Lab/TinkerCadWires.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/Week 4 Lab/TinkerCadWires.png
--------------------------------------------------------------------------------
/latex/Week 4 Lab/img/TinkerCadCode.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/Week 4 Lab/img/TinkerCadCode.PNG
--------------------------------------------------------------------------------
/latex/Week 4 Lab/img/TinkerCadWires.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/Week 4 Lab/img/TinkerCadWires.PNG
--------------------------------------------------------------------------------
/latex/Week 4 Lab/img/WireLibrary.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/Week 4 Lab/img/WireLibrary.PNG
--------------------------------------------------------------------------------
/latex/Week 4 Lab/img/imu_breakout.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/Week 4 Lab/img/imu_breakout.jpg
--------------------------------------------------------------------------------
/latex/Week 4 Lab/img/rp-mpu-6050.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/latex/Week 4 Lab/img/rp-mpu-6050.png
--------------------------------------------------------------------------------
/latex/Week 4 Lab/main.tex:
--------------------------------------------------------------------------------
1 | \documentclass{article}
2 | \usepackage{geometry}
3 | \usepackage{flafter}
4 | \geometry{letterpaper, portrait, margin=1in}
5 |
6 | \usepackage{hyperref}
7 | \hypersetup{
8 | colorlinks=true,
9 | linkcolor=black,
10 | filecolor=magenta,
11 | urlcolor=blue,
12 | }
13 |
14 | \usepackage{graphicx}
15 | \graphicspath{ {images/} }
16 |
17 | \usepackage{tcolorbox}
18 | \usepackage{textcomp}
19 | \usepackage{gensymb}
20 | \usepackage{indentfirst}
21 | \usepackage{courier}
22 |
23 | \newcommand{\ans}{$\rule{1.5cm}{0.15mm}$}
24 |
25 | \title{RoboJackets Firmware Training Week 4 Lab Guide}
26 | \author{Varun Madabushi, Joe Spall, edited by Andrew Roach}
27 | \date{\today\\v1.1}
28 |
29 | \begin{document}
30 | \maketitle{}
31 | \setcounter{tocdepth}{2}
32 | \tableofcontents
33 | \pagebreak
34 |
35 | %Everything below is for you to edit. Code above sets up the general formatting for the document
36 |
37 | \section{Background}
38 | \subsection{Topics}
39 | The important topics being discussed this week in lab include communication protocols (specifically I2C), register mapping on datasheets, and sensors.
40 | \subsection{Premise}
41 | The lab premise is to use a training board with a mounted MPU-6050 sensor to detect \href{https://en.wikipedia.org/wiki/G-force}{g-force}. This \href{https://upload.wikimedia.org/wikipedia/en/f/f5/G-Force_poster.jpg}{g-force} can be used to determine what angle the training board is held. This angle will then be used to determine which of the 5 controllable LEDs will light up on-board, acting like a \href{https://en.wikipedia.org/wiki/Spirit_level}{bubble level indicator}.
42 | \subsection{Inertial Measurement}
43 | Inertial Measurement Units (IMUs) are a type of sensor that respond to changes in force applied to them. These consist of Accelerometers (which measure linear force) and Gyroscopes (which measure rotational velocity). These sensors are made up of Micro Electromechanical Systems (\href{https://en.wikipedia.org/wiki/Microelectromechanical_systems}{MEMS}) which are precisely tuned vibrating microstructures in the chip. Forces change the frequency of these vibrations, and that information is translated into electrical signals. These sensors are commonly used in robotics for measuring the pose (position and orientation) and motion of the robot in space.
44 |
45 | \begin{figure}[ht]
46 | \centering
47 | \includegraphics[width = 0.7\textwidth]{img/rp-mpu-6050.png}
48 | \caption{The MPU-6050 from TDK}
49 | \end{figure}
50 | For this lab we will be interfacing with the MPU-6050 Inertial Measurement Unit. Further information about the section can be found in Section \ref{readwrite}. \\
51 |
52 | \clearpage
53 |
54 | \subsection{Simulation}
55 |
56 | \textbf{NOTE: THIS IS ONLY RELEVANT IF YOU ARE USING THE ONLINE SIMULATOR TINKERCAD!} \par
57 |
58 | If you are using a simulation instead of the hardware, do not worry. The steps are exactly the same. Go to the TinkerCad link and you will notice that the circuit has two Arduinos in it. One is emulating the features of the IMU, and the other one is taking place of the actual Arduino that will be used to communicate with the IMU.
59 |
60 | \begin{figure}[ht]
61 | \centering
62 | \includegraphics[width = 0.7\textwidth]{img/TinkerCadWires.PNG}
63 | \caption{The circuit window of TinkerCAD for this project}
64 | \end{figure}
65 | Since you can't tilt or move the IMU in the simulation, there are 3 knobs to represent the G-forces applied along each cardinal axis. Keeping the knob in the middle of the range represents 0 Gs, and the left-most or right-most rotations represent a negative or positive G-force at the max range.
66 |
67 | \begin{figure}[ht]
68 | \centering
69 | \includegraphics[width = 0.7\textwidth]{img/TinkerCadCode.PNG}
70 | \caption{The dropdown which you can use to select your target}
71 | \end{figure}
72 |
73 | The code for both Arduinos exists in the TinkerCAD code window. Arduino 1 is the target you should be writing code for, and Arduino 2 is running code to simulate the MPU-6050. You can switch between targets using the dropdown menu in the top-right corner of the screen.
74 | \\ \\
75 | \textbf{NOTE: PLEASE DON'T EDIT THE MPU-6050 CODE TO REDUCE THE LIKELIHOOD OF ERRORS}
76 |
77 | \clearpage
78 |
79 | \section{Materials}
80 | \begin{itemize}
81 | \item Firmware training board
82 | \item Mini usb cable
83 | \item MPU-6050 breakout board
84 | \end{itemize}
85 |
86 | \section{Relevant Information}
87 | \subsection{MPU-6050} \label{readwrite}
88 | The MPU-6050 is an Inertial Measurement Unit (\href{https://en.wikipedia.org/wiki/Inertial_measurement_unit}{IMU}) which is mounted to the training board by means of a breakout board (the smaller PCB).
89 | In order to control it, first familiarize yourself with the register map found \href{https://cdn.sparkfun.com/datasheets/Sensors/Accelerometers/RM-MPU-6000A.pdf}{here} (click on Section 3 from the Table of Contents).
90 |
91 | \begin{figure}[ht]
92 | \centering
93 | \includegraphics[scale = 0.25]{img/imu_breakout.jpg}
94 | \caption{Picture of the MPU-6050}
95 | \end{figure}
96 |
97 | As per the datasheet, communicating with this involves interacting with the internal read/write pointer of the microcontroller. \\
98 |
99 | \noindent If you wish to write to a particular register, the following steps must be taken:
100 | \begin{enumerate}
101 | \item Begin a transmission (\texttt{Wire.beginTransmission(DEV\_ADDR)}).
102 | \item Send the address of the register you wish to write to (\texttt{Wire.write(REG\_ADDR)}).
103 | \item Send the value you wish to write to the register (\texttt{Wire.write(VALUE})).
104 | \item End the transmission (\texttt{Wire.endTransmission()}).
105 | \end{enumerate}
106 | \noindent A similar process can be followed for reading from registers:
107 | \begin{enumerate}
108 | \item Begin a transmission (\texttt{Wire.beginTransmission(DEV\_ADDR)}).
109 | \item Send the address of the register you wish to start reading from (\texttt{Wire.write(REG\_ADDR)}).
110 | \item End the transmission (\texttt{Wire.endTransmission()}).
111 | \item Request a number of bytes you want to receive (\texttt{Wire.requestFrom(DEV\_ADDR, BYTES, true)}).
112 | \item Read in the bytes, repeating for the number of bytes to be read (\texttt{Wire.read()})
113 | \end{enumerate}
114 | \subsection{Important MPU-6050 Registers}\label{registers}
115 | The particular registers we use in this lab are the following:
116 | \begin{itemize}
117 | \item \texttt{PWR\_MGMT\_1} - Turns on device
118 | \item \texttt{WHO\_AM\_I} - Identifies device
119 | \item \texttt{ACCEL\_XOUT\_H} - Accelerometer X, high 8 bits
120 | \item \texttt{ACCEL\_XOUT\_L} - Accelerometer X, low 8 bits
121 | \item \texttt{ACCEL\_YOUT\_H} - Accelerometer Y, high 8 bits
122 | \item \texttt{ACCEL\_YOUT\_L} - Accelerometer Y, low 8 bits
123 | \item \texttt{ACCEL\_ZOUT\_H} - Accelerometer Z, high 8 bits
124 | \item \texttt{ACCEL\_ZOUT\_L} - Accelerometer Z, low 8 bits
125 | \item \texttt{ACCEL\_CONFIG} - contains scaling between bits and g-force
126 | \end{itemize}
127 |
128 | A good practice for readability is to reference these registers by name in the code. To do this, first fill out \texttt{\#define} statements which will represent the hexadecimal values of the registers as readable words. For example, the statement \texttt{\#define PWR\_MGMT\_1 0x6b} gives the text \texttt{PWR\_MGMT\_1} a value of \texttt{0x6b} in the code.
129 |
130 | \subsection{\texttt{Wire} Library}
131 | The library we will be using for I2C communication is the \texttt{Wire} Library. You can refer to the reference page \href{https://www.arduino.cc/en/reference/wire}{here} for understanding the necessary functions along with examples.
132 |
133 | \begin{figure}[ht]
134 | \centering
135 | \includegraphics[width = 1.0\textwidth]{img/WireLibrary.PNG}
136 | \caption{\texttt{Wire} Library on the Arduino website}
137 | \end{figure}
138 |
139 | \section{Lab Objectives}
140 |
141 | Go to the RoboJackets Github
142 | \href{https://github.com/RoboJackets/firmware-training}{here}. Open up \texttt{code} $>$ \texttt{Week4} $>$ \texttt{Week\_ 4\_Template} $>$ \texttt{Week\_4\_Template.ino} in the Arudino IDE.
143 |
144 | \subsection{Task 1 - Get the IMU to turn on}
145 |
146 | In \texttt{Week\_4\_Template.ino}, look at the end of the \texttt{setup()} function.
147 |
148 | \begin{enumerate}
149 | \item Set the IMU to 'Awake' by writing 0 to \texttt{PWR\_MGMT\_1}
150 | \begin{itemize}
151 | \item The register names for a few relevant registers have been predefined in the code template. Please take a moment to look through these at the top of the code file. They can be accessed directly by name.
152 | \item Page 41-42 of the MPU-6050 \href{https://cdn.sparkfun.com/datasheets/Sensors/Accelerometers/RM-MPU-6000A.pdf}{datasheet} shows the various fields of this register.
153 | \item Writing 0 to this register sets all bits such that the device is not reset, the sleep mode is disabled, the chip does not cycle on-off, the temperature sensor is enabled, and the internal oscillator is used.
154 | \item A refresher on reading and writing from external devices with I2C can be found in Section \ref{readwrite}.
155 | \end{itemize}
156 | \item Run a "Who Am I" test to ensure communication.
157 | \begin{itemize}
158 | \item A "Who Am I" test asks the chip to return a known value so we can ensure data is transferring smoothly.
159 | \item Read from the \texttt{WHO\_AM\_I} register and use Arduino's \texttt{Serial.print()} to print the result to the console. This should return the value specified in the register map.
160 | \end{itemize}
161 | \end{enumerate}
162 |
163 | \subsection{Task 2 - Read raw data}\label{Sec2}
164 |
165 | In \texttt{Week\_4\_Template.ino}, look at the beginning of the \texttt{loop()} function.
166 |
167 | \begin{enumerate}
168 | \item We would like to read the X, Y, and Z accelerations from the IMU, so we must request these values from the sensor with \texttt{Wire.requestFrom()}.
169 | \begin{itemize}
170 | \item Each acceleration value is represented by 16 bits spread across 2 8-bit (1 byte) registers.
171 | \item We want to read from 6 registers starting from \texttt{ACCEL\_XOUT\_H} (\texttt{0x38}).
172 | \item Refer to Page 30 of the MPU-6050 datasheet for more information.
173 | \end{itemize}
174 | \item Now, receive the individual bytes and reconstruct them into sensor readings.
175 | \begin{itemize}
176 | \item The High byte (e.g. \texttt{ACCEL\_XOUT\_H}) corresponds to the first 8 bits, while the low byte (e.g. \texttt{ACCEL\_XOUT\_L}) corresponds to the last 8 bits.
177 | \item These must be combined into a 16-bit data type (such as \texttt{int16\_t}).
178 | \item Shift the high byte over by 8 bits and bitwise-OR it with the low byte.
179 | \end{itemize}
180 | \item Lastly, we must convert the \texttt{int16\_t} values into decimal accelerations in Gs.
181 | \begin{itemize}
182 | \item Data usually comes in units of least significant bits (LSBs), which are divisions of the Full-Scale Range into $2^{BIT\_DEPTH}$ number of divisions.
183 | \item The \texttt{AFS\_SEL} register changes the Full-Scale range of the sensor and thus sets the conversion factor between LSBs and Gs.
184 | \end{itemize}
185 | \item Print the resulting G-Force values to the console to make sure they are reasonable. If you have the board, place it stationary and flat on the table, \texttt{x\_g} and \texttt{y\_g} should be close to 0, and \texttt{z\_g} should be close to 1.
186 | \end{enumerate}
187 |
188 | \subsection{Task 3 - Use acceleration data to light up LEDs}
189 |
190 | In \texttt{Week\_4\_Template.ino}, look at the end of the \texttt{loop()} function.
191 |
192 | \begin{enumerate}
193 | \item Instantiate a struct to hold the acceleration vector.
194 | \begin{itemize}
195 | \item Construct an instance of the vector struct by creating a new \texttt{tb::Vector3D}.
196 | \item Assign each of the fields \texttt{x\_g, y\_g, z\_g} of your new \texttt{Vector3D} variable using the values calculated in Section \ref{Sec2} step 3.
197 | \end{itemize}
198 | \item Light up LEDs corresponding to value in the struct.
199 | \begin{itemize}
200 | \item A method, \texttt{setBubbleIndicator(tb::Vector3D vector)}, is also provided for you.
201 | \item Pass the \texttt{tb::Vector3D} struct into this method, and your LEDs should light up corresponding to the angle.
202 | \end{itemize}
203 | \end{enumerate}
204 |
205 |
206 | \section{Troubleshooting}
207 | \begin{itemize}
208 | \item Remember to use the \texttt{\#define} macros, especially when referring to device addresses. Don't re-invent the wheel!
209 | \item If you don't see any input/output from the IMU, remember to use \texttt{Wire.beginTransmission()} and \\ \texttt{Wire.endTransmission()} when sending and \texttt{Wire.requestFrom()} when receiving.
210 | \item By default, the \texttt{AFS\_SEL} register has a value of 0; you can see what value this corresponds to on page 30 of the IMU documentation. You can use the \texttt{SCALE\_FACTOR\_2G} macro to scale the IMU outputs by the proper amount.
211 |
212 | \end{itemize}
213 |
214 | \section{Egg}
215 | There is a virtual egg in this document. If you find it, contact the authors of this document with proof of what you think the virtual egg is and you will receive one (1) real egg in return.
216 | \end{document}
217 |
--------------------------------------------------------------------------------
/presentations/Week 0 (2023-2024).pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/presentations/Week 0 (2023-2024).pdf
--------------------------------------------------------------------------------
/presentations/Week 1 (2023-2024).pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/presentations/Week 1 (2023-2024).pdf
--------------------------------------------------------------------------------
/presentations/Week 2 (2023-2024).pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/presentations/Week 2 (2023-2024).pdf
--------------------------------------------------------------------------------
/presentations/Week 3 (2023-2024).pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/presentations/Week 3 (2023-2024).pdf
--------------------------------------------------------------------------------
/presentations/Week 4 (2023-2024).pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/presentations/Week 4 (2023-2024).pdf
--------------------------------------------------------------------------------