Pages: 1 2 [3]   Go Down
Author Topic: (not a ) switch case question (anymore...)  (Read 2636 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It is fairly simple. For example, this would be my implementation, high-level:

Code:
void led2_display(void) {
  static unsigned char current_dig=0; //current digit to be displayed. 0=tenth digit, 1=sigle digit

  //turn off all digits, optional
  //DIG_OFF(DIG_0); DIG_OFF(DIG_1);
  switch (current_dig) {
    case DIG_0: DIG_OFF(DIG_1); SEG_OUT(LRAM[DIG_0]); DIG_ON(DIG_0); current_dig=DIG_1; break; //turn off the previous digit, send data to segments, and turn on the current digit, advance to the next digit
    case DIG_1: DIG_OFF(DIG_0); SEG_OUT(LRAM[DIG_1]); DIG_ON(DIG_1); current_dig=DIG_0; break; //turn off the previous digit, send data to segments, and turn on the current digit, advance to the next digit
    default: continue; //do nothing for invalid input
  }
}

Each time led2_display() is called, it shows the next digit (from display buffer LRAM[]). If you call it fast enough, it appears to show both.

You just need to figure out how to implement DIG_ON/OFF() and SEG_OUT() based on your hardware.

Logged

Ohio USA
Offline Offline
Jr. Member
**
Karma: 1
Posts: 57
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Soooo, here we go, totally revised v4.o

I finally threw in the towel on making a dual 7seg display, even with some code I simply copied and pasted, it wasn't quite working right.  (the code I copied was for a 4 digit display, while I only had two digits, had to mod it a little, and lost something in the translation...)  it would not scroll the message properly, so I got pretty frustrated after a whole weekend spent on it, and went to radio shack and picked up a simple LCD display...

I really like this option for my project, and I think it works better anyway.  Now I can always display on the screen which dice mode you are in, and I am now starting to think of ways to add more dice to the mix.  that way you can roll multiple dice at the same time.  probably going to use a toggle switch and some basic digitalRead arguments to tell the arduino to display 2 or maybe even 3 random results of the current dice mode.  Really increase the functionality of this thing.

So far, everything is working nearly perfect.  Only glitch is, when I have cycled through all the dice modes, my default D2 mode (coin flip) is called D1 instead of D2.  When it first comes on, it shows D2, then D4, D6, D8, D10, D12 and D20 as you cycle through the modes.  One more button push should cycle back to D2, but instead reads D1.

here is my code...

Code:
#include <LiquidCrystal.h>

LiquidCrystal lcd(2,3,4,5,6,7);

const int mButton = 9;
int mode = 0;
int oldMode = 0;
const int Tilt = 8;
int val = 0;
int oldVal = 0;
int state = 0;

int dValue[] =
{2,4,6,8,10,12,20};

long result;


void setup()
{
  Serial.begin(9600);
  pinMode(Tilt, INPUT);
  pinMode(mButton, INPUT);
 
  lcd.begin(16,2);
  lcd.print("DigiDice - D");
  lcd.print(dValue[state]);
 
  randomSeed(analogRead(0));
}

void loop()
{
  {
    mode = digitalRead(mButton);
    if ((mode == HIGH) && (oldMode == LOW))
    {
      state++;
      {
        lcd.begin(16,2);
        lcd.print("DigiDice - D");
        lcd.print(dValue[state]);
      }
    }
    if (state > 6)
    {
      state = 0;
      delay(10);
    }
    oldMode = mode;
  }
     
  val = digitalRead(Tilt);
  if ((val == HIGH) && (oldVal == LOW))
  {
    result = random(1, dValue[state] + 1);
    lcd.setCursor(0, 1);
    lcd.print("Result = ");
    lcd.print(result);
    lcd.print("       ");
    delay(3000);
  } else
  {
    lcd.setCursor(0,1);
    lcd.print("Give Me A Shake");
   
  }
  Serial.println(result);
}

sorry for the lack of comments, I honestly just threw this together on the fly, and it worked nearly out of the box.  I haven't taken the time to comment it yet, but will before I am all done.
pretty basic code, and the LiquidCrystal library is great!  Made this a snap.
if anyone could let me know why my dice mode is displaying wrong (I still get the correct expected results, no false numbers outside the dice range) and maybe point me to a fix, I would greatly appreciate it!

This has been a very twisty, educational project for me, and I cannot express how much I have appreciated everyone who took the time to try and walk me through this.
Logged

absence of proof is not proof of absence

Corinth, TX
Offline Offline
Jr. Member
**
Karma: 1
Posts: 92
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You do have some unnecessary curly braces in there (they aren't hurting anything) and your style differs a bit from mine smiley  but I don't see any obvious reason this should ever print "D1".  Quick question - if you press that button again, does it go to D2 or D4 (or something else)?
Logged

Ohio USA
Offline Offline
Jr. Member
**
Karma: 1
Posts: 57
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am having trouble pinning it down also.
if you push the button again, it goes to D4 like it is supposed to.
The only mode that doesn't display correctly, no matter how many times you cycle through, is D2.

I have tried adding and subtracting 1 at various points in the code where the display is called, but that only seems to effect my dice results, or limits my results by one.
I am honestly stumped, but for the moment it is a minor issue, and I have moved on.
When I get the rest of the functions I am trying to work out done and working correctly, I will probably go back and see if I can fix it.
If it can't be fixed, then so be it, I could have done worse in my opinions smiley-razz

Out of curiosity, do you mind explaining how you would have handled it?
I am always interested in learning other ways to do things with the Arduino.  The more ways you can do one things, the more tools you have in the toolbox smiley

I seem to be nutty for curly brackets, I always end up with many of them smiley-razz
Logged

absence of proof is not proof of absence

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12577
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This bit of code does things in the wrong order:
Code:
      state++;
      {
        lcd.begin(16,2);
        lcd.print("DigiDice - D");
        lcd.print(dValue[state]);
      }
    }
    if (state > 6)

You print the new dice value before you do the 'if(state > 6)' check to reset it to zero. The '1' you're seeing on the display is just whatever happens to be in the memory location after the last dice.

A better way to do this would be like this:

Code:
      // DICE_COUNT is the number of elements in the dValue array
      state = (state+1) % DICE_COUNT;
      lcd.begin(16,2);
      lcd.print("DigiDice - D");
      lcd.print(dValue[state]);
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Ohio USA
Offline Offline
Jr. Member
**
Karma: 1
Posts: 57
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This bit of code does things in the wrong order:
Code:
     state++;
      {
        lcd.begin(16,2);
        lcd.print("DigiDice - D");
        lcd.print(dValue[state]);
      }
    }
    if (state > 6)

