Wiblocks --- PICO1TRC HALL EFFECT DEMO

PICO1TRC Hall-effect Sensor Example

The PICO1TRC features the hardware of the PICO1TR and adds a real-time clock (RTC) and a prototype area. The wiblocks TWI library and wiblocks RTC library are compatible with the PICO1TRC

For this example the prototype area is used to wire a Honeywell SS345PT hall-effect sensor to ATmega328 pin PB1 (Arduino pin 9). The SS345PT has a TTL output (internal pull-up) and can be powered with voltages from 2.7 to 7V. Since the PICO1TRC typically runs at either 3.3V or 5V no additional components are required to use the SS345PT.

To wire the SS345PT I used Vector K24A pins. Each lead of the SS345PT are soldered to a pin and a jumper wire connects from each pin to the interface row of the prototype area.

Sketch

The sketch uses an interrupt routine to track the state of the SS345PT output. When a magnetic field of sufficent strength and oriented in the proper direction passes through the SS345PT the output state changes from high to low.


The interrupt routine is called whenever the PB1 pin changes state. When the interrupt routine is called a flag, alarm_flag is set and the output state of the SS345PT is saved.

The inner loop of the program reads the RTC registers every second. The loop exits if a magnetic field was detected or if the seconds count is zero. When the loop exits the time is printed. If there was a change in the magnetic field then a message is printed.

The screenshot on the right shows a sample run from the program.


#include <avr/interrupt.h>    
#include <avr/io.h>  

#include <TWI.h>
#include <RTC.h>

//
// The two testpoints in the PICO1TRC prototype
// area are connected to PB1 and PB2. For this
// demo the hall-effect sensor is wired to 
// PB1. 
//
// Atmel Pin Change Interrupt Arduino Pin
// ----- -------------------- -----------
// PB1   PCINT1                   9
// PB2   PCINT2                  10
//
#define SNS_HALL_EFFECT_DDR    DDRB
#define SNS_HALL_EFFECT_PIN    PINB
#define SNS_HALL_EFFECT_BIT    PB1
#define SNS_HALL_EFFECT_INT    PCINT1
#define SNS_HALL_EFFECT_PCMSK  PCMSK0

#define DEBUG_LED_DDR          DDRD
#define DEBUG_LED_PORT         PORTD
#define DEBUG_LED_BIT          PD7
//
// There are three pin change interrupt (PCI) lines.
// PCI0 triggers for pin change interrupt pins PCINT0..PCINT7
//
#define int_enable   PCICR  |=  _BV(PCIE0)
#define int_disable  PCICR  &= ~_BV(PCIE0)

#define led_on()  DEBUG_LED_PORT |=  _BV(DEBUG_LED_BIT);
#define led_off() DEBUG_LED_PORT &= ~_BV(DEBUG_LED_BIT);

#define magnetic_field_p() (SNS_HALL_EFFECT_PIN & _BV(SNS_HALL_EFFECT_BIT) ? 0 : 1)

RTC       rtc;

unsigned char alarm_flag = 0;
unsigned char mag_field = 0;

void setup() {

  Serial.begin(19200);

  // setup the TWI 

  TWBR = TWI_TWBR;             // Set bit rate register (Baudrate). Defined in TWI.h  
  TWDR = 0xFF;                 // Default content = SDA released.
  TWCR = (1<<TWEN)|            // Enable TWI-interface and release TWI pins.
         (0<<TWIE)|(0<<TWINT)| // Disable Interupt.
         (0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)|  // No Signal requests.
         (0<<TWWC);


  //
  // Configure the debug LED as an output
  //
  DEBUG_LED_DDR |= _BV(DEBUG_LED_BIT);
  //
  // Configure the hall-effect sensor pin as an input
  //
  SNS_HALL_EFFECT_DDR &= ~_BV(SNS_HALL_EFFECT_BIT);
  //
  //
  // uncomment the set_date and set_time commands to set initial date
  // and time.  This is only required immediately after a battery is
  // installed.
  //
  //initialize the date
  //rtc.set_date(2010, 7, 3);

  // intialize the clock
  //rtc.set_time(13, 34, 20);

  // Initialize the pin change interrupt mask for the
  // pin that is connected to hall effect sensor.

  SNS_HALL_EFFECT_PCMSK |= _BV(SNS_HALL_EFFECT_INT);

  // Enable the pin change interrupts

  int_enable;

}

char timestr[22];

void loop() {
  while(1) {
    rtc.read_regs();
    if (alarm_flag) break;
    led_on();
    delay(300);
    led_off();
    delay(700);
    if (rtc.get_secs() == 0) break;
  }
  rtc.localtime(timestr);
  Serial.print(timestr);

  // If there was an alarm then print the alarm
  // message, clear the alarms and re-enable the
  // interrupts.

  if (alarm_flag) {
    int_disable;
    alarm_flag = 0;
    if (mag_field) Serial.print("  *** Magnetic Field Present\n");
    else           Serial.print("  *** Magnetic Field Absent\n");
    SNS_HALL_EFFECT_PCMSK |= _BV(SNS_HALL_EFFECT_INT);
    int_enable;
  } else {
    Serial.print("\n");
  }
}

// When this routine is called the alarm flag is set and the
// state of the magnetic field is read into mag_field_p.

// The interrupt flags are read and reset in the main loop.

ISR( PCINT0_vect )
{
  alarm_flag = 1;
  mag_field = magnetic_field_p();
  SNS_HALL_EFFECT_PCMSK &= ~_BV(SNS_HALL_EFFECT_INT);
}