Monthly Archives: June 2019

Introducing the Pizza Roll Console!

via SparkFun: Commerce Blog

If you were keeping an eye on E3 last week - that’s the Electronic Entertainment Expo, one of the premiere events for the video gaming industry - then you know Miller Lite introduced the Cantroller™, a beer can, full of beer, that is also a Bluetooth gaming controller. Of course, you couldn’t buy one of these. But you could win one of the two hundred that Miller Lite was giving away, simply by beating comedian Eric Andre in a game of Street Fighter. And naturally, you would both be playing using the Cantroller. It was a great way for Miller Lite to get noticed at this year’s E3. They even released a heavy-on-visuals/light-on-copy commercial before the event, which you should definitely watch.

alt text

"It's a beer can. It's a controller. It's a Cantroller™." Image ©2019 Miller Brewing Co., Milwaukee, WI

This is the type of project I can wholeheartedly support. It’s ridiculous, kitchy and fully functional, and there was really no reason for it to exist other than because a bunch of people were sitting around in a meeting, and one said, probably in a Beavis-sounding voice, "Hey, you know what would be cool? If we made, like, a beer can, but it was also a game controller. Heh heh."

We’re no strangers to wireless controllers here at SparkFun - we’ve had the Sparkfun Wireless Joystick Kit for quite a while now. Nor are we strangers to hacking game controllers, so seeing Miller Lite’s controller immediately brought two things to the front of my mind: first, why didn’t I think of this, and second, what could I do that would be similar or complementary to this project?

alt text

From Phillip Torrone's Maker Faire 2007 Flickr

Creating a solution where there is no problem

Instead of looking for what’s needed, I decided to look for what was ridiculous. If you were lucky enough to win one of the Cantrollers, it’s a pretty good bet that you have several gaming consoles. I looked for obvious pairings – game controllers pair with gaming consoles, and cold beer pairs with tasty snacks. From this was born…

The Pizza Roll Console™!

I figured the gaming console would be fairly easy. I used a Raspberry Pi 3 B+, along with the Raspberry Pi 7” LCD Touchscreen, a Hamburger Mini Speaker, and one of our now-retired 5Ah Lithium Ion Battery Packs. I loaded up RetroPie, and Emulation Station, the video game emulator. The RaspberryPi 3 B+ seemed the perfect choice, since it has built-in Bluetooth, and would therefore be compatible with the Miller Lite Cantroller. You can learn how to set up your own RetroPie system here.

For reasons I cannot explain, my brain just kept yelling “Pizza rolls! Pizza rolls!” I found that the big box of Totino’s Pizza Rolls looked to be about the perfect size. I knew I would have to make some kind of insert for the Totino’s box so that it had a little structural stability. I also wanted to give it two sections: the bottom would house all of the electronics, while the top section would hold pizza rolls.

With access to a laser cutter here at SparkFun, I used MakerCase to create a finger-jointed box that I could cut out of quarter-inch and eighth-inch acrylic. I made a few adjustments to allow for the screen opening, a hole for the wired controller, some venting to keep the system cool and to let a little sound out, and the separator to keep the pizza rolls out of the electronics. I carefully opened the Totino’s box from the bottom, so I could open the factory sealed top in the video. I test fit the acrylic box, and it was just a little too large - my tolerances were too tight - a reduction in the outside dimensions by two percent, and it was a perfect fit.

Box for components and snacks

The acrylic box, with an opening for the Raspberry Pi screen, side opening for the wired controller, a separator, and some side venting.

It couldn’t be that easy

Having created the insert to house the electronics (and some pizza rolls), I put in the speaker, battery, Raspberry Pi and touchscreen. They all fit beautifully. Then I attempted to slide it all into the pizza roll box. That’s when I learned that the glass of the touchscreen was about 3mm too wide for the box.

Box With Components

Well look at that, the components fit, but the screen glass IS wider than the containment box!

