0

I've made a dice roller (to make it easier to roll the dice) using an Arduino UNO and an LCD keypad shield but I can't get the correct numbers (1, 6 (7)) to show up, I've tried using int, float and everything in between. the buttons on the shield are connected to A0, can someone help me please?

#include <LiquidCrystal.h>
// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

#include "DFRkeypad.h"
String line2 = "Press Select to roll"; // Scrolling line

// just some reference flags
//int stringStart, stringStop = 0;
//int scrollCursor = screenWidth;

// define some values used by the panel and buttons
int lcd_key     = 0;
int adc_key_in  = 0;
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

// read the buttons
int read_LCD_buttons()
{
  adc_key_in = analogRead(0);      // read the value from the sensor

  // For V1.0 comment the other threshold and use the one below:

  if (adc_key_in > 1000) return btnNONE; // We make this the 1st option
  for speed reasons since it will be the most likely result
  // For V1.1 us this threshold
  if (adc_key_in < 50)   return btnRIGHT;
  if (adc_key_in < 195)  return btnUP;
  if (adc_key_in < 380)  return btnDOWN;
  if (adc_key_in < 555)  return btnLEFT;
  if (adc_key_in < 790)  return btnSELECT;

  return btnNONE;  // when all others fail, return this...
}

void setup() {
  randomSeed(analogRead(1));
  lcd.begin(16, 2);              // start the library
  lcd.setCursor(3, 0);
  lcd.print ("Catan Dice");
  lcd.setCursor(0, 1);

  // while(line2)
  //
  // lcd.print(line2);
  // break;
}

void loop() {

  //Dice
  byte DiceOne = random(1, 7);
  byte DiceTwo = random(1, 7);

  //local varables
  int buttonState = read_LCD_buttons(); // read the button pad
  int lastButtonState = btnNONE; // previous state of the button

  // the following variables are unsigned longs because the time, measured in
  // milliseconds, will quickly become a bigger number than can be stored in an int.
  unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
  unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

  switch (buttonState)
  {
    case btnSELECT:
      lcd.clear();
      //Row, Colum
      lcd.setCursor (0, 4);
      lcd.print(DiceOne);
      lcd.setCursor (1, 4);
      lcd.print(DiceTwo);
      break;
  }

  DELAY(100)

  // read the state of the switch into a local variable:
  int reading = digitalRead(buttonState);

  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH), and you've waited long enough
  // since the last press to ignore any noise:

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the
    debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;
    }
  }

UPDATE, i got it working now

  • 2
    what do you mean by can't get correct numbers to show up? – jsotola Sep 27 at 4:03
  • The question is unclear, what do you mean do not get correct number? The official Arduino documentation recommends using a "long" type variable arduino.cc/reference/en/language/functions/random-numbers/… – emax Sep 27 at 10:13
  • i want 1 through 6 to show up insted of larger numbers – taran Sep 27 at 11:35
  • What "larger numbers" are you getting? – jose can u c Sep 27 at 14:12
  • 42, 43,62 and 55, i want it to generate numbers 1,2,3,4,5,6 at random when i push the button – taran Sep 27 at 17:48
2

You are calling setCursor() with:

//Row, Colum
lcd.setCursor (0, 4);
lcd.print(DiceOne);
lcd.setCursor (1, 4);
lcd.print(DiceTwo);

While your comment notes the order is Row, Column, there appear to be several LiquidCrystal libraries floating about, some of which use Column, Row order in the SetCursor() function. The official Arduino library source indicates the col, row order.

You are writing both values on row 4 (even though that doesn't exist on your display), and in columns 0 and 1, thus you are correctly computing the Dice values, but they are being written with no gap between.

  • Yes I'm writing them in the same row but different columns and I'll be away from my dice for a few days, we'll continue this when I get back, sound good? – taran Sep 27 at 20:59
  • You noted that you got it working. If you share the results, it may help others in the future who are having a possibly similar question. – jose can u c Oct 2 at 18:02
  • all i did was switched the numbers in the lcd.Setcusor from lcd.setCursor (0, 4); lcd.print(DiceOne); lcd.setCursor (1, 4); lcd.print(DiceTwo); to lcd.setCursor (4, 0); lcd.print(DiceOne); lcd.setCursor (4, 1); lcd.print(DiceTwo); – taran Oct 4 at 1:53
1

It seems that your issue is probably connected with LCD timing. Sending data to LCD requires a precise timings, and the onboard chip of the LCD module very much like a few milliseconds of time to finish processing the data sent, instead you pass the entire clear and draw command each loop cycle.

I used the default Tinkercad LCD display example. This code works fine:

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  randomSeed(analogRead(1));
  lcd.begin(16, 2);
  lcd.setCursor(3, 0);
  lcd.print ("Catan Dice");
  lcd.setCursor(0, 1);
}

void loop() {
  byte DiceOne = random(1, 7);
  byte DiceTwo = random(1, 7);

  lcd.clear();
  lcd.setCursor (0, 4);
  lcd.print(DiceOne);
  lcd.setCursor (1, 4);
  lcd.print(DiceTwo);
  delay(100);
}

tinkercad example

but as soon as I remove the delay(100)

void loop() {
  byte DiceOne = random(1, 7);
  byte DiceTwo = random(1, 7);

  lcd.clear();
  lcd.setCursor (0, 4);
  lcd.print(DiceOne);
  lcd.setCursor (1, 4);
  lcd.print(DiceTwo);
  //delay(100);
}

Weird things start to show on the LCD.

incorrect number displayed

Try rewriting your code that the commands are sent to LCD only once per button press.

  • I believe the serial LCD driver in the LiquidCrystal library is synchronous and won't return until it has finished sending the commands to display your desired characters. The digital interface should not get confused even without delays. – Duncan C Sep 27 at 17:39
  • My guess is that without the delay, the LCD updates so fast that the liquid crystals don't finish shifting to display a given pixel pattern before the next number is sent. (LCD displays have crystals suspended in a liquid, and when you change the pixel pattern, it takes significant time for the crystals to shift into the new patterns. If you watch the change with a high speed camera, the pixels seem to "ooze" into the new pattern.) – Duncan C Sep 27 at 17:39
  • i have it so it generates the numbers upon a push of the right button – taran Sep 27 at 17:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.