Arduino Forum upgrade scheduled for Monday, October 20th, 11am-4pm (CEST). Sorry for the inconvenience!
Pages: [1] 2   Go Down
Author Topic: Carpark entry counter  (Read 1601 times)
0 Members and 1 Guest are viewing this topic.
Dinmore, QLD, Australia
Offline Offline
Newbie
*
Karma: 1
Posts: 11
Oh fate most cruel, to be thusly boned!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, I've been working on a count to track cars entering a carpark,  and I'm having some monir trouble.

What I need, is for ir beam 1 to be triggered, then IR beam 2 to be triggered, whilst the first is still active, before I get a counter+1 event.
and the opposite for exiting the carpark, IR 2, then IR 1 whilst the first is active, before I get a counter-1 event.
i have 3 LEDs to light one to replicate IR 1, one to replicate IR2 and one to indicate that the counter has changed.

I thought I had it figured out, as the sketch compiled, but I'm not getting any results or not what I am expecting,anyway.
Sorry if its a bit messy, I have been chopping and changing it to try and get it to work.  it was a lot neater than this to begin with smiley-sad
Eventually I will be relaying the output to a web page, but first I need to get the data acquisition right.

Any help is very much appreciated.
cheers
Jason

Code:
const int IRTrigger1 = 1;     // the number of the pin used to read IR beam status
const int IRTrigger2 = 2;
const int CounterChange =  13;      // the number of the LED pin

// variables will change:
int IRState1 = 0;         // variable for reading the pushbutton status
int IRState2 = 0;
int totalcars =0;
int value = 0;
int entering = 0;
int leaving = 0;
void setup() {
 const int IRTrigger1 = 1;     // the number of the pin used to rear IR beam status
const int IRTrigger2 = 2;
const int CounterChange =  13;      // the number of the LED pin

// variables will change:
int IRState1 = 0;         // variable for reading the pushbutton status
int IRState2 = 0;
int totalcars =0;
int value = 0;
int entering = 0;
int leaving = 0;
  // initialize the LED pin as an output:
  pinMode(CounterChange, OUTPUT);     
  // initialize the pushbutton pin as an input:
  pinMode(IRTrigger1, INPUT);     
  pinMode(IRTrigger2, INPUT);
 Serial.begin(9600);
}

void loop(){
  // read the state of the pushbutton value:
  IRState1 = digitalRead(IRTrigger1);
  IRState2 = digitalRead(IRTrigger2);

   
 
if (IRTrigger1 < 1){
     IRState1=1; digitalWrite(CounterChange, HIGH);
}

if (IRTrigger2 < 1){
     IRState2=1;
}

if(IRState1 > IRState2){
  entering = 1;
} else if (IRState2 > IRState1){
     leaving=1;
}
 
if ((IRState1 + IRState2) ==2){
      if (entering == 1){
     totalcars = totalcars + 1;
     digitalWrite(CounterChange, HIGH);
     delay(200);
     digitalWrite(CounterChange, LOW);
     }  else if (leaving == 1){
    totalcars = totalcars - 1;
     }
entering=0; // reset everything
leaving=0;
IRState1=0;
IRState2=0;
}
}
Logged

one day, I'll be able to do this without help smiley

UK
Offline Offline
Tesla Member
***
Karma: 145
Posts: 8503
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

There is no point testing IRTrigger1 or IRTrigger2 as they are both defined as constants.

You should be testing IRState1 and IRState2.

You don't seem to have any code to figure out which IR was triggered first.

I think your logic needs to be something like this

wait until both sensors are off ... then
  if sensor1 is on and sensor 2 is off there is an incoming car
     but don't count it until sensor 2 goes on
  if sensor2 is on and sensor 1 is off there is an outgoing car
     but don't count it until sensor 1 goes on
 
...R
Logged

Dinmore, QLD, Australia
Offline Offline
Newbie
*
Karma: 1
Posts: 11
Oh fate most cruel, to be thusly boned!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Testing a constant....well done jason.

