<h3> Arduino Workshop </h3> <p> For this workshop, please collect the following: <ul> <li>Microcontroller </li> <li>breadboard</li> <li>hookup wires </li> <li>button </li> <!-- <li>MOSFET </li> <li>LED </li> <li>potentiometer </li> <li>DC motor</li> --> <li>10K resistor</li><!-- <li>470 Ohm resistor</li> --> </ul> </p> <h3> Conditional Statements </h3> <p> Let's start with the Button example (File > Examples > Digital > Button). We'll modify this using both pullup and pulldown resistors, then use Arduino's internal <a href='https://www.arduino.cc/en/Tutorial/InputPullupSerial'>INPUT_PULLUP</a></p> <p> Conditional statements allow a program to make decisions about which lines of code run and which do not. They let actions take place only when a specific condition is met.</p> <p>The test must be an expression that resolves to true or false. When the test expression evaluates to true, the code inside the { (left brace) and } (right brace) is run. If the expression is false, the code is ignored. Code inside a set of braces is called a block.</p> <p>Conditionals can be embedded to include more than one test to control which lines of code will run.</p> <p> The Button example uses this simple conditional statement: </p> <pre><code class="language-arduino"> if (buttonState == HIGH) { // turn LED on: digitalWrite(ledPin, HIGH); } else { // turn LED off: digitalWrite(ledPin, LOW); } </code></pre> <p>Build a circuit as described in the Button example (pushbutton attached to pin 2 from +3.3V and 10K resistor attached to pin 2 from ground): </p> <img src="./pulldown.png" alt="pulldown"> <br><br> <p>The 10k resistor is acting as a PULLDOWN resistor, meaning that in the absence of a connection to +3.3V, pin 2 will report it's connection to ground (LOW). Essentially we've created a "path of some resistance" to ground. When the button is unpressed, the circuit will take this path. When the button is pressed, a "path of much less resistance" is created to +3.3V, so pin 2 will report HIGH. What happens if you remove the resistor? Try moving your hand around the circuit. The results will be unpredictable (floating input). Read more about pullup and pulldown resistors on <a href='https://learn.sparkfun.com/tutorials/pull-up-resistors/all'>SparkFun</a>. </p> <p>We can convert this to a PULLUP resistor configuration by switching the 3.3V and GND connections on the breadboard. The behavior of the button is now reversed (pressing button turns LED off). </p> <img src="./pullup.png" alt="pullup"> <br><br> <p> Luckily, many microcontrollers have built-in PULLUP resistors, which operate in the opposite way. Open the DigitalInputPullup example and rewire your circuit so that the button connects pin 2 to ground:</p> <img src="./inputpullup.png" alt="inputpullup"> <br><br> <p> This example also allows us to see what's going on under the hood with the Serial monitor. </p> <h3> Nested Conditional Statements </h3> <p> We can put conditional statements inside one another in order to see if multiple conditions have been met. A great tool in Arduino is the <code>millis()</code> function, which returns the number of milliseconds since the program began. We can make a simple time-based conditional statement: </p> <pre><code class="language-arduino"> if (millis() > 3000) { // turn LED on: digitalWrite(ledPin, HIGH); } else { // turn LED off: digitalWrite(ledPin, LOW); } </code></pre> <p> Now, we can nest that inside of our previous conditional statement: </p> <pre><code class="language-arduino"> if (buttonState == HIGH) { if (millis() > 3000) { // turn LED on: digitalWrite(ledPin, HIGH); } else { // turn LED off: digitalWrite(ledPin, LOW); } } </code></pre> <h3> Logical Operators </h3> <p>Logical operators are used to combine two or more relational expressions and to invert logical values. They allow for more than one condition to be considered simultaneously.</p> <p>The logical operators are symbols for the logical concepts of AND (&&), OR (||), and NOT (!):</p> <table> <tr> <th>Expression</th> <th>Evaluation</th> </tr> <tr> <td>true && true</td> <td>true</td> </tr> <tr> <td>true && false</td> <td>false</td> </tr> <tr> <td>false && true</td> <td>false</td> </tr> <tr> <td>true || true</td> <td>true</td> </tr> <tr> <td>true || false</td> <td>true</td> </tr> <tr> <td>false || false</td> <td>false</td> </tr> <tr> <td>!true</td> <td>false</td> </tr> <tr> <td>!false</td> <td>true</td> </tr> </table> <p> If we consider a = 8 and b = 12, we'd follow these steps in order to resolve the expression (a > 4) || (b < 24): <ul> <li>(a > 4) || (b < 24)</li> <li>(8 > 4) || (12 < 24)</li> <li>true || true</li> <li>true</li> </ul> <p>In this example, the expression "a > 15" is false, but "b < 30" is true. Because the OR operator requires only one part to be true in the entire expression, the code in the block will run. Try changing the code to logical AND instead of OR</p> <pre><code class="language-arduino"> const int ledPin = 13; void setup(){ pinMode(ledPin, OUTPUT); int a = 10; int b = 20; if ((a > 15) || (b < 30)) { digitalWrite(ledPin, HIGH); } else { digitalWrite(ledPin, LOW); } } </code></pre> <p>We can modify our previous Button example such that both conditions are written in the same line. </p> <pre><code class="language-arduino"> const int buttonPin = 2; // the number of the pushbutton pin const int ledPin = 13; // the number of the LED pin // variables will change: int buttonState = 0; // variable for reading the pushbutton status void setup() { // initialize the LED pin as an output: pinMode(ledPin, OUTPUT); // initialize the pushbutton pin as an input: pinMode(buttonPin, INPUT); } void loop() { // read the state of the pushbutton value: buttonState = digitalRead(buttonPin); // check if the pushbutton is pressed AND more than 3 seconds have passed. // If both are true, the buttonState is HIGH: if (buttonState == HIGH && millis() > 3000) { // turn LED on: digitalWrite(ledPin, HIGH); } else { digitalWrite(ledPin, LOW); } } </code></pre> <!-- ////////////////// for loops //////////////////// --> <h3> <code>for()</code> Loops </h3> <p> For this exercise, please collect the following: <ul> <li>Microcontroller </li> <li>breadboard</li> <li>hookup wires </li> <!-- <li>button </li> <li>MOSFET </li> --> <li>LED </li> <li>potentiometer </li> <!-- <li>DC motor</li> <li>10K resistor</li> --> <li>1K resistor</li> </ul> </p> <p> The <code>for()</code> structure performs repetitive calculations and is structured like this:<br> <pre><code class="language-arduino"> for (init; test; update) { statements }</code></pre> </p> <p> Let's connect an LED to pin 10 with a 1K resistor in series. </p> <p> Let's say you want to incrementally brighten an LED. You might do that with repetitive commands:</p> <pre><code class="language-arduino"> int PWMpin = 10; // LED in series with 1K resistor on pin 10 void setup() { // no setup needed } void loop() { analogWrite(PWMpin, 0); delay(100); analogWrite(PWMpin, 50); delay(100); analogWrite(PWMpin, 100); delay(100); analogWrite(PWMpin, 150); delay(100); analogWrite(PWMpin, 200); delay(100); analogWrite(PWMpin, 250); delay(100); } </code></pre> <p> However, the same result can be generated with fewer lines of code using a <code>for</code> loop:</p> <pre><code class="language-arduino" > int PWMpin = 10; // LED in series with 1K resistor on pin 10 void setup() { // no setup needed } void loop() { for (int i = 0; i <= 255; i=i+50) { analogWrite(PWMpin, i); delay(100); } } </code></pre> <p> This flexible pattern allows you to easily change the resolution of the fade:</p> <pre><code class="language-arduino" > int PWMpin = 10; // LED in series with 1K resistor on pin 10 void setup() { // no setup needed } void loop() { for (int i = 0; i <= 255; i++) { analogWrite(PWMpin, i); delay(10); } } </code></pre> <p>The statements inside the loop can include conditional statements, and vice versa. Try modifying the conditions to get different results:</p> <pre><code class="language-arduino" > void loop() { for (int i = 0; i <= 255; i++) { if (millis() >= 2000) { analogWrite(PWMpin, i); } else { analogWrite(PWMpin, 0); } delay(10); } } </code></pre> <p>The modulus operator is often used within loops to create cycles:</p> <pre><code class="language-arduino" > void loop() { if (millis()%500 > 100) { analogWrite(PWMpin, 255); } else { analogWrite(PWMpin, 0); } delay(10); } </code></pre> <p>The modulus operator could even replace the <code>for()</code> loop as a timer, which would produce a more precise cycle based on clock time instead of delays. </p> <h3> Nested Iteration </h3> <p> The <code>for</code> structure allows us to cycle through the range of one parameter. Nesting this structure allows us to create more complex cycles. In this example, instead of always fading to the maximum analog value (255), we start by fading from 0-0, then 0-1, etc. until we fade from 0-255. Our new "maximum" variable is incremented in the outside loop. </p> <pre><code class="language-arduino" > void loop() { for (int maximum = 0; maximum <= 255; maximum++) { for (int i = 0; i < maximum; i++) { analogWrite(PWMpin, i); delay(1); } } } </code></pre> <p> Now let's connect a potentiometer to A0, and open the AnalogInput example (File > Examples > Analog > AnalogInput). This example uses the potentiometer to control the blink frequency. See if you can modify that example so that the potentiometer controls the "maximum" variable in the <code>for()</code> loop we used before: </p> <pre><code class="language-arduino" > void loop() { // set maximum equal to the incoming value for (int i = 0; i < maximum; i++) { analogWrite(PWMpin, i); delay(1); } } </code></pre> <p> You may notice that that sensor values range from 0-1023 while the analogWrite() function wants values between 0-255. Try using the map() function to convert one range to another. Your final code may look something like this:</p> <pre><code class="language-arduino" > int PWMpin = 10; // LED in series with 470 ohm resistor on pin 10 int potpin = A0; // select the input pin for the potentiometer int potValue = 0; // variable to store the value coming from the sensor int maximum; void setup() { Serial.begin(9600); } void loop() { maximum = map(analogRead(potpin), 0, 1023, 0, 255); Serial.println(maximum); for (int j = 0; j < maximum; j++) { analogWrite(PWMpin, j); delay(1); } } </code></pre> <p> This is just the beginning! Please check out Arduino's default examples as well as additional examples in the <a href="https://www.eitkw.com/wp-content/uploads/2020/03/Arduino_Projects_Book.pdf">Arduino Projects Book</a> .