Go Down

Topic: NEED HELP FINISHING MY CODE!!! CAN'T FIGURE IT OUT (Read 754 times) previous topic - next topic

Sammygrind

Yeah I realised that when I tried searching for it my bad... Here is the youtube code that takes you right to it. Sorry about that lol

youtube.com/watch?v=BqLVltHf2qM

larryd

Time to show the code as it is now.

Use CTRL T to format the sketch.

Please use code tags. Use the </> icon in the posting menu.   
[code] Paste sketch here. [/code]


No technical PMs.
The last thing you did is where you should start looking.

Sammygrind

Oh...that's how you do the code tags... Ok I didn't know. I will post it it now but I did CNTRL T to format it but I'll do it again right now. Thank you again.

Sammygrind

Code: [Select]

/* Object starts a pendulum swing between ldrPin1 and ldrPin2 going from
   right to left. Total recorded time from start to finish
*/

const int THRESHOLD_LOW = 650; // Threshold of amount of light in area, can be adjusted to fit lighting conditions
const int THRESHOLD_HIGH = 700; // Same as above
int ldrPin1 = A0; // object swings right, shadow passes over LDR starting timer
int ldrPin2 = A5; // object swings left, shadow passes over LDR stopping timer
int HystereticRead (int pin, int previousState) {

  int photo = analogRead (pin);
  if (previousState == LOW && photo >= THRESHOLD_HIGH) {
    return HIGH;
  }
  else if (previousState == HIGH && photo < THRESHOLD_LOW) {
    return LOW;
  }
  else {
    return previousState;
  }
}
void setup() {
  Serial.begin (9600);
}
void loop() {
  static int state0, state1;
  static double time0, time1, time2;

  int  new_state = HystereticRead (A0, state0);
  if (state0 == LOW && new_state == HIGH) {

    time0 = millis ();

  }
  state0 = new_state;

  new_state = HystereticRead (A5, state1);
  if (state1 == LOW && new_state == HIGH) {
    time1 = millis ();
    time2 = (time1 - time0) / 1000;

    Serial.println ("time passed: (s)");
    Serial.println (time2);
  }
  state1 = new_state;
}

I think this is what you are trying to do.
I hope it does not confuse you.
It is easier to read in the Arduino IDE - just copy and paste into your IDE, and see if it does what you want.


Code: [Select]
/* Object starts a pendulum swing between ldrPin1 and ldrPin2 going from
   right to left. Total recorded time from start to finish
*/

const int THRESHOLD_LOW = 650; // Threshold of amount of light in area, can be adjusted to fit lighting conditions
const int THRESHOLD_HIGH = 700; // Same as above
int ldrPin1 = A0; // object swings right, shadow passes over LDR starting timer
int ldrPin2 = A5; // object swings left, shadow passes over LDR stopping timer
boolean pin1Trigger=false;
boolean pin2Trigger=false;
double totalTime = 0;
double startTime = 0;
double stopTime = 0;

void checkPin(int pin){
  int pinRead = analogRead(pin);
  if(pinRead>THRESHOLD_HIGH){
    //an LDR has been triggered
    if(pin == ldrPin1){
      pin1Trigger=true;
      pin2Trigger=false;
    } else {
      pin1Trigger = false;
      pin2Trigger = true;
    }
  }
}

void setup() {
  Serial.begin (9600);
}

void loop() {
  totalTime = 0; //Reset the timer

  //While both are false, keep checking for a trigger on LDR1.
  while(!pin1Trigger && !pin2Trigger){   
    checkPin(ldrPin1);
    if(pin1Trigger){
      //start the timer when the shadow FIRST passes over the LDR on ldrPin1
      startTime = millis();
      //pin1Trigger is now true - and therefore will break the while loop.
    }
  }

  //While the LDR1 is true, and LDR2 is false, keep checking for a trigger on LDR2
  while(pin1Trigger && !pin2Trigger){   
    checkPin(ldrPin2);
    if(pin2Trigger){
      //Stop the timer when the shadow FIRST passes over the LDR on ldrPin2
      stopTime = millis();
      //pinTrigger will now be true - and therefore exit the while loop
    }
  }

  totalTime = (startTime - stopTime)/1000;
  Serial.print ("time passed: ");
  Serial.print (totalTime);
  Serial.println(" (s)");

//Reset the triggers for the next cycle
  pin1Trigger = false;
  pin2Trigger = false;
}

