Pages: [1]   Go Down
Author Topic: Reading a multiple digit number with Serial.read()  (Read 3086 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 1
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am very new to the arduino world and am struggling to recover that one high school programing class I took 8 years ago.

I'm trying to write a program to help roll dice for a tabletop game named 'shadowrun' and then display the results on some LED's. It is supposed to read the number of dice the user is supposed to roll and then roll that many six sided die. The program works great for single digit numbers, but when I enter 11, for instance, it rolls two sets of one dice each. or for 13 it rolls one dice then a set of three.

The program does some extra stuff specific to 'shadowrun' rules which you can ignore. If someone has an easy solution or just wants to provide some handy tips on my code let me know. My only request is to keep it simple I'm still pretty green.

Here is my code

int diecount = 0;
int hitcount = 0;
int glitchcount = 0;
int dienumber = 0;

void setup ()
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(7,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(4,OUTPUT);
  randomSeed(analogRead(0));
  Serial.println("Number of dice:");
}

void loop ()
{
  if(Serial.available() > 0)
  {
    int pin = 13;
    for(int i = 0; i < 9; i++)
    {
      digitalWrite(pin, LOW);
      pin--;
    }
    diecount = Serial.read() - '0';
    for(int i = 0; i < diecount; i++)
    {
      dienumber = random(1,7);
      Serial.println(dienumber);
      if(dienumber >= 5)
      {
        hitcount++;
      }
      if(dienumber <= 1)
      {
        glitchcount++;
      }    
    }
    Serial.println("-----------------------");
    Serial.print("Hits: ");
    Serial.println(hitcount);
    Serial.print("Glitches: ");
    Serial.println(glitchcount);
    Serial.println("~~~~~~~~~~~~~~~~~~~~~~~~");
    pin = 13;
    for(int i = 0; i < hitcount; i++)
    {
      digitalWrite(pin, HIGH);
      pin--;
      delay(200);
    }
    if(glitchcount > hitcount)
    {
      digitalWrite(5, HIGH);    
    }
    hitcount = 0;
    glitchcount = 0;
    Serial.println("Number of dice:");
  }
}


Logged

The Holy Land
Offline Offline
Jr. Member
**
Karma: 1
Posts: 60
Arduino stones
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The easy "on-the-spot" solution would be to always send two digits instead of one. So you will always read two digits, if it's a one digit number, send 0 and the number.

For example for 13 you will 1 and 3
for 8 you will send 0 and 8

That solution won't scale well though (if you want to roll a dice of 6 digit numbers smiley-grin). So you might use some kind of terminator character at the end of each number, which will tell you that the number is complete.

edit: me - dumb*ss smiley-grin You can simply send your number as a byte smiley that way you can have up to 255 dice at once. I don't know which language you are using on the computer end so can't really help you there, but when you read the number don't subtract the '0' char and what you'll receive will be the byte you have sent.
« Last Edit: March 23, 2010, 02:38:50 am by MeLight » Logged

0
Offline Offline
God Member
*****
Karma: 0
Posts: 731
skcor oniudrA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This code uses a handshake method. Start and stop characters are used, so the serial will start reading when it gets chr(10), and it stop's reading when it gets chr(13). Whatever is in between you add together using "code[bytesread] = val;"

You should be able to adapt this to suit your needs, otherwise there's plenty of other material around the forums for doing the same job.

Code:
void checkSerial() {
  if(Serial.available() > 0) {                  // if data available
    if((val = Serial.read()) == 10) {   // check for header start
      bytesread = 0;
      while(bytesread<1) {              // read 1 digit code
        if( Serial.available() > 0) {
          val = Serial.read();
          if(val == 13) { // check for header end
            break;                            // stop reading
          }
          code[bytesread] = val;         // add the digit
          bytesread++;                   // ready to read next digit
        }
      }
      if(bytesread == 1) {                 // if 1 digit read is complete
        incomingByte = int(code[0]);
        doSomething();
      }
      bytesread = 0;
      delay(50);                             // wait for a second
    }
  }


}
« Last Edit: March 23, 2010, 03:27:15 am by John_Ryan » Logged

Pages: [1]   Go Up
Jump to: