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 1, 2  Next
 
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

Hall sensor's problem with PIC16F887
PostPosted: Fri May 11, 2012 12:19 pm     Reply with quote

Hi guys,

I'm using a hardware project, connected hall sensor (here is his datasheet http://sensing.honeywell.com/index.php/ci_id/45265/la_id/1/document/1/re_id/0 ) with pic16f887. I found a code called count.c and I'm trying to make it work for me, but it's not happening.
Here is the main code:
Code:
#include <16F887.H>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
//#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#include "t6963.h"
#include "t6963.c"
#include "count.c"

//======================================
void main()
{
int8 rpm[50];
int result;


      GDispInit();                  //T6963C display initialization
      FontSize = 8;                  //8 font mode
      GDispSetMode(XOR_MODE|INT_CG_MODE);   //Exclusive OR mode, internal CG character RAM
      GDispSetMode(TEXT_GRH_ON);         //Text ON, Graphics ON
      GDispClrTxt();
      GDispClrGrh();                  //Clear the graphics area (dot-by-dot!)


// Measure the number of counts in one second
// from the input signal on Pin B0.  This will
// be the frequency (in Hz) of that signal.
while(1)
  {
   result = count(PIN_B0, 1000);   // count period = 1000 ms
   sprintf(rpm, "%d", result);
   GDispPixFontAt(1, 1, rpm, 1, BLACK);   //display a 10x14 font for string "Hey" in pixel   
  }

}


And count.c
Code:
// Count.c

#define BYTE_PTR(x) &(int8 *)(x)

#define COUNT_DELAY ((int16)(getenv("CLOCK") / 80000))

// ASM definitions
#define W  0
#define F  1

// Status Register Bits
#define Z  2
#define C  0

// Register addresses (16F)
#byte INDF   = 0x00
#byte STATUS = 0x03
#byte FSR    = 0x04

