Friday, May 6, 2016

So last week, I got the easy part out of the way: the serial-to-parallel shift out to an array of LEDs. This week, I'm going to be going through how I set-up a 16 bit parallel-to-serial shift in from an array of "buttons" to the Arduino in order to turn those LEDs on at will.

That Shift Register is Talking Some Mad Binary

This is a little less straight-forward than last week's endeavor. I had to take everything into account that was done then and add some practical way to control it.

What helped this time around was looking at the old code I wrote to do this back in 2011. The original code didn't work thanks to Arduino changing things in the compiler and the IDE, but a few hours of beating on it (and my desk) got it to work.

Materials Used:
  • Everything from last week's post
  • More hook-up wire
  • 2 - HCF4021B Shift Registers (Have a datasheet!)
  • 16 - 10kΩ resistors
Why 16 resistors when there will only be 10 buttons in the final product? The 4021 chip I chose freaks out whenever one of the data in pins doesn't have a path to ground. I played around with this in it's 8 bit form and without a single path to ground, it was sending me 11111111 or 255 and nothing else. 

If you're doing this and are getting weird results like the circuit is sending 127 or 255 constantly or whenever a button is pressed, check to see if your resistors are seated securely in the breadboard. The 4021 is a tricky, fickle demon.

Step 1: Put Some Wire on Board

This will at least power the chips

Step 2: The Control Wires


The Clock (yellow) is shared with the 595 circuit. Tie the Clock pins together.  There is no point in having a second clock.
Data (blue) goes to D5. Additionally, a wire needs to go from DS on the top IC to Q7 on the bottom.
The Latch (orange) goes to D4. Tie the Latch pins together. Why the separate Latch? I don't know.

Step 3: The "Button" Debounce Circus

If you have access to 10kΩ DIP resistors, not only will you be better off, but I hate you out of jealousy.

My end-result ended-up being 16 10kΩ resistors straight from the pin line on the breadboard from the chip directly to ground. Since I don't have this many buttons to play with, I just probed the board at certain points with a wire hooked directly to the 5v rail. It does the same thing as a button and is as expensive as a foot of hookup wire.
I used purple in the sketch for lines from pins. RIP Prince

Step 4: The Code

Here's what works:


int latchPin = 4;
int dataPin = 5;
int clockPin = 7;
int led_latchPin = 11;
int led_dataPin = 10;
byte switchVar1 = 72;
byte switchVar2 = 159;

void setup() {
  //start serial
  Serial.begin(9600);

  //define pin modes
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, INPUT);
  pinMode(led_latchPin, OUTPUT);
  pinMode(led_dataPin, OUTPUT);
  unsigned int bitsToSend = 0;
  digitalWrite(led_latchPin, 0);
  bitWrite(bitsToSend, 8, HIGH);
  byte registerOne = highByte(bitsToSend);
  byte registerTwo = lowByte(bitsToSend);
  shiftOut(led_dataPin, clockPin, MSBFIRST, registerTwo);
  shiftOut(led_dataPin, clockPin, MSBFIRST, registerOne);
  digitalWrite(led_latchPin, 1);
}
void loop() {
  int LED;
  digitalWrite(latchPin, 1);
  delayMicroseconds(40);
  digitalWrite(latchPin, 0);
  switchVar1 = shiftIn(dataPin, clockPin);
  switchVar2 = shiftIn(dataPin, clockPin);
  unsigned int allIn = switchVar1 * 256 + switchVar2; //The total value of what is being sent to the Arduino
  if (allIn != 0) {
    switch (allIn) {
      case 1:
        LED = 1;
        break;
      case 2:
        LED = 0;
        break;
      case 4:
        LED = 15;
        break;
      case 8:
        LED = 14;
        break;
      case 16:
        LED = 13;
        break;
      case 32:
        LED = 12;
        break;
      case 64:
        LED = 11;
        break;
      case 128:
        LED = 10;
        break;
      case 256:
        LED = 9;
        break;
      case 512:
        LED = 8;
        break;
      default:
        LED = 8; //Don't know what to do? Go home.
        break;
    }
    Serial.println(switchVar1);
    Serial.println(switchVar2);
    Serial.println(allIn);
    Serial.println("--------------");
    unsigned int bitsToSend = 0;
    digitalWrite(led_latchPin, 0);
    bitWrite(bitsToSend, LED, HIGH);
    byte registerOne = highByte(bitsToSend);
    byte registerTwo = lowByte(bitsToSend);
    shiftOut(led_dataPin, clockPin, MSBFIRST, registerTwo);
    shiftOut(led_dataPin, clockPin, MSBFIRST, registerOne);
    digitalWrite(led_latchPin, 1);
    //changeProgram(LED);
    delay(200);
  }

}


