Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- April 15, 2019
- Reddit electronic dice sketch
- This is a electronic dice program for an Uno with a generic 16x2 LCD + keypad shield.
- (The generic shield has resistive buttons; this is *NOT* the Adafruit shield with the MPC23017 i2c expander chip).
- ...This is a complete re-write of the original sketch, so the order of things is different than before...
- How this sketch should work:
- 1. When no dice value is selected, the display should show two always-changing digits (values from 1 to 6) on the upper line.
- ...One issue here is that LCds can't really change values very fast.
- Under normal circumstances they might require 1/10th of a second to update, and in cold weather they might take 1/4th of a second to update.
- So there will be a delay value used to control how fast new numbers are drawn and written to the LCD.
- 2. Two random numbers are selected, both with values of 1 to 6, as if one were rolling a pair of normal 6-sided dice.
- 2. When the [select] button is pressed, the changing numbers should stop changing.
- 3. If the total of the two numbers is not 7, one message is displayed.
- 4. If the total of the two numbers is 7, then another message is displayed.
- 5. Either of the messages in (3) and (4) is maintained until any of the programmable keypad buttons is pushed again.
- There is a 1-second delay after any programmable button press.
- The button-debounce code here is not really the way that I would usually do it, but it is simple and it works reliably.
- There is just a time lag after the button press, before anything happens.
- */
- #include <LiquidCrystal.h> // <---------------- This is the standard Arduino IDE library.
- LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
- int keypad_pin = A0; // On the generic LCD+keypad shields, this is the Arduino pin that the buttons are connected to.
- /*
- If you are using the generic shield, then you don't need to use the code below at all.
- This code was carried over from the Adafruit shield sketch out of convenience, when I converted that sketch to work with a generic 16x2LCD + keypad shield.
- On the Adafruit shield, I think that each of the numbers of those buttons below corresponds to the pin of the MPC23017 i2c expander chip that each button is connected to.
- The call to read the buttons goes to the MPC23017 chip, it doesn't just use regular Arduino I/O pins (even though there is direct I/O shield pins that could be used).
- The generic shield does not use the MPC23017 chip, so there is really no reason to use these defined values.
- #define btnRIGHT 0
- #define btnUP 1
- #define btnDOWN 2
- #define btnLEFT 3
- #define btnSELECT 4
- #define btnNONE 5
- */
- int random_number_draw_interval = 250; // This is the time in milliseconds to wait between drawing new random numbers, to allow the LCD screen to update.
- // Normal LCDs usually take at least 1/10th of a second to change their state, and when cold (below freezing) they can take 1 second or more to change.
- // If you don't give them long enough to change, then you don't really see anything displayed. You just faint flickering that can't be identified as any character.
- int random_number = 0; // This is the variable for generating the random numbers.
- int random_seed_pin = A1; // You can use an analog-input pin for a random seed, but the pin must not be connected to anything, so you can't use A0 since the buttons are connected to that.
- // Also, analog input pins must start with the letter "A", unless you use the high-integer pin ID numbers.
- int selected_state = 0; // There is two states that must be identifiable: when no values are selected (zero), and when values are selected (1).
- // Since the below variables always get used, I would just declare them as globals...
- long diceOne = 0;
- long diceTwo = 0;
- int total_dice = 0;
- int button_pin_value = 0;
- // setup() cannot be placed inside any other function.
- void setup() {
- Serial.begin(9600);
- lcd.begin(16, 2); // start the LCD library
- lcd.setCursor(0, 0);
- lcd.print("select = dice"); // Message is shortened to less than 17 characters.
- randomSeed(analogRead(random_seed_pin)); // Changed to use named random seed pin number
- Serial.println("Exiting setup()");
- }
- // loop() cannot be placed inside any other function.
- void loop() {
- if (selected_state == 0) {
- // As long as no number has been selected, this is the code that gets run.
- roll_the_dice();
- print_rolling_dice_to_LCD();
- // The line below makes the sketch wait long enough to see the random values appearing on the LCD screen.
- delay(random_number_draw_interval);
- }
- else { // if (selected_state == 1)
- // There is not anything to do here.
- // The important thing is that the code above gets skipped when selected_state is not zero.
- }
- read_LCD_buttons();
- Serial.print("button value = ");
- Serial.println(button_pin_value);
- }
- void roll_the_dice() {
- diceOne = random(1, 7);
- diceTwo = random(1, 7);
- total_dice = diceOne + diceTwo;
- }
- void print_rolling_dice_to_LCD() {
- // This function is only for showing the un-selected changing dice values.
- lcd.clear();
- lcd.setCursor(7, 0);
- lcd.print(diceOne);
- lcd.print(",");
- lcd.print(diceTwo);
- }
- // read the buttons
- int read_LCD_buttons() {
- button_pin_value = analogRead(keypad_pin); // It is helpful to name your input/output pins, and then to refer to them only by name.
- // Below is some troubleshooting code to see what values the buttons are putting out...
- //if (button_pin_value < 900) {
- //Serial.print("button value = ");
- //Serial.println(button_pin_value);
- //}
- // my buttons when read are centered at these values: 0, 144, 329, 504, 741
- // we add approx 50 to those values and check to see if we are close
- // The below values should work for yours and my shields, although the values are slightly different.
- if (button_pin_value < 50) {
- // This is the [right] button value.
- if (selected_state == 1) {
- selected_state = 0;
- }
- }
- else if (button_pin_value > 49 && button_pin_value < 200) {
- // This is the [up] button value.
- if (selected_state == 1) {
- selected_state = 0;
- }
- }
- else if (button_pin_value > 250 && button_pin_value < 350) {
- // This is the [down] button value.
- if (selected_state == 1) {
- selected_state = 0;
- }
- }
- else if (button_pin_value > 450 && button_pin_value < 550) {
- // This is the [left] button value.
- if (selected_state == 1) {
- selected_state = 0;
- }
- }
- else if (button_pin_value > 600 && button_pin_value < 850) {
- // This is the [select] button value.
- // This button must do two different things, depending on if selected_state is set to zero or 1.
- if (selected_state == 0) {
- selected_state = 1;
- display_dice_values(); // This is what happens when the [select] button is pressed, to stop the dice from changing.
- }
- else {
- selected_state = 0;
- }
- }
- else {
- // This is the [none] button value.
- }
- delay(1000); // This is to prevent the buttons from bouncing.
- }
- void display_dice_values() {
- // First of all, we will generate new dice values one more time, to make sure that the user can't press the button when they see dice values they want:
- roll_the_dice();
- // Clear both LCD lines:
- clear_both_lcd_lines();
- // Now there is two different displays to show, if the total value is 7 or not:
- if (total_dice == 7) {
- lcd.setCursor(7, 0);
- lcd.print(total_dice);
- // print second line
- lcd.setCursor(2, 1);
- lcd.print("the robber");
- }
- else {
- // Print the two die values to the top line:
- lcd.setCursor(7, 0);
- lcd.print(diceOne);
- lcd.print(",");
- lcd.print(diceTwo);
- // print second line
- lcd.setCursor(0, 1);
- lcd.print("press to reroll");
- }
- }
- // The LCD already has a command to clear the whole thing,
- // but often it is useful to write your own named functions to clear out just one line, or both lines.
- void clear_both_lcd_lines() {
- clear_lcd_top_line();
- clear_lcd_bottom_line();
- }
- void clear_lcd_top_line() {
- lcd.setCursor(0, 0);
- lcd.print(" "); // Printing 16 spaces.
- }
- void clear_lcd_bottom_line() {
- lcd.setCursor(0, 1);
- lcd.print(" "); // Printing 16 spaces.
- }
Add Comment
Please, Sign In to add comment