Go Down

Topic: Camshafts Mesurements Project (Read 2666 times) previous topic - next topic

Ervann

Sep 04, 2012, 09:38 am Last Edit: Sep 04, 2012, 09:43 am by Ervann Reason: 1
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 :

Code: [Select]

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)

cyclegadget


  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".

Code: [Select]
while(digitalRead(clk) == LOW) { } // hold until clock is high
      while(digitalRead(clk) == HIGH) { } // hold until clock is low
Good links: Eagle tutorial= http://www.youtube.com/playlist?list=PLDE1858BD83D19C70
General Arduion tutorials = http://tronixstuff.wordpress.com
http://www.gammon.com.au/forum/bbshowpost.php?bbtopic_id=123

MarkT

Also you'll get an order of magnitude speed up in the interrupt routine if you replace digitalRead/Write with direct port manipulation.
[ I won't respond to messages, use the forum please ]

dc42

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.
Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Go Up