Advice page for lab 2b

Need help getting started? Check out our guide to the Arduino to help you get underway.

General

  • You’re allowed to make one box per person. Some pairs might choose to make a second box for the computerized useless box, and keep the first one as is. This is completely acceptable, and has its advantages: you can easily re-optimize wire lengths and it’s a great way to improve your soldering. The catch, of course, is that it takes longer. You might want to come in before your lab to construct a box and put the toggle and limit switches in place (with overlength wires that you’ll cut to length later), so that you can get underway with the Arduino as soon as you get to your lab section.

  • Don't just build your whole circuit in one go! Test out each section as you build. Test the first CMOS inverter as soon as you've built it. Then test the second inverter. Then put a voltmeter between the two outputs and test that they can work together to flip the voltage on a (hypothetical) motor. Then insert a real motor and check that you can change which direction it goes in. Then try driving the motor forward and back with the Arduino… and so on…

Taking care of soldering irons

  • We have replacement soldering tips available, which we can use to replace the tips that were too oxidized last week. But we need to take care of our soldering equipment, otherwise they'll be in an equally dire state within a week. To be more specific, wipe the tip on a damp sponge every time you pick up and put down the iron. It sounds obsessive, but it makes a huge difference.

  • If your sponge isn't damp, make it damp! There are bottles of water around that can squirt water on to sponges.

Soldering and wiring

  • If you’re reusing your existing box, you’ll want to desolder all the wires from the toggle switch except two. Make sure you know which two you’re leaving there. There is no stylistic advantage in having input values the “right way round” or the “wrong way round” in software, so this shouldn’t be a factor in consideration when you wire your circuit together. (There are plenty of other factors in style, we're just saying this isn't one of them.) It’s very common practice to have “active-low” inputs in industry. (“Active-low” means that the voltage is low when the input is doing something exciting.) In fact, if anything, we’d rather that you used the Arduino’s internal pull-up resistor (see below).

  • You might, and should, choose pins for convenience in wiring. Just be aware that not all pins will do everything. Specifically, not all pins support the analogWrite() function. There’s a list of pins that do in the Arduino Nano specifications.

  • Let's talk about jumper wires, or jumpers. Jumpers are short wires that we use to make connections on the same board (in our case, breadboards). In your lab kit, there are two sets of jumpers. One of them is in a plastic box, and they look all nice and straight and their ends are pre-bent. The other is in a bag, and is a bunch of longer, flexible cables. In general, you shoud use the straight ones for connections you don't want to fall off your breaboard, and the flexible ones for temporary connections that you're still playing with.

  • The catch is that the short jumpers come in colors that match their lengths, which makes color-coding wires hard. This is fine; we're aware of it. But if you're a perfectionist, there are several reels of solid-core wire of lots of different colors, that you can cut to perfect length if you like =)

  • We now have an electric wire stripper that basically melts that basically melts the wire insulation to cut it. Feel free to use it.

  • You can, and should, cut the leads of components (like resistors) if it makes them easier to work with, or if it makes your breadboard neater.

Working with the Arduino

  • Remember that input pins measure voltage, so you have to set up your switch inputs to place a high (5 V) or low (0 V) voltage on your pin depending on whether the switch is pressed. The easiest way to do this is using a pull-up resistor, as we explained in class. But guess what: your Arduino already has a pull-up resistor inside it, which you enable using pinMode(pin, INPUT_PULLUP). Check out our pull-ups EveryCircuit simulation if pull-up resistors are confusing you.

  • You might find the Arduino’s reference documentation helpful if you’re trying to get your head around the intricacies of any function (say, analogWrite()).

Coding practice

  • It’s good practice to make it easy to change which pins you’re using in your code. You might find, after you write your code, that some other pin arrangement is better for wiring, and life is a lot easier if you can just change one line to effect this. It also makes your code more readable. Compare digitalWrite(LED_PIN, HIGH); to digitalWrite(7, HIGH);: which one makes the intended effect of that line more obvious? So you should define constants for pin numbers near the top of your file, using const int LED_PIN = 7; or something like that. (If you've studied preprocessor macros in another class and know how they work, you could also use #define.)

Some common gotchas

Code not working? Here are some common errors and typos people make:

  • Using single equals signs for assignment. if (togglePressed = HIGH) doesn't check for equality like if (togglePressed == HIGH) does. It assigns HIGH to togglePressed. In Java, this would be a compile error. In C (the language of Arduino), it will evaluate as the right-hand side (in this case, HIGH, which is a true value).

  • Mismatched braces are a common cause of bugs. A good way to manage these is to keep your indentation tidy, just like you learnt in your CS classes!

  • Don't forget to configure your pins as inputs or outputs, and the pull-up resistors, using pinMode().

Pushing towards the top style buckets

If you really want to impress us, here's a (very) non-exhaustive list of things you might consider:

  • Avoid delay statements; call the millis() function to keep track of time instead. You'll have to take note of a “start time” (by calling millis()), then check every loop whether your desired time has elapsed since then. The advantage of doing this is that you can do things in between calls to millis(), so you won't miss switch changes that happen while you're in the middle of your delay() call.