Skip to content

Commit

Permalink
Demonstrating MM3 usage with interrupts for convert and reading.
Browse files Browse the repository at this point in the history
  • Loading branch information
stevemarple committed Jan 28, 2012
1 parent b6a6807 commit 3b8d911
Showing 1 changed file with 174 additions and 0 deletions.
174 changes: 174 additions & 0 deletions examples/MicroMagConvGetResInt/MicroMagConvGetResInt.ino
@@ -0,0 +1,174 @@
/*
* MicroMagConvGetRes.ino
* Author: Steve Marple
* License: GNU Lesser General Public License, version 2.1
*
* Example sketch to demonstrate reading from a MicroMag2 or MicroMag3
* module using the convert() and getResult() functions. The initial
* convert is started from a match interrupt generated by
* timer/counter2.
*
* Requirements:
* Arduino >= 1.0
* Calunium (standard Arduino cannot access the DRDY pin and the
* Arduino Mega(2560) doesn't have timer/counter2 connected to the
* shield headers.
* MicroMag library, see https://github.com/stevemarple/MicroMag
* MicroMag2 or MicroMag3 module
*
* Calunium configuration:
* RTC (DS1307 or similar) fitted, with battery
* RTC square wave routed to D15 (JP1 fitted)
*/

#include <Wire.h>
#include <RealTimeClockDS1307.h>

#include <SPI.h>
#include <MicroMag.h>

#include <util/atomic.h>

// Adjust these pin definitions to suit your hardware. They are chosen
// to match the RN-XV and SD shield with the MicroMag3 module option
// on Calunium. Ensure the correct interrupt service routine is
// defined for the DRDY pin.
#define DRDY_PIN 14
const uint8_t mmResetPin = A3;
const uint8_t mmDrdyPin = DRDY_PIN;
const uint8_t mmSsPin = A0; // This is the chip select pin on the MM3

// Change this to suit your version.
const uint8_t model = 3;

// The sampling period
uint8_t period = MM_PERIOD_4096;

// Create a MicroMag object
MicroMag MM = MicroMag::MicroMag3(mmSsPin, mmDrdyPin, mmResetPin);

// Use an 8-bit variable to obtain atomic read/write access. Disabling
// interrupts is therefore not needed.
/// volatile uint8_t dataReady = false;

// The 2 or 3 samples are taken in different invocations of loop() so
// use static variables to hold the results until all 2 or 3 have been
// taken and can be printed.
volatile uint8_t axis = 0;
volatile uint8_t sampleInProgess = false;
volatile int16_t data[model];
volatile unsigned long timestamps[model] = {0};


// This ISR is called when the state has *changed*. Act only when the
// current state is high (data is ready)
ISR(PCINT2_vect){
ATOMIC_BLOCK(ATOMIC_FORCEON) {
if (!digitalRead(DRDY_PIN))
return; // Data not ready (new sample started?)

data[axis] = MM.getResult();
++axis;
if (axis == model)
sampleInProgess = false;
else {
timestamps[axis] = millis();
MM.convert(axis, period); // Start sampling next axis
}
return;
}
}

void setupPinChangeInterrupts(void)
{
*(digitalPinToPCMSK(DRDY_PIN)) |= _BV(digitalPinToPCMSKbit(DRDY_PIN));
*(digitalPinToPCIR(DRDY_PIN)) |= _BV(digitalPinToPCICRbit(DRDY_PIN));
}

// When the counter matches sample X
ISR(TIMER2_COMPA_vect)
{
ATOMIC_BLOCK(ATOMIC_FORCEON) {
if (sampleInProgess)
return;
sampleInProgess = true;
axis = 0;
timestamps[axis] = millis();
MM.convert(axis, period);
return;
}
}

// Configure counter/timer2 in asynchronous mode, counting the rising
// edge of signals on TOSC1. This always triggers on the rising edge;
// if connecting SQW from a DS1307 then this means the ticks occur
// halfway through the second.
void setupTimer2(void)
{
noInterrupts();
ASSR = (_BV(EXCLK) | _BV(AS2));
TCCR2A = 0;
TCCR2B = 0;
TCNT2 = 0;
OCR2A = 3; // Have the ISR called every 10th (n+1) tick
TCCR2A |= _BV(WGM21); // CTC mode
TCCR2B |= _BV(CS20);
TIMSK2 |= _BV(OCIE2A);
interrupts();
}


void setup()
{
pinMode(SS, OUTPUT); // Prevent SPI slave mode from happening
Wire.begin();
Serial.begin(9600);

// For calunium: enable inputs on pin 6 in case JP4 is fitted and
// routing SQW there also
pinMode(6, INPUT);

// On Calunium timer/counter2 is connected to digital pin 15.
pinMode(15, INPUT);
setupTimer2();

if (MM.begin() != 0) {
Serial.println("Could not initialise MicroMag");
while (1)
; // no point in continuing
}
setupPinChangeInterrupts();

// Set up the RTC output
RTC.sqwEnable(RealTimeClockDS1307::SQW_1Hz);
}

unsigned long lastDisplayed = 0;
void loop()
{
// Check if new data is ready
if (!sampleInProgess && axis == model && timestamps[0] != lastDisplayed) {
lastDisplayed = timestamps[0];
double total = 0.0;

// Display the results
for (uint8_t i = 0; i < model; ++i) {
if (i)
Serial.print(" ");
Serial.print(char('X' + i));
Serial.print(" = ");
Serial.print(data[i]);
total += sqrt(double(data[i]) * data[i]);
}
Serial.print(" Total = ");
Serial.println(total);

for (uint8_t i = 0; i < model; ++i) {
if (i)
Serial.print(" ");
Serial.print(timestamps[i]);
}
Serial.println();
}

}

0 comments on commit 3b8d911

Please sign in to comment.