I struggled, forced and pleaded, but it looked like there was no way it would all fit in without tearing the box edges. So I took my hobby knife and carefully opened the box on its seam. I was then able to slide the entire assembly in, then hot glue the box back together as tightly as it would fit. I also made a hole in the side of the box where the Raspberry Pi’s USB ports sit, so I could insert the wired controller once the assembly was sealed inside the box. Of course, this wouldn’t be necessary with a wireless controller.

alt text

Party in the front, party in the back. What's not to like?

Thinking of building your own? Here are some thoughts

Since this was basically just a fast and fun build, designed for a quick fake commercial, there were definitely some shortcuts taken. The biggest, of course, is that the entire system needs to be powered up, then hermetically sealed inside the pizza roll box. To power it down, you either have to tear the box open again, or just play until the battery drains completely.

Ah yes, the battery. This setup could be quite a drain on a single cell LiPo battery. Knowing I would not be using a wireless controller, and not knowing how long the shoot would take, I swapped out the Raspberry Pi 3 B+ for an older Pi 2 that I had sitting around. Since this board lacks Wifi and Bluetooth, I knew it would draw less current, and therefore last longer. With the now-retired 5Ah battery pack, it was still running strong after four and a half hours.

Ideally, a finished product would have, hidden on the bottom of the box, a way to turn the system on/off, a way to turn the speaker on/off (or just use a speaker that could be powered from the Raspberry Pi), and a USB port to charge the battery. The immediate issue that comes to mind there, however, is that single cell LiPo chargers that also allow for output have a current limit of about 1A - not enough to run a system like this. But hey, that’s future me’s problem, and something I’ll worry about if the good people at Miller Lite find it in their hearts to send me a Cantroller™ to go with my Pizza Roll Console™!

comments | comment feed

Friday Product Post: Artemis

via SparkFun: Commerce Blog

Hello everyone, and welcome back to another Friday Product Post at SparkFun Electronics! You are joining us on a very special and momentous day because today we announce Artemis! The SparkFun Artemis is an open-source, Bluetooth enabled, microcontroller modular. This is the first time we have ever developed a module on our own and we got so excited to get it into your hands that we are releasing an "Engineering Version" today while we continue to get FCC Certification for it. Yes, you read that right, we are creating the first open-source, FCC Certified microcontroller module on the market and you get to try it out first. Please be aware that this certification could happen as soon as a few weeks to a month so these Artemis versions are for those of you who can't wait and want to start using the SparkFun Artemis as soon as possible! We also put it on three Arduino format boards to help you try it out! Now, let's take a closer look!

Shoot for the moon. Even if you miss, you'll land among the stars.

SparkFun Artemis Module - Engineering Version

SparkFun Artemis Module - Engineering Version

WRL-15376
$8.95

The Artemis Module from SparkFun is a Cortex-M4F with BLE 5.0 running up to 96MHz and with as low power as 6uA per MHz (less than 5mW). This is the world's first module to bridge the market between hobbyists and consumer products. We've packaged all the power of a modern microcontroller into a module that is both extremely easy to use but is mass-market ready.

The flexibility of the Artemis module starts with our Arduino core. You can program and use the Artemis module just like you would an Uno or any other Arduino. Time to first blink is just 5 minutes away! We built the core from the ground up, making it fast and as light weight as possible.


Start experimenting with Artemis today!

BlackBoard Artemis

BlackBoard Artemis

SPX-15332
$19.95

Think of the BlackBoard Artemis as just another Arduino... That has BLE. And one meg of flash. And runs at less than 1mA. Oh, and it can run TensorFlow models. Ya, that too. The BlackBoard Artemis takes the incredibly powerful Artemis module from SparkFun and wraps it up in an easy to use and familiar Uno footprint. We've written an Arduino core from scratch to make programming the Artemis as familiar as Serial.begin(9600). Time-to-first-blink is less than five minutes.


BlackBoard Artemis Nano

BlackBoard Artemis Nano

SPX-15411
$14.95