Sammygrind

Ok, I ran the code and it did work the time did stop when the shadow of the object passed over ldrPin1 on first and second pass and when it passed over ldrPin2. However, it did not show the total time in the serial monitor all it showed was time passed 0.00 (s) as it ran over and over but it does seem like it is on the right track. Making progress I will try this again later on today maybe look over the code more thorough and see why it was'nt recording time. Thanks Scott C for all the  continued help. Whether it works or not, it is all informative knowledge. knowledge is power...
 

#21
Sep 15, 2018, 03:02 am Last Edit: Sep 15, 2018, 03:06 am by ArduinoBasics
Ooops:

I think you might need to change this line:

 totalTime = (startTime - stopTime)/1000;

to

  totalTime = (stopTime - startTime)/1000;


Sorry for that minor bug !!

I would also advise to use some additional  Serial.print() commands within the code to monitor the variables within the various loops. This will help you to see what is happening more clearly.

Sammygrind

Ok, it does work because the "tx light" on the Arduino blinks every time my object passes over ldrPin1 and ldrPin2 casting the shadow which means it is sending the byte of data.... big smiles. However, it still does not give the time that it took my object to complete the pass.

 I did load my old code again to see if the "tx light" would come on like it does on the code that you made and it only blinks during the pass over ldrPin2 not when it passes over ldrPin1 which is odd.  Your code is progress in the direction that I am pursuing. I just need the time to record like it does on my code...thumbs up

My code should only send data through the serial monitor when it passes over the LDR2.
Based on what you said, it looks like LDR2 is being triggered when the shadow is passing over LDR1. So basically, LDR1 is being triggered, and then LDR2 is being triggered immediately afterwards.
Which is probably why you are getting a time of zero.

Try this code to see if it works. If not, then you may need to consider introducing a small delay between the while loops.

Code: [Select]
/* Object starts a pendulum swing between ldrPin1 and ldrPin2 going from
   right to left. Total recorded time from start to finish
*/

const int THRESHOLD_LOW = 650; // Threshold of amount of light in area, can be adjusted to fit lighting conditions
const int THRESHOLD_HIGH = 700; // Same as above
int ldrPin1 = A0; // object swings right, shadow passes over LDR starting timer
int ldrPin2 = A5; // object swings left, shadow passes over LDR stopping timer
boolean pin1Trigger=false;
boolean pin2Trigger=false;
double totalTime = 0;
double startTime = 0;
double stopTime = 0;
boolean pin2count = 0;

void checkPin(int pin){
  int pinRead = analogRead(pin);
  if(pinRead>THRESHOLD_HIGH){
    //an LDR has been triggered
    if(pin == ldrPin1){
      pin1Trigger=true;
      pin2Trigger=false;
    } else {
      pin2count = pin2count+1;
      if(pin2count>1){
        pin1Trigger = false;
        pin2Trigger = true;
        pin2count = 0;
      }
    }
  }
}

void setup() {
  Serial.begin (9600);
}

void loop() {
  totalTime = 0; //Reset the timer

  //While both are false, keep checking for a trigger on LDR1.
  while(!pin1Trigger && !pin2Trigger){   
    checkPin(ldrPin1);
    if(pin1Trigger){
      //start the timer when the shadow FIRST passes over the LDR on ldrPin1
      startTime = millis();
      //pin1Trigger is now true - and therefore will break the while loop.
    }
  }

  //While the LDR1 is true, and LDR2 is false, keep checking for a trigger on LDR2
  while(pin1Trigger && !pin2Trigger){   
    checkPin(ldrPin2);
    if(pin2Trigger){
      //Stop the timer when the shadow FIRST passes over the LDR on ldrPin2
      stopTime = millis();
      //pinTrigger will now be true - and therefore exit the while loop
    }
  }

  totalTime = (stopTime - startTime)/1000;
  Serial.print ("time passed: ");
  Serial.print (totalTime);
  Serial.println(" (s)");

//Reset the triggers for the next cycle
  pin1Trigger = false;
  pin2Trigger = false;
}

Sammygrind

Oh no not at all, I guess I didn't explain myself to well. My LDR's are being triggered accordingly except for ldrPin1 which on the second pass. It starts recording when my the shadow of the object makes the first pass then as my object comes back and makes the second pass over ldrPin1 it resets the timer and starts counting from 0.00 until it passes over ldrPin2 and records the time. So if it takes my object a total time of one second to pass over both LDR's it is only showing a quarter of a second or thereabouts (.25, .20, .19 etc..) which means the shadow is resetting the timer when it passes over ldrPin1 for the second time and that is what I am trying to have NOT happen. I have included the you tube code to view exactly what my project does what I want it to do and the problem Im having.  I'm certain the video will clear things up.



youtube.com/watch?v=BqLVltHf2qM

I saw your video before, and wrote my first script based on what you wanted.
My code will start the timer when it first passes over LDR1, and will stop the timer when it first passes over LDR2. But it should ONLY transmit a Total time when the shadow goes over LDR2.
It should not transmit a time when it goes over LDR1.

You said in your last post that it was transmitting a time of 0.0 when it went over LDR1 AND LDR2.
So I modified my code  - hoping to fix that...

Try my latest code, and tell me what happens.
If you are still getting a total time of zero, then another approach is required.

When are you seeing the time getting transmitted?
And another point to clarify:
Do you need the total time to increment with every cycle?
If every measurement is 1 second long, should the total time remain as 1 second, or should it display, 1 second, 2 secs, 3 secs etc?
I have it resetting with every cycle. As per the table below.


TriggerCode___Cycle______LDR_Triggered______Timer_Action___TotalTime
A1 LDR1Start Timer
B1 LDR1
C1 LDR2Stop Timer1.0 second
D1 LDR2
-- -----------
E2 LDR1Start Timer
F2 LDR1
G2 LDR2Stop Timer1.0 second
H2 LDR2


           

Sammygrind

I guess what I meant was that as soon as I uploaded the code and opened the serial monitor the time was being already displayed as 0.00 as it was continuously scrolling down so it was not recording any time when I would pass over ldrPin1 and ldrPin2. It would stop the scrolling briefly as I would pass over both LDR's..., telling me that it was doing what I wanted but did not record the time at all.

As far as your second ?, as long as it records the total time. It does not need to be incremented. Whether it takes my object 1 second or 5 seconds to pass over the LDR's  as long as it records the actual and total time. with a reset option after each total time is recorded. So on the first pass lets say it took 2.5 seconds total time, then on the serial monitor it should show time passed 2.5. Then it will reset and when I pass my object over again lets say for 1 second it should show on the serial monitor  time passed 1.00 just like my video so on and so-forth... but I gotta tell you that all your coding gives me ideas where I can take certain portions and try which is all good info in my opinion. Because I am out of my element on this but it is fun! Again thank you for all your time and diligence.   

Sammygrind

Ok I just tried the code you put and it did not even show a "time passed..." in the serial monitor page was blank hmmm

Sammygrind

OK OK OK ! I got it! with your help Scott my project is working like it should... as I was looking over the code in your last msg I saw this  if (pinRead>THRESHOLD_HIGH) // an LDR has been triggered......

and I thought to myself the pinRead needs to be less than or else it will never record time so I tweaked it to,  if (pinRead<THRESHOLD_HIGH)

and bam it worked the way I need it to. There is one small bug though the time recorded is in negative seconds so and example: time passed -1.25

which is not really a big deal as long as it recorded the total time, which it does. I would like to know why it is recording in negative time though and maybe a fix for that

I will post another video with the you tube code so you can see how it works and the "negative"  portion. Thanks for the help always appreciative.

Double check that

totalTime = (stopTime - startTime)/1000;

Go Up