Go Down

Topic: Counter of light change (Read 736 times) previous topic - next topic

DiMedici

Hi all
I try to use a Phototransistor to count objects passing a tube.

I have already a lot of code but there is still a problem:
If I use this code...

/if (senseSignal < 450)
  {       

    buttonPresses++;
 
 

   lcd.setCursor(0,1);
   lcd.print (buttonPresses);
  }

...the counter is counting many times during the object passes the phototransistor.
For Ex.: I put my hand over the transistor and during this time the counter counts from 1 to 21.
But I would like the counter to ad 1 after or while my hand covers the phototransistor.

Is There any possibility to solve my problem without using other Hardware?

Her is the complete code:

Code: [Select]
[/#include <LiquidCrystal.h>

LiquidCrystal lcd(12,11,10,7,6,5,4); //Pins für Disply werden festgelegt

//Zähler:

int buttonPresses = 0;      // Wie oft ist der Schalter gedrückt   

//Lichtschranke:
int sensePin = 0;
int senseSignal;     //geänderter Wert



void setup()
  {
  //Zähler:
  Serial.begin(9600);                     // Start der seriellen Kommunikation mit 9600bps
  lcd.begin(16,4);
  lcd.setCursor(0,0);
  lcd.print("100% i.O.  Dobry");
 
  //Lichtschranke:
  Serial.begin(9600);
  pinMode(13, INPUT);                  //Pullup für Sensor
  digitalWrite(13,HIGH);               //Pullup aktivieren
  senseState = analogRead(sensePin);   //Anfangszustand lesen
 


}     

void loop()
{   
  //Lichtschranke:
  senseSignal = analogRead(sensePin);
 
  if (senseSignal < 450)
  {       

    buttonPresses++;
    // Inkrementieren der Variablen buttonPresses
 
 
 
    Serial.print("Schalter wurde ");
    Serial.print(buttonPresses);
    Serial.println(" gedrueckt");
   lcd.setCursor(0,1);
   lcd.print (buttonPresses);
  }}]



Arrch

What you're looking for is edge detection. Edge detection is accomplished by keeping track of the last value read. The "edge" occurs when your last senseSignal reading was >= 450 and your current reading is < 450. The pseudo code would be something like this.

get currentReading from sensor

if lastReading is less than 450 and currentReading is greater than or equal to 450
  increment counter variable

set lastReading to currentReading

majenko

Simple enough to achieve.

At the moment, you are saying "While the input value is less than 450, add one to the count".

What you need is something more like:

"If the input value is less than 450 then add one to the count and wait for the input value to rise above 450."

You need to look for the object entering the beam and leaving the beam - not just its presence within the beam.
Get 10% off all 4D Systems TFT screens this month: use discount code MAJENKO10

DiMedici

Thanks a a lot. I think I understand.

How can I get this into code? Im not very advanced?:


if lastReading is less than 450 and currentReading is greater than or equal to 450
  increment counter variable

set lastReading to currentReading

majenko

That should certainly be a way of doing it, yes.
Get 10% off all 4D Systems TFT screens this month: use discount code MAJENKO10

DiMedici

like this?
Code: [Select]
[/  if (senseState > 450)
  {  if senseSignal < 450)

    {buttonPresses++;
    // Inkrementieren der Variablen buttonPresses
    }}
 
 
    Serial.print("Schalter wurde ");
    Serial.print(buttonPresses);
    Serial.println(" gedrueckt");
   lcd.setCursor(0,1);
   lcd.print (buttonPresses);
  }}]

Arrch

Code: [Select]
if (senseState > 450)
  {  if senseSignal < 450)

I have no idea what these variables are in the context of your code, so I can't say, but I can tell you that neither of those take into account if the value is exactly 450.

DiMedici

Ok. The Programm looks now like this... But the serial shows constantly 0 button presses. Can you give me any advice.

Code: [Select]
[/#include <LiquidCrystal.h>

LiquidCrystal lcd(12,11,10,7,6,5,4); //Pins für Disply werden festgelegt

//Zähler:

int buttonPresses = 0;      // Wie oft ist der Schalter gedrückt   

//Lichtschranke:
int sensePin = 0;
int senseState;      //Anfangszustand
int senseSignal;     //geänderter Wert



void setup()
  {
  //Zähler:
  Serial.begin(9600);                     // Start der seriellen Kommunikation mit 9600bps
  lcd.begin(16,4);
  lcd.setCursor(0,0);
  lcd.print("100% i.O.  Dobry");
 
  //Lichtschranke:
  Serial.begin(9600);
  pinMode(13, INPUT);                  //Pullup für Sensor
  digitalWrite(13,HIGH);               //Pullup aktivieren

 


}     

void loop()
{   
  //Lichtschranke:
  senseState = analogRead(sensePin);
 
 
 
 
  if (senseState > 450)
  { 
    senseSignal= analogRead(sensePin);
   
    if (senseSignal < 450)   
   
   {
     buttonPresses++;  // Inkrementieren der Variablen buttonPresses
     senseState = senseSignal;
   } 
 
  }
 
 
   
    Serial.print(buttonPresses);
   
lcd.setCursor(0,1);
   lcd.println (buttonPresses);
   delay(500);
  }]

majenko

You're resetting senseState every time through the loop.  You should set the initial value only once in the setup() routine.
Get 10% off all 4D Systems TFT screens this month: use discount code MAJENKO10

DiMedici

Ok. I did this. But there must be an other mistake. Ofter the first contact a 1 appeared. But than nothing happened.

majenko

Here is a little sketch I have knocked together which uses the Serial port to display the transition values.  Use it for inspiration ;)

Code: [Select]

int inState;

void setup()
{
  Serial.begin(9600);
  inState = analogRead(0);
}

void loop()
{
  int state;
  state = analogRead(0);
  if(state <= 512)
  {
    if(inState > 512)
    {
      Serial.print(inState);
      Serial.print(" => ");
      Serial.println(state);
    }
  }
  inState = state;
}


Basically it's:

1. Is the input value in the "on" region?
2. > Yes: Is the previous value in the "off" region?
3. > > Yes: Do something interesting
4. Store the current value as the previous one.
Get 10% off all 4D Systems TFT screens this month: use discount code MAJENKO10

Arrch

Code: [Select]

  if (senseState > 450)
  ...
     senseState = senseSignal;


Just look at that small part. senseState will ONLY change if it is greater than 450. That means, that after the first transition, it is set to something less than 450, and never changes. Thus, that first if statement will ALWAYS fail thereafter.

You should consider using Serial.print to help debug your code. Seeing the value of senseState stay the same after the first transition would have clued you in to your assignment being in the wrong place.

Go Up