We like to joke the Artemis Nano is a party on the front and business on the back. And that's by design! All the important LEDs, connectors, labels, and buttons are presented on the front for the best user experience with all the supporting circuitry on the rear of the board. The BlackBoard Artemis Nano is a minimal but extremely handy implementation of the Artemis module. A light weight, 0.8mm thick PCB, with on board lipo-battery charging and a Qwiic connector, this board is easy to implement into very small projects. A dual row of ground connections make it easy to add lots of buttons, LEDs, and anything that requires its own GND connection. At the same time, the board is breadboard compatible!


BlackBoard Artemis ATP

BlackBoard Artemis ATP

SPX-15412
$24.95

The BlackBoard Artemis ATP is affectionately called 'All the Pins!' at SparkFun. The Artemis module has 48 GPIO and this board breaks out absolutely every one of them in a familiar Mega like form factor. What's with the silkscreen labels? They're all over the place. We decided to label the pins as they are assigned on the Apollo3 IC itself. This makes finding the pin with the function you desire a lot easier. Have a look at the full pin map from the Apollo3 datasheet. If you really need to test out the 4-bit SPI functionality of the Artemis you're going to need to access pins 4, 22, 23, and 26. Need to try out the differential ADC port 1? Pins 14 and 15. The BlackBoard Artemis ATP will allow you to flex the impressive capabilities of the Artemis module.


Header - 2x5 Pin (Female, 1.27mm)

Header - 2x5 Pin (Female, 1.27mm)

PRT-15363
$1.50
SWD Cable - 2x5 Pin

SWD Cable - 2x5 Pin

CAB-15364
$1.95

A few weeks ago we released a male JTAG header and this week we figured it would be good to release a female JTAG header and a SWD Cable for the Artemis boards!


That's it for this week! As always, we can't wait to see what you make especially this week! So let us know what you think by shooting us a tweet @sparkfun, or letting us know on Instagram or Facebook. We’d love to see what projects you’ve made!

comments | comment feed

Enginursday: Get Wired Up!

via SparkFun: Commerce Blog

We are hard at work getting a brand new product, that we are incredibly excited about, ready for release tomorrow! Unfortunately, this means we needed to write up a shorter Enginursday post this week to get everything ready for the Friday Product Post. Be sure to check back tomorrow, June 21st, to find out more!

And now, on to your Enginursday!


When it comes to prototyping and making your project come to life, working with wire is an essential skill to have! We've updated one of our older skill tutorials with more tips and techniques. Some of the updates include how to splice, wire wrap, crimp, and manage wire.


For more information, check out the updated resource!

Working with Wire

February 8, 2013

How to strip, crimp, and work with wire.

comments | comment feed

Let’s "Electrify" a Korean Board Game

via SparkFun: Commerce Blog

This is a guest blog post by close SparkFun friend, Jackson Hootman. Jackson is currently studying Mechanical Engineering at the University of Colorado Boulder. Last summer, Jackson had the opportunity to work with SparkFun as an intern, and ever since then has had a passion for creating his own electronics projects. You may remember his post from last year about adding electronics and lighting effects to existing Lego® kits.

How to Play

Yut Nori is a popular Korean board game. It has been played for hundreds of years and consists of players moving four horses (tokens) through a series of stations.

Yut Stations

Yut stations for a rectangular configuration.

Each horse begins and ends at the blue station. The player to first return all of their horses is the winner. If a horse lands on a large station (highlighted in red) then the player has the option of taking a shortcut by moving towards the center station on their next turn.

Yut Courses

There are four possible routes to take.

These short cuts can only be taken if a player lands on the red stations above. Otherwise, the light green path is taken. The number of stations moved per turn is determined by the throwing of four yut sticks. Yut sticks are half cylinders, meaning that when thrown they will either land on a curved side or a flat side. The combination of flat and curved sticks determines the number of stations a player will be able to move. One point is earned per stick that lands on its curved side. The following image gives the corresponding value to each possible combination.

Point Values

Point values for possible yut stick combinations.

What really makes the game fun though is the ability to have multiple tokens from the same team on the board at the same time. Instead of moving a horse already on the game board, a player can choose to add a new horse to the game. Additionally, if a token lands on another token from the same team, those horses can be stacked such that they move together for the remainder of the game. This is dangerous, however, because if an opposing player lands on a station with your horses, then all of your horses at that station are returned home. Below are the tokens and yut sticks I made for my board.