//---------------------------------------
int16 count(int8 ccs_pin, int16 period)
{
int8 const bitmask_table[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
int8  io_port;
int8  bitmask;
int16 R0;
int16 R1;
int16 R2;
int16 R3;
int32 loop_count;

// These variables are used in the ASM code
// and must be located in the same RAM bank.
#locate R0      = 0x30
#locate R1      = 0x32
#locate R2      = 0x34
#locate R3      = 0x36
#locate io_port = 0x38
#locate bitmask = 0x39

// Extract the Port address and bitmask from
// the CCS pin number.
io_port = ccs_pin >> 3;
bitmask = bitmask_table[ccs_pin & 7];

// Set the pin to be an input pin.
output_float(ccs_pin);

// Calculate the number of loop iterations to do.
loop_count = _mul(period, COUNT_DELAY);

// Put loop_count into R0 (msb), R2+1 (mid), R2 (lsb)
R0 = make8(loop_count, 2);  // msb
(int8)R2 = make8(loop_count, 1);  // Get mid into  R2
R2 <<= 8;  // Move mid into R2+1
(int8)R2 = make8(loop_count, 0); // lsb

#asm   
    movf    io_port, W         ; Get port
    movwf   FSR
    incf    R0, F              ; Bump up high and mid for dec
    incf    BYTE_PTR(R2) +1, F
    clrf    R1                 ; Zero counter
    clrf    BYTE_PTR(R1) +1
    movf    INDF, W            ; Read pin
    andwf   bitmask, W         ; Isolate it
    movwf   R3                 ; Save starting state as last

countloop:                     ; 20 usec loop (at 4 MHz)
    nop                        ; 1
    movf    INDF, W            ; 1 Read pin
    andwf   bitmask, W         ; 1 Isolate it
    movwf   BYTE_PTR(R3) +1    ; 1 Save state
    xorwf   R3, W              ; 1 Compare with last time
    andwf   BYTE_PTR(R3) +1, W ; 1 Only count high states
    xorwf   bitmask, W         ; 1 Flip for next test
    btfsc   STATUS, Z          ; 1 / 2
    incf    R1, F              ; 1 / 0 Count pulse
    btfsc   STATUS, Z          ; 1 / 2
    incf    BYTE_PTR(R1) +1, F ; 1 / 0
    movf    BYTE_PTR(R3) +1, W ; 1 Set new last state
    movwf   R3                 ; 1
    decf    R2, F              ; 1 Count time
    btfsc   STATUS, Z          ; 1 / 2
    decf    BYTE_PTR(R2) +1, F ; 1 / 0
    btfsc   STATUS, Z          ; 1 / 2
    decfsz  R0, F              ; 1 / 2
    goto    countloop          ; 2 / 0
    movf    R1, W              ; Result to W
#endasm

return(R1);  // R1 holds the result
}


I changes my port that the hall sensor is connected (B2), but the lcd displays only 0 and when I brush a metal through the sensor the number doesn't change. Maybe someone sees the problem?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri May 11, 2012 12:31 pm     Reply with quote

Quote:
I'm trying to make it work for me, but it's not happening.

Always tell us what you expect to see, and what are actually getting.
One of the biggest repetitive annoyances on this forum is when people
tell us that a project "don't work", and don't tell us anything more.

In this case, what is the expected signal frequency from the sensor ?
What frequency is displayed ?
adrix



Joined: 04 May 2012
Posts: 24

View user's profile Send private message

PostPosted: Fri May 11, 2012 12:52 pm     Reply with quote

Well I expect that it would show the freq. of how many times the dc motor spins though the hall sensor. I am trying to imitate the car's rpm.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri May 11, 2012 1:03 pm     Reply with quote

You still didn't answer my questions at all.

What is the expected frequency ? Is it 10 Hz ? Is it 100 or 1000 Hz ?

What frequency do you see displayed on the lcd ? Do you see a blank
screen ? Or do you see a number displayed ? If so, what is it ?!
adrix



Joined: 04 May 2012
Posts: 24

View user's profile Send private message

PostPosted: Fri May 11, 2012 1:48 pm     Reply with quote

Oh sorry, I need to make 10-80 Hz frequency. I wrote that lcd shows only "0" and doesn't change or blink.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri May 11, 2012 2:17 pm     Reply with quote

The sensor requires a pull-up resistor on the output pin. Do you have one ?
If your PIC runs at +5v, then the pull-up should connect to +5v also.

See the schematic link below (It's the same one that you posted).
In Figure 3, in the upper left corner, they show a 10K pull-up resistor
to +5v. Instead of the logic gate, the connection should go to pin B0
on your PIC.
http://sensing.honeywell.com/index.php/ci_id/45265/la_id/1/document/1/re_id/0

The sensor also requires connections to +5v and ground. See the pin
labels in the upper left corner of Figure 4.
Mike Walne



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

View user's profile Send private message

PostPosted: Fri May 11, 2012 3:09 pm     Reply with quote

Take a step back.

Quote:

I changes my port that the hall sensor is connected (B2), but the lcd displays only 0 and when I brush a metal through the sensor the number doesn't change. Maybe someone sees the problem?

A hall sensor responds to magnetic field.

(1) What is the "metal" you brush through the sensor?
(2) Are you testing with the correct polarity magnetic field?
(3) Are you using a large enough magnetic field?
(4) Have you monitored the signal from the sensor?

Mike
temtronic



Joined: 01 Jul 2010
Posts: 9245
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri May 11, 2012 3:34 pm     Reply with quote

another tip..

Replace the hall sensor with whatever your line frequency is (50 or 60 hz). A simple 6V power transformer-diode-resistor-zener setup should be fine (google 'tachometer calibration' or similar words) should come up with a schematic for you.

If you use a full wave bridge you'll get 100 or 120 hz.

This should be a good 'calibration' standard for you to confirm the program you wrote is running correctly.
adrix



Joined: 04 May 2012
Posts: 24

View user's profile Send private message

PostPosted: Sat May 12, 2012 12:56 am     Reply with quote

Ok I got it working, I thought that I needed a metal to get it working, but it needed a magnet. So now the lcd is showing the counts, but I have one question: if I understand the program correctly it counts the number of spins made in 1000ms, am I right?
Mike Walne



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

View user's profile Send private message

PostPosted: Sat May 12, 2012 2:32 am     Reply with quote

Do what Temtronic suggests and do a crude calibration with a mains transformer.

I don't like the way you're getting the timing.

(1) You're dependant on all paths through the code taking the same time.
(2) Your variables don't convey meaning, so it's difficult to decipher what you are doing.
(3) Any change in the count loop has to be corrected for.
(4) You're resorting to machine code for a task which 'C' can easily handle.
(5) There's a discrepancy in your clock rate, so we can't tell you what your timing period is.

You start with a 20MHz clock
Code:

#use delay(clock=20000000)

Then later you've got 4MHz
Code:

countloop:                     ; 20 usec loop (at 4 MHz)


Work on the KISS principle.

Use one of the built in timers to generate the 1000ms interval. That way you don't have to worry about software timing issues.
Write the counting code in readable 'C'.

Mike
dyeatman



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

View user's profile Send private message

PostPosted: Sat May 12, 2012 6:39 am     Reply with quote

Quote:
So now the lcd is showing the counts, but I have one question: if I understand the program correctly it counts the number of spins made in 1000ms, am I right?


yes, thats what HZ is... The number of Cycles Per Second.
_________________
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: Sat May 12, 2012 7:23 am     Reply with quote

Mike Walne wrote:
Do what Temtronic suggests and do a crude calibration with a mains transformer.

I don't like the way you're getting the timing.

(1) You're dependant on all paths through the code taking the same time.
(2) Your variables don't convey meaning, so it's difficult to decipher what you are doing.
(3) Any change in the count loop has to be corrected for.
(4) You're resorting to machine code for a task which 'C' can easily handle.
(5) There's a discrepancy in your clock rate, so we can't tell you what your timing period is.

You start with a 20MHz clock
Code:

#use delay(clock=20000000)

Then later you've got 4MHz
Code:

countloop:                     ; 20 usec loop (at 4 MHz)


Work on the KISS principle.

Use one of the built in timers to generate the 1000ms interval. That way you don't have to worry about software timing issues.
Write the counting code in readable 'C'.

Mike





I tried to hook up a square wave generator to the project, but it showed only "1" and "2" on the lcd, however the frequency was set to 15Hz.

I found this code , that's why it is written in asm, I'm new to programming so I can't change it to C. Off course it would be much easier to read in C. I tried looking for tachometer project in search, but none of them worked.
Mike Walne



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

View user's profile Send private message

PostPosted: Sat May 12, 2012 4:36 pm     Reply with quote

Quote:
I tried to hook up a square wave generator to the project, but it showed only "1" and "2" on the lcd, however the frequency was set to 15Hz.

Looks like your timing is out by a factor of ~10.

Many of the guys here charge $$$$ ££££ to cut code. I'm certainly not going to analyse a sample you "found". I suspect that you don't have a clue about how it's supposed to work.

What we will do, for free, is offer help and advice if you make an effort.

You could test your code with MPLAB SIM.

Set it up with the crystal that you're actually using, then time the count_loop routine.

Quote:
I found this code , that's why it is written in asm, I'm new to programming so I can't change it to C. Off course it would be much easier to read in C. I tried looking for tachometer project in search, but none of them worked.

You will learn more by doing it yourself. CCS provides loads of short sample code. Have a play with some.

I've outlined where to start with your specific project. Have a go, when you get stuck, come back to the forum, show us what you've done and somebody will probably offer assistance.

To reiterate a possible solution:-

Timing:-

(1) Set up a timer to create interrupts at say 1ms intervals.
(2) You've now got 1ms ticks.
(3) Count 1000 ticks for your 1 second period.
(4) Set a flag when 1 second period is up.

In main()

(1) Reset flag, and reset ticks count to zero.
(2) Start ticking timer.
(3) Look for rising edge from Hall device.
(4) Advance count if edge found.
(5) Poll flag to see if 1 second period is up.
(6) Back to (3) till timing done.
(7) Stop ticking timer.
(8) Process edge count.
(9) Back to (1).

Once it 'works' after a fashion, you will want to make it better.

My experience with "found" code is, by the time I've taken it apart to debug, I might as well have started from scratch myself.

Best of luck.

Mike
adrix



Joined: 04 May 2012
Posts: 24

View user's profile Send private message

PostPosted: Sat May 19, 2012 5:50 pm     Reply with quote

Thanks, I got the hall sensor to work correctly. But I need to connect another hall sensor and read its value. I connected it to RB1, but I am getting very random numbers although the motor is spinning 1 time/sec. I know that the #INT_RB goes to interrupt on low edge and high edge, I guess that is the problem that the numbers are completely random. How can I make it count correctly?
Mike Walne



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

View user's profile Send private message

PostPosted: Sun May 20, 2012 2:12 am     Reply with quote

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
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 1, 2  Next
Page 1 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