Go Down

Topic: IR rpm, trigger led on with analog delay ? (Read 2340 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
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy