PIC16F877A - Object Detection and Rejection - Timer Interrupt

LesJones

Joined Jan 8, 2017
4,191
Hi Max,
I think the TS said at one point that the distance between the sensor and the reject point was 1.2 metres. In post #93 I made a mistake. I read the value to pre load the counter for one of the TS's requested count values. So if we use the count value of 16500 (Quoted in post #97 ) then one count = 1200mm /16500 = 0.073mm.

Les.
 

JohnInTX

Joined Jun 26, 2012
4,787
Sorry, I didn't mean to open a can of worms here :confused:

I recalled the shift register approach when the TS added the requirement that multiple items be on the belt. That is different than just counting into TIMER1. Since there is only one TIMER 1, counting multiple objects between the sensor and blow-off jet will be problematic. Multiple counters could work but since I brought it up, here's how I would consider doing it.

The encoder has much more resolution than necessary but that doesn't mean that you need a huge shift register either.

  • First, determine how many objects fit between the sensor and blow-off jet. For the sake of argument let's say that 10 objects fit between the sensor and the kicker, in any orientation. That divides the distance between the sensor and kicker into 10 slots. That sets the minimum resolution needed by the system.
  • Now, imagine that as the objects go by you look at each one (at the sensor) and you put a sticker on any that need kicking off. When an object with a sticker on it goes by, fire the air jet and kick it off. That is the basic problem statement.
  • But we're not using stickers but we could use a shift register that a bit is entered and shifted ONCE each time an object went by the sensor. If the object needs kicking, the bit is 1. If the object is OK, the bit is 0.
  • The distance between the sensor and kicker is 10 objects long so if the shift register is 10 bits long, the 'kick-it' bit set by the sensor will 'follow' the object down the belt, (one shift for each object distance on the belt) and appear at the end of the shift register when the object is at the kicker. The kicker will activate whenever it sees a '1'. Note that as objects go by the sensor, a new bit gets shifted in. There can be as many 1's as there are bad object. A '1' in the shift register is like the sticker in the example.
  • So we have a belt 10 objects long and a shift register 10 bits long that follows the objects down the belt. How do we know where each 'slot' on the belt is? That's what the encoder is for.
  • We know that the encoder generates way more than 10 pulses between the sensor and kicker. Someone said 36000 so let's use that. If you divide that number into 10 object-lengths you get 3600 encoder pulses per object. So.. I would use that timer/counter setup that you just did to generate a signal (TMR1IF) every 3600 pulses. On that signal, inspect the object under the sensor and shift a 1 or 0 into the shift register.
  • Continue, watching successive objects every TMR1IF (3600 encoder pulses) and shifting 1 or 0 as required. As it shifts, the first object will be at the jet after 10 shifts (36000) counts and the output bit of the shift register will be indicate whether it should be kicked.

The shift register can be a simple integer. Use arithmetic shifts and add bits to the location you need. For example a 16 bit unsigned integer making a 10 bit shift register:

C:
unsigned int ShiftReg = 0; //  Init to 0

if (3600 pulses){
  reload_timer(3600);
  ShiftReg << 1;  // shift the integer shift register one bit left. LSbit = 0 after shift
  if (object_is_bad)
     ShiftReg |= 0x0001;  // bad object, put 1 in LSbit
if(ShiftReg & 0x0400) // and if the #10 bit after shift is '1', kick it
    kick_the_object();
}
In practice, you likely would want a bit more resolution so divide the belt into zones 1/2 or 1/4 objects long if you need to. If you need more bits, use an unsigned long (32 bits). Chain them if you need even more bits.

That's one, simple way to do it. It does assume that the objects are more or less evenly spaced along the belt.

Just my .02
 
Last edited:

MaxHeadRoom

Joined Jul 18, 2013
28,699
I used to be called in to service the local brewery's bottling line for Canada's three main beer companies and IIRC when a reject was detected, it was dealt with immediately at that position, rather than further down the line.
Max.
 

Ian Rogers

Joined Dec 12, 2012
1,136
I think the best way to get a different count each time would be to use a simple array... That is of course if the counter is known in advance.

int counters[5] = { 1st count, 2nd count, 3rd count etc..}

Then increment an index each time..
 

djsfantasi

Joined Apr 11, 2010
9,163
I think the best way to get a different count each time would be to use a simple array... That is of course if the counter is known in advance.

int counters[5] = { 1st count, 2nd count, 3rd count etc..}

Then increment an index each time..
I think that’s similar to what I suggested. FIFO lists or queues are implemented as a simple array. I precalculate the value of the counter when a rejected item will be in front of the reject station. Then, I store this in an array. Two indices are used. One is the pointer or subscript to the front of the list. The other is the pointer or subscript of the end of the list. Calculating the next subscript value is simple, integer modulus arithmetic.

This approach does not depend on the spacing nor size of the objects. To be modular, functions to insert and delete a counter value from the list can be used.
 