Ok, I have the logic part sorted, I messed with it a bit before posting, so it didnt look right. Thanks Robin2!
Logged

one day, I'll be able to do this without help smiley

Dinmore, QLD, Australia
Offline Offline
Newbie
*
Karma: 1
Posts: 11
Oh fate most cruel, to be thusly boned!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi again,
I have sorted the Logic part of the code, and cleaned it up a bit, but now that I have inserted the websever side of it, I am getting weird results(web server worked by itself, but as a function, not so much

what i get in the serial monitor is:
"New client
G
client Disconnected"


Now I cannot for the life of me, figure out where this "G" is coming from, nor why I am getting no "Digital Input pin is: x" data on the web page.

I realise it is probably not syntax that is the issue, as it compiles. I have been staring at theis for hours, and just can't see it.

any help is appreciated
Regards
Jason

Code:
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1, 100);
const int IRTrigger1 = 2;     // the number of the pin used to read IR beam status
const int IRTrigger2 = 3;
const int CounterChange =  13;      // the number of the LED pin

// variables will change:
int IRState1 = 0;         // variable for reading the pushbutton status
int IRState2 = 0;
int totalcars =0;
int IRvalue1 = 0;
int IRvalue2 = 0;
int entering = 0;
int leaving = 0;
int webserver();
// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);

void setup() {

  // initialize the LED pin as an output:
  pinMode(CounterChange, OUTPUT);     
  // initialize the pushbutton pin as an input:
  pinMode(IRTrigger1, INPUT);     
  pinMode(IRTrigger2, INPUT);
  Serial.begin(9600);
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}

void loop(){
 
   EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    webserver();}
  // read the state of the pushbutton value:
  IRState1 = digitalRead(IRTrigger1);
  IRState2 = digitalRead(IRTrigger2);

   
  Serial.print("IRvalue1= ");
     Serial.println(IRState1);
if (IRState1 >0){
     IRvalue1=1; digitalWrite(CounterChange, HIGH);
     Serial.print("IRvalue1= ");
     Serial.println(IRState1);}

if (IRTrigger2 >0){
     IRvalue2=1;}

if(IRState1 > IRState2){
  entering = 1;} else if (IRState2 > IRState1){
     leaving=1;}
 
if ((IRState1 + IRState2) ==2){
      if (entering == 1){
     totalcars = totalcars + 1;
     digitalWrite(CounterChange, HIGH);
     delay(1000);
     digitalWrite(CounterChange, LOW); }
     else if (leaving == 1){
    totalcars = totalcars - 1;
     }
entering=0; // reset everything
leaving=0;
IRState1=0;
IRState2=0;
}
}
int webserver(){

   EthernetClient client = server.available();
 boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        client.println("<br />");
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connnection: close");
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
                    // add a meta refresh tag, so the browser pulls again every 5 seconds:
          client.println("<meta http-equiv=\"refresh\" content=\"5\">");
          // output the value of each analog input pin
          for (int digitalChannel = 0; digitalChannel < 3; digitalChannel++) {
            int inputs = digitalRead(digitalChannel);
            client.print("Digital input Pin");
            client.print(digitalChannel);
            client.print(" is ");
            client.print(inputs);
            client.println("<br />");       
          }
          client.println("</html>");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        }
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
          // give the web browser time to receive the data
      delay(5); 
      }
    delay(5000);
   
         
       
 
      }
   //close the connection:
    client.stop();
   Serial.println("client disonnected"); 
  }}
   
Logged

one day, I'll be able to do this without help smiley

California
Offline Offline
Faraday Member
**
Karma: 92
Posts: 3453
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Assuming you're using an SPI-based Ethernet shileld...

http://arduino.cc/en/Main/ArduinoEthernetShield

