Embedded Programming

Back to EAGLE

I never got my board from two weeks ago working, so I redesigned it in EAGLE to be more spacious so that it would mill more reliably. It also gave me a chance to keep the black plastic casing around the serial pins inside the board's border for better stability.


Programming

Programming the board was surprisingly straightforward. I first thought I'd use Atmel Studio, so I downloaded and installed it before thinking "why?" and then just used the Arduino IDE following this guide instead. Remember to set the right board, processor, and clock under Tools, or you will regret it later. You probably want "ATtiny24/44/84", "ATtiny44", and "External 20 MHz", respectively.

My board only has one button and one LED, so I didn't have much I/O bandwidth to play with. I first wrote a simple program that would turn the LED on when the button was pressed and off when it was released:

int out = 7;
int in = 8;

void setup() {
  pinMode(out, OUTPUT);
  pinMode(in, INPUT_PULLUP);
}

void loop() {
  digitalWrite(out, digitalRead(in) ? HIGH : LOW);
  delay(100);
}

It turns out that this actually did the opposite of what I wanted:

... this was because digitalRead(in) returns 0 when the button is pressed (i.e. grounded) and floats high (i.e. 1) otherwise.

After that, I made it keep an incrementing counter of how many blinks to blink:

int out = 7;
int in = 8;
int c = 0;

void setup() {
  pinMode(out, OUTPUT);
  pinMode(in, INPUT_PULLUP);
}

void blink(int n) {
  for (;n;n--) {
    digitalWrite(out, HIGH);
    delay(500);
    digitalWrite(out, LOW);
    delay(500);
  }
}

void loop() {
  if (digitalRead(in)) {
    delay(100);
  } else {
    blink(c++);
  }
}