Yut Tokens

The tokens are made from multiple layers of acrylic. They are made to stack together.

Yut Sticks

The sticks are made of 4in long wood half cylinders (with diameter 3⁄4”).


Let’s Add Some Electronics

The electronics of my game board consists of three major parts. First, there is one LED per player. The LEDs are used to indicate to the players whose turn it is. In this way, only one LED will be powered at a time and that respective LED will be on for the entirety of that players turn.

Yut LED

Basic Blue LED in series with 1000 Ohm resistor.

Next, buttons are used to start the game, end the game, finish turns, and change an individual's score. For my project, I used three separate push buttons. One button is used to add points to a players score, one is used to subtract points from a players score (just in case mistakes were made in adding points). The last button is held for a few seconds to start a game and once on, is used to switch between players. Once gameplay is done, pushing down on this button for a few seconds will shut the board off. Once this is done, the scores will be reset.

Yut Button

Each player’s score (the number of horses they have returned) is displayed using a seven segment display. Because I wanted this game board to handle up to four players, I’d need a way to control at least 28 individuals pins. That's where shift registers came in handy. I utilized one shift register per seven segment display. This meant that in my final circuit, I had four daisy chained shift registers.

Yut Circuit

Four daisy chained shift registers.

One of the most interesting parts of this project was programming the seven segment displays. Each display has 10 pins, which meant it was important to be uniform in my notation and coding. While writing the Arduino code for this project I chose to define the pins in the following way:

Seven Segment Diagram

Each pin (except for the two common anode pins) controls one segment.

Each pin controls the segment highlighted with the corresponding color. These are common anode displays, meaning that when power is supplied to pin-3 or pin-8, segments will only be powered when their respective pin is set to low.

If for example, you wanted to display the number one, pin-5 and pin-7 should be set to low. To program the seven segment display with a shift register, this information should be sent as a byte. There is one bit per each of the eight pins that control an LED. If only pin-5 and pin-7 are set to low, the byte we want to send to the shift register is 11101011.

Seven Segment Example

Byte to send to shift register to display the number one.

I repeated this process for all the other numbers I wanted to display. I stored the bytes for each number in an array for easy access in Arduino. Feel free to take a look at the code attached below for more information.

//Jackson Hootman
//Yut Game Board

// shift register pins
#define dataPin 2
#define latchPin 3
#define clockPin 4

// inputs
#define ButtonBlack 13
#define ButtonBlue 12
#define ButtonRed 11

// turn indicators
int LED[4];

//player 4 - initially all off
byte sevenSegD = 0xFF;
//player 3 - initially all off
byte sevenSegC = 0xFF;
//player 2 - initially all off
byte sevenSegB = 0xFF;
//player 1 - initially all off
byte sevenSegA = 0xFF;

//array to store byte inputs for 0-4
byte sevenSegArray[5];

//other variables
boolean gameOn = false;
boolean finished[4];
int player = 1;
int score[4];
int place = 1;

void setup() {

  //initial score for each player
  score[0] = 0; //player 1
  score[1] = 0; //player 2
  score[2] = 0; //player 3
  score[3] = 0; //player 4

  //no one has finished
  finished[0] = false; //player 1
  finished[1] = false; //player 2
  finished[2] = false; //player 3
  finished[3] = false; //player 4

  //LED pins
  LED[0] = 9;
  LED[1] = 8;
  LED[2] = 7;
  LED[3] = 6;

  pinMode(LED[0], OUTPUT);
  pinMode(LED[1], OUTPUT);
  pinMode(LED[2], OUTPUT);
  pinMode(LED[3], OUTPUT);

  //byte values for 0-4 on seven segment display
  sevenSegArray[0] = 0x88; // zero in hexidecimal
  sevenSegArray[1] = 0xEB; // one in hexidecimal
  sevenSegArray[2] = 0x4C; // two in hexidecimal
  sevenSegArray[3] = 0x49; // three in hexidecimal
  sevenSegArray[4] = 0x2B; // four in hexidecimal

  // shift register pins
  pinMode(dataPin, OUTPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);

  // input pins
  pinMode(ButtonBlack, INPUT_PULLUP);
  pinMode(ButtonBlue, INPUT_PULLUP);
  pinMode(ButtonRed, INPUT_PULLUP);

  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST, sevenSegD);
  shiftOut(dataPin, clockPin, LSBFIRST, sevenSegC);
  //latch pin to high - data done transmitting
  digitalWrite(latchPin, HIGH);
  delay(1000);
}

