CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Pulse counting routine

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
RandyP



Joined: 15 Jun 2015
Posts: 16
Location: Dallas, TX

View user's profile Send private message Visit poster's website

Pulse counting routine
PostPosted: Sat Jul 04, 2015 1:48 pm     Reply with quote

Using PIC 16F690, MPLAB 8.92, and PicKit3, and CCS V4.050

I am working on a program in which a number of pulses at Pin RA4 are to be counted and actions taken based on the number of pulses.

The first pulse acts as a start pulse. On seeing the first pulse the program should wait for the falling edge of the pulse and count pulses from there.

The input pulse train is:
start bit: Ton is 2msec, Toff is 2msec,

each pulse after start pulse is:
Ton is 4msec, Toff is 4msec

The pulses are generated by 1st 16F690 (works great) and come out of the chip at pin C4. At C4 there is 10K to gnd, and a 1K to the input of 2nd chip (Pin A4).

Here is the schematic:


Here is what I think I am doing:


And here is the section of code relevant to this task:
Code:

  Valid = 0;                      // initialize global variable Valid
  Pulse = 0;                       // initialize global variable Pulse
   
    while(!input(PIN_A4))            // wait for PIN_A4 to go low: known starting point
    {Valid = 0;}

      delay_ms(4);                  // get to middle of Ton 1st pulse

         //***********************************************************************************

     if(input(PIN_A4))                // Pulse 1 Ton check
   {Pulse = 0.5;                  // Pulse = 0.5
    Valid = 1;}
     else{Valid = 0;}
     delay_ms(4);

     if (!input(PIN_A4))             // Pulse 1 Toff check
   {Pulse = Pulse + 0.5;            // Pulse = 1.0
    Valid = 1;}
     else {Valid = 0;}
     delay_ms(4);   


         //***********************************************************************************

    if(input(PIN_A4))                // Pulse 2 Ton check
   {Pulse = Pulse + 0.5;            // Pulse = 1.5
    Valid = 1;}
     else {Valid = 0;}
     delay_ms(4);

     if(!input(PIN_A4))                // Pulse 2 Toff check
   {Pulse = Pulse + 0.5;            // Pulse = 2.0
    Valid = 1;}
     else {Valid = 0;}
     delay_ms(4);


          //***********************************************************************************

     if(input(PIN_A4))                // Pulse 3 Ton check
   {Pulse = Pulse + 0.5;            // Pulse = 2.5
    Valid = 1;}
     else {Valid = 0;}
     delay_ms(4);

     if(!input(PIN_A4))                // Pulse 3 Toff check
   {Pulse = Pulse + 0.5;            // Pulse = 3.0
    Valid = 1;}
     else {Valid = 0;}
     delay_ms(4);

         //***********************************************************************************

     if(input(PIN_A4))                // Pulse 4 Ton check
   {Pulse = Pulse + 0.5;            // Pulse = 3.5
    Valid = 1;}
     else {Valid = 0;}
     delay_ms(4);

     if(!input(PIN_A4))             // Pulse 4 Toff check
   {Pulse = Pulse + 0.5;            // Pulse = 4.0
    Valid = 1;}
     else {Valid = 0;}
     delay_ms(4); 

         //***********************************************************************************

    if (input(PIN_A4))                // Pulse 5 Ton check (is invalid)
   {Pulse = Pulse + 0.5;            // Pulse = 3.5
    Valid = 0;}   
 

         // Convert from number of pulses to channel (pin number)
   if (Pulse == 1.0)
      {pin = PIN_C0;}
   if (Pulse == 2.0)
      {pin = PIN_C1;}
   if (Pulse == 3.0)
      {pin = PIN_C2;}
   if (Pulse == 4.0)
      {pin = PIN_C3;}

   output_low(LastPinHigh);// turn off last led
   output_high(pin);// turn on new led
   LastPinHigh = pin;// save pin name for next time
   


This is just a section of main code, all variables have been declared. Anyone see anything obviously wrong?

The problem is when I close SW1 LED 1 for both chip should go on. Chip 1 does light LED 1 and properly sends the correct number of pulses to chip 2. But the LEDs for chip 2 turn on and off erratically. I don't want to use RS-232 communications or I2C. Any suggestions?

Randy P
_________________
Randy Principe
Electrical Engineering Technician
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Sat Jul 04, 2015 3:26 pm     Reply with quote

For starters, try using integers rather than FP.

Mike

It's more helpful if you post short, complete compilable code we can copy and paste to test.
RandyP



Joined: 15 Jun 2015
Posts: 16
Location: Dallas, TX

View user's profile Send private message Visit poster's website

Pulse counting routine
PostPosted: Sat Jul 04, 2015 3:36 pm     Reply with quote

Thanks. Are you saying I can ignore the low part of the pulses and just count the highs? I will try it.

I purposely didn't put the entire code up because it is long. I must say I never thought someone might try to run it...
_________________
Randy Principe
Electrical Engineering Technician
RandyP



Joined: 15 Jun 2015
Posts: 16
Location: Dallas, TX

View user's profile Send private message Visit poster's website

once more
PostPosted: Sat Jul 04, 2015 3:38 pm     Reply with quote

Oh, I get what you are saying. Create a short compilable program that illustrates my problem. Not necessarily the entire program, much of which is irrelevant to my post. I got it, thanks.
_________________
Randy Principe
Electrical Engineering Technician
RandyP



Joined: 15 Jun 2015
Posts: 16
Location: Dallas, TX

View user's profile Send private message Visit poster's website