byte shiftIn(int myDataPin, int myClockPin) {
  int i;
  unsigned temp = 0;
  int pinState;
  byte myDataIn = 0;

  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, INPUT);
  for (i = 7; i >= 0; i--)
  {
    digitalWrite(myClockPin, 0);
    delayMicroseconds(2);
    temp = digitalRead(myDataPin);
    if (temp) {
      pinState = 1;
      myDataIn = myDataIn | (1 << i);
    }
    else {
      pinState = 0;
    }
    digitalWrite(myClockPin, 1);
  }
  return myDataIn;
}

 There are very few things in common with last week's code. For those following along at home: my apologies.

Step 5: The Madness Sets In

From there, I probed around - putting the hot wire between the resistors and the 4021 chips. The lights turned on and off. It was a success.

For further troubleshooting, the Arduino will print out the high bit, the low bit and the combined 16 bit value of what is sent back to the console. Additionally, here's the Fritzing sketch I put together for this post.

If you're seeing a behavior like the following, you too have success. If not, troubleshooting will lead to eventual insanity.



Sunday, May 1, 2016

It's been a long time (5-6 years) since I started this project. Things change. With the struggle of work, life, and family, hobbies and interests sometimes have to take a back seat to things with higher priority.
Pretty much unchanged in 5-6 years

Not too long ago, I looked up on my shelf of stuff (you know you have one) and saw a breadboard with some ICs and an Arduino Uno on it. I don't know if it was a sudden outbreak of nostalgia, or if it was the self-loathing of realizing that I never finished such an ambitious project; but I felt a sudden need to complete what I started.

Over the next few weeks, I will be breaking-down the hardware and code of the individual parts of this build. Going from a Mega 2560 board with about a million I/O pins and handing everything in code to as few I/O pins as possible and handling things in hardware is no small task.

Getting Some LEDs to Turn On

Part of the FCB1010 is the LEDs on the board that indicate what pedal was pressed. I previously handled this in code.

I couldn't find any useful or practical tutorials on how to get a 16 bit shift register setup working. That being said, this is not going to even touch on running a basic 8 bit shift register. The following is cobbled together from various sources around the internets and hours of troubleshooting. I apologize ahead of time as my Fritzing skills have much to be desired.

Materials Used:

Step 1: Wire the Power

I hear electronics like electrons.

I used D2 for the constant 5v

Step 2: Wire the Control Lines

I used blue for Data (D10), Yellow for Clock (D7), and Green for Latch (D11).

The two 74HC595 chips share the same latch and clock lines. The data out from the top chip goes to the data in on the bottom. An extra 5v needs to be supplied to the MR pin of the top chip to enable cascading to the bottom chip.

Step 3: Wire the Data Out Circuits

Purple is a nice color. RIP Prince.

Step 4: Add Some LEDs

Since only one will be on at any one time, I figured one resistor would do.

Step 5: There Is No Step 5

Sit back and admire your work. Here's the Fritzing sketch I used if you need any help. 

Step 6: Test Code

Since there won't really be any practical use of hardware to control which light is on or off, the code doesn't really have to be practical either.

All this code does is throw a rotating sequence of high and low bytes of a 16 bit unsigned integer at the shift registers.

#include <stdio.h>
//Pin connected to ST_CP of 74HC595
int latchPin = 11;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 10;

unsigned  data[] = {
0B0000000000000001,
0B0000000000000010,
0B0000000000000100,
0B0000000000001000,
0B0000000000010000,
0B0000000000100000,
0B0000000001000000,
0B0000000010000000,
0B0000000100000000,
0B0000001000000000,
0B0000010000000000,
0B0000100000000000,
0B0001000000000000,
0B0010000000000000,
0B0100000000000000,
0B1000000000000000
};

void setup() {
  //set pins to output because they are addressed in the main loop
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  for (int j = 0; j < 16; j++) {
    digitalWrite(latchPin, 0);
    int data = data[j];
    byte first = lowByte(data);
    byte second = highByte(data);
    shiftOut(dataPin, clockPin, MSBFIRST, first);
    shiftOut(dataPin, clockPin, MSBFIRST, second);
    digitalWrite(latchPin, 1);
    delay(1000);
  }
}

If you end-up with something that looks like the following, you're done! Yay!



Tuesday, January 12, 2016

I catch some flack sometimes. Mostly when I forget to do what I say I would. Today I'm making good on a 9 month old promise to you, the reader. This is how to have {as much hard drive space as your computer's body has room for} space for RetroPie and the Raspberry Pi for you, the Windows user.
I had my hot wife help me with this one. She knows more about Doze stuff than I do. I've been out of the Windows game at home at at work for years now. Special thanks to her for the screenshots.

Step 1: Create a Directory

Put it on the drive where you will store the juicy payload for the Pi.
For illustration purposes, a Documents folder will do. Probably not for you though


Step 2: Copy roms/BIOS or other folders (RetroPie only)

In your Explorer sidebar, click network and root around a bit until you find your Raspberry Pi. Find the roms and other directories that are shared by the Pi and copy the contents to the directory created in Step 1.
Dem Games
It's important to note that if you want to do this with more than one directory that is already on the Pi, you will have to repeat steps 1 and 2 as many times as you have folders you want to share from your bad ass rig.


Step 3: Delete the contents of the folders on the Pi

This might be painful if you have quite the collection of games and sundries. Relax. You just backed them up in Step 2. Should anything go sideways, you can always restore!

Go back to that network share you copied all the stuff from in Step 2 and delete EVERYTHING. This is important as future steps will not work without the directory being absolutely devoid of anything resembling a file.
Oh Damn! She got Zork!

Step 4: Share your badass file source

Let's take a minute and disclaim that this is what is considered by the paranoid who don't want their links to pornhub or /r/gonewild exposed on the interwebs to be insane or insecure. I beg to differ as far as the paranoia goes in terms of network security. This tutorial is just for a simple share.
Right click the folder you created in Step 1 -> Sharing
For least possible sadness and greatest possible happiness, select the "Everyone" user to share with.
Everyone is getting into my private stash now


It's important to give the "Everyone" user Read/Write access if you want things to be saved like game state, configs, or other important things.

Step 5: Save share and take note of the directory

That greyed-out mess is important
In this example, everything after \\LADY-PC\ is relevant. Be sure to copy it to something or leave the confirmation window open for reference.


Step 6: Acquire Software on the Pi

Uhhhh wait.. who is writing this? The Pi already has everything ready to go for this with Windows. Take a break. Have a beer and a smoke if you're inclined and enjoy what you've accomplished so far.

Step 7: Configure the Pi to map the share

This step is the same as the most previous post with some variation. SSH into the Pi and open /etc/fstab in an editor of your choice (nano, vi, vim, emacs, your choice). Open with sudo for least possible rage.

Add a new line with something like


//HostIPAddress/Path/To/Your/Share /place/to/share/on/pi cifs guest,uid=1000,gid=1000,iocharset=utf8 0 0
Parts in red are pretty much mandatory for this sort of open setup. Parts in black are up to you and what you want to do with it. Replace spaces with \040 since you use Windows and can't help but put spaces in directory paths. This is your punishment.

Save and quit your editor.

Step 8: mount -a

Put "sudo mount -a" in the console and hit enter. If it doesn't bitch at you, congrats, you win. Type in "sudo init 6" for a restart and you should be off to the races!


Sunday, March 22, 2015

The Situation 

 So I recently got my hands on a Raspberry Pi 2 Model B. And like any red-blooded American with a game controller, I felt compelled to install Emulation Station and RetroPie on it for some classic gaming awesomeness.

Since I only had an 8GB microSD card to donate to the effort, I soon ran into issues with space. My wife and I enjoy playing classic PS One games which range in size between 200MB to around 700MB. Multi-disc sets like Final Fantasy quickly make the storage requirements ridiculous.