... and after that, I made it count button-presses and play that number back: Warning! This code was written at 3am. This is not Good Code. There is no Good Code. T̗h̙i͙s̘ ̪c͚o̠d̮e̲ ͙iͅs̗ ͚ķn̥o̲w̲n̺ ̺t̲o̪ ̞t̘h͚e͙ ̘S̭t̠a̰t̠e̫ ̪o̩f͔ ͖C̤a̢ḽi̬f͓o͚r̝n͇i̲a̳ ̰t̪oͅ ̝c̪a͍u̮s͚e̘ ͔b͓ḭr̞t͇h͓ ̪d͔e̤f̬e̮c̼t̮s͜.̜ I di͉̎d͍̒ ̭͘n͚̓ỏ̰ṫ̹ ̲̽i͍̽n͑͜v͇̓e̞̋ṋ͝t͈̐ ̱̽t͔͂ȟ̪i̮̔s̠̓ ͇͘ċ͔ö͍́d͚̿é̩.̜͠ T̰̚h̢̽i͂͜s̲̓ ̖̎c̫̿o̦̿d̙̐e̥̒ ̛̘c̠͂ò͉n̢̈s̡̅i͎̍s̞̕t͕̋ë̫́ñ͚ẗ̰́l̨̉y̺͐ ̭̊f̲͗i̮͑ň̩d̯̀s̰̃ ̖̓J̘̐e̬͝s̢̔ū̹s̗̿.̡͂ ͖̄T̯̀h̛͍i̠̓s͙͋ ̨͂c̬̕ô̻d̩̽e̫͆ ͓̅k̭̀ḭ͊ḷ̒ľ̜e̩̍d̼͛ ̱̐J̠̋e̫͝e̥͐v̙̏e̮͌ş͌.̜̓ ̶̞̀T̸̟̀h̶̳͋i̴̘̍s̵̠̐ ̴̨̄c̵̛̪o̶͉̾d̸̢͒é̸͖ ̷͍̈́i̵͚̎s̶͈̐ ̴̙͐b̴͉̄a̴͍̚n̴̜͋n̸̘̊ê̵̖ḓ̴̛ ̸̨̆i̷̙͑n̴͉̎ ̶̖̈́C̴̄͜h̸̩̒i̷̤͌n̵̰̐a̵̮̕.̴̡͑ ̶̙̈́Ţ̵͘h̴̼̉i̴͇͂s̵̜͆ ̵͙̈́c̴̙̅o̷͇̽d̴̘̄ȇ̶̘ ̵̡̆ǐ̵̞s̵̖̃ ̶̖͒f̵̖͑ŕ̴̢ọ̶̈́m̷͕̔ ̷̱̃J̴̗͂e̵͍͛ṙ̷̪s̴̙̏ȇ̸̲y̵̢̿.̷̱̇ ̵̝̐̒ͅT̷̖̳̈́̅h̶͍̲͊́ì̵͙̬̃s̵̲͚͑͗ ̷̠̽́ͅc̵̳̹͂͒ó̶̗͇͘ḑ̸̳͆́ḙ̷̃̊ͅ ̸͖̮̊̕ć̵̱͇͛o̶̦̻͒̈ń̶̩̻͝s̷̨̤͂͠t̸͔͖̉̉ȧ̷̧̻̈́n̷̫͔̓̄ẗ̸̝̩̀l̴̟̪̈̂ỳ̸̘͉͂ ̵͔̜͊̍f̷̛͓̖͝i̶͚͈͆̉n̷̤̩̄̚d̷͖̹̎͂s̴͕̣̑̽ ̶̝͎̐̓J̷̗̲͋́ë̸̹̲́̋s̷̻͚̀͘ȗ̴͔̭̀s̷̗̃̑͜.̷̬̳̿͘ T̴̢̛̬͕̮͐͗͠ḥ̶̙͈̹̑̏̀̕ỉ̵͚̻̰̦̂͒͘s̴̤̼͈̃̀͂̚ͅ ̵͎̳͇͌́̈̍͜i̵̢͈̮͍͐͗̄͝s̸̨̯͔͒͑̏͠ͅ ̸̼̱̫͙͗͐͐͘ṅ̸̩͉̣̖̈̒͂ȍ̷̲͓͎̣̅̀̄ṫ̵̲͓̺͙̑̏͝ ̴̡̧̗̞̔͛͊̕t̸̡̛͖̼̼͒̀͂h̵̙͇̯͉͂̓̐͠ë̷̦͍̞̙́̑̆͠ ̵͍͉̘͓̉͋̈́̏ć̶̻͕̲͗̂̏ͅȏ̵̠̠̻̖̑̒̕d̵̛̟̞̼̖͌̿͐e̶̢͓͉̻͗̑̀̚.̸̨̢̣̘͌̉̐́ ̵̭̱͙̥̐͑̍̆Ţ̶̛̘̲͎͌̇͆h̷̡̟͍̗͛͗͝͝i̸̭͍̦̽̂͐͝ͅş̸̡̗̑͑̈́̍ͅ ̵͖̠͎̮̀͒́̒i̶̻͓̜͖͊̓͐̕š̸͖̲̟͙̈́̅͝ ̴̢̢͕̼̊́̄̚c̴̦͔̠̺̽̈̏͗ļ̶̙͚̦͋̿͑͂ơ̸̟͔̲̞̈́̂̄ş̷͉͍̏̈́̿̔ͅě̵͈̼̥͔̒̽̏.̷̝͔͉̯͂͋͗͑.

int out = 7;
int in = 8;
int c = 0;

int little = 100;
int big = 300;

int maxTrip = 10;

void setup() {
  pinMode(out, OUTPUT);
  pinMode(in, INPUT_PULLUP);
}

void output(int n) {
  for (;n;n--) {
    digitalWrite(out, HIGH);
    delay(big);
    digitalWrite(out, LOW);
    delay(big);
  }
}

int input() {
  bool go = true;
  bool reset = false;
  int value = 0;
  int trip = 0;
  while (trip < maxTrip) {
    if (digitalRead(in)) {
      if (reset) {
        reset = false;
      }
      trip += 1;
    } else {
      trip = 0;
      if (!reset) {
        reset = true;
        value += 1;
      }
    }
    delay(little);
  }
  return value;
}

void loop() {
  output(input());
}

And you thought you'd go the rest of your life without seeing another <marquee> tag!