PIC16F877A - Object Detection and Rejection - Timer Interrupt

Ian Rogers

Joined Dec 12, 2012
1,136
  • ShiftReg &= ~0x0002 // CLEAR the kick bit
That would not compile..Your compiler would have winged.... As I said before the external clock ( provided it's clean enough ) can be as high as 50Mhz.. The counter is independent of clock speed.... Reading Timer1 at that speed brings it's own problems...If you read the high byte the low byte is still changing... rapidly.. A read is almost impossible at high speed.. The datasheet has a recommendation, but there is always going to be a difference.

But as you are using the CCP module it should be okay...
 

Thread Starter

daljeet795

Joined Jul 2, 2018
295
What belt speeds do you expect? Does the belt vary it’s speed or you don’t know the answer. Maybe you can estimate or know a range... 5-10 cm/sec?
VFD is used to control the speed of the motor. We can set at any speed

The conveyor has 1400 RPM motor and roller diameter 72 mm, a circumference of 72 x 3.14159 is 226.19448.

I think Conveyor speed = 1400rpm * 226.2= 316680 mm/s

That would not compile..Your compiler would have winged......
are you talking about missing semicolons?

then you missed a post #359 if I add semicolons It does compiles
 
Last edited:

JohnInTX

Joined Jun 26, 2012
4,787
That would not compile..Your compiler would have winged.... As I said before the external clock ( provided it's clean enough ) can be as high as 50Mhz.. The counter is independent of clock speed.... Reading Timer1 at that speed brings it's own problems...If you read the high byte the low byte is still changing... rapidly.. A read is almost impossible at high speed.. The datasheet has a recommendation, but there is always going to be a difference.

But as you are using the CCP module it should be okay...
Semicolon, OK.
The counting speed and using TIMER1 with external clocking and COMPARE with automatic reset to divide the belt into segments that map to a shift register as well as max speed calculations were shown in detail way back in #150 here and detailed in subsequent posts.
https://forum.allaboutcircuits.com/...on-timer-interrupt.158059/page-8#post-1389586

We're not reading TIMER1 at all.
 

djsfantasi

Joined Apr 11, 2010
9,156
That would not compile..Your compiler would have winged.... As I said before the external clock ( provided it's clean enough ) can be as high as 50Mhz.. The counter is independent of clock speed.... Reading Timer1 at that speed brings it's own problems...If you read the high byte the low byte is still changing... rapidly.. A read is almost impossible at high speed.. The datasheet has a recommendation, but there is always going to be a difference.

But as you are using the CCP module it should be okay...
So, if it moves at 316680 mm/sec or 3,166 cm/sec, how far will it move in 30 ms?

3,166.8 cm/s * 0.03s
95.04 cm​

And at 3,168.8 cm/sec, how far will the belt move between interrupts. You should be able to calculate that figure with the information you’ve supplied me.

It’s important to verify that your program will work in the real world. We know it works in the theoretical world.

* NOTE: I didn’t verify the belt speed calculations, yet. But for purposes of this discussion, the result is acceptable.
 

djsfantasi

Joined Apr 11, 2010
9,156
There is an error in the calculation in post #362. The result should 316680 mm/minute. ( NOT 316680 mm/s)
Thanks for catching that, Les!

That’s why I added a disclaimer to my reply. I wasn’t near the resources I’d use to check the calculation.

My question to the TS stands. What is the time between interrupts.
 

djsfantasi

Joined Apr 11, 2010
9,156
With the information provided by @LesJones , my calculations change to

316,680 mm/minute =
3,166.8 cm/minute =
52.78 cm/sec
So, in the 30ms delay for the scan, the object will move
52.78 cm/sec * 30ms =
52.78 cm/sec * 0.03 sec =
1.58 cm​
So, if an interrupt occurs in less than every 30ms and the object keeps on moving,
Where will the object be at the end of the scan delay?

 

LesJones

Joined Jan 8, 2017
4,174
Hi djs,
Here is a text file I created some time back to save having to search through the thread for the values being used. I don't know if these values are being used at the moment. (It gets confusing when the specifications and the values keep changing.)
Start of text file.
5000 line encoder

1.2 metres from fail detector to reject point.
16500 pulses per 1.2 metres. (13750 pulses per metre.)
Conveyor speed 5.3 metres per second . So counts per second = 5.3 x 13750 = 72875 (13.7 uS) (Conveyor moves (5300 x 13.7)/1000000 = 0.073 mm)

Object length 190mm (so object will take 190/5300 seconds to pass a point = 0.0358 seconds (36 mS)

Object spacing. 20 mm

In 30 mS conveyor moves 5300 x 30/1000mm = 5.3 x 30mm = 159mm
In 30 mS there will have been 30000/13.7 (30 mS divided by 13.7 uS.) steps of the shift register = 2189.8 steps
End of text file,
The speed of 5.3 metres per second in the above table is close to the (corrected. ) calculation of 5.278 metres per second in post #362

Les.
 

JohnInTX

Joined Jun 26, 2012
4,787
Hi djs,
Here is a text file I created some time back to save having to search through the thread for the values being used. I don't know if these values are being used at the moment. (It gets confusing when the specifications and the values keep changing.)
Start of text file.
5000 line encoder

1.2 metres from fail detector to reject point.
16500 pulses per 1.2 metres. (13750 pulses per metre.)
Conveyor speed 5.3 metres per second . So counts per second = 5.3 x 13750 = 72875 (13.7 uS) (Conveyor moves (5300 x 13.7)/1000000 = 0.073 mm)

Object length 190mm (so object will take 190/5300 seconds to pass a point = 0.0358 seconds (36 mS)

Object spacing. 20 mm

In 30 mS conveyor moves 5300 x 30/1000mm = 5.3 x 30mm = 159mm
In 30 mS there will have been 30000/13.7 (30 mS divided by 13.7 uS.) steps of the shift register = 2189.8 steps
End of text file,
The speed of 5.3 metres per second in the above table is close to the (corrected. ) calculation of 5.278 metres per second in post #362

Les.
Thanks, Les, but don't forget that we are using TIMER1/COMPARE to prescale the encoder so that the belt is divided into larger segments. Currently, it's 900 encoder counts per interrupt i.e. 900 encoder counts per belt segment - based on the code in #356. That allows the shift register to be much smaller - it currently fits into about 11bits of a 16 bit integer IIRC, with the distance between sensor and kicker divided into the corresponding 11 equal-length segments. The effective length of each belt segment can be adjusted by varying the value of the COMPARE register in the PIC. When that happens, the effective shift register length must change also so that each belt segment has one corresponding bit in the shift register.

So far, at least :)
 
Last edited:

djsfantasi

Joined Apr 11, 2010
9,156
Hi djs,
Here is a text file I created some time back to save having to search through the thread for the values being used. I don't know if these values are being used at the moment. (It gets confusing when the specifications and the values keep changing.)
Start of text file.
5000 line encoder

1.2 metres from fail detector to reject point.
16500 pulses per 1.2 metres. (13750 pulses per metre.)
Conveyor speed 5.3 metres per second . So counts per second = 5.3 x 13750 = 72875 (13.7 uS) (Conveyor moves (5300 x 13.7)/1000000 = 0.073 mm)

Object length 190mm (so object will take 190/5300 seconds to pass a point = 0.0358 seconds (36 mS)

Object spacing. 20 mm

In 30 mS conveyor moves 5300 x 30/1000mm = 5.3 x 30mm = 159mm
In 30 mS there will have been 30000/13.7 (30 mS divided by 13.7 uS.) steps of the shift register = 2189.8 steps
End of text file,
The speed of 5.3 metres per second in the above table is close to the (corrected. ) calculation of 5.278 metres per second in post #362

Les.
Thanks for the summary. After 18 pages, I know somethings there but it’s a pain to search through all the posts on my mobile phone.
 

Thread Starter

daljeet795

Joined Jul 2, 2018
295
There is an error in the calculation in post #362. The result should 316680 mm/minute. ( NOT 316680 mm/s)

Les.
Thanks, @LesJones for catching that error,

Here is a text file I created some time back to save having to search through the thread for the values being used. I don't know if these values are being used at the moment. (It gets confusing when the specifications and the values keep changing.)Les.
I fully agree with you. This is also a big pain for me. I do not want to do this but I have to do it. whatever I have available at the movement I have to work with that
 

LesJones

Joined Jan 8, 2017
4,174
Hi John,
I think I have lost track of more than the pre scaling of the encoder output by a factor of 900. I will stay out of the discussion until I have worked out the current configuration.

Les.
 

JohnInTX

Joined Jun 26, 2012
4,787
Hi John,
I think I have lost track of more than the pre scaling of the encoder output by a factor of 900. I will stay out of the discussion until I have worked out the current configuration.

Les.
No worries, Les. It has been through a lot of iterations. Good input is always welcome
 

Thread Starter

daljeet795

Joined Jul 2, 2018
295
Great! Let me know how it works out...
Hi John,
I think I have lost track of more than the pre-scaling of the encoder output by a factor of 900. I will stay out of the discussion until I have worked out the current configuration.Les.
I have tested code but It was not working as it supposes to do. I saw the scanner doesn't trigger an accurate position. I think there may be one reason that the interrupt time is less than the scanning time

.@LesJonse I can understand that this is a little difficult to remember the specification. I am sorry because again I am posting a new calculation. I thought I should share real calculation so you can give better advice.

Now I will keep this specification until I get success
  • The distance between the sensor and kicker is 400 mm long
  • Object length is 40 mm
  • 400 mm distance is equal to 10000 pulses of the encoder
  • The distance between the sensor and scanner is 50 mm long
  • let's say 7 objects fit between the sensor and the kicker
  • one segment is equal to 1428 pulses
  • Conveyor speed = 1400rpm * 226.2= 316680 mm/minute
  • Scanner response time is 30 ms
  • Kicker response time is 40 ms
C:
#include <xc.h>
#include <stdio.h>
#include <conio.h>

// CONFIG
#pragma config FOSC = HS
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config BOREN = ON
#pragma config LVP = OFF
#pragma config CPD = OFF
#pragma config WRT = OFF
#pragma config CP = OFF
//END CONFIG

#define ENCODER   RC0
#define SENSOR    RC1
#define Scanner   RD0
#define KICKER    RD1

#define _XTAL_FREQ 20000000

__bit gotIRQ;  // signals main that an interrupt occurred

void putch(char data)
{
    while(!TRMT);
    TXREG = data;
}

  char  getch ()
{
   if(OERR == 1){     // reset UART on overflow error
       CREN = 0;
       CREN = 1;
  }
  while(RCIF==0);   // Wait till the data is received
   return(RCREG);   // Return the received data to calling function
}

void send (char *s)
{
  while (*s != 0)
  putch(*s++);
}

void main(void)
{
  char data;
  unsigned int ShiftReg = 0; //  Init to 0
  INTCON = 0;  // No interrupts
  TRISC = 0b00000011; // RC0 Encoder Pin RC1 Sensor Pin
  TRISD = 0b00000000; // RD0 Kicker pin
  TXSTA = 0b00100100;  // TX enabled, BRGH=1
  RCSTA = 0b10010000;  // Serial Port, Continuous Receive enabled
  SPBRG = 0x81;  // baud rate 9600

  //CCP1 MODULE INITIALIZATION
  T1CON = 0b00000011;  // 1:1 prescale, OSC disabled, Input Synchronized, External clock on T1CKI(RC0), Timer ON
  CCP1CON = 0b00001011;  // Compare mode using CCPR1H and CCPR1L as a 16 bit value

  //Set CCPR1H and CCPR1L (16 bits) to the number of encoder pulses e
  CCPR1H = 0x01;
  CCPR1L = 0x2C;
  CCP1IF = 0;
  CCP1IE = 1;  //Enabled CCP1 interrupt
  INTCON = 0xc0;  //Enabled Global interrupts & Peripherals interrupt

  while (1)
  {
      if  (gotIRQ)
         {
           gotIRQ = 0;  // acknowledge the interrupt ** ALWAYS and before the delay **

          ShiftReg <<= 1;  // shift the integer shift register one bit left. LSbit = 0 after shift

           if (SENSOR == 1)
              ShiftReg |= 0x0001;  // bad object, put 1 in LSbit

           if (ShiftReg & 0x0002)
              Scanner = 1;  // enable
              __delay_ms(30);  // response time
             data = getch();
              Scanner = 0;  //  disable
   
           if (data == 'B')
             ShiftReg |0x0002; // set the kick bit,

           if ( data == 'G')
               ShiftReg &= ~0x0002; // CLEAR the kick bit

           if (ShiftReg & 0x100)
              KICKER = 1;  // set output pulse high
               __delay_ms(40);
              KICKER = 0;  // set output pulse low
         }
    }
}

void __interrupt() IRQ(void){
  // CCP1 Interrupt
  if(CCP1IF == 1)  // if the CCP1 Interrupt flag is set...
  {
    CCP1IF = 0;
    gotIRQ = 1;  // 'Signal' main that an interrupt happened
  }
}
Note: I have changed the timer register value in the program such as 700, 800, 500, 1428 1228
 
Last edited:

LesJones

Joined Jan 8, 2017
4,174
If I understand you code correctly you are setting / clearing bit 1 of the shift register with the scanner result but in the 30 mS the object an the shift register bit representing the object have moved on in during that time.
Here are the values you gave in post #377 plus calculations for division ratios of 1428 and 300.

Now I will keep this specification until I get success

The distance between the sensor and kicker is 400 mm long
Object length is 40 mm
400 mm distance is equal to 10000 pulses of the encoder
The distance between the sensor and scanner is 50 mm long
let's say 7 objects fit between the sensor and the kicker
one segment is equal to 1428 pulses
Conveyor speed = 1400rpm * 226.2= 316680 mm/minute ( = 5278 mm / Sec. )
Scanner response time is 30 ms
Kicker response time is 40 ms

-----------------------------------

With prescale of 1428

1 segment = (400 x 1424 )/10000 = 57.12mm (Or 57.12/5278 second = 0.0108 seconds = 10.8 mS)

In 30 mS object moves (5278 x 30)/1000 =158.24mm So the bit in the shift register representing the object will be in bit position 4 of the shift register. (1 + 30/10.8 = ~1 +3)

-----------------------------------
With prescale of 300

1 segment = (400 x 300 )/10000 = 12.00mm (Or 12.0/5278 seconds = 0.00227 seconds = 2.27 mS)

In 30 mS object moves (5278 x 30)/1000 =158.24mm So the bit in the shift register representing the object will be in bit position 14 of the shift register (1 + 30/2.27 = ~ 1 + 13)

Les.
 
Top