Monday, August 26, 2013

Software Bug

I thought I ruined some of my IC shift registers due to my inexperience with hardware.  Turns out it was a bug I introduced in the duino sketch when i was cleaning up the comments and debugging output.  I cleaned up a little bit that pushes the shift register's serial shift-parallel load from low to high.  This was the "serial shift" part of the deal and a good reason for the shift register to stop shifting.

I suppose I should have more confidence in my hardware abilities... and less in my coding :)

Of course I spent way too much time troubleshooting and building and rebuilidng circuits than I should have before I looked at the code, but I gained some experience in the process... and tested my duino assembly a little more completely... although I still haven't messed with the analog ports.

I see how cluttered these relatively simple circuits can get on a breadboard, so I'm going to start looking for some options... maybe more breadboards.  I also have a nice tangled mess of resistors in my little plastic craft box.  Somewheres I saw someone mentioned getting a 3 ring binder with plastic inserts for collecting baseball cards.  I'm going to look into that and see if someone has a sticker template to print out resistor values along with the color codes, since I'm slow at learning my colors.

With my troubleshooting disaster behind me, I am ready to move on... maybe daisy chaining the shift registers and then reading an 8x8 "button" matrix with one of each shift register.  Then I'll open up the dartboard and see what's inside.

*EDIT*
Decided to add my troubleshooting sketch to my git, ShiftInBasic.  This is what I was messing with to find the problem with my circuit when I ended up finding the problem with my code.

And here's a pic of the circuit... you can see I got me an 8 bit dip switch which made things a little easier to test. And look at those professional solders on the Boarduino's breakout pins :)  I'm really glad I finally put the little bastard together, I am thoroughly enjoying his company.



Starting at the bottom right corner, the 7 yellow wires extend the 10K pull down resistors to the far-right ground rail.  Above them is the dip switch with 8 blue wires touching the middle 5v rail.  There are 7 yellow wires running from the dip switch to the 7 parallel input ports on the right of the shift register (which is "upside down" at the bottom of the small breadboard.  By upside down, I mean pin one is on the lower right instead of on the upper left).  The green wire coming from the dip switch runs to the first parallel input pin on the left of the shift register.  It's hard to see the other pull down resistor, but it is plugged in beside the green wire running up the left to the leftmost ground rail.  Finally, 2 yellow and 2 orange wires run up the left of the shift register to the duino's data ports on the upper left of the small breadboard.  From bottom to top, these are the Serial Shift-Parallel Load (yellow, to digital 8), the latch clock (yellow, to digital 9), the shift clock (orange, to digital 10) and the Serial Data Output (orange, to digital 11). The rest of the wires extend the 5v and ground rails and attach these to the duino and shift register.  

I'm messy.

Maybe I'll look into getting some software to make nice circuit diagrams.  I wasn't going to do all that here since all the examples that I link to tend to have really nice diagrams and better writing... but maybe I'll start putting some on here in case those links get broken in the future.  Maybe I will, I should write down a reminder. Someday, I suppose. 

Sunday, August 25, 2013

Still Shifting LEDs

I think I ruined something, maybe my 74HC589.  I left  it running and had 2 LEDs turned on and at some point the LEDs went out.  I tested the circuit with the shiftOutBlinkPlus sketches which showed that the HC595 and 4 LEDs were all working.  Maybe I shorted the circuit some how, I dunno.

So I dismantled the circuit and bought some more LEDs and resistors, and redid the basic ShiftOutBlinkPlus circuit, but with 8 LEDs, called it ShiftOutBlinkPlus8.

This is pretty much the same as the code for the 4 bit version, except I changed the way I created the last few patterns.

Instead of this:

// shifts every other LED on and off
void eitherOr() {
  // getting lazy about generating patterns algorithmically
  // so just setting the nybbles by hand
  bitWrite(pattern, 0, pos);
  bitWrite(pattern, 1, neg);
  bitWrite(pattern, 2, pos);
  bitWrite(pattern, 3, neg);
  displayPattern();
  delay(delayCount);
  
  bitWrite(pattern, 0, neg);
  bitWrite(pattern, 1, pos);
  bitWrite(pattern, 2, neg);
  bitWrite(pattern, 3, pos);
  displayPattern();
  delay(delayCount); 
}

I added a new helper method:

// return positive or negative pattern according to
// negation settings
byte posNegPattern(byte pattern) { 
  if (neg)
  {
    pattern = ~pattern;
  }
  return pattern;
}

And the pattern for 8 LEDs became this (the "0b" prefix indicates a binary number and, as you know, there are 10 types of people, those who know binary and those who do not):

void eitherOr() {
  // getting lazy about generating patterns algorithmically
  // so just setting the nybbles by hand
  pattern = posNegPattern(0b10101010);
  displayPattern();
  delay(delayCount);
  
  pattern = posNegPattern(0b01010101);
  displayPattern();
  delay(delayCount); 
}

Next time I'll try building a circuit with only the HC589 and see if it still works.


Saturday, August 24, 2013

More Shift RegisterTests

So I updated the ShiftOutBlinkPlus code with all the patterns from the BlinkPlus code and everything was working just swell.

I decided to kick it up a notch and introduce the parallel in-serial out 74HC589 shift register to my test circuit.  I wired 4 digital i/o pins from the arduino to the 589's shift clock, latch clock, serial shift-parallel load and serial out pins.

I give some more details on this Arduino Forum post, which also explains the trouble I had.  I was always missing the first bit, and the 8th parallel input pin seemed pretty useless.

As the post explains, this is because the shiftIn() function sets the clock to HIGH first, then reads the data.  It was not obvious to me at first, but looking at the datasheet for the 74HC589, this approach will lose the first bit placed on the output pin (which is actually the bit coming from the 8th parallel input pin).

So how the 74HC589 basically works is, there are 8 input pins, one output pin and 3 control pins.  Inside, it has a data latch and the shift register.  You toggle the latch control to send data from the 8 inputs into the data latch.  You toggle the parallel-load control to send the data from the data latch to the shift register prepare for shifting.  Then you toggle the shift clock control to shift the data out through the serial output pin.

Again, the Arduino's shiftIn() code first toggles the shift clock, then reads the data.  The problem is that when you finish toggling the parallel load control for the "prepare for shifting" part, the first shift occurs and the first bit (from the 8th input pin) is available on the data pin.  When shiftIn() is called, the clock is toggled and the next bit (form the 7th input pin) is shifted to the data pin and is the first bit actually read by the code.

Anyway, the Arduino code is freely available on github, so I just copied the code into my project and changed it so it reads the data pin before toggling the shift clock, like so:

// replaces built-in shiftIn to read the first bit before pulsing the clock
uint8_t naShiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) {
uint8_t value = 0;
uint8_t i;

for (i = 0; i < 8; ++i) {
// digitalWrite(clockPin, HIGH); // this was here
if (bitOrder == LSBFIRST)
value |= digitalRead(dataPin) << i;
else
value |= digitalRead(dataPin) << (7 - i);

digitalWrite(clockPin, HIGH); // this is now here
digitalWrite(clockPin, LOW);
}
return value;
}

So my new test sketch is ShiftInAndOutBurger which reads a byte from the 74HC589 shift register every 5 seconds and passes the byte to the 74HC595 which is still connected to my 4 red LEDs.  So, connecting a wire from the vcc to any of the 1st four parallel input pins of the HC589 will light up the matching LED.

Another note about this circuit is the use of pull-down resistors.  When any of the 8 input pins is NOT connected to vcc, they are essentially open switches and they are "floating."  When floating, the input can be influenced by white noise and start lighting things up that you don't want lit up.   To prevent this white noise, you connect the floating pit to ground through a resistor, typically 10k ohms, which will sufficiently suppress the noise.

My next test will be to daisy chain 2 74HC595s and 2 74HC589s to control 16 LEDs, but I'm gonna need more LEDs and more resistors.

Once I get that working, then I think I will have learned enough to build a circuit to read the dartboard.

Friday, August 23, 2013

Shift RegisterTests

Finished testing all of the digital outs, looking good.

Decided to test the 74HC595 shift register in the circuit instead of testing the analog ports.. I'll get to that later, maybe.

The 74HC595 is an 8-bit serial to parallel shift register.  What that means is you send it 8-bits in a row, one at a time on its input pin, flip a switch and it throws all 8 bits to 8 output pins at the same time, in parallel. This shift out example was very helpful in explaining how the 74HC595 works and how to wire it up to the duino.