void loop() {
  if (gameOn) {
    if (digitalRead(ButtonBlack) == HIGH) {
      player = switchPlayer(player); // next players turn
      delay(2000);
      if (digitalRead(ButtonBlack) == HIGH) {
        gameOn = false; // if button is held down, turn off
        shutDown();
      }
    }
    if (digitalRead(ButtonBlue) == HIGH) {
      if (score[player - 1] == 3) {
        score[player - 1] = place; //player finished
        finishSegment(player, place, score);
        finishSegment(player, place, score);
        finishSegment(player, place, score);
        updateSevenSeg(sevenSegArray[score[0]], sevenSegArray[score[1]], sevenSegArray[score[2]],                          sevenSegArray[score[3]]);
        place++;
        finished[player - 1] = true;
        delay(1000);
      }
      if (finished[player - 1] == false) {
        score[player - 1]++; //add one
        updateSevenSeg(sevenSegArray[score[0]], sevenSegArray[score[1]], sevenSegArray[score[2]],                          sevenSegArray[score[3]]);
       delay(1000);
      }
    }
    if (digitalRead(ButtonRed) == HIGH) {
      if (score[player - 1] == 0) {
      } else {
        score[player - 1]--; //subtract one
        updateSevenSeg(sevenSegArray[score[0]], sevenSegArray[score[1]], sevenSegArray[score[2]],                          sevenSegArray[score[3]]);
        delay(1000);
      }
    }
 }
  else
 {
    if (digitalRead(ButtonBlack) == HIGH) {
      delay(1000);
      if (digitalRead(ButtonBlack) == HIGH) {
        gameOn = true; //if held, start up
        startUp();
      }
    }
  }
}

void startUp() {
  //blink 3 times

  updateSevenSeg(0, 0, 0, 0); // switch on
  updateLEDs(false, false, false, false); // LEDS off
  delay(500);

  updateSevenSeg(0xFF, 0xFF, 0xFF, 0xFF); // switch off
  updateLEDs(true, true, true, true); // LEDS on
  delay(500);

  updateSevenSeg(0, 0, 0, 0); // switch on
  updateLEDs(false, false, false, false); // LEDS off
  delay(500);

  updateSevenSeg(0xFF, 0xFF, 0xFF, 0xFF); // switch off
  updateLEDs(true, true, true, true); // LEDS on
  delay(500);

  updateSevenSeg(0, 0, 0, 0); // switch on
  updateLEDs(false, false, false, false); // LEDS off
  delay(500);

  updateSevenSeg(0xFF, 0xFF, 0xFF, 0xFF); // switch off
  updateLEDs(true, true, true, true); // LEDS on
  delay(1000);

  updateLEDs(true, false, false, false); // LEDS off

  //initiallize start order
  //player 1 light up
  updateSevenSeg(sevenSegArray[1], 0xFF, 0xFF, 0xFF);
  delay(1000);

  //player 2 light up
  updateSevenSeg(sevenSegArray[1], sevenSegArray[2], 0xFF, 0xFF);
  delay(1000);

  //player 3 light up
  updateSevenSeg(sevenSegArray[1], sevenSegArray[2], sevenSegArray[3], 0xFF);
  delay(1000);

  //player 4 light up
  updateSevenSeg(sevenSegArray[1], sevenSegArray[2], sevenSegArray[3], sevenSegArray[4]);
  delay(2000);

  //all players to zero
  updateSevenSeg(sevenSegArray[0], sevenSegArray[0], sevenSegArray[0], sevenSegArray[0]);
  delay(5000);

  // start with player 1
  player=1;

  //initial score for each player
  score[0] = 0; //player 1
  score[1] = 0; //player 2
  score[2] = 0; //player 3
  score[3] = 0; //player 4

}