You print the new dice value before you do the 'if(state > 6)' check to reset it to zero. The '1' you're seeing on the display is just whatever happens to be in the memory location after the last dice.

A better way to do this would be like this:

Code:
     // DICE_COUNT is the number of elements in the dValue array
      state = (state+1) % DICE_COUNT;
      lcd.begin(16,2);
      lcd.print("DigiDice - D");
      lcd.print(dValue[state]);

you are 100% correct sir!
while you posted that, I had accidentally stumbled on the answer myself, but hadn't realized it yet, or why.
I am very nearly successful at my next stage of complexity with this project.
here is what I am doing with it now....

There is a push button to select through the range of dice modes.
there is a toggle switch to select rolling one dice or two dice at a time. (both dice must be of the same value though, ex - two d6.)
I can get the LCD to display the correct dice mode all through the count now, and I can get two different results with one shake of the dice.

my only problem now is the LCD seems to be trying to display both modes at the same time, and it makes the words flicker like mad, and is a bit hard to read everything.
I am using a switch case at the moment to handle switching between one and two dice per throw.  I originally wrote it as an if/else, but changed it to a switch to see if that would cure my screen flicker.  It seems to have helped a bit, but it is still very much an issue.
I am working my way through the LCD examples now trying to find out how to change the number of dice, and print two completely different screen readouts, without the flicker
if that makes any sense...

here is the code as I have it wrote now...
Code:
#include <LiquidCrystal.h>

LiquidCrystal lcd(2,3,4,5,6,7);

const int nButton = 11;
const int mButton = 9;
int mode = 0;
int oldMode = 0;
const int Tilt = 8;
int val = 0;
int oldVal = 0;
int state = 0;
int number = 0;

