lava lamp π

You've seen lava lamps, and thought they were the bomb. (Do people still say things are "the bomb?") In this exploration, we'll tie external inputs and outputs into our Freeduinos and build a lava lamp version 3.14.  

This homework is analytical in nature: you'll be doing less writing of code and more reading or analysis of code. 

expectations

This exploration assumes that you've successfully managed to write code for your Freeduino in occam-π that can blink LEDs in parallel. We have just begun our discussions of patterns for parallelism (the Pipeline and Black Hole), this laboratory will mostly involve the composition of components with channels. That's a fancy way of saying "you will use pre-written processes defined in the Plumbing library and connect them together." 

You may also find Pountain and May's Tutorial Introduction a good read during this next two weeks. The Burns is a good resource as well, and the occ2.1 language reference can serve... as a reference...

I expect that you will engage in learning this material—I am a resource you can use as often as you like to work through this homework, but I will not, in lecture, be feeding you all of the detail you need for this work. Dig in!

build the circuit

Your circuit will ultimately include 3 LEDs and a slide potentiometer. It should look something like this:

blinkenlights-circuit-72

I would develop this on your breadboards first, and then solder things together in your sweet, sweet cardboard box.

The LEDs should be connected up to PWM pins. I used 560Ω resistors in series with the LED.

Your slider has four connection points, one of which is actually "dead," or unconnected. The two connections that are fully connected should go between +5V and GND. The remaining connection (which is where we read the value of the slider) should go into an "Analog In" pin on the Freeduino—one of the analog pins 0 through 5.

Fritzing, the tool I use for building diagrams, does not yet have a slider. Hence, I used a sticky note. (Fritzing is an open source project aiming to build a circuit design tool "for the rest of us." For a Comp Sci student interested in circuit design, this might be a really great tool to explore. Certainly, I'm enjoying using it.)

QUESTIONS

  1. Why do we put a resistor in series with the LED?

  2. What is the minimum resistance value we need to include if the maximum forward current of our LEDs is 30mA?

  3. Use a multimeter to determine the maximum and minimum resistance of our linear slide potentiometer (fancy word for "slider").

enter the skeleton

We'll start with the following skeleton code.

20100220-occam1

You'll need the standard #INCLUDE "plumbing.module". Type this code into your text editor (this is so you get practice typing occam-π), and it should compile as-is.

QUESTIONS

What do the following PROCs do?

  1. beginAnalog()
  2. analogWrite()
  3. delay()

  4. What does pwm.cycle() do? What is the equivalent of a "replicated SEQ" in other programming languages?

  5. What is the range of values that can come in on the adc channel?

You can refer to the Plumbing and Wiring occamdoc for support.

your first process network

Next, lets experiment with adc(). You can find it in the Plumbing documentation. Draw the process in your notebook, so you know what it should look like when included in a process diagram.

Now, write a new process called show.int(). In an infinite loop (WHILE TRUE) it should, in SEQuence:

  1. SIGNAL the adc() process (to start a reading)

  2. read the INT that adc() produces

  3. Output that number to the screen. 

  4. Output a newline

You can generate a newline in your printed output this way:

serialWrite("*n")

In Java, you would have written \n. In occam, you write *n. Each language has its syntax.

Wire this new process up with adc() and run them in parallel in a main() process. If you've wired your circuit up correctly, you should be able to see the values read from the adc() process printed to your screen.

NOTE

SIGNAL channels are simpler than any other kind of channel. You still declare them as you would anything else:

CHAN SIGNAL s:

However, to write to them, you just say

s ! SIGNAL

And, to receive at the other end, you write

s ? SIGNAL

Put simply, a SIGNAL isn't a value. It's more like a submarine ping. Or, if you prefer, a "high-five."  We added SIGNALs to occam-π this past summer, because we wanted a really simple way for one process to communicate with another.

QUESTIONS

  1. show.int consumes data and displays it to the screen. In terms of its channels in and out, what pattern does it most resemble? 
  2. What happens if you comment out the line for signaling the ADC? Why?

expanding your network

Eliminate the signaling portion of  show.int(). Replace it with an output channel; at the bottom of the loop, pass the INT you just printed on through this channel.  

Extend the process network in your main() with fader(). The network should look something like this:

blinkenlight-network

QUESTIONS

  1. This network forms a ring. Why doesn't it deadlock?
  2. Modify your code so that show.int() is no longer in your network. What does the diagram look like now?

extension

The challenge now is to extend your network to support 3 LEDs.

You can use three fader() processes; that's not a problem. Note, though, that there is only one adc() process. The reason for this should be obvious: there's only one slider.

You need to write a process that lives in-between the ADC and the fader processes; it should handle requests from the three faders (each of which may request a reading at any time), do the reading, and then send the result back to the fader who made the request. This will combine the Client/Server and Multiplexer patterns.

I'm scaffolding this less than previous parts, because I want you to dig into the design of this process a bit on your own. It won't be a long process, but it does contain some big ideas.

QUESTIONS

  1. What is a semaphore?

  2. Is your new PROC the process-oriented equivalent of a semaphore? 
    Why or why not?

in conclusion

Save your completed code, and submit it along with answers to the questions asked to the Sakai dropbox.

There is a large question lurking in this lab: if you were to use the pwm() process from the Plumbing library, how would it change the structure of your solution? Further, can you come up with another solution that allows 1. each LED to update its rate independently, but 2. gets rid of the semaphore construct we had to implement?

Creative Commons License This work is licensed under a CC BY-SA 3.0 License.