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 CCS Technical Support

Hall sensor's problem with PIC16F887
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
adrix



Joined: 04 May 2012
Posts: 24

View user's profile Send private message

PostPosted: Sun May 20, 2012 4:01 am     Reply with quote

Mike Walne wrote:
Quote:
, but I am getting very random numbers although the motor is spinning 1 time/sec.

What range of numbers are you expecting?

What sort of random numbers are you getting?

Have you looked at your Hall sensor output on a 'scope?

Is the waveform sharp and clean?

Mike


Well as the motor spins at 1 time/sec I expect to show number "1", but the range would be 0-200.
I figured out the random number thing.
Code:
#int_rb     
void RB_ISR(void)
{
if (input(PIN_B2))  //[b]I added this if, and the numbers is showing correctly[/b]
{
 rpm_kint++;
}

}

But when I add another hall sensor on PORTB1 and try to get both values, the lcd is very lagging (every number or letter on lcd is changing very slowly) This is the code:
Code:

#int_rb      //Set external interrupt on pin RB0
void RB_ISR(void)

{

if (input(PIN_B2)) 
{
 rpm_kint++;
}
if (input(PIN_B1))
{
 greicio_kint++;
}
}
   


I can't think of anything that could cause this problem.
I haven't tested the sensors on scope, but when I connect one sensor the outputs is correct, so I think that the sensor works fine.






p.s. I saw that on my pic there are different interrupts on every RB pins, but when I try to make an interrupt called #int_RB1 I get an error. So I have to work with #int_rb am I right?[/code]
Mike Walne



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

View user's profile Send private message

PostPosted: Sun May 20, 2012 6:52 am     Reply with quote

Quote:
I connected it to RB1, but I am getting very random numbers although the motor is spinning 1 time/sec.

I'll re-phrase one of my previous questions:-

When the motor is spinning a 1 turn/sec, do you expect the display to show (a) 1 Hz or (b) 60 rpm ?


Further questions:-

Are you now trying to read rotational speeds for two motors?
Have you read the PIC data sheet on portB change interrupts?

Further comment:-

I don't think that you are going about measuring rotational speed correctly.

I'm surprised that you're even getting one 'good' reading.

Again I suggest you look at your waveforms with a 'scope, so that you can see what you are trying to deal with.

Mike
adrix



Joined: 04 May 2012
Posts: 24

View user's profile Send private message

PostPosted: Sun May 20, 2012 10:33 am     Reply with quote

Mike Walne wrote:
Quote:
I connected it to RB1, but I am getting very random numbers although the motor is spinning 1 time/sec.

I'll re-phrase one of my previous questions:-

When the motor is spinning a 1 turn/sec, do you expect the display to show (a) 1 Hz or (b) 60 rpm ?


Further questions:-

Are you now trying to read rotational speeds for two motors?
Have you read the PIC data sheet on portB change interrupts?

Further comment:-

I don't think that you are going about measuring rotational speed correctly.

I'm surprised that you're even getting one 'good' reading.

Again I suggest you look at your waveforms with a 'scope, so that you can see what you are trying to deal with.

Mike


I want to display 60rpm. Yeah I need to connect 2 hall sensors (one on portb1 and the other on portb2) like I said when I make an interrupt of one sensor, everything works great, but when I put both of them in interrupt the lcd is very laggy. I read about those interrupts on change, but I still cant get those two sensors working together. Well everything with the calculation is ok. I will connect the sensors with a scope tomorrow.

But still maybe you have any suggestions how can I make those two sensors work in the interrupt? btw thanks for your help.
dyeatman



Joined: 06 Sep 2003
Posts: 1949
Location: Norman, OK

View user's profile Send private message

PostPosted: Sun May 20, 2012 12:23 pm     Reply with quote

The problem is likely when both inputs arrive at the same time. Why are you
trying to make them work in the same INT_RB interrupt? You have
separate/individual interrupts available for each pin. Then you know exactly
which input the interrupts are coming from and can treat them separately.
Look in the device header for the definitions.
_________________
Google and Forum Search are some of your best tools!!!!
adrix



Joined: 04 May 2012
Posts: 24

View user's profile Send private message

PostPosted: Sun May 20, 2012 12:51 pm     Reply with quote

dyeatman wrote:
The problem is likely when both inputs arrive at the same time. Why are you
trying to make them work in the same INT_RB interrupt? You have
separate/individual interrupts available for each pin. Then you know exactly
which input the interrupts are coming from and can treat them separately.
Look in the device header for the definitions.


Yeah, I think that too, but the problem is that in the header file I see that there are individual interrupts (INT_RB0, INT_RB,..., INT_RB7) How must I name the interrupt
Code:

#int_rb    // How I must name this part?
void RB_ISR(void)
{
}


Because when I name it #int_rb1 or similar I get an error in the compiler.
Mike Walne



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

View user's profile Send private message

PostPosted: Sun May 20, 2012 1:58 pm     Reply with quote

I would hope your waveforms look somthing like the ones below.

Code:

Waveform A

--      ----      ----      ----      ----      ----      ----      ----      ----      ----      ----      ---
  |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |   
  |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |    |   
   ----      ----      ----      ----      ----      ----      ----      ----      ----      ----      ----     
       0s        1s        2s        3s        4s        5s        6s        7s        8s        9s        10s

Waveform B

---     ---     ---     ---     ---     ---     ---     ---     ---     ---     ---     ---     ---     ---   
   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   
   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   
    ---     ---     ---     ---     ---     ---     ---     ---     ---     ---     ---     ---     ---     ---
       0s        1s        2s        3s        4s        5s        6s        7s        8s        9s        10s

Waveform A performs 4 full cycles in 4 seconds, converts to 60rpm.
Waveform B performs 5 full cycles in 4 seconds, converts to 75rpm.

If you want to measure rate in rpm to the nearest 1 by counting pulses you will have to wait for a full minute between updates.

On the other hand you could measure the period of one sample, then convert to rpm. So at 60rpm the update rate will be once per second, and at 120rpm, twice per second.

Which conversion method would you prefer?


What you APPEAR to be doing is looking to see how often each pin is high when triggered by a PortB change.
BUT you don't KNOW which channel caused the change.
So if B1 is permanently high its counter will increment on every change of B2 and vice-versa.
That's NOT what you want, it's nonsense.

What you DO want is, to count the number of rising or falling edges.

The PIC manual explains the problem you may encounter on trying to use RB interrrupts with two channels.

Quote:

Note: If a change on the I/O pin should occur when
the read operation is being executed (start of
the Q2 cycle), then the RBIF interrupt flag
may not get set. Furthermore, since a read
or write on a port affects all bits of that port,
care must be taken when using multiple pins
in Interrupt-on-Change mode. Changes on
one pin may not be seen while servicing
changes on another pin.

I did ask if you had read the manual!

What you COULD do is:-

(1) Set a timer to create 100us ticks and interrupt at that rate.
(2) Create two up_counters (one for each channel).
(3) Create two period_registers (one for each channel).
(4) Create two update_flags (one for each channel).
(4) In the timer ISR, poll each Port pin in turn.
(5) Compare pin to its previous state.
(6) If pin is unchanged, or has gone low, increment that pin's up_counter.
(6) If pin has gone high, copy its up_counter to its period_register, set its update_flag & reset its up_counter.

(7) Main polls update_flags.
(8) When main finds update_flag set, use period_register to calculate new rpm, reset update_flag.

Mike
dyeatman



Joined: 06 Sep 2003
Posts: 1949
Location: Norman, OK

View user's profile Send private message

PostPosted: Sun May 20, 2012 2:21 pm     Reply with quote

There is a function in the manual that can help called input_change_x()
_________________
Google and Forum Search are some of your best tools!!!!
adrix



Joined: 04 May 2012
Posts: 24

View user's profile Send private message

PostPosted: Thu May 24, 2012 5:33 pm     Reply with quote

I got it working, I don't know how precise it is, but it will satisfy my needs for now. Thanks guys for your help, I wouldn't done it without you.

I have one off topic question, but I don't want to create another thread.
Is there a function that as one variable is incrementing the other would increment too but with a different ratio?

For example:

One variable Second variable

1000 11
...
1500 16
...
2000 21
...
2500 26
...
Mike Walne



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

View user's profile Send private message

PostPosted: Fri May 25, 2012 10:38 am     Reply with quote

Write your own along the lines:-
Code:
  {
    one_variable+=500;
    two_variable+=5;
  }


Will do what you demonstrated.

Mike
adrix



Joined: 04 May 2012
Posts: 24

View user's profile Send private message

PostPosted: Fri May 25, 2012 5:16 pm     Reply with quote

Maybe I asked a question in a wrong way. Here is what I want to do:
I have a motor and I am getting its rpms (0-5000rpm) (rpms is variable X) and I have another variable Y. And as I am increasing the motor speed X variable is increasing, and I want to make that as X is increasing, Y would also increase but not in the same ratio.

I tried to make this with if, but it didn't work.
Code:

if(0<X<1000)
{
Y=30;
}
if(1000<X<2000)
{
Y=50;
}
if(2000<X<3000)
{
Y=60;
}

Maybe you can help me?
and so on.
Mike Walne



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

View user's profile Send private message

PostPosted: Sat May 26, 2012 2:56 am     Reply with quote

How many values does your variable y take?

If it's only a small number then something (untested) like :-

Code:

{
  y = 30;
  if (x>1000) { y = 50; }
  if (x>2000) { y = 60; }
  if (x>3000) { y = 70; }
  if (x>4000) { y = 80; }
}

Will do the job.

If you want more values for y then derive a formula relating y to x, and use that.

OR

Use a lookup table.

Mike
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
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