This is overkill for my test, but useful.  It basically allows you to turn 3 ports into 8 ports - you use 3 ports from the duino to control the shift register: 1 to send the data, 1 to tell the 74HC595 to "shift in" the bit you are sending it, and 1 to flip the "latch" when you're done to send out the data to the parallel pins.

I used the shift out example's hello world example, modified it slightly for my test (i used different duino ports and only 4 LEDs) and felt pretty confident about using this little guy in my circuits.

So I had all these grand ideas of how I could use classes and dynamic arrays to build bytes to send to the shift register and turn my BlinkPlus sketch into an awesomely elegant piece of code.  This is where I learned some lessons about the limitations of programming a microcontroller like the duino and how the code is built and compiled.  So much for dynamic array type definitions, linked lists, and so on and so forth.

Eventually, I updated BlinkPlus to use the shift register.  Right now I only implemented one of the patterns, but it should be pretty quick and painless to convert the rest.  Here's how it works...

First I set up the 3 digital ports that the duino will use to control the 595:

//Pin connected to latch pin (ST_CP) of 74HC595
const int latchPin = 3;
//Pin connected to clock pin (SH_CP) of 74HC595
const int clockPin = 2;
////Pin connected to Data in (DS) of 74HC595
const int dataPin = 7;

// control variables
int delayCount = 500;
int repeatCount = 4;

byte pos = 1;
byte neg = 0;

byte pattern = 0;

// the setup routine runs once when you press reset:
void setup() {     
  //set pins to output so you can control the shift register
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}

The main loop iterates through each of the 4 LEDs and blinks them on and off a set number of times:

// the loop routine runs over and over again forever:
void loop() {
  
  reset();
  delay(delayCount*2);
  
  for (int i=0; i < 4; i++)
  {
    for (int j=0; j < repeatCount; j++)
    {
      blinkoUno(i);
    }
  }
  
  // toggle negative
  setPos(neg);
}

blinkoUno was rewritten to modify the bits of the global byte variable named "pattern" instead of sending HIGHs and LOWs directly to the LEDs.

// blink the given bit on then off
void blinkoUno(int ledNum) {
  bitWrite(pattern, ledNum, pos);
  displayPattern();
  delay(delayCount);
  
  bitWrite(pattern, ledNum, neg);
  displayPattern();
  delay(delayCount);
}

It calls the displayPattern function which jumps through all the necessary hoops to send the byte to the 595 serially (one bit at a time) and then flip the latch switch to send all 8 bits to the 595's 8 output pins:

// sends the given byte to the shift register
void displayPattern() {

  // take the latchPin low so 
  // the LEDs don't change while you're sending in bits:
  digitalWrite(latchPin, LOW);
  
  // shift out the bits:
  shiftOut(dataPin, clockPin, MSBFIRST, pattern);
  
  //take the latch pin high so the LEDs will light up:
  digitalWrite(latchPin, HIGH);
}

Just in case... a byte consists of 8 bits.  A bit is a value that can either be 1 or 0, bits are like switches, they are on (1) or off (0).  Each bit corresponds to one of the shift register's ouput pins... the first bit in the byte controls the first ouput pin, the second bit controls the 2nd ouput pin, etc.  So if I want to turn on both the first and third LEDs, i would send the byte 00000101 (assuming the first LED is wired to the first output pin, and so on).

One thing that can be confusing is that most people look at a row of LEDs and think the leftmost LED is the first LED.  In the byte, the rightmost bit is the first bit: 00000001.

I used the bitWrite command to turn the bits on and off.  To turn on bits 1 and 3 in the byte variable "pattern", you would do this;
 bitWrite(pattern, 1, 1); // set bit 1 of the byte "pattern" to 1 (on)
bitWrite(pattern, 3, 1); // set bit 3 of the byte "pattern" to 1 (on)

Another way to do this would be using the bitSet command:
bitSet(pattern, 1);  // set bit 1 of the byte "pattern" to 1 (on)
bitSet(pattern, 3);  // set bit 3 of the byte "pattern" to 1 (on)

To turn bits off, you can either use the bitWrite or bitClear commands:

bitWrite(pattern, 2, 0); // set bitv2 of the byte "pattern" to 0 (off)
bitWrite(pattern, 4, 0); // set bit 4 of the byte "pattern" to 0 (off)

bitClear(pattern, 2);  // set bit 2 of the byte "pattern" to 0 (off)
bitClear(pattern, 4);  // set bit 4 of the byte "pattern" to 0 (off)


Anyway... a couple more procedures from the code that I haven't mentioned yet are reset and setPos.

SetPos lets you switch the values of the pos and neg variable to on or off to easily display the patterns as negative images.

void setPos(byte posVal)
{
  pos = posVal;
  neg = !pos;
}

This is why I used the bitWrite command instead of bitSet and bitClear.  I just send bitWrite either "pos" or "neg" to generally define the pattern and calling setPos defines whether pos is on and neg is off, or the other way around.

Reset switches all bits off:

// sets all bits to off
void reset() {
  if (pos == 1)
  {
    pattern = 0;
  }
  else
  {
    pattern = ~0;
  }
  
  displayPattern();
}

If pos is set to display positive images, then I set the byte to 0 (which is really 00000000).  If it is set to display negative images, then I set it to ~0, which uses the bitwise NOT operator - which flips every bit in the byte to the opposite setting.  So if 0 = 00000000, then ~0 = 11111111.  I could have also just set it to 255, which is the decimal equivalent of 11111111, but I wanted to have an example of ~ in my toolbox.

So the complete code is all checked into git, and what it does is:

  • reset, turn all 4 LEDs off
  • blink the first LED on and off 4 times
  • blink the second LED on and off 4 times
  • blink the third LED on and off 4 times
  • blink the fourth LED on and off 4 times
  • set pos to 0 (OFF, or negative mode)
  • reset, turn all 4 LEDs ON
  • blink the first LED off and on 4 times
  • blink the second LED off and on 4 times
  • blink the third LED off and on 4 times
  • blink the fourth LED off and on 4 times
  • repeat until you unplug it or something breaks
I'm going to update it to display more patterns and do the whole random thingy stuff.

Thursday, August 22, 2013

BlinkPlus

As I mentioned in my previous post, I dug into the Blink example and played around.  This got me comfy with the Arduino IDE, working with the digital out pins, breadboarding simple boarduino circuits and it allowed me to test the boarduino (at least with the digital outs) to make sure my soldering was adequate.

