intro  mechanical  electrical  software  parts  results  team

software

complete code listing:  geld.c

coin counting
Our coin sorter has a very unique way of deterring total coin value. This calculation is performed by counting the total number of coins to enter each level and subtracting a level from the previous one to generate the count for the previous level. The levels are numbered 0 to 3 where 0 is the highest level and 3 is the lowest level. The following code produces our coin counts:

quarters = sensorCount[0] - sensorCount[1];
nickels = sensorCount[1] - sensorCount[2];
pennies = sensorCount[2] - sensorCount[3];
dimes = sensorCount[3];  
sortTotal = (float)quarters*.25 + (float)dimes*.1 +
            (float)nickels*.05 + (float)pennies*.01;
  

state system
The coin sorter code can be thought of as a complex state machine. Pressing keys on the keypad move the software into different states. By keeping track of the state globally, any running process can check to see how it should behave in the current state or move the machine into a different state. For example, the numeric keys are only functional in the INPUT state.

#define READY 0
#define SORTING 1
#define GAMING 2
#define INPUT 3
#define INPUTDONE 4
#define CREDITS 5
  

keypad
Our matrix-encoded keypad is controlled by the Handyboard by individually activating each row and checking which column is active. This process can be done in hardware by using a keypad encoder chip, but is pretty simple to handle in software. Specifically, the code activates a row, produces a 4-bit binary representation of the active columns, verifies that only one key is pressed, and calls the key handler function with the row and column of the pressed key. The keypad controller function is listed below:

void keypadLoop()
{
  int row,prevRow,col,keypadOut;
  
  for (row = 0; row < 4; row++)
    digital_out(row,TRUE);

  prevRow = 3;
  row = 0;

  while (1) {
    digital_out(prevRow,TRUE);
    digital_out(row,FALSE);
    
    keypadOut = digital(14);
    keypadOut = (keypadOut << 1) + digital(13);
    keypadOut = (keypadOut << 1) + digital(12);
    keypadOut = (keypadOut << 1) + digital(11);
    
    if (keypadOut == 1)
      getKey(row,0);
    else if (keypadOut == 2)
      getKey(row,1);
    else if (keypadOut == 4)
      getKey(row,2);
    else if (keypadOut == 8)
      getKey(row,3);

    prevRow = row;
    row = (row+1)%4; 
  }
}
  

numeric input
The game that is included with the sorter requires input numeric input from the user. This is accomplished by first putting the system into state and keeping track of the keypad values that have been entered. The value is calculated by multiplying the current value by 10 and adding the new value. If a decimal is entered then the code also keeps track of an exponential multiplier and uses it in the end to determine the floating point value. The two functions that achieve this actually run in two separate processes, and have to monitor the machine state to determine what to do.

float getInput(int currentState)
{
  float val;
  inputVal = 0;
  inputExp = 0;
  decimalMode = FALSE;
  systemState = INPUT;
  
  while (systemState != INPUTDONE);
  if (inputExp < 0)
    val = (float)inputVal * exp10((float)inputExp);
  else
    val = (float)inputVal;
  printf("\n");
  systemState = currentState;
  return val;
}

void storeInput(int val)
{
  if (val != -1) {
    inputVal = 10*inputVal + val;
    if (decimalMode)
      inputExp--;
    printf("%d",val);
  }
  else if (!decimalMode) {
    /* val == -1 -> decimal point*/
    decimalMode = TRUE;
    printf(".");
  }
}
  

sensors
The sensor checking code is crucial so that we can guarantee an accurate coin count. The key feature of this code snippet is that as soon as a sensor detects something blocking it, the sensor moves into a BLOCKED state and increments its counter. Until the sensor is unblocked and moved into the UNBLOCKED state, the counter cannot become BLOCKED again and increment.

void sensorScan()
{
  int i;
  for (i=0; i < 4; i++) {
    sensorState[i] = UNBLOCKED;
    sensorCount[i] = 0;
  }
  while(systemState == SORTING) {
    for (i=0; i < 4; i++) {
      checkSensor(i);
    }
  }
}

void checkSensor(int s)
{
  if (digital(s+7)) {
    if (sensorState[s] == UNBLOCKED) {
      sensorState[s] = BLOCKED;
      sensorCount[s]++;
      displayTotal();
    }
  }
  else 
    sensorState[s] = UNBLOCKED;
}