The Solution 

 The Raspberry Pi is just like any Debain based computer. That being said, NFS will work rather well. I have about 3TB of space to spare, so why not?!

 Step 1: Create Folder on the computer

 Because I'm lazy, I copied the “roms” directory tree to the future home of the roms file server.

 Step 2: Empty the heavy use folders from the Pi


 You can do this through the Samba share or through ssh. Your choice. I'm lazy, so I went the Doze share route.



 Step 3: Acquire software on the computer 

 All I had to install was nfs-kernel-server from the apt repository
  sudo apt-get install nfs-kernel-server

 Step 4: Edit /etc/exports 

 You have to do this as super user. Once again, since I'm lazy and don't want to mess around with vi...
sudo nano /etc/exports

 Your /etc/exports file should look something like this.

 Depending on how you want to do this, you could either have one line going directly to the roms directory or have individual lines to turn individual systems on and off in Emulation Station. I opted for the latter route.

The only line in the above screenshot that I added for example purposes was
/media/justin/Monster_Drive/roms/psx *(rw,sync,no_root_squash,no_subtree_check)

Add more lines changing the directory only as needed. Some might cringe with the rw rights given, but that's necessary for game save data. When you're done, save your /etc/exports file and give the nfs service a restart.
sudo service nfs-kernel-server restart

Step 5: Acquire software on the Raspberry Pi 

Whether you have a keyboard hooked-up or you ssh into it because you can't be bothered to get out of your chair (like my lazy ass), these instructions should work just the same. Everything you will be doing on the Pi side of things will be super user. In order to drop into super user mode...
sudo su

 Celebrate that you are root! Good job!

 Install nfs-common
apt-get install nfs-common

 Edit fstab
nano /etc/fstab

Note: This is why I had the clearing-out of the roms directories early on. If the directories aren't empty, you can't mount a network resource to the folder and this won't work!

Your fstab file should look something like this


The only thing I've added so far for demonstration purposes is the line:
192.168.0.4:/media/justin/Monster_Drive/roms/psx /home/pi/RetroPie/roms/psx nfs auto 0 0

 Substitute the IP address with whatever IP your nfs server is and the directory following the colon to be your roms directory. The second set of directory structures should be the same. The only thing you might need to edit is the “psx” at the end. If you're doing this for Nintendo 64 roms, substitute “n64” in there.

Save your fstab file and restart your Pi.

 Step 6: Test it out 

 VICTORY!

Notes

  • Static IPs are a good idea to avoid having to re-configure the fstab file every time your computer gets a new IP address.
  • Gigabit network is a must. When you're loading large files like this over the network, loading will lag even with the fastest of LANs. Be patient.
  • With the roms located elsewhere, you can potentially run EmulationStation/Retropie with the bare minimum of SD card.
Coming soon: How to do this on Windows.

Tuesday, April 1, 2014

Sometimes, as programmers, we get set in our ways. We tend to get lazy, and as a result, our code gets cluttered and unmanageable. Here’s a great example of a good developer that had to clean up their code. http://playrust.com/friday-devblog/

What I propose is to get back to CS 101 basics with a small twist. Over the next few weeks, I will be posting a series of programming challenges. Here are the rules:
  1. Use any programming language that you want.
  2. Perform the task as instructed in AS FEW lines of code as possible.
  3. Brackets, comments, whitespace and display code don’t count toward line count.
  4. Minification will hurt you.
  5. Post your code in the comments.

The Fibonacci Sequence

Anyone who has been in a programming class knows of this algorithm. Each number in the sequence is the sum of the previous two numbers. E.g. 1,1,2,3,5,8,13,21…

What you have to do for this first challenge is generate an array that contains the first 20 iterations of the Fibonacci Sequence.

Here is my submission in PHP: 4 lines according to the rules.

<?php
$seq = array();
$last = 0;
for ($i = 0; $i <= 19; $i++) {
    $i == 0 || $i == 1 ? $last = $seq[] = 1 : $last = $seq[] = $seq[$i - 1] + $seq[$i - 2];
}
print_r($seq);

Good Luck!
Subscribe to RSS Feed Follow me on Twitter!