Week 6: Programming Circuit Boards

2018-10-24

The Task

Program circuit board.

My Idea

I wanted my circuit board to do something cool that isn’t just LEDs turning on and off by button switch. I decided on making a coin flipper. Because I spent so long making the circuit board during the electronics design week, I decided to use that board. The fact that it has 1 LED sort of makes it better as an innocuous coin flipper because there is less of an obvious visual cue as to what the result is. I wanted the functionality of blinking twice for success and once for failure. Further, I wanted to add arbitrary number of sides of coin - when the button is pressed n times, the probability of success is 1/n.

Coding

I wanted to start with something basic just to make sure that things were wired up correctly. I decided to implement the “blink” code that can be found here. At first, I also used the Makefile that is associated with this file - however, that was a big mistake because that Makefile is associated with the ATmega328P and not the Attiny44, which we use. The result was running into a bunch of weird undefined macros that confused me a lot. The solution was to just steal the Makefile found here, which we used two weeks ago in the Hello World board. All that I needed to do was change ports to the ones that I used in my board - otherwise, the file was exactly the same, and the commands run are also exactly the same.

What followed next was a long attempt to implement my coin flipper in C. This involved a heavy reading of the ATTIny44 data sheet as well as looking at tons of examples from previous years such as Julia Ebert. At the end of many hours of struggle, it became apparent to me that it is really hard to read data sheets and figure out which bitshifts on which registers perform what operations. Further, I needed to have real time because I need to time button presses to know when someone stops pressing, but including time.h would involve changing the make file. All of these factors made me try out using Arduino. At first, button presses did not work - I realized that I had soldered my button on in the wrong orientation, so I resoldered and was then good to go. The rest was just figuring out which Arduino functions I would need. Arduino has some very convenient functions such as random for pseudorandom number generation and also debugging my program for some finicky things unrelated to the controller and just to programming. My final code was the following:

/*
  Coin Flipper
  Jeffrey Wang, 10/23/2018
 */

const int led_pin = 7;
const int button_pin = 8;

// the setup routine runs once when you press reset:
void setup() {
  pinMode(led_pin, OUTPUT);
  pinMode(button_pin, INPUT_PULLUP);
}

int num_presses = 0;
unsigned long last_press_time = 0;
bool was_pressed = false;

// the loop routine runs over and over again forever:
void loop() {
  // button is not pressed
  if (digitalRead(button_pin) > 0) {
    // if pressed and now unpressed, increment num_presses
    if (last_press_time != 0 && millis() - last_press_time < 0.5 * 1000 && was_pressed){
      num_presses++;
      was_pressed = false;
    }
    // if stopped pressing button, flash LED with probability 1/num_presses
    if (millis() - last_press_time > 1 * 1000 && num_presses >= 1){
      if (random(num_presses) == 0){
        digitalWrite(led_pin, HIGH);
        delay(100);
        digitalWrite(led_pin, LOW);
        delay(100);
        digitalWrite(led_pin, HIGH);
        delay(100);
        digitalWrite(led_pin, LOW);
      } else {
        digitalWrite(led_pin, HIGH);
        delay(100);
        digitalWrite(led_pin, LOW); 
      }
      num_presses = 0;
      last_press_time = 0;
      was_pressed = false;
    }
  } else {
    if (!was_pressed){
      last_press_time = millis();
    }
    was_pressed = true;
  }
}

The arduino settings were the following:

  • Board: ATTiny24/44/84
  • Processor: ATTiny44
  • Clock: Internal 8 MHz
  • Programmer: USBTiny ISP

For instructions on how to get ATTiny boards, go here.

Final Result