void shutDown() {
  //blink 3 times

  updateSevenSeg(0xFF, 0xFF, 0xFF, 0xFF); // switch off
  updateLEDs(true, true, true, true); // LEDS on
  delay(1000);

  updateSevenSeg(0, 0, 0, 0); // switch on
  updateLEDs(false, false, false, false); // LEDS off
  delay(500);

  updateSevenSeg(0xFF, 0xFF, 0xFF, 0xFF); // switch off
  updateLEDs(true, true, true, true); // LEDS on
  delay(500);

  updateSevenSeg(0, 0, 0, 0); // switch on
  updateLEDs(false, false, false, false); // LEDS off
  delay(500);

  updateSevenSeg(0xFF, 0xFF, 0xFF, 0xFF); // switch off
  updateLEDs(true, true, true, true); // LEDS on
  delay(500);

  updateSevenSeg(0, 0, 0, 0); // switch on
  updateLEDs(false, false, false, false); // LEDS off
  delay(500);

  updateSevenSeg(0xFF, 0xFF, 0xFF, 0xFF); // switch off
  updateLEDs(true, true, true, true); // LEDS on
  delay(1000);

  updateLEDs(false, false, false, false); // LEDS off
}

int switchPlayer(int player) {
  switch (player) {
    case 1:
      player = 2;
      updateLEDs(false, true, false, false);
      break;
    case 2:
      player = 3;
      updateLEDs(false, false, true, false);
      break;
    case 3:
      player = 4;
      updateLEDs(false, false, false, true);
      break;
    case 4:
      player = 1;
      updateLEDs(true, false, false, false);
      break;
  }
  return player;
}

void finishSegment(int player, int place, int score[4]) {
  switch (player) {
    case 1:
      updateSevenSeg(0xBF, sevenSegArray[score[1]], sevenSegArray[score[2]], sevenSegArray[score[3]]);
      delay(200);
      updateSevenSeg(0xDF, sevenSegArray[score[1]], sevenSegArray[score[2]], sevenSegArray[score[3]]);
      delay(200);
      updateSevenSeg(0xEF, sevenSegArray[score[1]], sevenSegArray[score[2]], sevenSegArray[score[3]]);
      delay(200);
      updateSevenSeg(0xFB, sevenSegArray[score[1]], sevenSegArray[score[2]], sevenSegArray[score[3]]);
      delay(200);
      updateSevenSeg(0xFD, sevenSegArray[score[1]], sevenSegArray[score[2]], sevenSegArray[score[3]]);
      delay(200);
      updateSevenSeg(0xFE, sevenSegArray[score[1]], sevenSegArray[score[2]], sevenSegArray[score[3]]);
      delay(200);

      break;
    case 2:
      updateSevenSeg(sevenSegArray[score[0]], 0xBF, sevenSegArray[score[2]], sevenSegArray[score[3]]);
      delay(200);
      updateSevenSeg(sevenSegArray[score[0]], 0xDF, sevenSegArray[score[2]], sevenSegArray[score[3]]);
      delay(200);
      updateSevenSeg(sevenSegArray[score[0]], 0xEF, sevenSegArray[score[2]], sevenSegArray[score[3]]);
      delay(200);
      updateSevenSeg(sevenSegArray[score[0]], 0xFB, sevenSegArray[score[2]], sevenSegArray[score[3]]);
      delay(200);
      updateSevenSeg(sevenSegArray[score[0]], 0xFD, sevenSegArray[score[2]], sevenSegArray[score[3]]);
      delay(200);
      updateSevenSeg(sevenSegArray[score[0]], 0xFE, sevenSegArray[score[2]], sevenSegArray[score[3]]);
      delay(200);
      break;
    case 3:
      updateSevenSeg(sevenSegArray[score[0]], sevenSegArray[score[1]], 0xBF, sevenSegArray[score[3]]);
      delay(200);
      updateSevenSeg(sevenSegArray[score[0]], sevenSegArray[score[1]], 0xDF, sevenSegArray[score[3]]);
      delay(200);
      updateSevenSeg(sevenSegArray[score[0]], sevenSegArray[score[1]], 0xEF, sevenSegArray[score[3]]);
      delay(200);
      updateSevenSeg(sevenSegArray[score[0]], sevenSegArray[score[1]], 0xFB, sevenSegArray[score[3]]);
      delay(200);
      updateSevenSeg(sevenSegArray[score[0]], sevenSegArray[score[1]], 0xFD, sevenSegArray[score[3]]);
      delay(200);
      updateSevenSeg(sevenSegArray[score[0]], sevenSegArray[score[1]], 0xFE, sevenSegArray[score[3]]);
      delay(200);
      break;
    case 4:
      updateSevenSeg(sevenSegArray[score[0]], sevenSegArray[score[1]], sevenSegArray[score[2]], 0xBF);
      delay(200);
      updateSevenSeg(sevenSegArray[score[0]], sevenSegArray[score[1]], sevenSegArray[score[2]], 0xDF);
      delay(200);
      updateSevenSeg(sevenSegArray[score[0]], sevenSegArray[score[1]], sevenSegArray[score[2]], 0xEF);
      delay(200);
      updateSevenSeg(sevenSegArray[score[0]], sevenSegArray[score[1]], sevenSegArray[score[2]], 0xFB);
      delay(200);
      updateSevenSeg(sevenSegArray[score[0]], sevenSegArray[score[1]], sevenSegArray[score[2]], 0xFD);
      delay(200);
      updateSevenSeg(sevenSegArray[score[0]], sevenSegArray[score[1]], sevenSegArray[score[2]], 0xFE);
      delay(200);
      break;
      }
}


void updateSevenSeg(byte A, byte B, byte C, byte D) {
  //update seven segment displays
  digitalWrite(latchPin, LOW);
  sevenSegD = D; //display 4
  sevenSegC = C; // display 3
  sevenSegB = B; //display 2
  sevenSegA = A; // display 1
  shiftOut(dataPin, clockPin, LSBFIRST, sevenSegD);
  shiftOut(dataPin, clockPin, LSBFIRST, sevenSegC);
  shiftOut(dataPin, clockPin, LSBFIRST, sevenSegB);
  shiftOut(dataPin, clockPin, LSBFIRST, sevenSegA);
  //latch pin to high - data done transmitting
  digitalWrite(latchPin, HIGH);
}

void updateLEDs(boolean A, boolean B, boolean C, boolean D) {
  //update LEDs
  if (A) {
    digitalWrite(LED[0], HIGH);
  } else {
    digitalWrite(LED[0], LOW);
  }
  if (B) {
    digitalWrite(LED[1], HIGH);
  } else {
    digitalWrite(LED[1], LOW);
  }
  if (C) {
    digitalWrite(LED[2], HIGH);
  } else {
    digitalWrite(LED[2], LOW);
  }
  if (D) {
    digitalWrite(LED[3], HIGH);
  } else {
    digitalWrite(LED[3], LOW);
  }
}

Final Product

The housing for the circuit was made with acrylic sheets. This way exact holes could be made using a laser cutter to fit the seven segment displays, LEDs, and buttons.

Final Game Board in the Dark

Game board in the dark.

I chose to not paint the acrylic so all the electronics were visible. The displays were especially fun in the dark.

Final Game Board in the Light

Tokens on the game board.

The great part about this project is that I had the freedom to create the user experience I wanted. If anyone wants to give this project a go, I recommend you switch things up and make it your own. Perhaps you want to use an LCD instead of seven segment displays. Go for it!

Yut Circuit in its Housing

Circuit in housing.

Regardless, I hope you give this game a try. I’d love to hear what you think and I hope you have as much fun as I did when I first played!

comments | comment feed

NVIDIA Goes Live with Complimentary Course: "Getting Started on AI with the Jetson Nano"

via SparkFun: Commerce Blog

With the release of the Jetson Nano™ Developer Kit, NVIDIA® empowers developers, researchers, students, and hobbyists to explore AI. Reinforcing its commitment to widening the accessibility to and innovation in the area of deep learning, NVIDIA has created a free, self-paced, online Deep Learning Institute (DLI) course, “Getting Started on AI with Jetson Nano.” The goal of the course is to build foundational skills to enable people to get creative with the developer kit (essentially - get the kit; take the course; build something with AI).

About the Course - “Getting Started on AI with Jetson Nano”

In this eight-hour course, participants use Python notebooks with the Jetson Nano to build a deep learning classification project with computer vision models. Participants will learn how to:

  • Set up the Jetson Nano and camera
  • Collect image data for classification models
  • Annotate image data for regression models
  • Train a neural network - use data to create models
  • Run inference on the Jetson Nano with the models created

    Upon completion, participants will be able to create their own deep learning classification and regression models with Jetson Nano. Certificates are available. Course is free to purchasers of the developer kit.

    To enroll, please visit the registration page.

    To purchase the materials you need for the course, use this wish list at SparkFun.com.


    Have You Built Anything with Jetson Nano Yet?

    We are interested in knowing more about how you are using your developer kit - what are you building? Is it personal or professional? Tell us about it in the comments below - pics would be great!

    alt text


    About the Jetson Nano Developer Kit

    The latest addition to the Jetson family, the NVIDIA Jetson Nano Developer Kit is a small, powerful computer that lets you run multiple neural networks in parallel for applications like image classification, object detection, segmentation, and speech processing. All of this is in an easy-to-use platform that runs in as little as 5 watts. The developer kit can be powered by micro-USB and comes with extensive I/Os, ranging from GPIO to CSI. This makes it simple for developers, hobbyists, students, and researchers to connect a diverse set of new sensors to enable a variety of AI applications.

    NVIDIA Jetson Nano Developer Kit

    NVIDIA Jetson Nano Developer Kit

    DEV-15297
    $99.00
    10


    Don’t Forget About the SparkFun JetBot AI Kit, Powered by the NVIDIA Jetson Nano!

    This robotics platform provides the foundation to build an AI robot powered by the Jetson Nano Developer Kit. This SparkFun kit is based on the open-source NVIDIA JetBot, only it removes the need for 3D printing and hunting for parts, is easy to assemble and is designed to get users up and running as quickly as possible. This kit is currently available to preorder.

    SparkFun JetBot AI Kit Powered by NVIDIA Jetson Nano

    SparkFun JetBot AI Kit Powered by NVIDIA Jetson Nano

    KIT-15365
    $274.95


    Don't forget to share your Developer Kit projects below!

    comments | comment feed

  • New products: more special servos with position feedback

    via Pololu Blog

    We have expanded our selection of specially modified FEETECH servos that have direct access to the feedback potentiometer through an extra fourth (green) wire! Several months ago, we started carrying similarly modified micro FS90-FB and standard-sized FS5103B-FB servos. Now, our larger selection includes a variety of sizes from compact sub-micro servos all the way up to ultra-high torque giant servos:

    FEETECH Sub-Micro Servo FS0403-FB with Position Feedback.

    FEETECH Mini Servo FT1117M-FB with Position Feedback.

    FEETECH High-Torque Servo FS5115M-FB with Position Feedback.

    FEETECH Ultra-High-Torque, High-Voltage Digital Giant Servo FT5335M-FB with Position Feedback.

    These new additions are special versions of the normal sub-micro FS0403, mini FT1117M, high-torque standard-size FS5115M, and ultra-high-torque giant FT5335M FEETECH servos.

    The feedback voltage, which varies linearly over the servo’s range of motion by a couple of volts, is especially useful for more complex robotic applications that require monitoring the actual servo position. For example, it can be used for determining if the servo is stalled or when it has reached it’s target position. It also allows you to implement your own higher-level closed-loop position control or create servo movements by hand that you can record and play back later.