├── .gitignore ├── LICENSE ├── README.md ├── board ├── firmware_training_board.brd ├── firmware_training_board.lbr ├── firmware_training_board.pdf ├── firmware_training_board.png └── firmware_training_board.sch ├── code ├── README.md ├── RoboJackets Training Firmware Setup Guide.pdf ├── Week2 │ ├── Week_2_Solution │ │ └── Week_2_Solution.ino │ └── Week_2_Template │ │ └── Week_2_Template.ino ├── Week3 │ ├── Week_3_Solution │ │ └── Week_3_Solution.ino │ └── Week_3_Template │ │ └── Week_3_Template.ino └── Week4 │ ├── Project4Rewrite │ ├── Project4Rewrite.ino │ ├── TiltSensor.cpp │ └── TiltSensor.h │ ├── Week_4_IMU │ └── Week_4_IMU.ino │ ├── Week_4_Solution │ └── Week_4_Solution.ino │ └── Week_4_Template │ └── Week_4_Template.ino ├── demos ├── Week1 │ ├── Week_1_Demo_Solution.ipynb │ └── Week_1_Demo_Template.ipynb ├── Week2 │ ├── Week_2_Demo_Solution.ipynb │ └── Week_2_Demo_Template.ipynb └── Week3 │ ├── Week_3_Demo_Solution.ipynb │ └── Week_3_Demo_Template.ipynb ├── labs ├── Week 1 Lab (Fall 2023).pdf ├── Week 2 Lab (Fall 2023).pdf ├── Week 3 Lab (2021-2022).pdf └── Week 4 Lab (Fall 2023).pdf ├── latex ├── RoboJackets Training Firmware Setup Guide │ ├── images │ │ ├── Uno_to_Nano_burn_bootloader.png │ │ ├── linux-arduino-ready.png │ │ ├── linux-module-load-correct.png │ │ ├── linux-module-load-incorrect.png │ │ ├── linux-module-present.png │ │ ├── windows-arduino-ready.png │ │ ├── windows-driver-setup.png │ │ ├── windows-module-load-correct.png │ │ └── windows-module-present.png │ └── main.tex ├── Week 1 Lab │ ├── images │ │ ├── ArduinoNanoPinout.png │ │ ├── ArduinoReady.png │ │ ├── blinkLEDcircuit.png │ │ ├── breadboard_diagram.jpg │ │ ├── breadboard_example.JPG │ │ ├── debouncing.png │ │ ├── examples.png │ │ ├── pullup.png │ │ └── verifyupload.png │ └── main.tex ├── Week 2 Lab │ ├── images │ │ ├── AttachInterrupt.png │ │ ├── StateMachine.png │ │ ├── TinkerCadCode.png │ │ └── TinkerCadWires.png │ └── main.tex └── Week 4 Lab │ ├── TinkerCadCode.png │ ├── TinkerCadWires.png │ ├── img │ ├── TinkerCadCode.PNG │ ├── TinkerCadWires.PNG │ ├── WireLibrary.PNG │ ├── imu_breakout.jpg │ └── rp-mpu-6050.png │ └── main.tex └── presentations ├── Week 0 (2023-2024).pdf ├── Week 1 (2023-2024).pdf ├── Week 2 (2023-2024).pdf ├── Week 3 (2023-2024).pdf └── Week 4 (2023-2024).pdf /.gitignore: -------------------------------------------------------------------------------- 1 | # ignore LaTeX files 2 | *.aux 3 | *.synctex.gz 4 | *.out 5 | *.log 6 | *.toc 7 | 8 | .vscode/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 20 Georgia Tech RoboJackets 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RoboJackets Firmware Training 2 | 3 | **Please bookmark this page!** 4 | 5 | **Also, be sure to visit the RoboJackets Electrical Training page as well:** https://github.com/RoboJackets/electrical-training 6 | 7 | Welcome to the RoboJackets Firmware training repository! 8 | 9 | ## Training Schedule 2022 10 | 11 | * Location: Skiles 12 | * Time: 6:30pm - 8:00pm on Mondays and Wednesdays 13 | * Bring: Your computer 14 | 15 | Here is a breakdown of what firmware training is week-to-week: 16 | * Week 0: Introductions, Electrical Basics* 17 | * Week 1: Introduction to Prototyping and Arduino* 18 | * Week 2: More C++ and Interrupts 19 | * Week 3: PWM and Bitwise Operations 20 | * Week 4: Communication Protocols 21 | * Week 5: Debugging and Soldering* 22 | 23 | NOTE: Weeks 0, 1, will be joint sessions between electrical and firmware held in electrical's classroom. Weeks 1, 2, 3, 4 will be held in the firmware training classroom. Week 5 is a special session, usually held in the Hive. You get to practice surface mount soldering and debugging firmware on an actual PCB. 24 | 25 | ## About this Repository 26 | 27 | This repository has all the resources you need to get started! Although we'll walk through this when we start training, 28 | it wouldn't hurt to familiarize yourself with the repository in advance. 29 | 30 | ```code/```: Used for the lab portion of the Firmware Training. Simply download the template and open it up in the Arduino IDE. Be sure to download the template, don't look at the solution early! 31 | 32 | ```labs/```: Instructions for the lab portion of the Firmware Training. Read this carefully! 33 | 34 | ```presentations/```: A pdf version of the lecture slides. Feel free to look at them beforehand. 35 | 36 | ```demos/```: ```.ipynb``` files used for the interactive C++ portion of the lecture. Open these in [Google Colab](https://colab.research.google.com/). 37 | 38 | ## Additional Resources 39 | 40 | [Arduino IDE Installation Instructions](code/README.md) 41 | 42 | [Google Colab](https://colab.research.google.com/) 43 | 44 | 45 | -------------------------------------------------------------------------------- /board/firmware_training_board.lbr: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | Arduino Clone pinheaders 158 | By cl@xganon.com 159 | http://www.xganon.com 160 | 161 | 162 | <b>Arduino Nano</b> 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | NANO 206 | >NAME 207 | 208 | 209 | <B>LED</B><p> 210 | 5 mm, round 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | >NAME 223 | >VALUE 224 | 225 | 226 | 227 | 228 | <B>LED</B><p> 229 | 5 mm, round 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | <b>Arduino Nano</b> 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | Arduino Nano 273 | >NAME 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | >NAME 286 | >VALUE 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | Arduino Nano 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | <b>LED</b> 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | Since Version 8.3, EAGLE supports URNs for individual library 373 | assets (packages, symbols, and devices). The URNs of those assets 374 | will not be understood (or retained) with this version. 375 | 376 | 377 | Since Version 8.3, EAGLE supports the association of 3D packages 378 | with devices in libraries, schematics, and board files. Those 3D 379 | packages will not be understood (or retained) with this version. 380 | 381 | 382 | 383 | -------------------------------------------------------------------------------- /board/firmware_training_board.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/board/firmware_training_board.pdf -------------------------------------------------------------------------------- /board/firmware_training_board.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/board/firmware_training_board.png -------------------------------------------------------------------------------- /code/README.md: -------------------------------------------------------------------------------- 1 | # Arduino IDE Installation Instructions 2 | 3 | 1. Download the Arduino IDE [here](https://www.arduino.cc/en/software). Just do a normal install. 4 | 5 | 2. Most of Arduino Nanos are old, so they need the old bootloader. Follow the instructions [here](https://learn.sparkfun.com/tutorials/how-to-install-ch340-drivers/all) to install the old bootloader. 6 | 7 | 3. Before uploading to the firmware training board make sure you select: 8 | * Tools > Board > Arduino Nano 9 | * Tools > Processor > ATmega328P (Old Bootloader). If that doesn't work, try Tools > Processor > ATmega328P. -------------------------------------------------------------------------------- /code/RoboJackets Training Firmware Setup Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoboJackets/firmware-training/cbcb758acfb897bf1efe07eb601b0833c2d7dcaa/code/RoboJackets Training Firmware Setup Guide.pdf -------------------------------------------------------------------------------- /code/Week2/Week_2_Solution/Week_2_Solution.ino: -------------------------------------------------------------------------------- 1 | // Firmware Training Week 2 2 | // User Code Example 3 | // Collin Avidano, Maanas Purushothapu, Arvind Srinivasan 4 | 5 | 6 | #define D1_PIN 11 7 | #define D2_PIN 10 8 | #define D3_PIN 9 9 | #define D4_PIN 6 10 | #define D5_PIN 5 11 | 12 | #define SW1_PIN 2 13 | #define SW2_PIN 3 14 | 15 | // Stores the LED pins 16 | int pinArray[5] = {D5_PIN, D4_PIN, D3_PIN, D2_PIN, D1_PIN}; 17 | 18 | // Stores the state machine state and sets initial state 19 | volatile int8_t state = 0; 20 | 21 | void setup() 22 | { 23 | Serial.begin(9600); 24 | 25 | // Set mode of all of the LED pins 26 | pinMode(D1_PIN, OUTPUT); 27 | pinMode(D2_PIN, OUTPUT); 28 | pinMode(D3_PIN, OUTPUT); 29 | pinMode(D4_PIN, OUTPUT); 30 | pinMode(D5_PIN, OUTPUT); 31 | 32 | digitalWrite(D1_PIN, LOW); 33 | digitalWrite(D2_PIN, LOW); 34 | digitalWrite(D3_PIN, LOW); 35 | digitalWrite(D4_PIN, LOW); 36 | digitalWrite(D5_PIN, LOW); 37 | 38 | // USER CODE - IMPLEMENT FOR LAB 39 | 40 | // SET UP INPUTS 41 | // Here set up the button inputs 42 | pinMode(SW1_PIN, INPUT); 43 | pinMode(SW2_PIN, INPUT); 44 | 45 | // ATTACH INTERRUPTS 46 | // Here attach the interrupt service routines to physical pins 47 | attachInterrupt(digitalPinToInterrupt(SW1_PIN), ISR_SW1, RISING); 48 | attachInterrupt(digitalPinToInterrupt(SW2_PIN), ISR_SW2, FALLING); 49 | } 50 | 51 | void loop() 52 | { 53 | // DISPLAY STATE 54 | // Here use the state variable and display the results using the LEDs 55 | // Make sure to use a for loop here, updating every LED 56 | for(int i = 0; i < 5; i++) 57 | { 58 | if(i < state) { 59 | digitalWrite(pinArray[i], HIGH); 60 | } else { 61 | digitalWrite(pinArray[i], LOW); 62 | } 63 | } 64 | 65 | // Print the current state to the serial monitor 66 | Serial.print("State "); 67 | Serial.println(state); 68 | 69 | // A delay of 100ms so we do not sample or print too fast 70 | delay(100); 71 | } 72 | 73 | // INTERRUPT 1 74 | // Here write the ISR linked to the SW1 button 75 | void ISR_SW1() 76 | { 77 | state++; 78 | if(state > 5) { 79 | state = 5; 80 | } 81 | } 82 | 83 | // INTERRUPT 2 84 | // Here write the ISR linked to the SW2 button 85 | void ISR_SW2() 86 | { 87 | state--; 88 | if(state < 0) { 89 | state = 0; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /code/Week2/Week_2_Template/Week_2_Template.ino: -------------------------------------------------------------------------------- 1 | // Firmware Training Week 2 2 | // User Code 3 | 4 | 5 | #define D1_PIN 11 6 | #define D2_PIN 10 7 | #define D3_PIN 9 8 | #define D4_PIN 6 9 | #define D5_PIN 5 10 | 11 | #define SW1_PIN 2 12 | #define SW2_PIN 3 13 | 14 | // Stores the LED pins 15 | int pinArray[5] = {D5_PIN, D4_PIN, D3_PIN, D2_PIN, D1_PIN}; 16 | 17 | // Stores the state machine state and sets initial state 18 | volatile int8_t state = 0; 19 | 20 | void setup() 21 | { 22 | Serial.begin(9600); 23 | 24 | // Set mode of all of the LED pins 25 | pinMode(D1_PIN, OUTPUT); 26 | pinMode(D2_PIN, OUTPUT); 27 | pinMode(D3_PIN, OUTPUT); 28 | pinMode(D4_PIN, OUTPUT); 29 | pinMode(D5_PIN, OUTPUT); 30 | 31 | digitalWrite(D1_PIN, LOW); 32 | digitalWrite(D2_PIN, LOW); 33 | digitalWrite(D3_PIN, LOW); 34 | digitalWrite(D4_PIN, LOW); 35 | digitalWrite(D5_PIN, LOW); 36 | 37 | // USER CODE - IMPLEMENT FOR LAB 38 | 39 | // SET UP INPUTS 40 | // Here set up the button inputs 41 | 42 | // ATTACH INTERRUPTS 43 | // Here attach the interrupt service routines to physical pins 44 | } 45 | 46 | void loop() 47 | { 48 | // DISPLAY STATE 49 | // Here use the state variable and display the results using the LEDs 50 | // Make sure to use a for loop here, updating every LED 51 | 52 | // Print the current state to the serial monitor 53 | Serial.print("State "); 54 | Serial.println(state); 55 | 56 | // A delay of 100ms so we do not sample or print too fast 57 | delay(100); 58 | } 59 | 60 | // INTERRUPT 1 61 | // Here write the ISR linked to the SW1 button 62 | void ISR_SW1() 63 | { 64 | } 65 | 66 | // INTERRUPT 2 67 | // Here write the ISR linked to the SW2 button 68 | void ISR_SW2() 69 | { 70 | } 71 | -------------------------------------------------------------------------------- /code/Week3/Week_3_Solution/Week_3_Solution.ino: -------------------------------------------------------------------------------- 1 | // Firmware Training Week 3 2 | // User Code Example 3 | // Marine Maisonneuve, Logan Schick 4 | 5 | #define D1_PIN 11 6 | 7 | #define SW1_PIN 2 8 | 9 | // Stores the light value 10 | uint8_t light_value = 0; 11 | 12 | void setup() 13 | { 14 | Serial.begin(9600); 15 | 16 | // Set mode of the LED pin 17 | pinMode(D1_PIN, OUTPUT); 18 | digitalWrite(D1_PIN, LOW); 19 | 20 | // Set mode of the button input 21 | pinMode(SW1_PIN, INPUT); 22 | 23 | // USER CODE - IMPLEMENT FOR LAB 24 | 25 | // ATTACH INTERRUPTS 26 | // Here attach the interrupt service routines to physical pins 27 | attachInterrupt(digitalPinToInterrupt(SW1_PIN), LED_INT, RISING); 28 | 29 | // SET REGISTER VALUES 30 | // Here set the initial values of TCCR2A, TCCR2B, and OCR2A 31 | TCCR2A = 0b10000011; //Datasheet section 15.11.1 32 | TCCR2B = 0b00000111; //Datasheet section 15.11.2 33 | OCR2A = 0b00000000; //Datasheet section 15.11.4 34 | } 35 | 36 | void loop() 37 | { 38 | // Print the current light value to the serial monitor 39 | Serial.print("Light value: "); 40 | Serial.println(light_value); 41 | 42 | // A delay of 100ms so we do not sample or print too fast 43 | delay(100); 44 | } 45 | 46 | // INTERRUPT 47 | // Here write the ISR linked to the SW1 button 48 | void LED_INT() { 49 | light_value += 17; 50 | 51 | if (light_value >= 255) { 52 | light_value = 0; 53 | } 54 | 55 | OCR2A = light_value; 56 | } 57 | -------------------------------------------------------------------------------- /code/Week3/Week_3_Template/Week_3_Template.ino: -------------------------------------------------------------------------------- 1 | // Firmware Training Week 3 2 | // User Code 3 | 4 | #define D1_PIN 11 5 | 6 | #define SW1_PIN 2 7 | 8 | // Stores the light value 9 | uint8_t light_value = 0; 10 | 11 | void setup() 12 | { 13 | Serial.begin(9600); 14 | 15 | // Set mode of the LED pin 16 | pinMode(D1_PIN, OUTPUT); 17 | digitalWrite(D1_PIN, LOW); 18 | 19 | // Set mode of the button input 20 | pinMode(SW1_PIN, INPUT); 21 | 22 | // USER CODE - IMPLEMENT FOR LAB 23 | 24 | // ATTACH INTERRUPTS 25 | // Here attach the interrupt service routines to physical pins 26 | 27 | // SET REGISTER VALUES 28 | // Here set the initial values of TCCR2A, TCCR2B, and OCR2A 29 | TCCR2A = //Datasheet section 15.11.1 30 | TCCR2B = //Datasheet section 15.11.2 31 | OCR2A = //Datasheet section 15.11.4 32 | } 33 | 34 | void loop() 35 | { 36 | // Print the current light value to the serial monitor 37 | Serial.print("Light value: "); 38 | Serial.println(light_value); 39 | 40 | // A delay of 100ms so we do not sample or print too fast 41 | delay(100); 42 | } 43 | 44 | // INTERRUPT 45 | // Here write the ISR linked to the SW1 button 46 | void LED_INT() { 47 | 48 | } 49 | -------------------------------------------------------------------------------- /code/Week4/Project4Rewrite/Project4Rewrite.ino: -------------------------------------------------------------------------------- 1 | #include "TiltSensor.h" 2 | #include "Wire.h" 3 | 4 | tilt_sensor::BubbleIndicator bubbleIndicator; 5 | tilt_sensor::IMU imu; 6 | 7 | bool value; 8 | 9 | void setup() { 10 | // Begin i2c 11 | Wire.begin(); 12 | Serial.begin(9600); 13 | 14 | bubbleIndicator.initIndicator(); 15 | imu.initIMU(); 16 | } 17 | 18 | void loop() { 19 | tilt_sensor::AccelVector vector = imu.getMeasurement(); 20 | tilt_sensor::printVector(vector); 21 | delay(1000); 22 | } 23 | -------------------------------------------------------------------------------- /code/Week4/Project4Rewrite/TiltSensor.cpp: -------------------------------------------------------------------------------- 1 | #include "TiltSensor.h" 2 | 3 | namespace tilt_sensor { 4 | 5 | void printVector(AccelVector vector) { 6 | Serial.print("x: "); 7 | Serial.print(vector.x); 8 | Serial.print(", y: "); 9 | Serial.print(vector.y); 10 | Serial.print(", z: "); 11 | Serial.println(vector.z); 12 | } 13 | 14 | BubbleIndicator::BubbleIndicator() {} 15 | 16 | void BubbleIndicator::initIndicator() { 17 | for (int i = 0; i < 5; i++) { 18 | pinMode(pinArr[i], OUTPUT); 19 | digitalWrite(pinArr[i], LOW); 20 | } 21 | } 22 | 23 | void BubbleIndicator::updateIndicator(AccelVector vector) { 24 | float angle = atan2f(vector.y, vector.z); 25 | int pinPos = -1; 26 | 27 | if (angle < THRESHOLD_1) { 28 | pinPos = 0; 29 | } else if (angle < THRESHOLD_2) { 30 | pinPos = 1; 31 | } else if (angle < THRESHOLD_3) { 32 | pinPos = 2; 33 | } else if (angle < THRESHOLD_4) { 34 | pinPos = 3; 35 | } else { 36 | pinPos = 4; 37 | } 38 | 39 | for (int i = 0; i < 5; i++) { 40 | if (i == pinPos) { 41 | digitalWrite(pinArr[i], HIGH); 42 | } else { 43 | digitalWrite(pinArr[i], LOW); 44 | } 45 | } 46 | } 47 | 48 | IMU::IMU() {} 49 | 50 | bool IMU::initIMU() { 51 | // Write PWR_MGMT_1 to the IMU 52 | writeByte(PWR_MGMT_1, 0); 53 | 54 | // Check that the IMU has the right I2C addr 55 | int id = getID(); 56 | 57 | // Write ACCEL_CONFIG to the IMU 58 | writeByte(ACCEL_CONFIG, 0); 59 | 60 | return (id == MPU_ADDR); 61 | } 62 | 63 | int IMU::getID() { 64 | char buffer[1]; 65 | readConsecutiveBytes(WHO_AM_I, 1, buffer); 66 | 67 | return buffer[0]; 68 | } 69 | 70 | AccelVector IMU::getMeasurement() { 71 | // Read data from the MCU 72 | char buffer[6]; 73 | readConsecutiveBytes(ACCEL_XOUT_H, 2, buffer); 74 | 75 | // Format data into an AccelVector 76 | AccelVector vector; 77 | vector.x = (buffer[0] << 8 | buffer[1]) / SCALE_FACTOR_2G; 78 | vector.y = (buffer[2] << 8 | buffer[3]) / SCALE_FACTOR_2G; 79 | vector.z = (buffer[4] << 8 | buffer[5]) / SCALE_FACTOR_2G; 80 | 81 | return vector; 82 | } 83 | 84 | void IMU::readConsecutiveBytes(char addr, int len, char *buffer) { 85 | Wire.beginTransmission(MPU_ADDR); 86 | Wire.write(addr); 87 | Wire.endTransmission(); 88 | Wire.requestFrom(MPU_ADDR, len, true); 89 | 90 | for (int i = 0; i < len; i++) { 91 | buffer[i] = Wire.read(); 92 | } 93 | } 94 | 95 | void IMU::writeByte(char addr, char data) { 96 | Wire.beginTransmission(MPU_ADDR); 97 | Wire.write(addr); 98 | Wire.write(data); 99 | Wire.endTransmission(true); 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /code/Week4/Project4Rewrite/TiltSensor.h: -------------------------------------------------------------------------------- 1 | #ifndef TILT_SENSOR 2 | #define TILT_SENSOR 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace tilt_sensor { 9 | 10 | struct _AccelVector { 11 | float x; 12 | float y; 13 | float z; 14 | }; 15 | typedef _AccelVector AccelVector; 16 | 17 | void printVector(AccelVector vector); 18 | 19 | class BubbleIndicator { 20 | public: 21 | BubbleIndicator(); 22 | void initIndicator(); 23 | void updateIndicator(AccelVector vector); 24 | private: 25 | // Pin values for the 5 LEDs 26 | const int D1_PIN = 11; 27 | const int D2_PIN = 10; 28 | const int D3_PIN = 9; 29 | const int D4_PIN = 6; 30 | const int D5_PIN = 5; 31 | 32 | // Array of output pins 33 | const int pinArr[5] = {D1_PIN, D2_PIN, D3_PIN, D4_PIN, D5_PIN}; 34 | 35 | // Threshold Values used to determine how many lights to turn on 36 | const float THRESHOLD_1 = -0.95 * M_PI; 37 | const float THRESHOLD_2 = -0.45 * M_PI; 38 | const float THRESHOLD_3 = 0.45 * M_PI; 39 | const float THRESHOLD_4 = 0.95 * M_PI; 40 | }; 41 | 42 | class IMU { 43 | public: 44 | IMU(); 45 | bool initIMU(); 46 | AccelVector getMeasurement(); 47 | int getID(); 48 | private: 49 | const char MPU_ADDR = 0x68; 50 | const char PWR_MGMT_1 = 0x6B; 51 | const char WHO_AM_I = 0x75; 52 | const char ACCEL_XOUT_H = 0x3B; 53 | const char ACCEL_XOUT_L = 0x3C; 54 | const char ACCEL_YOUT_H = 0x3D; 55 | const char ACCEL_YOUT_L = 0x3E; 56 | const char ACCEL_ZOUT_H = 0x3F; 57 | const char ACCEL_ZOUT_L = 0x40; 58 | const char ACCEL_CONFIG = 0x1C; 59 | const float SCALE_FACTOR_2G = 16384.0; 60 | 61 | void readConsecutiveBytes(char addr, int len, char *buffer); 62 | void writeByte(char addr, char data); 63 | }; 64 | 65 | } 66 | 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /code/Week4/Week_4_IMU/Week_4_IMU.ino: -------------------------------------------------------------------------------- 1 | //Firmware Training Week 4 2 | //MPU 6050 Emulation 3 | //Joe Spall, Varun Madabushi 4 | 5 | //***********************************************// 6 | // DO NOT EDIT THIS FILE // 7 | //***********************************************// 8 | 9 | #include 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


--------------------------------------------------------------------------------