Go Down

Topic: IR rpm, trigger led on with analog delay ? (Read 2 times) previous topic - next topic

darkdude

Alright, now I'm getting somewhere.   :D

so now, I have this going pretty well. Now I just need that loop to end after the first shot. so down where it sais
( lastIRState = IRState;  ) If the counter reads 2, it starts the SSR loop. which is what I want, however, it continues to loop UNTIL the IR gets triggered again.... I want that loop to only loop ONCE. I tried using the ( while ) code, but when I use it, it wont even allow the loop to start, so I get no ssr output.

Heres what I got. the last piece to the puzzle is that loop stop just once.

Code: [Select]
const int  IR = 2;    // IR input
const int ledPin = 3; // Injector SSR
int  load = A0 ;      // Analog input to increase or decrease how long the injctor stays energized
int ledState = LOW;
int IRCounter = 0;   
int IRState = 0;       
int lastIRState = 0;     
long previousMillis = 0;
long interval = 0;         

void setup() {
  pinMode(IR, INPUT);
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}


void loop() {
  IRState = digitalRead(IR);
  if (IRState != lastIRState) {
    if (IRState == HIGH) {
      IRCounter++;
      Serial.println("on");
      Serial.print("IR triggers:  ");
      Serial.println(IRCounter);
    }
    else {
    Serial.println("off");
    }
  }
  lastIRState = IRState;         // after 2 revolutions, it begins the SSR trigger
  if (IRCounter % 2 == 0) {
  unsigned long currentMillis = millis();
  interval = analogRead ( load) ;
  if(currentMillis - previousMillis > interval) {
     previousMillis = currentMillis;   
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;
    digitalWrite(ledPin, ledState);
  }} else {
   digitalWrite(ledPin, LOW);
  }
}



strykeroz


Alright, now I'm getting somewhere.   :D
Good to hear
Quote from: darkdude
If the counter reads 2, it starts the SSR loop. which is what I want, however, it continues to loop UNTIL the IR gets triggered
Code: [Select]
// after 2 revolutions, it begins the SSR trigger
  if (IRCounter % 2 == 0)

okay, here your intent and code don't match up.  Using mod (the % operator) means this is true every even value of IRCounter.  Try
Code: [Select]
if (IRCounter == 2)if you only want it to trigger ON 2.

Cheers! Geoff
"There is no problem so bad you can't make it worse"
- retired astronaut Chris Hadfield

darkdude

Hello, ok I tried that.. I am not sure how it made a difference, but now with  [ if (IRCounter == 2) ]   I cant even get the SSR on.  not sure why. o.o  But is there a way to stop that loop from continuing ?  instead of having all the millis commands, is there some way I can do the following ?

Code: [Select]
  if (IRCounter % 2== 0) {
    interval = analogRead ( load) ;
   
//somehow turn on the ssr, leave it on according to interval, then shut off and stop this loop.
   
  }} else {
   digitalWrite(ledPin, LOW);
  }

strykeroz

Can you please copy and paste here the output you're seeing on the serial monitor?

Thanks
"There is no problem so bad you can't make it worse"
- retired astronaut Chris Hadfield

darkdude

Sure, it looks like this. ( its endless and continues as the rpms continue )

IR triggers:  363
off
on
IR triggers:  364
off
on
IR triggers:  365
off
on
IR triggers:  366
off
on
IR triggers:  367

strykeroz

#20
Apr 22, 2012, 07:51 am Last Edit: Apr 22, 2012, 07:52 am by strykeroz Reason: 1
Hi

A couple of minor changes.  I've commented them, and hope this does what you intend, which is (as I understand it)

1. Count revolutions
2. After the 2nd revolution, turn a LED on for a duration set by a potentiometer
3. After the LED has been on for the duration, turn it off
4. Rinse, repeat

If this is the case, something like this might do the trick:
Code: [Select]
const int  IR = 2;    // IR input
const int ledPin = 3; // Injector SSR
int  load = A0 ;      // Analog input to increase or decrease how long the injctor stays energized
int ledState = LOW;
int IRCounter = 0;  
int IRState = 0;      
int lastIRState = 0;    
long previousMillis = 0;
long interval = 0;          

void setup() {
 pinMode(IR, INPUT);
 pinMode(ledPin, OUTPUT);
 Serial.begin(9600);
}

void loop() {
 // check iR sensor and update counter if it sees the trigger
 IRState = digitalRead(IR);
 if (IRState != lastIRState) {
   if (IRState == HIGH) {
     IRCounter++;
     Serial.println("on");
     Serial.print("IR triggers:  ");
     Serial.println(IRCounter);

   }
   else Serial.println("off");
 }

 lastIRState = IRState;

 // Check to see if you need to update the LED (only occurs after the 2nd rotation detected)
 if (IRCounter >= 2) {          // If we're on or after 2nd count
   if(ledState == LOW) {        // we've not turned it on yet
     ledState = HIGH;           // set the state to on
     previousMillis = millis(); // record when we turn the LED on
     interval = analogRead(load);    // read how long to leave it on for
   }
   else {                       // else, the LED is already on
     if(millis() - previousMillis >= interval) { // it's time to turn the LED off again
       ledState = LOW;          // set state to off
       IRCounter=0;             // reset the counter so it will start counting from 0 again
     }
   } // end of else
   digitalWrite(ledPin, ledState);
 }
}


Now the downside here is your IRCounter will be zeroed out when the LED has been on and is turned off.  If you want to keep a total that keeps climbing you may need to consider a second counter, and maybe make it an unsigned int, unsigned long etc (ie a variable type that can deal with very large positive values) depending how long you want to run this.

Cheers !
Geoff
"There is no problem so bad you can't make it worse"
- retired astronaut Chris Hadfield

darkdude

it works!!!!! omg!! thank you so muchhhhh!!!!

Go Up