Pages: [1]   Go Down
Author Topic: Trouble with attachinterrupts  (Read 1124 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am using this to sense when a magnet passes the hall effect sensors. They are both trying to do the same thing. The below code works:
Code:
const float kDistance = 0.063;
unsigned long timeStarted;

void setup() {
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  Serial.begin(9600);
  timeStarted = 0;
 
 
}

void loop() {
  // put your main code here, to run repeatedly:
  if (!digitalRead(2) && !timeStarted)
  {
   timeStarted = millis();
   Serial.println("Start time");
   
  }
  if (!digitalRead(3) && timeStarted)
  {
  float deltaTime = (millis()-timeStarted)/1000.0;
  float velocity = kDistance/deltaTime;
  Serial.print("Velocity = ");
  Serial.println(velocity, DEC);
  Serial.print("Time = ");
  Serial.println(deltaTime, DEC);
  timeStarted = 0;
  Serial.println("End time");

  }

}

However this code does not - It is using attachinterrupts which would work much better, especially if I added more to my code and made it more complex.
Code:
const float kDistance = 0.063;
unsigned long timeStarted;

void setup() {
  timeStarted = 0;
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  digitalWrite (2, HIGH);
  digitalWrite (3, HIGH);
  attachInterrupt(0, startTime, FALLING);
  attachInterrupt(1, endTime, FALLING);
  Serial.begin(9600);
 
 
 
}

void loop() {

}

void startTime()
{
  Serial.println("Start time");
  if (!timeStarted)
  {
    timeStarted = millis();
  }

}
void endTime()
{
  Serial.println("End time");
  if (timeStarted)
  {
  float deltaTime = (millis()-timeStarted)/1000.0;
  float velocity = kDistance/deltaTime;
  Serial.print("Velocity = ");
  Serial.println(velocity, DEC);
  Serial.print("Time = ");
  Serial.println(deltaTime, DEC);
  timeStarted = 0;
  }
  else
  {
   Serial.println("Testing Error!");
  }
 
 
}

Thanks in advance!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If I remember correctly you cant make calls to Serial from within an interrupt. I would remove them from your interrupt functions.
Logged

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17262
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If I remember correctly you cant make calls to Serial from within an interrupt. I would remove them from your interrupt functions.

That's correct, all further interrupts are disabled once you are inside a ISR function so anything that requires the active use on interrupts (like serial) will just hang inside the ISR. The general rule for writing good effective ISR functions is to keep it simple, just do the bare minimum needed to be done, increment a variable, set a flag, save a value, etc, and do all the heavy lifting in the main loop by testing such flags, or variables to actually do stuff.

Lefty
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks, now I have another problem.
When either interrupt triggers both timeStarted and timeEnded are the same...

Code:
const float kDistance = 0.063;
unsigned long timeStarted = 0;
unsigned long timeEnded = 0;


void setup() {
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  digitalWrite (2, HIGH);
  digitalWrite (3, HIGH);
  attachInterrupt(0, startTime, FALLING);
  attachInterrupt(1, endTime, FALLING);
  Serial.begin(9600);
 
 
 
}

void loop() {
  if (timeStarted && timeEnded)
  {
//  float deltaTime = (timeEnded-timeStarted)/1000.0;
//  float velocity = kDistance/deltaTime;
//  Serial.print("Velocity = ");
//  Serial.println(velocity, DEC);
//  Serial.print("Time = ");
//  Serial.println(deltaTime, DEC);
  Serial.println(timeStarted, DEC);
  Serial.println(timeEnded, DEC);
  timeStarted = 0;
  timeEnded = 0;
  }
}

void startTime()
{
  if (!timeStarted)
  {
    timeStarted = millis();
  }

}
void endTime()
{
  if (!timeEnded)
  {
    timeEnded = millis();
  }
 
 
 
}
Logged

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17262
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks, now I have another problem.
When either interrupt triggers both timeStarted and timeEnded are the same...

Code:
const float kDistance = 0.063;
volatile unsigned long timeStarted = 0;
volatile unsigned long timeEnded = 0;



void setup() {
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  digitalWrite (2, HIGH);
  digitalWrite (3, HIGH);
  attachInterrupt(0, startTime, FALLING);
  attachInterrupt(1, endTime, FALLING);
  Serial.begin(9600);
 
 
 
}

void loop() {
  if (timeStarted && timeEnded)
  {
//  float deltaTime = (timeEnded-timeStarted)/1000.0;
//  float velocity = kDistance/deltaTime;
//  Serial.print("Velocity = ");
//  Serial.println(velocity, DEC);
//  Serial.print("Time = ");
//  Serial.println(deltaTime, DEC);
  Serial.println(timeStarted, DEC);
  Serial.println(timeEnded, DEC);
  timeStarted = 0;
  timeEnded = 0;
  }
}

void startTime()
{
  if (!timeStarted)
  {
    timeStarted = millis();
  }

}
void endTime()
{
  if (!timeEnded)
  {
    timeEnded = millis();
  }
 
 
 
}


I think you have to make those two variables 'volatile' as I added to your code above. Give it a try and report back.
http://arduino.cc/en/Reference/Volatile

Lefty
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I think you have to make those two variables 'volatile' as I added to your code above. Give it a try and report back.
http://arduino.cc/en/Reference/Volatile

Lefty

I tried this but both variables are still printing as the same number.
Logged

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17262
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I think you have to make those two variables 'volatile' as I added to your code above. Give it a try and report back.
http://arduino.cc/en/Reference/Volatile

Lefty

I tried this but both variables are still printing as the same number.


Well maybe the interrupts are coming faster then you think. Try using micros():

timeStarted = micros();

timeEnded = micros();

Lefty
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Well maybe the interrupts are coming faster then you think. Try using micros():

timeStarted = micros();

timeEnded = micros();

Lefty

After a further look I realized that one pin is triggering both the start time and end time.
Do you know why one input is triggering start time and end time?
Logged

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17262
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Well maybe the interrupts are coming faster then you think. Try using micros():

timeStarted = micros();

timeEnded = micros();

Lefty

After a further look I realized that one pin is triggering both the start time and end time.
Do you know why one input is triggering start time and end time?


Short of a wiring problem, that is not really possible. Can you explain how you have the sensors arranged in relationship to the magnet and how fast the magnet is moving between them?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Short of a wiring problem, that is not really possible. Can you explain how you have the sensors arranged in relationship to the magnet and how fast the magnet is moving between them?

The signal being generated by the sensors is correct as it works flawlessly in the loop code. The two sensors are about 10cm apart, and the magnet passes by them in about 0.2 seconds. Even after I unplug a sensor, the one pin will still trigger both startTime and endTime.
 I appreciate your help.
Logged

Pages: [1]   Go Up
Jump to: