Go Down

Topic: Mitutoyo Digimatic SPC (Read 13692 times) previous topic - next topic

GoForSmoke

#105
Dec 03, 2011, 02:52 am Last Edit: Dec 03, 2011, 02:58 am by GoForSmoke Reason: 1
Your code-internal units might be better suited to .0001 mm then, if you go with the more accurate/faster integers.

Internal units and displayed values can easily be different animals without screwing anything up.

Consider tool codes that have no decimals but always either (usually) leading or trailing zeros. Those machines use integers internally just because of speed and accuracy. They -show you- decimals but they don't -use- decimals.

Case in point ... your Mitutoyo caliper that reports separate significant digits and decimal position, it uses integers inside and 1.0 is always 1.0.

Which route do -you- want to go in your code? Floating-point or Integer? It will make a difference in the code and it's not a good idea to code first and decide later.

Edit: BTW, taking time to really think on this now will probably save you more time and frustration later. Don't make it a snap-decision, that's for know-nothing office managers and shop-monkeys.
Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

Steve Spence - KK4HFJ

fast is important. ignoring the decimal point and using a long sounds intriguing. since I'm not actually displaying the real measurement, just using it for calculations, it's probably the best way to go. I have a max of 6 digits (no negatives) I have to deal with coming from the micrometer.

I still have not been able to concatenate the 6 digits yet. that needs to come first. then dump the result into a variable, and I'm on my way.
Steve Spence - ET/AT/R&D KK4HFJ

AWOL

#107
Dec 03, 2011, 03:26 pm Last Edit: Dec 03, 2011, 05:18 pm by AWOL Reason: 1
Google "fixed-point " numbers, or even "binary coded decimal".
I wasn't being obtuse, I was trying to find out why you were willing to potentially lose precision when you didn't need to.
You never actually said what the application was.

Years ago, I wrote reconstruction software for computed tomography machines.
The maths involved logarithms, trig functions, FFTs and digital filters and interpolation.
All implemented in fixed point.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Steve Spence - KK4HFJ

I not only said what the application was. but I posted the data specification. You asked me If wanted to use some foreign language forum, and some other nonsense. I am being as clear about what my inputs are (a mitutoyo micrometer), and what I need out as possible.
Steve Spence - ET/AT/R&D KK4HFJ

wildbill

Quote
I still have not been able to concatenate the 6 digits yet. that needs to come first. then dump the result into a variable, and I'm on my way.

Code: [Select]

long num;
char buf[7];
buf[0]=v1;
buf[1]=v2;
buf[2]=v3;
buf[3]=v4;
buf[4]=v5;
buf[5]=v6;
buf[6]=0;
num=atol(buf);

Syntax checked, not tested

Steve Spence - KK4HFJ

I'll try that on tuesday when I get back to the shop.
Steve Spence - ET/AT/R&D KK4HFJ

wildbill

Don't. Try this instead:
Code: [Select]

long num;
char buf[7];
buf[0]=v1+'0';
buf[1]=v2+'0';
buf[2]=v3+'0';
buf[3]=v4+'0';
buf[4]=v5+'0';
buf[5]=v6+'0';
buf[6]=0;
num=atol(buf);

AWOL

Quote
I not only said what the application was. but I posted the data specification

Classic noob mistake - asking how you think something should be done, not what it is you want to do.
It took quite some time before I associated the data conversion problem posed in this thread
http://arduino.cc/forum/index.php/topic,81149.0.html
with the micrometer mentioned in
http://arduino.cc/forum/index.php/topic,79900.0.html


"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

giantsfan3

@Steve Spence:
For your reference, Page 2 of this document covers in visual detail the BCD format (in fact the whole document deals pretty much exactly with your project):
http://www.tinaja.com/glib/muse145.pdf

Steve Spence - KK4HFJ

That article is fatally flawed. I spoke with Don about it, and he's not interested in updating or fixing it.
Steve Spence - ET/AT/R&D KK4HFJ

GoForSmoke

Quote
On my calculator, .05035 in. x 25.4 = 1.27889 but on my mic, it equals 1.279 mm. That shouldn't matter to my program, but I could round up to 1.279 I suppose.


That's because 25.4 mm/in is only an approximation. But then, LOL, so is the measurement! What happens when you cut or grind and measure metal at one temperature and then later at another perhaps 15F different? If the object is small, it won't matter much but there are tolerances that can't be universally held.


fast is important. ignoring the decimal point and using a long sounds intriguing. since I'm not actually displaying the real measurement, just using it for calculations, it's probably the best way to go. I have a max of 6 digits (no negatives) I have to deal with coming from the micrometer.

I still have not been able to concatenate the 6 digits yet. that needs to come first. then dump the result into a variable, and I'm on my way.


If you want to go with the small units approach then it won't be so hard. D12 will be used to tell us how many zeros to tack on the end of the data digits.

Your accuracy being .001 mm I had suggested you going to units of .0001 because back when I took science courses we would be able to talk about weights and measures to within 1/2 a unit though IIRC that was in averaging and it has been almost 40 years so please forgive me if I am wrong. My belief is to go the extra digit so that the system/unit used can handle calculations made with the measures without hiccuping. But since YOU will be the person using it, YOU must make the choice! My way you _can_ do the math and round the results to the precision you can measure to every time.

Quote
0 001526 3 0


where 0 means +
001526 is the measurement
3 is the number of decimal places to the left
and 0 means mm


That would yield 1.526 but in my units, 15260.

Maybe this would work to put that data into 10th-micrometer units (# of .0001 mm's).

Code: [Select]

//  BCdigit[] is an array of binary coded decimal digits, BCdecPt is one BCD as decimal place
//  the output unit is ten-thousandths, check that what is fed in is mm outside this routine
//  take care that the BCdigit array is 6 bytes long.

unsigned long tenthMicroMeters( byte *BCdigit, byte BCdecPt ) {
  unsigned long retval = 0;
  for (byte i=0; i<6; i++) {
    retval *= 10UL;
    retval += unsigned long (BCdigit[i]);
  }
  for (i=0; i<BCdecPt+1; i++) {
    retval *= 10;
  }
}


I think that should do it but haven't tested. Remember the value is in tenths of micrometers and why.
Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

GoForSmoke



Sorry, the code in the last post --wrong--.
// make SURE measurement is always in mm and that BCdecPt is never more than 4
// (if mm then the mic should never return more than 3 decimal places, only inches should)


Code: [Select]

//  BCdigit[] is an array of binary coded decimal digits, BCdecPt is one BCD as decimal place
//  the output unit is ten-thousandths, check that what is fed in is mm outside this routine
//  take care that the BCdigit array is 6 bytes long.
// make SURE measurement is always in mm and that BCdecPt is never more than 4
// (if mm then the mic should never return more than 3 decimal places, only inches should)

unsigned long tenthMicroMeters( byte *BCdigit, byte BCdecPt ) {
  unsigned long retval = 0;
  for (byte i=0; i<6; i++) {
    retval *= 10UL;
    retval += unsigned long (BCdigit[i]);
  }
  for (i = 0; i < 4 - BCdecPt; i++) {
    retval *= 10;
  }
}


Still not tested but one error corrected!
Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

Steve Spence - KK4HFJ

I'll test that tomorrow when the office opens back up. Thanks. I had hoped to be able to adapt, no matter what the user has the mic set for, but throwing an error message on screen if the mic is set to inches would be acceptable.
Steve Spence - ET/AT/R&D KK4HFJ

GoForSmoke

Oh, finish to 1.0 before you go on to work on 2.0. The difference would be using 5 decimal places (the most) instead of 4 and of course a conditional block to go from mm to inch. But most of the code would be the same and only one or a few constants and label would change.
But get this much working and test time behind it to work out any bugs before making it any more complicated.

Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

Steve Spence - KK4HFJ

#119
Dec 06, 2011, 02:55 pm Last Edit: Dec 06, 2011, 03:01 pm by Steve Spence Reason: 1
wildbill, your concatenation code worked beautifully. I now have the actual measurement, ignoring decimal places, in a long variable called num. I have the sign, units, and number of decimal paces in another set of variables. If the units != 0, or the decimal places != 3, or sign != 0, I can throw an error message. I've decided to not allow inches input.

I don't need decimal places in my actual measurement, because my application just does calculations based on the measurement, and does not display the measurement itself. Thanks to AWOL and others for finally getting that through my thick head.

GoForSmoke, I believe this resolves my requirements.

Code: [Select]

int req = 5; //mic REQ line goes to pin 5 through q1 (arduino high pulls request line low)
int dat = 2; //mic Data line goes to pin 2
int clk = 3; //mic Clock line goes to pin 3
int i = 0; int j = 0; int k = 0;
int sign = 0;
int decimal;
int units;
int error = 0;
int v1;
int v2;
int v3;
int v4;
int v5;
int v6;

byte mydata[14];

void setup()
{
 Serial.begin(19200);
 pinMode(req, OUTPUT);
 pinMode(clk, INPUT);
 pinMode(dat, INPUT);
 digitalWrite(clk, HIGH); // enable internal pull ups
 digitalWrite(dat, HIGH); // enable internal pull ups
 digitalWrite(req,LOW); // set request at high
}



void loop()
{   digitalWrite(req, HIGH); // generate set request
   for( i = 0; i < 13; i++ ) {
     k = 0;
     for (j = 0; j < 4; j++) {
     while( digitalRead(clk) == LOW) { } // hold until clock is high
     while( digitalRead(clk) == HIGH) { } // hold until clock is low
       bitWrite(k, j, (digitalRead(dat) & 0x1)); // read data bits, and reverse order )
     }

     mydata[i] = k;
     sign = mydata[4];
     v1= mydata[5];
     v2= mydata[6];
     v3= mydata[7];
     v4= mydata[8];
     v5= mydata[9];
     v6= mydata[10];  
     decimal = mydata[11];
     units = mydata[12];
         
         
   }
long num;
char buf[7];
buf[0]=v1+'0';
buf[1]=v2+'0';
buf[2]=v3+'0';
buf[3]=v4+'0';
buf[4]=v5+'0';
buf[5]=v6+'0';
buf[6]=0;
num=atol(buf);

if (units != 0) error=1;
if (sign != 0) error=2;
if (decimal != 3) error=3;



if (error != 0)
{
 Serial.print ("error ");
 Serial.println (error);
}
else
{
 Serial.println(num);
}


   digitalWrite(req,LOW);
   error=0;
   delay(100);
}


Steve Spence - ET/AT/R&D KK4HFJ

Go Up