Image of a steam locomotive with the caption Pittsburgh Locomotive Works

(image from Hill, John A. Locomotive engineering: a practical journal of railway motive power and rolling stock. New York: A. Sinclair, J.A. Hill. 1892. Via the Internet Archive)

due at the start of class on Thursday, Sept. 10th

Your work assignment from the Pittsburgh Train Company

The Pittsburgh Train Company (PitTraCo) needs a new light-blinking system, and they think you’re the right person for the job. They use signal lights to communicate with the train engineers, and want to replace the 80 year old system they’ve been using with new electronically controlled hardware.

First, you’ll build a prototype system, just to prove to them that you are able to use a potentiometer to change the rate at which some lights blink:

Warmup/prototype

  • Input: one potentiometer.
  • Output: two LEDs.
  • Behavior: the two LEDs alternate blinking at a steady pace at all times; adjusting the position of the potentiometer changes the rate at which they blink: 🔴🔴

Once you show them that prototype, they’ll definitely be impressed. Then, you’ll need to make it a little better: you’ll have to upgrade it to a system that can change blinking modes, so they can are able to send two different kinds of signals to the train engineers. That is your real assignment:

Assignment

1. Build a light-blinking system matching the below parameters:

  • Input: one potentiometer and one momentary pushbutton (called simply “Pushbutton” in Tinkercad)
  • Output: two LEDs and serial feedback
  • Behavior: the pushbutton acts as a mode selector, and the potentiometer acts to change the rate of the LEDs blinking

Explanation of behavior: When the pushbutton is not pressed, the hardware behaves exactly as described in the warmup above, including that the potentiometer changes the rate of blinking: 🔴🔴
However, while the pushbutton is pressed, the two LEDs blink both on at the same time, both off at the same time, instead of alternating: 🔴🔴 (The potentiometer can still be used to change the rate of blinking during this time.)

At all times, once per on-blink, there should be serial feedback formatted like this:

Alternating mode. Blinking once per 123ms.
Alternating mode. Blinking once per 456ms.

where the values such as 123ms are the actual blinking rate, as reported in milliseconds. While the mode-changing button is pushed, the serial feedback should instead read:

Unison mode. Blinking once per 234ms.
Unison mode. Blinking once per 567ms.

A small note on code style: we didn’t quite get to this point in class (though we addressed it elliptically), but please refer to this section of the Code Bites page for our preferred style for naming pins.

1a. Bonus (strictly optional, if you have extra time)

“Wow,” the PitTraCo executive says, leaning back in her cushy chair, “that was pretty good. We would love just one more feature, please…”

PitTraCo needs to be able to send an automated emergency signal to their train engineers. At the push of a button (you’ll need a second momentary button), the LEDs should interrupt whatever they’re doing and blink in unison three quick blinks, pause, three quick blinks, pause, three quick blinks, pause, and then return to their regular blinking after.

When the emergency signal button is first pressed, the serial feedback should read:

*****Emergency signal dispatched!*****

and then once the triple signal has been completely transmitted, the serial feedback should read:

-----End emergency signal. Resuming regular service.-----

2. Use Canvas to submit your code and schematic

Submit your .ino code (downloaded from Tinkercad or written in the Arduino IDE), as well as your schematic, to this Canvas assignment.

For your code: Be sure to add a standard comment block at the top of the code as specified in the syllabus. Use good names for your variables and good formatting practices. Add comments as needed to help explain non-obvious things to any future readers.

For the schematic: draw neatly; the emphasis is on legibility and clarity, but it need not be precisely rendered. Use standard symbols for all circuit elements.

3. Use Canvas to submit your Tinkercad sketch

Use this Canvas assignment to submit your Tinkercad sketch. Just as in last time, to generate a link for your design, click “share” in the upper right corner of a Tinkercad sketch, then “Invite people.”


Hints please!

Potentiometer

In class we learned about how to use the analogRead() function to read a potentiometer’s position. To review: we initialize the potentiometer pin by running this line inside the setup:

pinMode(A0, INPUT);

We can later perform an analogRead() of that pin at any time we’d like to find its current value. This could look like this inside the loop:

int potVal; // create a variable with a name that's short for 'potentiometer value'
potVal = analogRead(A0); // perform an analogRead on pin A0 and then save that value into the variable potVal

In the above case, the variable potVal will contain the most recently found value, so we should expect it to change very often.

What you can expect from analogRead()

The way the analogRead() function runs on our Uno R3 hardware, we are guaranteed it will always return a value between 0 and 1,023, inclusive. This number is a linear approximation of the voltage present on the pin you are measuring. To be clear:

voltage present at a pin ÷ 5V = analogRead() of that pin ÷ 1,023

A few values to illustrate the above equation:

volts analogRead() value
0 0
1 205
2.5 512
4.5 921
5 1023

Adding a button

Tactile pushbuttons are available in bin 12, row 4, column 1 in the Physical Computing Lab.

Consult the course tutorial page on buttons and switches to learn how to wire up a tactile pushbutton for this homework assignment. Pay careful attention to:

  • the need for a “pull-down” resistor, and
  • the non-intuitive internal wiring of a tactile pushbutton.

Other points

Q: How do I check to see if a button is in a particular position?

By running an if test on its latest observed value. For instance, after running code that detects a button’s state and loads it into the value buttonState:

if (buttonState == HIGH){
    // code in between these curly brackets will run only if the button state is "HIGH"
} else {
    // code in between these curly brackets will run otherwise
}

You can test for equality using the == operator, as shown above1. Further operators:

  • greater than: if (potVal > 10)
  • less than: if (potVal < 10)
  • greater than or equal to: if (potVal >= 10)
  • less than or equal to: if (potVal <= 10)
  • not equal to: if (potVal != 10)

For a review of if, head over to its Arduino language reference page.

Q: How can I change the rate of blinking?

Well, remember how earlier we put a number into our delay() statements, like delay(1000) or delay(20), etc.? Instead of putting a number into the parentheses, you can put a variable in there—and whatever value the variable has, will be the length of the delay in milliseconds.

Q: How can I format the serial feedback with words and numbers in it?

Here’s an example:

Serial.println((String)"This first variable's value is " + varOne + ", and the second one's is " + varTwo);

The key part here is the (String) at the beginning of the stuff in the parentheses; that will turn everything in there into text which the Serial.println command knows how to read. Please see this section of the “Code bites” tutorial page for more on this topic.

Collaboration and help

Just the same as Homework #2: You are welcome to collaborate with your classmates, friends, etc., on this homework assignment. Look up help in any source that you find useful, including the web, reference books, whatever you’d like to use.

However:

  1. You must type out the code you use. That means that while you can copy parts of it from another source, you have to type every single letter yourself! We’re building muscle memory. (If you work with a partner, you can both have identical code, but you must both type it out yourself.)

  2. You must build your own circuit. You can make the same circuit your friend does, but you have to actually use your own hands to make yours.

Questions? Concerns? Email me and ask! I’m here to help.

Grading rubric

points part
5 blinking matches spec, and rate/pattern properly affected by potentiometer and button
2 serial feedback as per specification: the correct messages at the correct time
1 LEDs wired properly: each driven by its own Arduino output, with its own 270Ω current-limiting resistor
1 potentiometer wired correctly
3 schematic properly formatted and electrically valid
5 code written with correct comment block and reasonable formatting throughout
2 bonus (blinking and serial messages as per spec)
17 total

Footnotes:

  1. Why use == and not simply = to test for equality? This is a moment when we must remember that writing programs in C is different than writing out math equations; the = symbol has a particular meaning, called assignment, which is to take the value on its right and “assign” it to the variable on its left, as in x = 10. While == asks the question “are they equal?” on the other hand = says “now the thing on the left is equal to the thing on the right.” Don’t confuse these!