So, in my first test with the Blink example, I didn't use an LED, i  just let it flash the on-board LED which is connected to the duino's digital port 13.  So this time, I grabbed a generic red LED, a 330 Ohm resistor and some jumper wires (the examples say 220 Ohm, but I didn't have any and I referred to my Electrodroid app which recommended 330 for a red LED)
I plugged the duino, LED and resistor into the breadboard, wired duino gnd to the negative (short) LED pin, wired duino d13 to the resistor, and wired the resistor to the positive (long) LED pin.

Then I plugged the duino into my laptop with USB and since it was already running the Blink sketch, and since the blink sketch flashes d13, and since the on-board LED and my red LED were both wired to d13, both blinked.

I had exactly 3 more red LEDs in my bag of tricks, and at least as many 330 Ohm resistors, so I added 3 more resistor/LED pairs and wired them up like the other one, except i wired the 4 LEDs to duino ports d8, d9, d10 and d11.

Then I modified the Blink sketch to look like this:

/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.

  This example code is in the public domain.
 */

// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
//int led = 13;

// array, 4 pins for 4 LEDs
int led[4] = {8,9,10,11};

// the setup routine runs once when you press reset:
void setup() {                
  // initialize the digital pin as an output.
  //pinMode(led, OUTPUT);

  // loop through array of pins, set each to OUTPUT
  for (int i=0; i<4; i++)
  {
    pinMode(led[i], OUTPUT);
  }

}

// the loop routine runs over and over again forever:
void loop() {
    // loop through pins, turning all LEDs on
    for (int i=0; i<4; i++)
    {
      digitalWrite(led[i], HIGH);   // turn the LED on (HIGH is the voltage level)
    }

    delay(1000);               // wait for a second

    // loop through pins, turning all LEDs off
    for (int i=0; i<4; i++)
    {
      digitalWrite(led[i], LOW);    // turn the LED off by making the voltage LOW
    }

    delay(1000);               // wait for a second
}

Uploaded the sketch to the duino, and all four LEDs blinked.  Magic.

So then I started to add methods to the sketch that turned the LEDs on and off in patterns, like the knightrider pattern.... I added them one at a time and updated the sketch to run the same pattern over and over and finally, wrote a method that randomly sets the delay, repeat and picks a pattern to run.  I checked this code into git, named it BlinkPlus.

I am going to rerun it with ports d2-d7, d12 and then try out an analog example to test out the remaining I/O ports.  So far so good.

Wednesday, August 21, 2013

Moving Right Along

I have made some progress.

On the software side, I have been working on a MVC design for the dart game engine, which will allow for easy plug-in capability.  No more real code has been written, though.  Looking at the following examples for guidance:
http://learn.adafruit.com/boarduino-kits/usb-boarduino-assembly
http://stackoverflow.com/questions/7249388/python-duck-typing-for-mvc-event-handling-in-pygame

On the hardware side, I got me a desk and set up my mackerspace and assembled the boarduino.  I started out soldering the socket to the board with a 40W iron, which was probably too hot.  It's been awhile since I've soldered, and I've never soldered much, so i was worried about ruining the boarduino. I went pretty quickly on most of the pins, so hopefully i didn't do any damage.  For the header pins, I went to a 25W iron which worked just as well and made me less nervous about a meltdown.

This here is what I did:
http://learn.adafruit.com/boarduino-kits/usb-boarduino-assembly

I loaded up the Arduino IDE hooked the boarduino to the laptop with a mini USB cable and loaded on the Blink sketch, the "hello world" of Arduinos.  Of course, I picked the wrong board in the IDE, so the first few attempts to upload the code failed and made me think I destroyed the board or let it sit in the closet for too many years.  Finally picked the correct board and had it blinking in no time.

My next step will be to get familiar with the shift registers and writing sketches.  Will probably start with controlling 8 LEDs since there are examples on the web I can reference if I get stuck.

Not much exciting here to anyone but me... getting the boarduino built was my big first step in making progress on the dartboard project.

Thursday, August 8, 2013

Setting Up My Google Project and git in Windows

I decided to use Google Code Project Hosting for my source code repository and git as the Source Control Manager (SCM).

Why?

Well, I'm doing this Blogger thing in Google, so might as well put the code on Google, too.


git was one of a few choices for SCM on Google Code Project Hosting.  SubVersion was another, and I have used SubVersion before... am familiar with it, yet I picked git.  I just did.


The thing about git, is it is really a unix/linux thingy, and I am developing on a Windows machine right now.    Seems that when you install the git client, it installs a bash terminal, so you kind of end up using whateverNIX anyway.  Might end up on Linux since Raspberry Pi is in my Dartboard Hack design.  No big deal for me since I've been on a whateverNIX system a few times before.


So, after you create a new project and repository, you need to create a local repository on your development machine.  Here's partly what I did and partly what I should have did if i had did it right the first time.


On Google Code, I created my new project named  "no-arms-darts," selected git as the SCM and went to the "Source" tab.


On my development (windows) system, I created a "git" folder in my Documents folder.  Then I installed the git client for windows and ran the git bash app from the link conveniently created in the start menu by the installer.  I changed the directory to my new git folder:


$ cd ~/Documents/git


Then I set git up to connect to my repository on Google code.  Looking back to my project source page on Google code, it gives the following option to do this:


Option 2: Stay authenticated with .netrc:
Add the following to your .netrc.
machine code.google.com login [Me@Gmail.com] password [generated googlecode.com password]

To use .netrc, make sure the clone URL doesn't contain your username:
git clone https://code.google.com/p/no-arms-darts/


To do this on windows, .netrc is actually _netrc.  So I clicked the link to generate my googlecode.com password and copied it to my clipboard.  Then I opened a command prompt in windows and:


C:\Users\Me> echo machine code.google.com login [Me@Gmail.com] password [generated password] > %HOMEPATH%\_netrc


Where [Me@Gmail.com] is my Gmail account and [generated password] is the password generated by the link on my Source code page under Option 2 shown above.


Then I went back to the git bash and executed the clone command, also shown above under option 2:


$ clone https://code.google.com/p/no-arms-darts


You would substitute your project name in place of no-arms-darts to clone your project... (or you can execute this for my project to clone all of my crappy code onto your development system).  This should create a new folder with the same name as your project under the git folder.


Since I already had some code for my project elsewhere on my system under a folder named "Python", I went to Windows explorer and copied the Python folder to the clipboard, then pasted it into C:\Users\Me\Documents\git\no-arms-darts.

Most of the time when you are developing with source control, there are files and directories used for developing, testing, debugging, etc that you don't want to be saved in the shared repository.  git has several ways to handle this ...like per repository, or globally.  I added a .gitignore file that I found on github among many prefab ignore files for specific development platforms.  This will effectively exclude the pycache folders, compiled scripts and so forth.


I just browsed my project and think I put the ignore file in the wrong place... looks like it is working out in its current location, but maybe should be at the root or master folder of the repository.


The next thing to do was copy all the files to my google code repository which took 6ish steps: add the Pyhton folder and its files to the local repository, set my email address and user name for the git config, commit the changes, set the default push mode, push the changes.... all done in the git bash, from the no-arms-darts folder:


$ cd no-arms-darts

$ git add Python



$ git config --global user.email "Me@Gmail.com"


$ git config --global user.name "Me"


$ git commit

git config --global push.default simple
$ git push


Now, the commit command opens up a whateverNIX text editor which I know as vi, and it prepopulates a commit document with comments detailing the files being committed, adds, mods, deletes... and requests that you add a version comment, and I think if you don't, it cancels the commit.  If you don't know how to use vi, you might want to try a git GUI or learn some vi commands. Quick and dirty:  press i to insert the comment, type the comment, press Esc to exit insert mode, then :wq to write your changes to the file and quit vi.

Oh, ok.  I actually read some of the git documentation and you can avoid the whole text editor thing by using the -m switch on the commit command like:

$ git commit -m "fixed another stupid mistake (rtfm)"


As I implied earlier, I didn't do this right the first time through... so I became acquainted with a few more git commands along the way: status and reset.  These are all explained very well in the git documentation.


After pushing the code to google, I went back to my source browser and the code was there.  If you are reading this and decide to look at this code, it's probably not the highest quality Python code... hopefully I will clean it up so it's actually worth looking at.  Maybe I'll run through this all again and take some screen shots and rewrite this post to make it more like a tutorial than a memoir.

Monday, August 5, 2013

Dartboard Hack - Software Design Ideas

The Dartboard Hack (or Mack?) will require several pieces of software:


  • Arduino sketch running on boarduino to read dartboard and send data to the game engine
  • Game engine - python/pygame running on RPi
  • Android app to remote control game over bluetooth
I have a bit of programming experience, but none of it falls within any of the 3 realms listed above.
The game engine will be the meat of the system, so I started learning python and pygame.

I spent a weekend writing an intro animation.  It could use some refactoring... like using an actual game engine structure with some FPS BS... but that's not really important to me at the moment.  I will create the proper game engine structure when I get into the dart game engine and maybe retrofit the intro later.

The intro pays homage to the classic game Jumpman.  I borrowed some sounds and sprites from another project,so I think I'll make sure it's ok to use them before putting them on here.

Sunday, August 4, 2013

Dartboard Hack - Intro

I've been looking for a project to get me going in my new hobby, and this is it.  The dartboard hack. 

Why do I want to do it?  Well, I came up with my own stupid dart games and wanted to code a web or android version.  Then I looked at my electronic dartboard and wondered if I could hook it up to my laptop or something to have it play my games.

I found that it's been done (or attempted) before:
http://forum.arcadecontrols.com/index.php?topic=34866.0
http://web.archive.org/web/20021017065130/http://ice.fas.harvard.edu/~sander/dip/
http://amqsoftware.com/~yocom/projects/darts.php
http://www.martinpersson.org/wordpress/category/dart/

After researching these projects and similar projects, here is my initial design idea:



Perhaps an ambitious first macker project, perhaps not.  I ordered the shift registers and sockets and a soldering fume filter fan thing.  I still have a little work to get my mackerspace set up, but the first step in hardware will be assembling the boarduino

I have already taken the first step in software and jumped into pygame.  I'll make that a new post.