Using a debug would help, but...
PostPosted: Sat Jul 04, 2015 3:45 pm     Reply with quote

I was going to debug with the PicKit3 but the setup required different OSC settings and different pins, etc. and I didn't want to start tearing up my board, so I was turning chip 2's led's on at certain points to help me troubleshoot. Wish I could simulate the whole thing.

Randy
_________________
Randy Principe
Electrical Engineering Technician
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

Re: once more
PostPosted: Sun Jul 05, 2015 2:40 am     Reply with quote

RandyP wrote:
Oh, I get what you are saying. Create a short compilable program that illustrates my problem. Not necessarily the entire program, much of which is irrelevant to my post. I got it, thanks.


Yes, most of the regulars here don't trust simulators (Proteus et. al.). We believe real hardware is the only true test.
If you only show us part of your code, we've no way of knowing what's missing, the problem could be in a declaration elsewhere!


A few more points:-

You've got repeating code for each pulse state. Hint, you should be able to reduce to one simpler occurrence.
You're using delay_ms(xx). Ties up your processor, so it can't do anything else.

Mike

PS You could test receiver code in MPLAB_SIM with an external stimulus to take the place of the pulse generator.
mbradley



Joined: 11 Jul 2009
Posts: 118
Location: California, USA

View user's profile Send private message Visit poster's website

PostPosted: Mon Jul 06, 2015 12:05 am     Reply with quote

Just thinking out of the box, what we have here is a serial stream, with a start bit start.

What about tweeking the baud rate on a uart, and then use the count of high bits?

Ex: 0b1100000 would equal 2 pulses

Just a thought.
_________________
Michael Bradley
www.mculabs.com
Open Drivers and Projects
Ttelmah



Joined: 11 Mar 2010
Posts: 19219

View user's profile Send private message

PostPosted: Mon Jul 06, 2015 1:14 am     Reply with quote

and in the code given, 'beware of latency'.

The code checks for an edge, and then delays, then tests again. If you think about it, the check for edge itself will always test 'true' a short time _after_ the edge (latency of the hardware and code), then add the delay, and the time for the next test, and you will always be a little while _after_ where you expect to be. It shouldn't be too bad as shown (since the data rate is slow), but could well lead to cumulative errors in where you are actually working in the waveform....
guy



Joined: 21 Oct 2005
Posts: 291

View user's profile Send private message Visit poster's website

PostPosted: Mon Jul 06, 2015 3:07 am     Reply with quote

Adding to the above tips, make sure RA4 (AKA AN3) analog function is disabled.
To debug the system I would first cut the system in half and *make sure* that the first PIC is indeed transmitting what you expect it to transmit. This could be done with an oscilloscope or with a very simple test program such as:
Code:

output_low(PIN_C5);
while(input(PUSHBUTTON)); // wait for pushbutton for example

output_high(PIN_C5);
delay_ms(2);
output_low(PIN_C5);
delay_ms(2);
output_high(PIN_C5);
delay_ms(4);
output_low(PIN_C5);
delay_ms(4);
output_high(PIN_C5);
delay_ms(4);
output_low(PIN_C5);
while(1);    // wait forever.

etc.

I don't see in your code that you wait for a RISING edge before waiting for a falling edge while waiting for a start pulse.
Also I can offer my version of the code which you could learn from (I haven't tested it).
Code:

int Pulse;

Pulse=0;
// ASSUMING that the system wakes up without a transmission in progress.
// if a transmission is in progress, data bits will be treated as start bits!

while(!input(PIN_A4));   // wait for rising edge of start bit
while(input(PIN_A4));    // wait for falling edge of start bit
delay_ms(4);
// now it's the middle of Ton (or end of pulse chain)
// the While sentence tests if line is high (there is a pulse) or low (the end of the pulse chain) :
while(input(PIN_A4)) {
    // now it's the middle of Ton, pulse is present
    Pulse++;  // increase pulse counter
    while(input(PIN_A4)) ;   // wait for falling edge. This is important to keep sync and avoid latency issues.
    delay_ms(6);    // skip Toff and half of the next Ton
    //now we are at the next sampling point
}
// Pulse will contain number of pulses.

Other things to consider: if for any reason the two PIC loose sync (for example noise on the line triggers the receiving side by mistake) there should also be some timeouts and re-synchronization in the code.
RandyP



Joined: 15 Jun 2015
Posts: 16
Location: Dallas, TX

View user's profile Send private message Visit poster's website

RE: Pulse counting routine
PostPosted: Mon Jul 06, 2015 8:26 am     Reply with quote

Thank you all. Great suggestions.

Somehow I started a new thread without knowing it and thanks to Guy I realized that I was watching the new thread while you were giving great suggestions on the real post. I guess that happened because I put a different subject. Am I correct in that the subject line always has to be the same for one thread?

It turns out the main problem was - say I had one pulse. I would count the first Ton and Toff and pulse would equal 1 (thanks for the tip about floating point Vs int) at that point if the next Ton was low I needed to get out of the string of if's. As it was I would still be counting the next several "lows" giving me an incorrect value of pulse.

I will try some of the previous suggestions to see if I can improve my code.

Thanks again everyone,
Randy
_________________
Randy Principe
Electrical Engineering Technician
guy



Joined: 21 Oct 2005
Posts: 291

View user's profile Send private message Visit poster's website

PostPosted: Mon Jul 06, 2015 8:47 am     Reply with quote

Quote:
Am I correct in that the subject line always has to be the same for one thread?

simply go into the thread you started and click Post Reply. Leave the subject line empty.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group