int dValue[] =
{2,4,6,8,10,12,20};

long result;
long resultA;
long resultB;


void setup()
{
  pinMode(Tilt, INPUT);
  pinMode(mButton, INPUT);
  pinMode(nButton, INPUT);
  
  randomSeed(analogRead(0));
}

void loop()
{
  mode = digitalRead(mButton);
  if ((mode == HIGH) && (oldMode == LOW))
  {
    state++;
  }
  if (state > 6)
  {
    state = 0;
    delay(10);
  }
  oldMode = mode;
  {
    number = digitalRead(nButton);
    switch(number)
    {
      case 0:
      {
        {
          lcd.begin(16,2);
          lcd.print("DigiDice - D");
          lcd.print(dValue[state]);
        }
        val = digitalRead(Tilt);
        if ((val == HIGH) && (oldVal == LOW))
        {
          result = random(1, dValue[state] + 1);
          lcd.setCursor(0, 1);
          lcd.print("Result = ");
          lcd.print(result);
          lcd.print("       ");
          delay(3000);
        } else
        {
          lcd.setCursor(0, 1);
          lcd.print("Give Me A Shake!");
        }
      }
      break;
      case 1:
      {
        {
          lcd.begin(16,2);
          lcd.print("Roll Two - D");
          lcd.print(dValue[state]);
        }
        val = digitalRead(Tilt);
        if ((val == HIGH) && (oldVal == LOW))
          {
            resultA = random(1, dValue[state] + 1);
            resultB = random(1, dValue[state] + 1);
            lcd.setCursor(0,1);
            lcd.print("R1 = ");
            lcd.print(resultA);
            lcd.print("   R2 = ");
            lcd.print(resultB);
            lcd.print("     ");
            delay(3000);
          } else
          {
            lcd.setCursor(0, 1);
            lcd.print("C'mon...Shake Me!!");
          }
        }
        break;
      }
    }
}

I seem to be off on my curly brackets somewhere, because my indenting is messed up a bit, but I will fix that when I have the whole code in working order.

off to keep researching, but will be happy to hear any suggestions to stabilize my display smiley

ETA:  I should mention that when you shake the "dice", the display does stabilize, and very clearly prints everything it is supposed to.
This makes me think I should have the mode selecting code in both cases, like the Tilt code, and maybe that will work it out.
seems very redundant to me, but this is how we learn smiley-wink

Again, very happy to take suggestion improvements and general criticism on the project!
be brutal if need be smiley
« Last Edit: January 14, 2013, 07:38:44 am by Neight » Logged

absence of proof is not proof of absence

Queens, New York
Offline Offline
Faraday Member
**
Karma: 86
Posts: 3459
"Of all the things I've ever lost, I miss my mind the most" -Ozzy Osbourne
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't think your lcd.print("     "); is long enough to clear the entire line in case 1, try to make it longer and see if that works.
Logged

Created Libraries:
NPV2 (NewPasswordV2),  TFT_Extension, OneWireKeypad, SerialServo.
Will provide libraries if asked in PM or forum.

Ohio USA
Offline Offline
Jr. Member
**
Karma: 1
Posts: 57
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

actually, I might not even need the "    " anymore.
that was there to clear the rest of the line earlier on.

I did fix the flicker problem after all.
at some point I must have deleted the line of code that initializes the screen size and positions
(lcd.begin(16,2))
without that, it was writing the data over and over on the whole screen.  The only reason text was visible at all is because of the repetitiveness of the message...

Now that I have put the initialization code back in the setup, it works like a charm, and is quite beautiful if you ask me smiley-razz