Quote
Arduino communicates with both the W5100 and SD card using the SPI bus (through the ICSP header). This is on digital pins 11, 12, and 13 on the Duemilanove Uno.

Code:
const int CounterChange =  13;      // the number of the LED pin
Logged

Mid-Atlantic, USA
Offline Offline
God Member
*****
Karma: 30
Posts: 515
"Remember kids, the only difference between Science and screwing around is writing it down." - Adam Savage
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Assuming you're using an SPI-based Ethernet shileld...

http://arduino.cc/en/Main/ArduinoEthernetShield

Quote
Arduino communicates with both the W5100 and SD card using the SPI bus (through the ICSP header). This is on digital pins 11, 12, and 13 on the Duemilanove Uno.

Code:
const int CounterChange =  13;      // the number of the LED pin

Simple trap to fall into. I did something similar with a little project. I wanted to toggle a light for diagnostics. I happened to have some small 0.1" lead spacing 5V LEDs (integrated resistor for running directly on 5V). Since there is a GND connection right next to D13, I dropped it in and added code to toggle that LED for my diagnostics. Scratched my head for a bit wondering why the LED was constantly on at a low level... (I couldn't easily see the on-board LED because I had the Ethernet shield plugged in...) Felt kinda silly after I discovered the error. What I ended up doing (so I could keep using the same LED plugged directly into the shield pass-through header) was putting it between A0 and A1. Set A0 as digital output LOW, and toggled A1 digitally as my diagnostics. That worked.

But to the OP... By your description, it looks much like you are using the two IR beams just like how a rotary encoder works. (Only you are trying to ignore single IR beam trips because that would be a person, not a car...) Check some of the rotary encoder examples for counting forward and backwards and get your code working counting cars in and out. Then add the code to ignore isolated single beam interruptions.
Logged


Dinmore, QLD, Australia
Offline Offline
Newbie
*
Karma: 1
Posts: 11
Oh fate most cruel, to be thusly boned!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

" LED was constantly on at a low level..."

now that you mention it, so is mine.

ill look at that first then move to the rest of your post, thanks!
Logged

one day, I'll be able to do this without help smiley

Dinmore, QLD, Australia
Offline Offline
Newbie
*
Karma: 1
Posts: 11
Oh fate most cruel, to be thusly boned!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've moved the diag LED to pin 10, or do you suggest moving it to analog pins?

it hasn't made any difference at D10

, still can't see where this "G" is coming from in the serial monitor.

and nothing shows on the web page, just a blank screen
the UNO derivative I'm using is the EtherTen, from freetronics

Regards
Jason
Logged

one day, I'll be able to do this without help smiley

California
Offline Offline
Faraday Member
**
Karma: 92
Posts: 3453
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've moved the diag LED to pin 10, or do you suggest moving it to analog pins?

http://arduino.cc/en/Main/ArduinoEthernetShield

Quote
On both boards, pin 10 is used to select the W5100 and pin 4 for the SD card.
Logged

Mid-Atlantic, USA
Offline Offline
God Member
*****
Karma: 30
Posts: 515
"Remember kids, the only difference between Science and screwing around is writing it down." - Adam Savage
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've moved the diag LED to pin 10, or do you suggest moving it to analog pins?

it hasn't made any difference at D10

, still can't see where this "G" is coming from in the serial monitor.

and nothing shows on the web page, just a blank screen
the UNO derivative I'm using is the EtherTen, from freetronics

Regards
Jason

Check the documentation for that board. I know when using my UNO r3 D10 is tied up when doing anything with ISP, so often boards use it as a CS. It might be the same with your board, I don't know but likely. In my "solution" I chose the analog pins just because they were available and I didn't have any wires to that side of my Arduino so the LED wasn't occluded by anything. Mostly an arbitrary choice. You can treat the analog pins like digital pins though. Reference them with A0-A5 when using the digital functions. (You could reference them as 14-19. Best to use the "A" numbers to make it easier to remember what they are called because the board silkscreen likely doesn't have the 14-19 indicators on it.)
Logged


