Another Chinese Digital Caliper

Hello all,

First of all thanks for the help i have found on this forum, its a great source of info.

Secondly i thought i would share my code to read my chinese digital verneer caliper. I have found lots of examples out there, but couldn't see a complete code for this type. Also i dont claim for one minute that i have (or could) write this code from scratch - it is more of a combination of lots of other peoples code as found on the net.

If anyone has advice of code improvement please let me know.

The caliper is the type that sends a single 24bit word of the structure described here -

I boutght mine from Chronos in the UK.

I hope this is of use to people.

Next i would like to expand it to read multiple calipers. I'm told that its possible to enable more than the standar 2 interrupts on a uno..... i'll put my investigating hat on.

Thanks again.

// code by mbconfuse 29/05/11

#include <avr/interrupt.h>

volatile int bumper;  
int clockPin = 2; 
int dataPin = 4;
int counter = 0;
const int numberBits = 24;
int data[numberBits];
int usedData[numberBits];
int decimalVal = 0;
int oldDecimalVal = 0;
int passedSync=0;

void setup()
{
  Serial.begin(9600); 
  pinMode(clockPin, INPUT);
  pinMode(dataPin, INPUT);
  attachInterrupt(0, bumperISR, FALLING);
  interrupts();
  bumper = 0;
}

void bumperISR()
{
char sample = 0;			  
  if(digitalRead(clockPin) == LOW)    sample++;
  if(digitalRead(clockPin) == LOW)    sample++;
  if(digitalRead(clockPin) == LOW)    sample++;
  if(sample > 2)			  
    bumper = 1;       
}

void loop()
{

// make sure loop starts at the begining of the data set
syncronization();

//start that data conversion
  if (bumper == 1 && passedSync ==1)
   {
    //sample the reading 3 times 	  
    data[counter] = sampleData (digitalRead(dataPin), 1);    
    
    bumper = 0;	
    counter++;
    
    if(counter >=numberBits)
    {
     // tick the syncronisatoin button
     passedSync = 1; 
     counter =0;
     //reverse the order of the binary bits
     reverseData();
     //printBinary();
     //convert the binary to decimal
     binaryToDecimal(usedData, numberBits);
    }	 
  } 
}

// convert a binary string to a decimal number, returns decimal value
void binaryToDecimal(int TheArray[], int numBits)
{
int b, k, m, n;
int len; 
//start bit and end bit are chosen to chop out the unwanted bits
int startBit = 3;
int endBit = 22;

  len = numBits;
  for(k = startBit; k <= endBit; k++)
  {
    n = TheArray[k];
    if ((n > 1) || (n < 0))
    {
      Serial.println("non_binary number!!");
    }
    for(b = 1, m = endBit; m > k; m--)  
    {
      // 1 2 4 8 16 32 64 ... place-values, reversed here
      b *= 2;  //same as b = b * 2
    }
    decimalVal = decimalVal + n * b;
   }
     
     //only print if the decimal value has changed
     if (decimalVal != oldDecimalVal)
     {
     Serial.print("Decimal =");
     // the 3rd bit is the positive/negative bit.  if it is 1 then value is negative.
     if(TheArray[2] == 1)
     {
      Serial.print(" -"); 
     }   
     Serial.println(decimalVal);
     
     oldDecimalVal = decimalVal;
     }
         
     decimalVal = 0;
     
}

//sample data three times
int sampleData(int readData, int highLow)
{
char sample = 0;			  
  if(readData == highLow)    sample++;
  if(readData == highLow)    sample++;
  if(readData == highLow)    sample++;
  if(sample > 2) 
  {
    return(highLow);
  }
  else return((1-highLow));			        
}

//reverse all the binary bits
void reverseData()
{
     int k=0;
     for(int j = (numberBits-1) ; j >= 0; j--)            
     {
       usedData[k] = data[j];
       k++;           
     }
}

//print the binary
void printBinary()
{
        for (int i = 0 ; i < numberBits; i++)
         {
           Serial.print(usedData[i]);;
         }
       Serial.println(""); 
}

//sync so we start at the begining of a data set
//320 is approx lenght of gap between data sets
void syncronization()
{
      if(bumper == 1 && passedSync == 0)
    {
      int time; 
       do
      {
        time = pulseIn(clockPin, HIGH);
      } while(time <  320);
           passedSync = 1;
           Serial.print("time - ");
           Serial.println(time);
           delay (320);
           bumper =0;
    }
}

I'm told that its possible to enable more than the standar 2 interrupts on a uno

Yes it's called the pin change interrupt and an example of using it is in this project of mine.
http://www.thebox.myzen.co.uk/Hardware/Crazy_People.html

Thanks GrumpyMike, ive had a look at the page and i'll check out your code. Nice project. I had a shufti through some of your other bits and found your cnc mill video, which linked me on to your maker fair 2011 vid - amazing how many of my boxes that show ticked! Something for everyone there. It made me think of RepRap - RepRap, have you come across it?