May not be the most efficient way to do it ( I am assuming it isn't anyway)  but it works perfectly, and I quite enjoy it.
Now to add some effects to make it a bit more fun to watch.
trying to figure out some simple animation to represent the dice rolling for a moment before displaying the results.

Even had an idea to mount this in a project box, and make a small box inside the project box that would hold an actual dice.  That way, when you shake the dice roller, there is a real dice rolling sound to go along with the shaking smiley  (kind of like the sound when you shake dice in a cup while playing yatzee.  Matter of fact, this kind of makes me want to make a whole new code specifically to handle dice rolling for yatzee.  building the new one around a full set of yatzee dice, and being able to roll them all at once, just like in the real game.

which makes me wonder how hard it would be to write code to play actual yatzee on the arduino would be....
good lord, I am getting ahead of myself here (to be honest, I have never played yatzee, so I don't know all the rules, but I know the game is structured around dice, so it has my brain spinning)

Logged

absence of proof is not proof of absence

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12577
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Rather than adding physical dice, you might continue the Arduino theme and see whether you can make your Arduino output the sound of dice rolling in a cup.

You might also add an accelerometer/tilt switch so that it makes the 'rolling' sound when you shake it, and rolls the dice when you put it down.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Ohio USA
Offline Offline
Jr. Member
**
Karma: 1
Posts: 57
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Rather than adding physical dice, you might continue the Arduino theme and see whether you can make your Arduino output the sound of dice rolling in a cup.

You might also add an accelerometer/tilt switch so that it makes the 'rolling' sound when you shake it, and rolls the dice when you put it down.

sounds like another shopping trip to me smiley-razz

First thoughts on that would be a music shield, or build my own, with an mp3 on an SD card of a dice rolling sound.

I have been wanting to pick up an accelerometer and play with it, and this is as good an excuse as any!

Great ideas BTW, and thanks for the suggestions.  It would keep the project that much more compact not having to build a chamber large enough for a die to roll around in.

I also like the shake then put down to roll idea quite a bit.  Anything to increase the sensation of rolling dice would be a good thing in my opinion.
thinking about an enclosure for this one, and making something permanent out of it.  It's been a struggle, and it would make a fun souvenir when I get it all done.  Could even have two larger modes, one for d2 - d20 for strategy gaming, and one that is just a set of multiple six sided dice for yatzee style, so you can roll both ways if you choose.
Lots of expansion could be done on this project, and this could really be a neat addition to any game where dice are involved smiley
Heck, I might even try for a third option, and come up with my own dice based game that could be played with two (or more?) players, and could be played all on the arduino with no external game mechanics involved.
Wonder how long it would take me to find the limits of the arduino with a dice rolling project?...
Logged

absence of proof is not proof of absence

Ohio USA
Offline Offline
Jr. Member
**
Karma: 1
Posts: 57
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

guess I am not doing as well as I hoped...

Tried rearranging the code to take out some elements I thought were redundant (like having the mode select code in both cases.)
now, the dice values displayed are not right again.
The roll results are still good, and the rate they cycle through the dice modes when you push the button is still correct also.
now, when you turn it on, it shows you are in D2 mode, which is correct, from there it goes through D4, D6, D8, D10, D12, then D20 which is also right. 
Here is where it gets odd.
it hangs on 20 for two pushes, then goes to 40, 60, 80, 10, 12, 20, 20, 40, 60.... on like that.
after the first time though, it starts displaying the modes in tens, instead of single and double digits.
on the second pass, the dice modes are still right, but the name for them is wrong.
once again, I cannot see where the code is making the error, so without further ado...

Code:
#include <LiquidCrystal.h>

LiquidCrystal lcd(2,3,4,5,6,7);

const int nButton = 11;
const int mButton = 9;
int mode = 0;
int oldMode = 0;
const int Tilt = 8;
int val = 0;
int oldVal = 0;
int state = 0;
int number = 0;


int dValue[] =
{2,4,6,8,10,12,20};

long result;
long resultA;
long resultB;


void setup()
{
  pinMode(Tilt, INPUT);
  pinMode(mButton, INPUT);
  pinMode(nButton, INPUT);
 
  lcd.begin(16,2);
 
  randomSeed(analogRead(0));
}

void loop()
{
  {
    mode = digitalRead(mButton);
    if ((mode == HIGH) && (oldMode == LOW))
    {
      state++;
    }
    if (state >= 7)
    {
      state = 0;
      delay(10);
    } oldMode = mode;
  }
  {
    number = digitalRead(nButton);
    switch(number)
    {
      case 0:
      {
        {
          lcd.setCursor(0,0);
          lcd.print("DigiDice - D");
          lcd.print(dValue[state]);
        }
        val = digitalRead(Tilt);
        if ((val == HIGH) && (oldVal == LOW))
        {
          result = random(1, (dValue[state] + 1));
          lcd.setCursor(0, 1);
          lcd.print("Result = ");
          lcd.print(result);
          lcd.print("       ");
          delay(3000);
        } else
        {
          lcd.setCursor(0, 1);
          lcd.print("Give Me A Shake!");
        }
      }
      break;
   
      case 1:
      {
        {
          lcd.setCursor(0,0);
          lcd.print("Roll Two - D");
          lcd.print(dValue[state]);
        }
        val = digitalRead(Tilt);
        if ((val == HIGH) && (oldVal == LOW))
        {
          resultA = random(1, (dValue[state] + 1));
          resultB = random(1, (dValue[state] + 1));
          lcd.setCursor(0,1);
          lcd.print("R1 = ");
          lcd.print(resultA);
          lcd.print("   R2 = ");
          lcd.print(resultB);
          lcd.print("     ");
          delay(3000);
        } else
        {
          lcd.setCursor(0, 1);
          lcd.print("C'mon...Shake Me!!");
        }
      }
      break;
    }
  }
}

This is where I have it at now.
The mode select part of the code seems to be working right, and I have wrote it several different ways, to test it. 
The code to show the dice value isn't something I changed, and it went from working fine to not.  Don't know what happened.
any help would be awesome.
it is possible I just need fresh eyes on it, and the problem is fairly obvious, but for right now, I am stumped.
Logged

absence of proof is not proof of absence

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12577
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thinking about an enclosure for this one, and making something permanent out of it.  It's been a struggle, and it would make a fun souvenir when I get it all done.

Have you considered using a cup of some sort as the enclosure? Perhaps with the display in the base so that you shake it, put it down upside down, and see the rolled values displayed in the base? Just make sure nobody tries to drink out of it. smiley
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Ohio USA
Offline Offline
Jr. Member
**
Karma: 1
Posts: 57
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thinking about an enclosure for this one, and making something permanent out of it.  It's been a struggle, and it would make a fun souvenir when I get it all done.

Have you considered using a cup of some sort as the enclosure? Perhaps with the display in the base so that you shake it, put it down upside down, and see the rolled values displayed in the base? Just make sure nobody tries to drink out of it. smiley


Man, you are full of great ideas!
I have been looking into 3D printers lately, and could even design and print something that could fit the hardware and battery in nice and secure.
very cool, I really did hope this project would turn into something fun and long term, that I could actually use.  I really liked the idea, and its only getting better as I move on!
Logged

absence of proof is not proof of absence

Corinth, TX
Offline Offline
Jr. Member
**
Karma: 1
Posts: 92
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

it hangs on 20 for two pushes, then goes to 40, 60, 80, 10, 12, 20, 20, 40, 60.... on like that.
after the first time though, it starts displaying the modes in tens, instead of single and double digits.
This one I know smiley

What's happening is you're overwriting the two digit number with a one digit number... with nothing to write in the second digit, the LCD continues to display what was already there.  Try using sprintf to format your number.  That should get rid of the unwanted 0
Logged

Ohio USA
Offline Offline
Jr. Member
**
Karma: 1
Posts: 57
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

it hangs on 20 for two pushes, then goes to 40, 60, 80, 10, 12, 20, 20, 40, 60.... on like that.
after the first time though, it starts displaying the modes in tens, instead of single and double digits.
This one I know smiley

What's happening is you're overwriting the two digit number with a one digit number... with nothing to write in the second digit, the LCD continues to display what was already there.  Try using sprintf to format your number.  That should get rid of the unwanted 0

HA!  you were right smiley-grin
I should have seen that, it wasn't the first time I ran into that problem, but last time it was much more obvious, I had a whole word that never left the screen.
I took the easy way out for a fix though, I just added a couple of spaces next to the result so it turns off the couple of spaces after every number.

Not sure why that started all of a sudden, but it's fixed now, and I probably just accidentally deleted something when I was rearranging the code...

Thank you so much for pointing out my error!

Now to start having fun with the display, make it a little more showy smiley
Logged

absence of proof is not proof of absence

Pages: 1 2 [3]   Go Up
Jump to: