|
|
View previous topic :: View next topic |
Author |
Message |
adrix
Joined: 04 May 2012 Posts: 24
|
Hall sensor's problem with PIC16F887 |
Posted: Fri May 11, 2012 12:19 pm |
|
|
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
|
|
Posted: Fri May 11, 2012 12:31 pm |
|
|
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
|
|
Posted: Fri May 11, 2012 12:52 pm |
|
|
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
|
|
Posted: Fri May 11, 2012 1:03 pm |
|
|
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
|
|
Posted: Fri May 11, 2012 1:48 pm |
|
|
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
|
|
Posted: Fri May 11, 2012 2:17 pm |
|
|
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
|
|
Posted: Fri May 11, 2012 3:09 pm |
|
|
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: 9229 Location: Greensville,Ontario
|
|
Posted: Fri May 11, 2012 3:34 pm |
|
|
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
|
|
Posted: Sat May 12, 2012 12:56 am |
|
|
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
|
|
Posted: Sat May 12, 2012 2:32 am |
|
|
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
|
|
Posted: Sat May 12, 2012 6:39 am |
|
|
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
|
|
Posted: Sat May 12, 2012 7:23 am |
|
|
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
|
|
Posted: Sat May 12, 2012 4:36 pm |
|
|
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
|
|
Posted: Sat May 19, 2012 5:50 pm |
|
|
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
|
|
Posted: Sun May 20, 2012 2:12 am |
|
|
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 |
|
|
|
|
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
|