buy hot The Fixer cool video Year One download Kasabian album nice Terminator Salvation hit cool track Jordin Sparks USA Whatever Works video download Check My Brain melodies nice video Finding Nemo nice Pop - Various Artists hit cheap DIVX Year One

digital-diy.com

Swordfish Tutorial - A1102 (Hall Effect Sensor) Print E-mail
( 2 Votes )
  
Saturday, 04 April 2009 09:10

Hall Effect sensors allow the detection of a magnetic field. They can be extremely small, and very accurate, and often used in applications that require some sort of speed/RPM feedback. For example, you wanted to make a digital speedometer for your car, and don't want to impede on the pre-existing circuit, you could use a Hall Effect sensor to determine how many revolutions/second your wheel is doing, and calculate your speed from there.


In this example, the A1102 made by Allegro is used. Other models (A110x) allow for different sensitivities and hysteresis properties. Hysteresis is important as you don't want false readings from ambient magnetic fields, as the devices react very quickly (400nS switching time).


The A1102 is a Unipolar Hall-Effect Digital Switch, this means that the device can detect a south polarized magnetic field when its perpendicular to the face of the device. As shown on the device list, the A1102 has an open collector output, this means when the device detects a southern magnetic field, the output is tied to earth through a transistor. We will need to add a pull-up resistor to bring the output up to 5V when it the transistor is off, perhaps the circuit diagram will explain it more,

 

wheel11


The A1102 shown above is grossly oversized compared to real life in the circuit diagram - its just an representation of the curved edges on the front that I was trying to portray. Its actually smaller than the picture displayed at the top of the topic.


Now for our program. I thought an RPM type display would be ideal for this device. There's no way you would sample for a whole minute to determine what the RPM of a device is (well you could - but simply wouldn't). So instead its much more efficient to sample over a known time period and then scale the result back up. The sample register is also known as a PreScaler.


For my example, I will sample for 500mS, and then scale it too RPM. The longer you sample for, the more accurate your results - but the slower the refresh rate. It's a trade off, but I have found 500mS to be a happy median.

Device = 18F452
Clock = 20
 
// some LCD options...
#option LCD_DATA = PORTB.4
#option LCD_RS = PORTB.2
#option LCD_EN = PORTB.3
 
// import LCD library...
Include "LCD.bas"
Include "utils.bas"
Include "ISRTimer.bas"
Include "convert.bas"        
 
Const Timer1 = 0
Dim
    Hall_Sensor As PORTA.0,
    PreScaler As Word
 
// Start Of Program...
SetAllDigital
ADCON1 = %00000110
 
Timer.Initialize                             // Activate the timer module
Timer.Items(Timer1).Interval = 500           // Set the Timer for 500ms
Timer.Start                                  // Start processing all timers
 
Input(Hall_Sensor)                           // Make the Hall-Effect sensor pin an input
 
DelayMS(150)                                 // Allow the LCD to warm up
 
Cls                                          // Clear the LCD, and display
WriteAt(1,1,"RPM Meter")                     //   default information
 
While 1 = 1                                  // Create an infinite loop
 
    PreScaler = 0                            // Reset PreScaler register
    Timer.Items(Timer1).Enabled = True       // Enable Timer1 event
 
    Repeat
 
        Repeat              // Wait for a rising edge
        Until Hall_Sensor = 1 Or Not Timer.Items(Timer1).Enabled
 
        Repeat              // Wait for a falling edge
        Until Hall_Sensor = 0 Or Not Timer.Items(Timer1).Enabled
 
        If Timer.Items(Timer1).Enabled Then      // If Timer1 is still enabled,
            PreScaler = PreScaler + 1            //   then increment PreScaler
            If PreScaler = 84 Then               // If PreScaler = 84, then
                Break                            //  leave the Repeat Until loop
            EndIf                                // as 84 * 2 * 60 = 10080
        EndIf
 
    Until Not Timer.Items(Timer1).Enabled        // Keep looping until Timer1 times out (500mS)
 
    Timer.Items(Timer1).Enabled = False          // Disable Timer1, as it may have left early
 
    PreScaler = PreScaler * 2 * 60               // * 2 = RPS, * 60 = RPM
 
    If PreScaler > 9999 Then                     // If the output is over 9999
        PreScaler = 9999                         //  then display 9999 by default
    EndIf
 
    WriteAt(2,1,DecToStr(PreScaler, 4))          // Display the variable on the LCD
                                                 // (always show 4 digits)
Wend

 


Notice that I cap the value of PreScaler to 84, this is to ensure that my program leaves the loop if the RPM > 10000, as 84 * 2 * 60 = 10080. The value of PreScaler does not need to be capped, however if it rolls over 65535 during any math routine then your result/accuracy goes out the window. An easy fix would be defining PreScaler as a different variable type (such as LongInt for values up to 2,147,483,647).

 

Just to go one bit further on sample times, I have used 500mS (1/2 a second), so the slowest recordable rate = 1 sample, which equals 1 * 2 * 60 (RPS to RPM) = 120. That is also my error rate (120 RPM), as I could miss one sample each loop. If my sample time was 100mS, then my slowest sample speed would be 1 * 10 * 60 (RPS to RPM) = 600. As you can see, the error rate increases as the sample time decreases... but its a matter of how fast you need the data/want to display it that accounts for what sample speed your happy with.

Comments (4)
  • MrDEB

    plan on using basic routine to measure wind speed.
    still working on wind direction using two optisensors from a mouse driven at a 9 to one ratio

  • MrDEB

    the LCD options?
    am new to all this .what and where to put??
    purchased some 16x2 and 20x4 LCD that are HD44780 compatable.
    planning on using this exact routine to count the number of slots on the mouse wheel for further project(wind direction and speed)

  • Jon Chandler

    The LCD tutorial covers this pretty well. http://digital-diy.com/swordfish/56-swordfish-tutorial-lcd.html< /p>

    A couple of things to remember:

    1. The data lines must be connected to the upper four bits of a port if 4 lines are used (the easiest case). #option LCD_DATA = PORTB.4 from above says that the upper 4 bits of PORT B will be used for data.

    2. The LCD_RS and LCD_EN lines can be connected to any port pin. Set the option statements to agree with your arrangement.

    3. The LCD r/w line must be connected to ground.

    4. It is absolutely necessary to connect a pot to the Vee terminal as shown in the LCD tutorial. If the contrast isn't adjusted correctly, you won't see anything on the display. Some displays have a really narrow range of adjustment where anything will show.

    5. Finally, the options statements always go ahead of the include statement where the module is loaded.

  • Graham

    Cheers for clarifying Jon.

    The above and other LCD options can be found in the SF help topics. The LCD.bas help topic also covers default settings for the options

Write comment
Your Contact Details:
Comment:
[b] [i] [u] [url] [quote] [code] [img]   
Security
Please input the anti-spam code that you can read in the image.
Last Updated ( Wednesday, 25 November 2009 21:47 )