Go Down

Topic: Temporarily halting a sensor? (help) (Read 722 times) previous topic - next topic

philip1304

Hi, I'm not too sure if this is possible. However here is the suss, I've got 4 sensors, 3 of which are LDR's. I've installed them in an art installation i've built. Thing is its a small space that gives you commands via MP3 trigger which are triggered by the LDR sensors. There is one at the base which gives you a command to stand up. The problem is that when you stand up in the space, the sensor is still active, and does not seem to let other sensors trigger while it is active. I've tried a delay but I doesn't seem to work. I don't know what the problem is or how to solve it. Any help would be much appreciated as the show is tomorrow. Thanks.

Here is the code;

Code: [Select]
#include <MP3Trigger.h>
MP3Trigger trigger;



 
const int sensor1 = A0;
const int sensor2 = A1;
const int sensor3 = A2;
const int sensor4 = A3;
const int LED = 12;
const int LED2 = 13;

int value1 = 0;
int value2 = 0;
int value3 = 0;
int value4 = 0;



void setup()
{
  trigger.setup(&Serial);
  Serial.begin( MP3Trigger::serialRate() );

pinMode(LED, OUTPUT);
pinMode(LED2, OUTPUT);

}



void loop()

{
  digitalWrite(LED, HIGH);
  digitalWrite(LED2, HIGH);
  value1 = analogRead(sensor1); //SENSOR1

if (value1 == 350)
delay(10)
    {

     
         Serial.write('t');
         Serial.write(1);
       
       
    }     


  value2 = analogRead(sensor2); //SENSOR2

  if (value2 == 200)
  delay(10)
    {

       
     
         Serial.write('t');
         Serial.write(2);
         
       
       
    }   
   
  value3 = analogRead(sensor3); //SENSOR3
 
  if (value3 == 200)
  delay(10)
    {

       
     
         Serial.write('t');
         Serial.write(3);
         
         
       
    }


value4 = analogRead(sensor4); //SENSOR4
 
  if (value4 == 200)
  delay(10)
    {

       
     
         Serial.write('t');
         Serial.write(4);
         
         
         
       
    }   
}

UKHeliBob

If I understand you correctly once the sensor that detects you standing up has triggered you want to stop it triggering again for a period.  Is that correct ?  If so, which one and how long should it be ignored ?

Some comments on your code.

Give the sensor pins meaningful names.
Give the values read meaningful names.
Give the LEDs meaningful names.
Get rid of the unnecessary blank lines.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

PeterH

You code is currently looking for exact values on the analog inputs. In practice, your analog inputs are not likely to be that consistent and you would be better off comparing against a threshold value or range of values.

I don't understand what inputs you expect to get when the subject goes through the expected sequence of actions, or how you can tell whether they have done so. If you haven't already done it, I suggest you simply read and print out the values from each sensor and make a note of how they change when a typical subject follows your instructions. You can then use this information to design your code to detect whether/when they have followed each instruction so that you can move on to the next instruction.

I guess you're using your hardware serial port 'Serial' to send instructions to the MP3 trigger. In that case you can't also use it to display diagnostic information. AT this stage, displaying diagnostic information is more important so I recommend you remove the MP3 trigger and connect the Serial output to a PC so you can see what's happening while you test your code. Once you have the code working correctly you can remove the PC connection and reconnect the MP3 trigger and (hopefully) it will all do what you expect.

On a more practical note, your code layout is far from the worst I've seen but leaves the code spread out which makes it hard to see. I suggest that anywhere you have two blank lines together, you remove one of them. If you have a blank line after a { or before a }, remove it. If you have a blank line before a {, remove it. Use the Tools / Auto Format command to make your indentation consistent.
I only provide help via the forum - please do not contact me for private consultancy.

philip1304

Thanks for the pointers on the code. Yeah, I want sensor2 to stop triggering for about 3 minutes.

UKHeliBob

You will need to use millis() for the timing to prevent the whole code stopping for 3 minutes.  Have a look at the BlinkWithoutDelay example.

Something like this will do what you want but you will need to turn it into real code.
Code: [Select]
set boolean OK2read2 to true
set unsigned long interval to 1000 * 60 * 3
set unsigned long startTime to zero

start of loop   
    if OKtoRead2 is true and sensor2 is triggered
      do actions for sensor2
      set startTime to millis()
      set OKtoRead2 to false
    end of if
   
    if OKtoRead2 is false and millis() - startTime > interval  //time's up
      set OKtoRead2 to true
    end of if
     
//read other sensors and do actions
end of loop


Please take note of the other comments about not expecting precise values from the LDRs and laying out your code sensibly
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

afremont


You will need to use millis() for the timing to prevent the whole code stopping for 3 minutes.  Have a look at the BlinkWithoutDelay example.

Something like this will do what you want but you will need to turn it into real code.
Code: [Select]
set boolean OK2read2 to true
set unsigned long interval to 1000 * 60 * 3
set unsigned long startTime to zero

start of loop   
    if OKtoRead2 is true and sensor2 is triggered
      do actions for sensor2
      set startTime to millis()
      set OKtoRead2 to false
    end of if
   
    if OKtoRead2 is false and millis() - startTime > interval  //time's up
      set OKtoRead2 to true
    end of if
     
//read other sensors and do actions
end of loop


Please take note of the other comments about not expecting precise values from the LDRs and laying out your code sensibly


You should increment startTime by interval, not set it to millis().  This will lead to a lot less drift.
Experience, it's what you get when you were expecting something else.

UKHeliBob

Quote
This will lead to a lot less drift.
Can you explain why ?
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

afremont

You can work it out on paper, but basically think about what happens when you arrive late to the interval check.  By incrementing the startTime by interval, you end up with values like 1000, 2000, 3000.....  Otherwise you can end up with values like 1000, 2001, 3002, 4004...  See the accumulated drift now?
Experience, it's what you get when you were expecting something else.

UKHeliBob

What values are you referring to that would be like 1000, 2000, 3000 or 1000, 2001, 3002 etc ?
Should this code exhibit the problem, and if so, how ?
Code: [Select]
unsigned long startTime;
unsigned long interval = 1000;

void setup()
{
  Serial.begin(115200);
  unsigned long startTime = millis();
}

void loop()
{
  delay(1100);
  if (millis() - startTime  > interval)
  {
    Serial.println(millis() - startTime);
    startTime = millis();
  }
}
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

afremont

#9
May 14, 2013, 10:28 am Last Edit: May 14, 2013, 10:48 am by afremont Reason: 1
I wrote up a big, detailed speil, but the unending bulletin board problems tossed my entire post because it's been 0 seconds since my last post.  If and when they get this BBS crap to work, I'll try again.

I was talking about startTime values.

EDIT:  Of course it lets this thru.  Sorry about the explanation I tried to post before.  Like I said, when they make this work dependably, maybe I'll try again.  I don't have time to constantly recreate my entire posting just because the database is having a temporary problem.

EDIT2:  Just pretend you are calling a routine called clockCycles() that returns exactly that.  It would never return the same value on back-to-back calls like millis() might.  When you start doing the reloads, what happens to those clock cycles that passed between the first call to clockCycles() to do the interval check and then the call that occurs to reload startTime()?

Yes, your second program will invite drift as well and for the exact same reasons.
Experience, it's what you get when you were expecting something else.

UKHeliBob

Thanks for your efforts struggling against the problems with the forum.  I will create some test code of both types and test it.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

afremont


Thanks for your efforts struggling against the problems with the forum.  I will create some test code of both types and test it.


I'm sorry, I don't mean to take it out on you.  I have a clock project that does some other things besides display the time.  When it is on the other display screens, my time loop doesn't roll.  But because I add a fixed offset, when it comes back to the clock display the time rolls quickly thru the skipped over time.  If I reloaded from millis() those seconds would just be lost.  Currently it doesn't blank the display during that time so you see the time tick by real quick until it is caught up.  Time is kept purely thru using millis() to keep track of the seconds passing.  The clock keeps time that is exactly as accurate as the resonator is regardless of how much time you spend playing on other display screens.
Experience, it's what you get when you were expecting something else.

UKHeliBob

Don't worry, I didn't think for a moment that you were taking out on me.  I am sorry if my reply came over as sarcastic.  I certainly didn't mean it to.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Go Up