Execute function after count

Hello,

I checked for threads with similar questions but wasn't able to find what I am looking for.

I am working on a project that identifies whether a part made in our factory should pass or fail a QC step. The parts run on a conveyor belt that steps at intervals and has a number of stations. At the inspection station a picture is taken and analysed, whether the part passes or fails the belt will continue to step forward.

If it fails though, a signal is sent to the arduino. At this point I need to initiate a counter and after four steps execute an output that will remove the part from the belt. The steps are controlled by a sensor that detects a marker on the belt, so my plan is to use the signal from the sensor and count that four times. Once the counter reaches 4 the output should be triggered.

How do I write a function that will initiate a counter when receiving the camera signal and then count every time the sensor signal is received?

This project is an upgrade to include more processes on the conveyor. The initial version is only used to engrave a batch # on the part. Now we want to have parts that have failed a previous process to be rejected before even making it to the engraver.

Here is what I have so far. I have recycled the code from version 1 and added the additional inputs and outputs to the scope as well as a rejectCount integer. In void setup I have declared whether the new connections are inputs or outputs. I have made no changes to void loop thus far, so this is what the previous conveyor runs on. The "relay" output controls the cut off to the motor to make the belt stop.

I work mostly with design and electronics, with limited coding knowledge, so please excuse anything outside best practise norms. I am using a Mega 2560 for this.

#define reject 40 //Reject output signal to solenoid
  #define camera 42 //Reject input signal from camera
    #define locator 44 //Locators for belt alignment
      #define conSens 46 //Sensor to detect connector presense
        #define laser 48 //Engraver
          #define relay 52 //Relay for motor cut off
            #define beltSens 50 //Sensor to trigger motor cut off

int rejectCount = 0;
  int beltState = 0;

void setup() {
pinMode (reject, OUTPUT); //Output signal for rejection
  pinMode(camera, INPUT); //Input signal to identify failed connector
    pinMode(locator, OUTPUT); //Output signal to trigger locators
      pinMode(conSens, INPUT); //Input signal to confirm connector presense
        pinMode(laser, OUTPUT); //Output signal to trigger engraver
          pinMode(relay, OUTPUT); //Output signal to stop motor
            pinMode(beltSens, INPUT); // Input signal to trigger motor stop + camera   
}

void loop() {

beltState = digitalRead(beltSens);  //Read sensor state to detect part

if(beltState == HIGH)
{   
digitalWrite(relay, HIGH); //Cut power passing through relay to bring motor to stop
  delay(250); //Delay before engaging locators
    digitalWrite(locator, HIGH);  //Engage locators
      delay(200); //Delay before starting engrave
        digitalWrite(laser, HIGH);  //Start engraving
          delay(200); //Delay to allow engrave to complete
            digitalWrite(laser, LOW); //Disengage engraver
              delay(1100); //Delay before disengaging locators
                digitalWrite(locator, LOW); //Disengage locators
                  delay(150); //Delay before re-engaging relay
                    digitalWrite(relay, LOW); //Engage relay to resume motor
                      delay(350); //Delay to avoid sensor reading HIGH for same part
}
}

void rejected() {
rejectCount = digitalRead(beltSens);
if (camera == HIGH) {

}
}

I think the best way to get this done is to write a function that does the counting and is called when the camera signal is received.

Any assistance will be greatly appreciated.

Regards
Deeds

not clear why you think you need a counter. suggests you already know how to do this.

seems that there should be a signal that triggers the process, regardless of # of steps to remove the part.

why 4? what fi there is only 3? presumably there is a signal to trigger the engraving and a separate signal to trigger the removing

do you want to detect a video stream or is it simply a digital level indicating what(?) ?

looks like you love 45° angles :slight_smile:

➜ make sure you indented the code in the IDE before copying, that's done by pressing ctrlT on a PC or cmdT on a Mac)


joke aside

  • I suppose the 4 steps are there so that the parts move to the position where it can be ejected?

  • do you have other parts coming in the mean time? if so you need to have a 4 unit buffering system for the possible other parts going in front of the camera to decide if you need to control ejection or not. a circular buffer would do

That is correct. The number of steps on the belt between where it is analysed and where it is rejected is 4 steps. The fail signal from the camera will come to the arduino immediately, but the belt will need to continue stepping and 4 steps later an output signal needs to be triggered to reject the part.

Parts basically never stop coming in, so the other functions should continue as normal and whenever the fail signal is received the part needs to be rejected after another 4 steps. If 2 or more consecutive parts fail the reject signal will need to go out with every instance.

Not sure what a circular buffer entails, but you seem confident that it can work. I will do some reading, but feel free to elaborate.

Thanks

//why dont you initialize a counter variable.
//i.e. 
int counter =0;
//on every pulse you receive do increment
counter++;

// then check 
if(counter == 4) {
// do what you want to
} 

what if 2 adjacent parts fail?

might be better to have a counter constantly incremented and track the ones that need to be rejected when count + 4 matches their values

yes some sort of a buffered output is required

i assumed this is why you mentioned circular buffer

The Arduino needs access to the sensors (photoelectrics?).

  1. The inspection station passes the result of the pass/fail decision to Arduino which will store this internally in stage one. One code for pass, a different code for fail.

  2. When sensor one detects part the pass/fail code moves from stage one to stage two and stage one is cleared.

  3. When sensor two detects part the pass/fail code moves from stage two to stage three and stage two is cleared.

  4. And so on and so on.

  5. When part reaches stage four and sensor reacts, the pass/fail code is checked and a decision made to actuate the reject mechanism, or not.

what does this look like? do you get a short pulse ?

what does this look like? do you get a signal (which one) if the part is OK ?

if you get pulses, basically the rejection signal just copies the camera signal but delayed by 4 belt steps ticks

1 Like

During a break in the action here I ran w/ @J-M-L's insightful diagram.


Play with it here on the wokwi simulator.

// https://forum.arduino.cc/t/execute-function-after-count/1057468
// https://wokwi.com/projects/349255255985226324

# define reject 2   // signals this item is a reject

void setup() {
  Serial.begin(115200);
  Serial.println("conveyor belt world\n");

  pinMode(reject, INPUT_PULLUP);
}

int currentPart;

# define FOUR 4       // steps from inspection to rejection
# define DWELL  1000  // time window for rejection

unsigned char tape[FOUR];   // circular buffer?
unsigned char writePosition;
unsigned char readPosition;

# define OK     0
# define REJECT 1

void loop() {

  static unsigned long lastTime;
  unsigned long now = millis();

// always check to see if we need to reject this part

  if (digitalRead(reject) == LOW) {
    if (tape[writePosition] != REJECT) {
      Serial.print("            REJECT PART ");
      Serial.println(currentPart);

      tape[writePosition] = REJECT;
    }
  }

// run the rest of loop every DWELL ms

  if (now - lastTime < DWELL) return;
  lastTime = now;

  currentPart++;
  Serial.print("now welcoming ");
  Serial.println(currentPart);

  writePosition++; if (writePosition >= FOUR) writePosition = 0;

  readPosition = writePosition; // oldest on the tape

  if (tape[readPosition] == REJECT) {
    Serial.print("                   rejecting ");
    Serial.println(currentPart - FOUR);
  }

  tape[readPosition] = OK; 
}

HTH

a7

The Arduino has access to the sensors. A number of the electronics, including the sensors, run off a 24V supply. The signal from the sensor is connected accross the coil of a relay which lets a 5V signal through to the Arduino.

I am unfamiliar with stages. Could you please give more information, I will also do some googling.

Thanks

So when there is no signal arduino sees GND level ?

Is the time diagram above meaningful?

That is correct. It is a photoelectric sensor that sends a 24V signal when the marker is detected. This signal triggers a relay which passes a 5V signal to the Arduino. When the Arduino receives this signal it passes a signal to another relay that cuts off the signal going to the motor.

The motor is a NEMA34 which is driven by a seperate Arduino Uno. I could possibly make use of this 2nd Arduino to assist with the rejection process.

The camera passes a 24V signal when a part fails. This signal reaches the Arduino in the same way as the signal from the sensor. Currently the fail signal is the only signal the camera puts out, I can however have it put out a pass signal as well.

Thanks for helping out.

Correct.

The time diagram is very helpful in visualising where the signals/pulses are relative to one another.

Thanks

So did you play with @alto777’s code ?

Just arrived at work, so about to get started on trying some things.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.