Go Down

Topic: Reading a multiple digit number with Serial.read() (Read 3243 times) previous topic - next topic

chrisswartzell

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:");
 }
}



MeLight

#1
Mar 23, 2010, 07:27 am Last Edit: Mar 23, 2010, 08:38 am by MeLight Reason: 1
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 :D). 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 :D You can simply send your number as a byte :) 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.

John_Ryan

#2
Mar 23, 2010, 09:22 am Last Edit: Mar 23, 2010, 09:27 am by John_Ryan Reason: 1
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: [Select]

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
   }
 }


}

Go Up