Dinmore, QLD, Australia
Offline Offline
Newbie
*
Karma: 1
Posts: 11
Oh fate most cruel, to be thusly boned!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thanks people!, I now have this working(as far as code is concerned)
now, I have a hardware issue smiley-sad

ok, i have a tactile switch with 2k2, pulldown resistor attached to D2, and another wired the same on D3,
there is a yellow led indicator attached to pin D5, red to pin D7, and green to D9.
now when i press switch 1, pin 5 lights the yellow LED
when i press switch two, pin 7 lights the red LED
when i hold one switch, and press the other, the code deciphers which was the first to trigger, modifies the counter(for total entries/exits) and pin 9 lights the green LED
these result are mirrored to the web server which can be viewed from a browser. until......

THE PROBLEM
when i press both buttons at once, the ethernet portion of the board drops out.
code is as follows:::

Code:
#include <SPI.h>
#include <Ethernet.h>
// For MEGA2560 with IEsheild v1.01 only
// #include <enc28j60.h>
// #include <ethershield>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,100);
const int IRTrigger1 = 2;     // the number of the pin used to read IR beam status
const int IRTrigger2 = 3;
const int CounterChange =  9;      // the number of the LED pin
const int IR1Triggered = 7;   // to show beam one is broken
const int IR2Triggered = 5;  // to show beam two is broken
// variables will change:
int IRState1 = 0;         // variable for reading the pushbutton status
int IRState2 = 0;
int totalcars =0;
int IRvalue1 = 0;
int IRvalue2 = 0;
int entering = 0;
int leaving = 0;
int webserver();
// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);

void setup() {

  // initialize the LED pin as an output:
  pinMode(CounterChange, OUTPUT);     
  // initialize the pushbutton pin as an input:
  pinMode(IRTrigger1, INPUT);     
  pinMode(IRTrigger2, INPUT);
  pinMode(IR1Triggered, OUTPUT);
  pinMode(IR2Triggered, OUTPUT);
  Serial.begin(9600);
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}

void loop(){
 
   EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    webserver();}
  // read the state of the pushbutton value:
  IRState1 = digitalRead(IRTrigger1);
  IRState2 = digitalRead(IRTrigger2);

   
     Serial.print("IRvalue1= ");
     Serial.println(IRState1);
     Serial.print("IRvalue2= ");
     Serial.println(IRState2);
     Serial.println(" ");
     Serial.println(" ");
if (IRState1 >0){
     IRvalue1=1; digitalWrite(IR1Triggered, HIGH);
     Serial.print("IRvalue1= ");
     Serial.println(IRvalue1);}
else digitalWrite(IR1Triggered,LOW);
if (IRState2 >0){
     IRvalue2=1;digitalWrite(IR2Triggered, HIGH);
     Serial.print("IRvalue2= ");
     Serial.println(IRvalue2);}
else digitalWrite(IR2Triggered,LOW);

if(IRState1 > IRState2){
  entering = 1;} else if (IRState2 > IRState1){
     leaving=1;}
 
if ((IRState1 + IRState2) ==2){
      if (entering == 1){
     totalcars = totalcars + 1;
     digitalWrite(CounterChange, HIGH);
     delay(1000);
     digitalWrite(CounterChange, LOW); }
     else if (leaving == 1){
    totalcars = totalcars - 1;
     digitalWrite(CounterChange, HIGH);
     delay(1000);
     digitalWrite(CounterChange, LOW);
     }
entering=0; // reset everything
leaving=0;
IRState1=0;
IRState2=0;
}
}
int webserver(){

   EthernetClient client = server.available();
 boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available())
      //{
        char c = client.read();
   //   Serial.write(c);
       
        client.println("<br />");
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
   //   if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connnection: close");
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
                    // add a meta refresh tag, so the browser pulls again every 5 seconds:
          client.println("<meta http-equiv=\"refresh\" content=\"5\">");
          // output the value of each Digital input pin
         
             client.println("<br />");
            client.print("Beam 1 is ");
            client.println(IRState1);
             client.println("<br />");
            client.print("Beam 2 is ");
            client.print(IRState2);
            client.println("<br />");
     client.print("Total cars in carpark is ");     
     client.println(totalcars);
    //      }
          client.println("</html>");
         
          break;
        }
    //  if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
   //     }
   //   else if (c != '\r') {
          // you've gotten a character on the current line
        currentLineIsBlank = false;
          // give the web browser time to receive the data
    delay(5); 
   //   }
    delay(5000);
     //}
   //close the connection:
    client.stop();
   Serial.println("client disonnected"); 
  }
//}
   



sorry to be such a pain, any help is muchos appreciado
Logged

one day, I'll be able to do this without help smiley

UK
Offline Offline
Tesla Member
***
Karma: 145
Posts: 8503
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

How do you know the ethernet portion drops out? Could it be that it just isn't called?

Can you run a version of the program without any ethernet stuff and see what happens when you press 2 buttons at the same time?

...R
Logged

Dinmore, QLD, Australia
Offline Offline
Newbie
*
Karma: 1
Posts: 11
Oh fate most cruel, to be thusly boned!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

All the lights on the ethernet side go out,(including the ones on the eth port) and i cant refresh the page.
while one button is pressed, the page can be refreshed(or does automatically every 15 sec)

without the ethernet portion running, the program does what it should. 

I'm wondering if the +5 rail cannot handle the load? and if so, how do remedy this?

Regards
Jason
Logged

one day, I'll be able to do this without help smiley

UK
Offline Offline
Tesla Member
***
Karma: 145
Posts: 8503
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Am I correct to assume that the tactile switches are a substitute for your IR sensors? If not what are they for?

I haven't used the ethernet shield but I wonder should you be creating a new instance of client in every iteration of the loop? I would be inclined to create the instance once in setup.

Am I correct to think that there is no problem when both switches are pressed provided one is pressed first and the problem only arises if both are pressed at the same time? Have you tried pressing them one after the other but with as short an interval as possible?

If your switches are each drawing 5v / 2200ohms = 2.3 mA then I can't see how they are overloading the 5v supply unless they are the last straw and the root of the problem is elsewhere.

Is it possible that when you press the two switches you move something else that has a poor connection?

It's an interesting problem.

...R
Logged

Dinmore, QLD, Australia
Offline Offline
Newbie
*
Karma: 1
Posts: 11
Oh fate most cruel, to be thusly boned!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Am I correct to assume that the tactile switches are a substitute for your IR sensors?
Correct

Quote
I haven't used the ethernet shield but I wonder should you be creating a new instance of client in every iteration of the loop? I would be inclined to create the instance once in setup.
hahaha,  God I'm daft sometimes.

Quote
Am I correct to think that there is no problem when both switches are pressed provided one is pressed first and the problem only arises if both are pressed at the same time? Have you tried pressing them one after the other but with as short an interval as possible?
No, as soon as the second one is pressed(regardless of which is pressed first) it dies/freezes/becomes unresponsive/etc.

Quote
Is it possible that when you press the two switches you move something else that has a poor connection?

I'm, beginning to think so, as after a PC reboot, an Arduino reload, a board reset, and trying my best not to scream like a madman and rip it all to pieces then set it on fire.....it's stopped doing it.



Now, i just need to add time stamping and SD card save, and i think its about ready!

thanks for your help smiley
« Last Edit: May 05, 2013, 05:53:17 am by JsGarage » Logged

one day, I'll be able to do this without help smiley

Pages: [1] 2   Go Up
Arduino Forum upgrade scheduled for Monday, October 20th, 11am-4pm (CEST). Sorry for the inconvenience!
Jump to: