Go Down

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

sspence65

Nov 16, 2011, 03:35 pm Last Edit: Nov 16, 2011, 03:51 pm by Steve Spence Reason: 1
Trying to get my Mitutoyo Micrometer to talk to my Mega 2560. Have verified with mitutoyo that cabling and interfacing is correct, so apparently it's a software issue.

I've documented the code, schematic, etc. at http://arduinotronics.blogspot.com/2011/10/digimatic-spc-to-arduino.html and am in desperate need of some help.

Grumpy_Mike seems to have some experience with this sort of thing, but it's different than the other project he worked on. Mike, hopefully you see this, and have interest.
Steve Spence - KK4HFJ

Grumpy_Mike

Quote
Have verified with mitutoyo that cabling and interfacing is correct,

How have you done that?

From the look of your schematic you appear to have the ready signal missing.
Also are you sure you have identified the configuration of the pin layout correctly, your diagram is at odds with the diagram in the Muse document.

Do you have an oscilloscope or a meter?

sspence65

#2
Nov 16, 2011, 08:23 pm Last Edit: Nov 18, 2011, 02:59 pm by Steve Spence Reason: 1
I listed the correct wiring diagrams direct from Mitutoyo. I've been in touch with one of their engineers, got the real schematic from them, and verified it with my meter. The Muse document is wrong, and I spoke to Don about that. He's not interested in revisiting the subject or correcting it. The ready signal is a switch (connects to ground) on the data cable for the operator to manually tell the computer to send a request for data. We are reading a constant stream of data, so we just send the request signal automatically in code.

I have a cheap Chinese 10mhz scope, and a half way decent meter. I loaded the blink sketch (modified for pin 5) to verify I can send a waveform to the request line. I have not been able to see the output of the "real" sketch.

Please see attachment for Mitutoyo's cable pinouts. I verified these with my meter.
Steve Spence - KK4HFJ

Grumpy_Mike

OK, it's hard to tell without the actual hardware but the first error I spotted is that you should have:-
Code: [Select]
volatile int i = 0;
As this variable is used in an interrupt service routine.
See if that improves things. If not keep it in, you still need it.

sspence65

#4
Nov 17, 2011, 04:33 pm Last Edit: Nov 17, 2011, 09:18 pm by Steve Spence Reason: 1
Ok. That did not make a difference. I was not understanding what volatile does, so I looked it up at http://www.arduino.cc/en/Reference/Volatile. Now it makes sense. Thanks for that. Sketch now reads:

Quote

int req = 5; //caliper REQ line goes to pin 5
int dat = 2; //caliper Data line goes to pin 2
int clk = 3; //caliper Clock line goes to pin 3
int iclk = 1; //pin 3 corresponds to interrupt number 1
volatile int i = 0; int j = 0; int k = 0; int n = 0;

int mydata[52];

void setup()
{
 Serial.begin(19200);
 pinMode(req, OUTPUT);
 pinMode(clk, INPUT);
 pinMode(dat, INPUT);
}

void loop()
{
 if (n == 0) attachInterrupt(iclk, myisr, RISING);
   PORTD |= (1<<5); // digitalWrite(req, HIGH);
   delay(10);
   PORTD &= ~(1<<5); // digitalWrite(req, LOW);
   if (i > 51)
   {
     for (j = 0; j < 13; j++)
     {
       Serial.print("--");
       for (k = 0; k < 4; k++)
       {
         Serial.print(mydata[(j*4)+k]);
       }
     }
   i = 0;
   }
}

void myisr()
{
 if (i == 0) PORTD |= (1<<5); //digitalWrite(req, HIGH);
 if(i < 52)
 {
   mydata[j] = digitalRead(dat);
   i++;
 }
}

Steve Spence - KK4HFJ

wildbill

Something odd here:
Code: [Select]

void myisr()
{
  if (i == 0) PORTD |= (1<<5); //digitalWrite(req, HIGH);
  if(i < 52)
  {
    mydata[j] = digitalRead(dat);
    i++;
  }
}

You're working with i, but using j as the index into your array. Typo?

Grumpy_Mike

When posting code use the # icon not the quote.

Quote
You're working with i, but using j as the index into your array.

Good catch!  :)

Code: [Select]
if (n == 0) attachInterrupt(iclk, myisr, RISING);
As n never changes the this gets done each time round the loop. This statement should be in the setup() but without the if.

sspence65

#7
Nov 17, 2011, 08:19 pm Last Edit: Nov 17, 2011, 09:28 pm by Steve Spence Reason: 1
Pasting from the arduino IDE requires quote instead of code to maintain readability.

