0
\$\begingroup\$

I need to count objects from 5-10 mm with using 2 sensors at arduino mega board. I have used photoelectric sensor but it's really very slow. I have to use delay(1000) commands after count an object because it's not ready to count a new item before this period(i don't know this issue is related with sensor or with mega) . If i don't use this waiting period then it counts 2-3 items although only 1 item passes through sensor.

I need to count 2 or 3 items every second. Even i couldn't use 1 sensor properly and i need to use such 2 sensor at 1 mega board. What do ypu offer to me? Capacitive sensors are better and faster? Or is not Arduino enough fast for this project?


Here is my code : (I also use Ethernet Shield)

#include <Ethernet.h>
#include <SPI.h>

int sensorPin = A2;    
int ledPin = 13;      
int MachineID=2;
int sensorValue = 0;  
int dummy=0;
unsigned long TimerB=0;
unsigned long LastTime=0;
unsigned long CurrentTime =0;
unsigned long ElapsedTime =0;
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xE0 };
byte ip[] = { 10, 10, 10, 113 };
byte server[] = { 10, 10, 10, 112 }; 
//byte server[] = { 10, 10, 10, 30 }; 
EthernetClient client;

void setup()
{
    Ethernet.begin(mac, ip);
    Serial.begin(9600);
    digitalWrite(ledPin, LOW);
    delay(1000);
    if (client.connect(server, 8080)) {
        Serial.println("connected");
        digitalWrite(ledPin, HIGH);
        LastTime = millis();    
    } else {
        Serial.println("connection failed");
    }
}

void loop()
{
    dummy=0;  
    dummy=SensorControl();
    if (dummy>0) {
       //Send data to SQL
    }
}

int SensorControl()
{
    sensorValue=0;
    sensorValue = analogRead(sensorPin);
    if (sensorValue>1020) {
        // Sometimes objects stays in front of sensor for a while.
        // So i have to wait until objects leave
        while (sensorValue>1020) {
            sensorValue = analogRead(sensorPin);
        }
        //Here i have to wait 1 seconds
        TimerB=millis();
        while (millis()-TimerB <= 1000) { }
        return MachineID;  
    } else {  
        return 0;
    }
}
\$\endgroup\$
  • \$\begingroup\$ What type of photoelectric sensors are you using? Photodiode/receiver pairs? Infrared? Are you just checking the receiver pin with your Arduino code? Are you running any resource intensive code? The arduino should be more than capable of such slow events. EDIT: just read that it's counting 2-3 objects at once. Maybe try adjusting the threshold of your detection so it doesn't count multiple objects? \$\endgroup\$ – FullmetalEngineer Jan 10 '15 at 22:11
  • \$\begingroup\$ Hi @pikafu, I don't know exactly what kind of sensor i use, i just found these sensors in spare part of a machine. But yes, i have found same sensors at internet. These are sensors which i have used : \$\endgroup\$ – Murat Jan 10 '15 at 22:43
  • 1
    \$\begingroup\$ Probably there is noise in the sensor and it is making multiple transitions across the threshold. You want a "dead zone" between object detected and not detected. \$\endgroup\$ – pjc50 Jan 11 '15 at 0:26
  • 1
    \$\begingroup\$ @pikafu, It's very interesting issue. Everything works great when i try my system in my office. But when i insert this system to machine then it started to give such unwanted results. I have 7 systems which is installed to 7 machines. Only 1 machine gives such unexpected results very frequently. Other 6 machines reads 1 card as 2-3 very rarely. But as a result i want that system works exactly and properly. \$\endgroup\$ – Murat Jan 12 '15 at 9:02
0
\$\begingroup\$

Don't know if you have solved this, but here is my thought.

To begin with, using the analog to read a signal is very inaccurate, especially that it is a photoresistor. I would recommend adding a comparator with hysteresis so as to get a clean digital pulse, pictured below:

schematic

simulate this circuit – Schematic created using CircuitLab

This has the correct values.

Then you would add an interrupt based code routine which will detect the rising edge of the signal, and stay inactive while it has something in front. Below code is done with the arduino attachInterrupt() for simplicity.

attach interrupt(0, isr, RISING); 

 volatile int flag = 0;

void isr(){
flag = 1;  // set the flag when a rising edge exists
}

void loop(){
// other code
  dummy = SensorControl2();
 if(dummy > 0){
  // do something
}

  else{
  return 0;
   }
}

void SensorControl2(){    

if(flag){

flag = 0;

return MachineID;

    }  

else{

return 0;

  }

}

This method produces very reliable results and it has no delay in the function. It is also accurate with objects moving rapidly because of the interrupt.

\$\endgroup\$
  • \$\begingroup\$ @Murat - that's fine, there is another solution for someone else who might have an issue. \$\endgroup\$ – RSM Mar 13 '15 at 5:45
  • \$\begingroup\$ Hi @RSM, i solved my problem with attaching a 10K resistor and 100nF capacitor to output(Simple RC filter circuit). \$\endgroup\$ – Murat Mar 13 '15 at 5:51
  • \$\begingroup\$ Before this correction, I always read analogous read values as 800~900 when there is not any object in front of sensor and I read 1022-1023 values when there is an object. After RC curcuit , I see values exactly "0" when there is not any object. So I understand that 800~900 values were noise of my circuit. Your circuit looks very good to obtain a clean signal. I want to try it. I just want to ask about interrupts. If I use interrup method then I will have faster results(I understood such because of your last sentence) \$\endgroup\$ – Murat Mar 13 '15 at 5:52
  • \$\begingroup\$ @Murat - yep, you will have faster results because the interrupt triggers immediately, also if you insure the flag is what determines if code runs or not in the loop you pick up stuff even quicker. \$\endgroup\$ – RSM Mar 13 '15 at 6:18
  • \$\begingroup\$ thanks for great ideas. Your answer is enough good. I hope it will help everybody whohas similiar problems \$\endgroup\$ – Murat Mar 13 '15 at 9:33
0
\$\begingroup\$

I think it's your code that's causing the slowdown, especially that while loop (already nested within loop()). It could also be the ethernet but I doubt it.

Try this. Use a flag to determine whether or not an object was previously detected so you don't have to write a nested while loop.

int objDetected = 0;    // flag
int detection = 1020;   // detection threshold

void loop()
{
    dummy=0;  
    dummy=SensorControl2();
    if (dummy>0) {
    //Send data to SQL
    }
}

int SensorControl2()
{
sensorValue = analogRead(sensorPin);

if (sensorValue > detection) {
    // Sensor senses something for the first time, sets flag
    if (objDetected == 0) {
        Serial.println("object detected");
        objDetected = 1;
        return MachineID;
    }
    // Sensor senses something but object is still there
    else {
        return 0;
    }
}
// There is no object detected, reset the flag
else {
    objDetected = 0;
}
\$\endgroup\$
  • \$\begingroup\$ you didn't show how should i use this flag in loop(). Or i should ask such, may be it will prevent complexity of main loop but i think it will not solve my main problem. Am i right? \$\endgroup\$ – Murat Jan 11 '15 at 11:01
  • \$\begingroup\$ May be this info can give some information. I read 900-970 values when there is not any item in front of sensor and vice versa i read 1020-1023 values. I don't use any resistor or another electronic component with this Photoelectric sensor and i connect it directly to arduino (+5V (Brown), Ground (Blue) and A2 (White)). May be voltage drop is not enough fast? I started to think to use resistor or capacitor to solve this issue. Here is its Specifications : Resp time Under light received condition:20 μs or less Under light interrupted condition:100 μs or less (Response frequency:1 kHz or more) \$\endgroup\$ – Murat Jan 11 '15 at 12:29
  • \$\begingroup\$ You don't have to use the flag in loop(). It's a global variable that is manipulated by SensorControl2(). \$\endgroup\$ – FullmetalEngineer Jan 11 '15 at 23:31
  • \$\begingroup\$ I tried your code but it detects 100-150 item at a second.. \$\endgroup\$ – Murat Jan 12 '15 at 9:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.