Introduction: AVR Assembler Tutorial 11
Welcome to Tutorial 11!
In this short tutorial, we are finally going to build the first part of our final project.
The first thing you should do is go to the very last step of this tutorial and watch the video. Then come back here. [pausing while you do that....] Okay. Now proceed.
If you haven't already guessed, we are building a Craps game! Of course, just because I am building a craps game certainly doesn't mean you have to. I hope that goes without saying. It is useful in any case to use microcontrollers to control segmented displays, etc., and to communicate with each other -- that is mainly what we are doing here. You can write code to use them anyway you like. For now I am going to code them to play craps although I may decide later to re-purpose the segmented displays to do something else.
The reason I am building this is because I am thinking that I might eventually want a full size Vegas craps table in my "man cave" in the basement of my house. However, none of my friends have the slightest idea how to deal, score, or payout craps bets and rolls. So I figured it would be cool to have the table do all the dealer work for us! When we place a bet on the table we can also push a little pushbutton next to the square that our chips are on showing how much is placed there, then the microcontroller can calculate the payout for that square after the dice roll and display it. I am still not quite sure how I will organize this aspect though. One thought I had was that each person will be asked to place all of their bets in turn so that the controller will record where each persons money is before recording the next player and so on. Then after the roll, the computer can show the payouts on each square and can also keep a running "total cash" for each player.
For one of the cover pictures of this tutorial I just had to use a picture of me pulling 5 aces at the poker table in Vegas this summer. Heheh. Indulge me.
Here is a link to the complete collection of my AVR assembler tutorials: http://media.nbcmontana.com/id/Command-Line-AVR-T...
Step 1: Craps!
In this tutorial we will only be constructing the simplest part of the final Craps game. This is called "The Pass Line" and you can bet on it. You can learn everything you need to know about the "pass line" part of the game by watching the short 2-minute instructional video I have attached to this step.
We will build another 4 digit display which will keep track of the Dealer's Cash in the same way that our current 4-digit display keeps track of the Player's Cash. The Dealer will start with $20 and the player will start with $20 (the total possible money in the game is $9999 -- the maximum of our 4-digit displays, but we will only need $20 for this first piece of the game or otherwise it would be tedious in the extreme and hard to win or lose in a decent amount of time). If the player takes all the dealer's money, the player wins. If the player loses all his money then the dealer wins.
How do you win or lose money? Well, those of you who have played Craps, seen people "shooting dice" in the street, or seen it played against the casino in Vegas, will already know. For the rest of you, let me give you a short description of the "pass line" part of the game that we will be coding today.
Craps has been played for hundreds of years, dating back to the time of the crusades. It was played by troops in the trenches of WWII, it was played on the streets, it was played in casinos and gambling halls. It started with just the pass line and all of the other things were added to it later. We will be following this same progression.
The way the pass line works is this. You place a bet and then you roll the dice. The first roll is called the "come-out roll". If you get a 2 (snake eyes), a 3 (ace deuce), or a 12 (box cars) on the come-out roll, you lose your bet and it is called "craps". If you roll a 7 (a natural) or an 11 (a yo, or yo-leven) you win. If you roll any other number then this number becomes your "point". Once a "point" is established you continue to roll the dice with the goal of hitting the point again before rolling a 7. If you get your point before a 7 is rolled you win even money. So a dollar bet wins you a dollar from the dealer. If you get a 7 before your point is rolled, this is called "seven out" and you lose your bet to the dealer.
After that you start again. Place a bet on the pass line and roll the dice, 7 or 11 wins, 2,3, or 12 loses.
There are many more kinds of bets, "don't pass", "pass odds", "don't pass odds", "come bet", "don't come bet", "field", "horn", "hard ways", etc etc etc. You can find details here:
As I said above, for now, we will only be coding the pass line part of the game which is all they had back in the day when kids were throwing dice against the wall for each other's lunch money and so this is where we will start.
However, before we start coding stuff, lets build the dealer cash display. For this, I want to use one of the larger 4-digit displays that you can get from Sparkfun or elsewhere. From now on I am not going to list materials on these tutorials. If you have actually been building everything all along with me then you already know where to get the materials and what they are. It is pointless for me to list them or how much they cost.
So lets grab one of our prototyping boards, a large 4-digit display, another ATmega328p to control that display, and build it like we did with the dice roller, and the player display before. We will also be attaching headers for power, for programming, and for TWI communications just like the others.
Step 2: Dealer's Cash Display
We construct the dealer display the same way we did with the player's 4-digit display in the last tutorial. The only differences are that it is bigger, and it has fewer pins, so we will be arranging it and wiring it differently.
I have attached a picture of the wiring of this display. You can see that it is larger and has fewer pins than our playercash display. The picture is from the sparkfun page where I got the display and it shows which pins are power for each digit and which pins control each of the segments in a digit.
As usual, you should begin by plugging the display into your prototyping breadboard and test each segment to be sure that you understand how it is wired. Then you should hook it up to the pins of an AVR microcontroller on your breadboard and run it from there until we have all of our code working in this tutorial. Finally, at the end, you should build the external board and solder it on. Then when you test the final product you will know that any problems come from your soldering and cutting job and not the code. Also, don't forgot the well known axiom from carpentry "measure twice, and cut once", or in the case of making circuit boards: "cut twice, solder once." As you can see by the picture, I finally broke down and bought the perfect Dremel attachment for this kind of work. A "Diamond Point Set". It costed 5 bucks but that is a lot less than the cost of the Anger Managment Therapy that comes with effing up my cutting job too many times in a row.
I am using 330 ohm resistors for this display. The COM pins go through the resistor to GND and the power goes to whichever segment you want to display. I am going to use PC0 through PC3 for the COM pins and PB0, PB1, PB2, PB3, PB4, PD5, PD6, and PD7 for the segments.
Here is the key to maximizing your chances of getting it right:
- map out the circuit
- cut the circuit
- check your wiring
- attach the resistors, the caps, and the crystal oscillator
- check the connections and wiring again
- attach the external wires
- attach the microcontroller
- check the wiring again
- attach the 4-digit display
- check each digit with a pair of wires from the breadboard
- set it aside and write the code, knowing that you will probably have to tweak things later and hoping you haven't covered up a connection that needs to be cut.
I have shown a series of pictures of my wiring job. Please realize that you are free to wire yours any way you like. It is very likely you can find a better map than I did and you should use it. Nothing in these tutorials depends on how your components are wired, as long as they have the correct output ports. Which reminds me. Notice that there are now two headers going to SDA and two going to SCL? Why do you suppose we did that?
Now, as you can see by the attached code at the end of the tutorial I simply cut and pasted the code from the player display of the last tutorial to a new file for the dealer display. Then I went through and changed the "segments" lookup table to correspond to the new pin map noting that for this display the "com" pins are ground and the segment pins are 5V rather than the other way around as it was for the other display. I also changed the initialization of the ports to reflect the new wiring, I changed the address of the dealercash display to 0b1000000 so that the dice roller will be able to talk to him, I changed the "cycle" subroutine so that it turns off the PC0 through PC3 "com" pins when it wants to power a particular segment and I changed the "digit" that gets displayed since the new wiring has the digits in the opposite order (if you left it as it was and tried to display 1234 it would have shown up as 4321 instead).
Here is the new register map:
(PD7, PD6, PD5, PB4, PB3, PB2, PB1, PB0) = (decimal point, c, g, b, f, a, e, d)
where 1 is ON and 0 is OFF.
Now test the display by first setting the initialized value of the display to various numbers so that when it turns on it shows them. This will tell you if everything is working correctly.
Then modify the diceroller code so that it uses the new address for the slave, hook them together, and run it. It should act exactly like what we did in the last tutorial except that the dice rolls now show up on the new display.
Great! Now we are ready to write the new dice roller code so that it communicates with both the player display and the dealer display.
Step 3: Program Outline
The way the code is going to work for our game is we will keep the dice roller as the master and add the dealer display as an additional slave. The dice roller will control the game and it will send the resulting changes in cash to the dealer and the player displays after each roll. For now we will just have the pass line bet being $10 each time so we don't have to get too complicated just yet with the player changing his bet. Later on, once we have the mechanics working, we will add another controller which will be an additional master which will control the betting and the payouts and our dice roller will remain a master but only used for rolling the dice. This will allow us to get in to TWI arbitration, collisions, and other important aspects of serial communication when you have multiple masters and slaves. We will also be adding a number of single 7-digit displays with push buttons under them that will allow us to bet on other types of rolls, but all that will come in future tutorials. For now, we just want the dice roller as master, and the two displays as slaves. When we push the button, the code will decide whether to payout a natural, take money from a craps, or branch to a "point" series of rolls until either a win or a seven-out.
Let's first write the slave routines. These are simple in that all they will do is watch the SDA line for their address, if they are called they will read the new number to display and display it. That is all! They don't even have to talk back to the master since the master will be keeping track of their totals and doing all the payout calculations before updating them. In future tutorials we will have slaves writing back to the master (for example when we have single 7-digit displays with push buttons for the betting amount, they will have to tell the master how much is being bet on each display and so we will address them with an address + read call with the master in "master receiver mode") but we will get to that in due time.
For now everything is instigated by the dice roll button push followed by a calculation or further button pushes and finally a message to each of the displays with their new totals. There will be a test after each payout to determine if the player has won or has lost, in other words, if the dealer cash becomes zero after a roll, or if the player cash becomes zero after a roll (neither the dealer or the player can go negative since they will only be allowed to bet $10 or else whatever is left if it is less than $10).
So that is how it is going to work. Let's get coding.
Step 4: Master Communications Code
We can now write the communications routine of the dice roller. It is also almost identical to the one we wrote last time except that we will be communicating with two different slaves rather than only one. Note that for each of the slaves we use a different address. You should modify the code yourself and then simply test it with each address and make sure it works just like last tutorial except with each separate display.
I will attach the code for each component which simply displays the result of the roll so that it can be used to get the displays working properly and check the wiring.
Coding the game introduces nothing new as far as assembly language commands or AVR microcontroller components and so I don't feel like I need to go through it line-by-line. You have probably noticed that when we introduce something new I go through each line in minute detail to the point of exasperating you if not putting you to sleep. On the other hand I will not do that if there is nothing new introduced. That is the case today. So I think that you are prepared by now to play with the code, read through the code, analyze the code, understand the code, criticize the code, scoff at the code, and laugh at the guy who wrote the code. So I will let you go ahead and do that. It is almost certain that you will find many places that you can improve or at least simplify what I have written.
I have, as usual, attached the final version of the code for the two displays and the diceroller in the next step along with a video of me testing the thing.
Step 5: Final Code and Video
I have attached the video and the 3 programs. You will notice that you can fix the wager and the starting dealer and player cash at the top of the program with .equ statements.
In the next tutorial we will add the ability to bet on different things which will make the game more exciting. The interesting thing about modern Craps is that you have a multitude of different ways to bet and try to maximize your odds. In fact, Craps is the highest odds game in the Casino! ... IF you know how to play it. On the other hand, if you don't know how to play then it becomes one of the lowest odds games.
Once we have more things to bet our money on then I will increase the total amount of money in the game.
I should be fun!
See you next time!