i is a loop to make sure each character in the data stream gets entered into the array (j). There are 52 characters in the data stream.

are you saying that "attachInterrupt(iclk, myisr, RISING);" should be in setup, without "if (n == 0) "?

If that is so, then myisr would only get called once, and I'd only get a single data packet. I want a data packet to be requested continually (after each packet has been collected and displayed).
Steve Spence - KK4HFJ

Grumpy_Mike

Sorry there are lots of things you don't understand:-
Quote
Pasting from the arduino IDE requires quote instead of code to maintain readability.

No pleas use the # icon to avoid the forum software corrupting the code. We don't ask much here but we do ask for this.

Quote
are you saying that "attachInterrupt(iclk, myisr, RISING);" should be in setup, without "if (n == 0) "?

Yes.
Quote
If that is so, then myisr would only get called once

No. That is an interrupt service routine it gets called every time there is a falling edge on pin 3.

There is no way to synchronise the changing variable j with the data you read. So you need to increment j in the interrupt service routine.

sspence65

ok, so I moved attachinterrupt to setup, but I'm confused as to how to increment j in the interrupt function, and what to remove from the loop.


Code: [Select]

int req = 5; //caliper REQ line goes to pin 5 through q1 (arduino high pulls request line low)
int dat = 2; //caliper Data line goes to pin 2
int clk = 3; //caliper Clock line goes to pin 3
int iclk = 1; //pin 3 corresponds to interrupt number 1
volatile int i = 0; int j = 0; int k = 0; int n = 0;

int mydata[52];

void setup()
{
  Serial.begin(19200);
  pinMode(req, OUTPUT);
  pinMode(clk, INPUT);
  pinMode(dat, INPUT);
  attachInterrupt(iclk, myisr, RISING);
}

void loop()
{
//  if (n == 0) attachInterrupt(iclk, myisr, RISING);
    PORTD |= (1<<5); // digitalWrite(req, HIGH);
    delay(10);
    PORTD &= ~(1<<5); // digitalWrite(req, LOW);
    if (i > 51)
    {
      for (j = 0; j < 13; j++)
      {
        Serial.print("--");
        for (k = 0; k < 4; k++)
        {
          Serial.print(mydata[(j*4)+k]);
        }
      }
    i = 0;
    }
}

void myisr()
{
  if (i == 0) PORTD |= (1<<5); //digitalWrite(req, HIGH);
  if(i < 52)
  {
    mydata[j] = digitalRead(dat);
    i++;
  }
}



Steve Spence - KK4HFJ

wildbill

From what I can see, you're trying to read 52 bits from your micrometer device. If that's the case, you're already counting bits received using i. That is the variable you should use to index into your array, not j.

sspence65

#11
Nov 18, 2011, 02:32 pm Last Edit: Nov 18, 2011, 03:00 pm by Steve Spence Reason: 1
excuse me if I'm just not getting it, but i is bit location in the stream (1-52), and j is the value of that position. I have to do a read for each incoming bit, and store it in the array.

D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13

are 4 bits each (LSB to MSB).

D1 = data type
D2-4 = Entry Number
D5 = Sign
D6-11 = numerical data
D12 = decimal place
D13 = units

but I'm not getting any data back at all, not even garbage.

Please see attached for Mitutoyo's communications spec.
Steve Spence - KK4HFJ

wildbill

Humour me and try using i - I suspect it'll at least move you on to the point where you may get some garbage.

sspence65

#13
Nov 18, 2011, 02:48 pm Last Edit: Nov 18, 2011, 03:20 pm by Steve Spence Reason: 1
I'm very willing to do so, but my sinus meds are interfering with my comprehension. Can you formulate that into actual code for me to swap in?

I'm reading http://arduino.cc/en/Reference/Array and I think I understand the point you are making. I've changed myisr to the following:

Code: [Select]
void myisr()
{
 if (i == 0) PORTD |= (1<<5); //digitalWrite(req, HIGH);
 if(i < 52)
 {
   mydata[i] = digitalRead(dat);
   i++;
 }
}


Still no output, however.
Steve Spence - KK4HFJ

Grumpy_Mike

One thing that is surprising is why you want to use an interrupt service routine in the first place. There should be no need.

Are you sure that the clock is being supplied by the micrometer and not that you have to supply the clock. It depends on if the micrometer is an SPI master.

Anyway have you checked that you are actually getting clocks. All the program needs to do is to look at clock line and when it sees the appropriate transition read the data bit and stores it in a variable.
You don't even need an array, you just shift the data bit into an int variable one bit at a time.

Go Up