Camshafts Mesurements Project

Hi !

I'm on a new project which consists in mesuring and loging cams diameters with a machine I developed.
I have :

  • Brushless motor with gearhead (1:100 ratio) and a controller (speed controled with potentiometer)
  • Absolute digimatic indicator from Mitutoyo
  • Incremental encoder (1000p/rev)
  • Arduino Mega 2650 Rev 3

Here's my Arduino Code :

int req = 13; //mic REQ line goes to pin 5 through q1 (arduino high pulls request line low)
int dat = 12; //mic Data line goes to pin 2
int clk = 11; //mic Clock line goes to pin 3
int INTVR = 52; // Internal potentiometer
int ALARM_RESET = 50;
int RUN = 48;
int START = 46;
volatile int i = 0; int j = 0; int k = 0;
volatile boolean go = false;

float mm;

int cmdByte;
byte mydata[14];

void setup()
{
  pinMode(INTVR, OUTPUT);
  pinMode(ALARM_RESET, OUTPUT);
  pinMode(RUN, OUTPUT);
  pinMode(START, OUTPUT);
  digitalWrite(RUN, HIGH);
  Serial.begin(19200);
  pinMode(req, OUTPUT);
  pinMode(clk, INPUT);
  pinMode(dat, INPUT);
  attachInterrupt(0, pulse, RISING);
  digitalWrite(clk, HIGH); // enable internal pull ups
  digitalWrite(dat, HIGH); // enable internal pull ups
  digitalWrite(req, LOW); // set request at high
}

void loop()
{
  
  if ( go )
  {
    go = false;

    long num;  // data treatment
    char buf[9];
  
    for(int lp=0;lp<6;lp++)
      buf[lp]=mydata[lp+5]+'0';
    
    buf[6]=0;
    num=atol(buf);
  
    mm = (float)num/100;
  
    if (mydata[4] < 1)
      Serial.print("+");
    else
      Serial.print("-");
     
     Serial.println(mm);
  
     digitalWrite(req,LOW); // stops set request
  }
}

void pulse()
{
  digitalWrite(req, HIGH); // generate set request
  go = true;
  
  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))); // read data bits, and reverse order
    }

    mydata[i] = k; // data received into this array
  }
}

void serialEvent()
{
  cmdByte = Serial.read(); // receive command from USB interface

  if (cmdByte > 48){
    digitalWrite(RUN, LOW);
  }else{
    digitalWrite(RUN, HIGH);
  }
}

I have troubles due to the fact that I only get values when I stop my motor. It seems that the interrupts are much closer than I thought and I don't know how to handle it. How could I decrease the loop time (perhaps by sending data directly to my PC instead of making the Arduino work on that) ?

The motor is at its minimum speed ... (about 1 rpm with gearhead)

These two lines say...while this is true, stay on this line until it becomes false. The lines could cause large delays. You need to change them to "if" statements or something besides "while".

 while(digitalRead(clk) == LOW) { } // hold until clock is high
      while(digitalRead(clk) == HIGH) { } // hold until clock is low

Also you'll get an order of magnitude speed up in the interrupt routine if you replace digitalRead/Write with direct port manipulation.

Instead of waiting for data 1 bit at a time in the ISR, I think you would be better off using the hardware SPI port to read in the data.