Thread Starter

daljeet795

Joined Jul 2, 2018
295
I might be getting it. From the inspection station to the reject station is 16,500 counts. That value represents the distance.
You don’t need a shift register. You need a FIFO list. Which is fairly simple to program. The maximum size of the list is equal to the number of objects that can fit from the inspection point to the reject point..
@djsfantasi
You are saying that we do not need shift register

@LesJone already said It CANNOT work with multiple items between the detector and reject point as it is using a physical counter in the PIC

I am not clear how the hardware timer will work in the FIFO list. As I understand the hardware counter can work once at one time and we have multiple objects between inspection station to the reject station

There are the many programs available for FIFO It would be challenging for me to write for PIC16f877a

If I don't need the shift register than how to start making a queue in program post #88
 

Thread Starter

daljeet795

Joined Jul 2, 2018
295
Hi Max,
I think the TS said at one point that the distance between the sensor and the reject point was 1.2 metres. In post #93 I made a mistake. I read the value to pre load the counter for one of the TS's requested count values. So if we use the count value of 16500 (Quoted in post #97 ) then one count = 1200mm /16500 = 0.073mm.
Les.
@LesJones I mentioned previously, The distance between the sensor and the reject point was 1.2 meters. I don't get the same conveyor for testing
But I think both the distance should be the same in the size because both conveyors looking same in size and distance
 

Thread Starter

daljeet795

Joined Jul 2, 2018
295
Sorry, I didn't mean to open a can of worms here :confused:

I recalled the shift register approach when the TS added the requirement that multiple items be on the belt.
The shift register can be a simple integer. Use arithmetic shifts and add bits to the location you need. For example a 16 bit unsigned integer making a 10 bit shift register:

C:
unsigned int ShiftReg = 0; //  Init to 0

if (3600 pulses){
  reload_timer(3600);
  ShiftReg << 1;  // shift the integer shift register one bit left. LSbit = 0 after shift
  if (object_is_bad)
     ShiftReg |= 0x0001;  // bad object, put 1 in LSbit
if(ShiftReg & 0x0400) // and if the #10 bit after shift is '1', kick it
    kick_the_object();
}
In practice, you likely would want a bit more resolution so divide the belt into zones 1/2 or 1/4 objects long if you need to. If you need more bits, use an unsigned long (32 bits). Chain them if you need even more bits.
@JohnInTX
Thank's for mentioning example code in your post You told about the shift register
I have code that can reject one object between the detector and reject point as it is using a physical counter in the PIC so If I use software shift registers How to start in program #88

I don't have the capability to write a complete program so I have to set small points to achieve a complete target
 

LesJones

Joined Jan 8, 2017
4,191
daljeet795,
Can you explain the reason for wanting to use a 5000 CPR encoder ? To design a system like this I would start by working out how many pulses are required per unit length of the belt. (This is to ensure that you can identify objects on the belt with the closest spacing that will occur.) From this information together with the diameter of the roller that is fitted to the encoder you would calculate the CPR value that was required. You seem to be working the other way round by just picking some random CPR value and trying to make it work. This is making the micro controller need to increment (Or decrement.) 5 counters and check if any of them have reached the value were the object is at the rejection point for every 0.07mm (From the last estimate.) movement of the belt. John's explanation of the shift register method shows a logical approach to designing the system.

Les.
 

Thread Starter

daljeet795

Joined Jul 2, 2018
295
Tell me the list of timer preloads... One is obviously 3001 counts... What are the others..
I have only one value 65536-16500 = 49,036. A timer should be starting from 49,036 for accurate rejection

@Ian Rogers perhaps rough diagram can clear doubts

There are five objects between the detector and reject point

upload_2019-5-3_15-27-13.png
 

Thread Starter

daljeet795

Joined Jul 2, 2018
295
daljeet795,Can you explain the reason for wanting to use a 5000 CPR encoder ? Les
I am looking for some part to purchases for the project. I had already 5000 PPR encoder before, That is the only reason to use in testing. I would order another encoder (500, 1000 PPR value )

I also want to change microcontroller pic16f877a I have been discussed before. Do I need to buy shift register IC ? or else we can make shift register in the program.
 

Ian Rogers

Joined Dec 12, 2012
1,136
Okay!! Looking at your diagram, I would like to steer you towards the CCP module.. This is a purpose built module for this sort of work.

This will be no different than frequency calculation.. I'll see if I can put a diagram and a bit of code together to show what I mean.
 

Thread Starter

daljeet795

Joined Jul 2, 2018
295
Okay!! Looking at your diagram, I would like to steer you towards the CCP module.. This is a purpose built module for this sort of work.
I'll see if I can put a diagram and a bit of code together to show what I mean.
@Ian Rogers That's good I would like to see if it happen
I think we can also use external hardware interrupt to count pulses but maintain the queue is a very difficult part of the project
 
Last edited:
Top