Tom Igoe Fall 2021

Class Times

  • Section 3: 09:10 AM – 11:40 AM Wednesday. 370 Jay Street, Room 409
  • Section 7: 3:30 PM – 6:00 PM Wednesday. 370 Jay Street, Room 408

Contacting Me

To book office hours, check my calendar. You’ll need to sign in with your NYU login to see it. I will schedule regular office hour appointment slots which you can book automatically once the semester starts.

My email:

Outside of office hours, I am generally working from 9 AM to 6 PM NYC time Monday-Friday. I’m usually on campus Tues – Thurs, and work at home other days. If you contact me outside of working hours, I’ll try to get back to you as soon as my next working time allows.

How Class Will Be Run

The most valuable thing we can do when we are in person or online in a class meeting together is to discuss and practice the subject that you’re learning. Any “lecture material” is on this site in video or written form, and assigned for the weeks where we will discuss it. I will expect that you’ve done the readings or watched the videos and tried the lab exercises assigned in advance of each class, and are coming to the class meetings with questions. Class meetings will be mainly discussions and shared demonstrations or experiments, not lectures. Use class time to get me or your classmates to clarify things you didn’t understand from the assigned material.

It’s okay if you couldn’t get a lab exercise or a project to work. When that happens, try to debug it, explain what you did in your blog, and come to class prepared to talk about the details and ask specific questions. Pay attention to your classmates’ work and their questions; quite often, they’ll be asking the same thing as you.

I will share any tools that we find useful on the Resources section of this site.

Useful links

Pin out for the Nano 33 IoT

A Few Good Reads

These are not on the main reading list or the Related Books and Articles page, but I think they’re excellent reads if you’re thinking about physical interface design.

  • Don Norman on the Paradox of Wearable Technologies, specifically heads-up displays like Google Glass.
  • Anil Dash on why There Is No “Technology Industry”
  • Bret Victor on Doug Engelbart and why Engelbart matters. A lovely tribute.
  • Ben Rubin’s redesign of the sounds in the NYC subway, circa 1998. In these, Ben looked at the sounds that are used to cue users of the subway and noted their limitations, then redesigned them to make them more understandable and useful. Video 1 and video 2 show the whole interaction.  Thanks to Alden Jones for finding them again.
  • Brenda Laurel’s Computers as Theatre, 2nd edition (NYU Library permalink). I first read this book in about 1993. It had a big impact on me, as I was working in theatre at the time, and it gave me a thorough, yet well explained, introduction to what computer interaction is all about, using theatre practice as an metaphor to explain it. Laurel stresses how it’s the action that is key to what we make, and the physical devices, controls, etc. set the stage for that. The 2nd edition, released in 2014, is a great update to a classic. Her writing is appropriately scholarly in its reference to the thinking of others in the field, yet very conversational, making it clearer than most theoretical writing.

Class Blogs

Section 3: 09:10 AM – 11:40 AM

Section 7: 3:30 PM – 6:00 PM

6 Oct 2021

A quick example of how to run three things at three different rates:

int ledInterval = 3000;
int servoInterval = 20;

long lastLEDChange = 0;
long lastServoChange = 0;
int lastButtonState = 0;
int LED = 3;

void setup() {
  pinMode (2, INPUT);
  pinMode(LED, OUTPUT);

void loop() {
  // read a button, see if it has changed
  int buttonState = digitalRead(2);
  if (buttonState != lastButtonState) {
    // change the LED
    ledState = !ledState;
    lastButtonState = buttonState;
  // blink an LED every three seconds
  if (millis() - lastLEDChange > ledInterval) {
    digitalWrite(LED, ledState);
    lastLEDChange = millis();

  // update the servo's angle only one degree every second:
  if (millis() - lastAngleChange > angleInterval) {
    // update the angle:
    if (angle > minAngle && angle < maxAngle) {
    } else {
      angle = 0;

  // update a servo motor every 20 seconds no matter what:
  if (millis() - lastServoChange > servoInterval) {
    // move the servo
    servo.write(pin, angle);
    lastServoChange = millis();

13 Oct 2021

Mentioned in the morning class:

  • HTML for Conndev – a repository of materials for my Connected Devices class
  • Displays for Microcontrollers – another repository from the Connected Devices class
    • Lab: OLED Display – a lab on this site showing how to connect a small screen (screens available in ER checkout)
  • Clock Club – a repository of clock and time-related projects
  • Lab: Rotary Encoder – A lab on this site showing how to use a rotary encoder

20 Oct 2021

  Serial port selector
  uses DOM elements to make a serial port selector
  created 20 Oct 2020
  by Tom Igoe

// variable to hold an instance of the serialport library:
let serial;
// HTML Select option object:
let portSelector;

let receivedData;
var vesper;

function setup() {
  createCanvas(320, 240);
  serial = new p5.SerialPort(); // new instance of the serialport library
  serial.on("list", printList); // callback function for serialport list event
  serial.on("data", serialEvent); // callback function for serialport data event
  serial.on("open", portOpen);
  serial.list(); // list the serial ports

function draw() {
  fill(color(0, 0, 0, vesper));
  text("Word", width / 2, height / 2);
  if (vesper > 0) {
// make a serial port selector object:
function printList(portList) {
  // create a select object:
  portSelector = createSelect();
  portSelector.position(10, 10);
  // portList is an array of serial port names
  for (var i = 0; i < portList.length; i++) {
    // add this port name to the select object:
  // set an event listener for when the port is changed:

function mySelectEvent() {
  let item = portSelector.value();
  // give it an extra property for hiding later:
  portSelector.visible = true;
  // if there's a port open, close it:
  if (serial.serialport != null) {
  // open the new port:;

function portOpen() {
  console.log("The port is open, people! Rejoice!");

function keyPressed() {
  // if port selector is visible hide, else show:
  if (portSelector) {
    if (portSelector.visible) {
      portSelector.visible = false;
    } else {;
      portSelector.visible = true;

function serialEvent() {
  console.log("got a new value");
  var input =;
  if (input) {
    vesper = input;

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:

// the loop routine runs over and over again forever:
void loop() {
  int sensor = analogRead(A0) / 4;
  if (sensor > 200) {

27 Oct 2021

The MAX30105 Sensor is the sensor I showed in the afternoon class today. Designed as a smoke detector particle sensor, it does a great job as a pulse oximetry sensor. Here is the Sparkfun breakout board for it I have on hand, and here is a Pimoroni version I have tried as well. There’s also a more expensive Sparkfun board with an additional sensor which I have not tried, and this one, with big solder pads. . It’s a useful sensor for those interested in getting heart rate, and can give you more than just the raw readings of the sensor. I use the Sparkfun MAX3010x library with it.