GY-63_MS5611/libraries/PulsePattern/PulsePattern.cpp

127 lines
2.9 KiB
C++
Raw Normal View History

2013-09-30 12:29:52 -04:00
//
2013-09-30 12:32:34 -04:00
// FILE: PulsePattern.cpp
2013-09-30 12:29:52 -04:00
// AUTHOR: Rob dot Tillaart at gmail dot com
2013-09-30 12:32:34 -04:00
// VERSION: see PULSEPATTERN_LIB_VERSION in .h
2013-09-30 12:38:54 -04:00
// PURPOSE: PulsePattern library for Arduino
2013-09-30 12:29:52 -04:00
//
// HISTORY:
// 0.0.1 - 2012-11-23 initial version
// 0.0.2 - 2012-11-23 adapted a static PPO
2013-09-30 12:32:34 -04:00
// 0.0.3 - 2012-12-27 renamed to PulsePattern
2013-09-30 12:38:54 -04:00
// 0.0.4 - 2012-12-27 code stable(?) enough to publish
// 0.0.5 - 2012-12-27 code cleanup+comment
2013-09-30 12:29:52 -04:00
//
// Released to the public domain
//
2013-09-30 12:38:54 -04:00
// TODO
// - fast function iso array to return the next period?
// more adaptive to e.g. sensor values. (investigate)
// - test PRE 1.0 backwards compatibility
// - move code to .h file so compiler can inline?
// - optimize timer code
// - adjust timing to more accurate values -> setTimer()
2013-09-30 12:38:54 -04:00
// - worker should be private - how???
// - test invalid array periods
2013-09-30 12:39:38 -04:00
// - start en stop index ipv size?
// - pulsepattern recorder
//
2013-09-30 12:29:52 -04:00
2013-09-30 12:32:34 -04:00
#include "PulsePattern.h"
2013-09-30 12:34:23 -04:00
#if defined(ARDUINO) && ARDUINO >= 100
2013-09-30 12:29:52 -04:00
#include "Arduino.h"
2013-09-30 12:34:23 -04:00
#else
#include "WProgram.h"
#endif
2013-09-30 12:29:52 -04:00
2013-09-30 12:38:54 -04:00
// Predefined generator (singleton)
PulsePattern PPGenerator;
ISR(TIMER1_COMPA_vect)
2013-09-30 12:29:52 -04:00
{
2013-09-30 12:38:54 -04:00
PPGenerator.worker();
2013-09-30 12:29:52 -04:00
}
2013-09-30 12:32:34 -04:00
PulsePattern::PulsePattern()
2013-09-30 12:29:52 -04:00
{
_size = 0;
_state = NOTINIT;
2013-09-30 12:29:52 -04:00
}
2013-09-30 12:34:23 -04:00
void PulsePattern::init(uint8_t pin, uint16_t * ar, uint8_t size,
uint8_t level, uint8_t prescaler)
2013-09-30 12:29:52 -04:00
{
stop();
_pin = pin;
2013-09-30 12:29:52 -04:00
_ar = ar;
_size = size;
2013-09-30 12:38:54 -04:00
// TODO: run over the array to test invalid values?
// constrain them 10-4095?
2013-09-30 12:34:23 -04:00
_level = constrain(level, LOW, HIGH);
_prescaler = constrain(prescaler, PRESCALE_1, PRESCALE_1024);
2013-09-30 12:29:52 -04:00
_cnt = 0;
pinMode(_pin, OUTPUT);
digitalWrite(_pin, _level);
2013-09-30 12:29:52 -04:00
}
2013-09-30 12:32:34 -04:00
void PulsePattern::start()
2013-09-30 12:29:52 -04:00
{
if (_size == 0) return;
if (_state == RUNNING) return; // no restart
2013-09-30 12:29:52 -04:00
setTimer(1); // start asap
_state = RUNNING;
}
2013-09-30 12:32:34 -04:00
void PulsePattern::stop()
2013-09-30 12:29:52 -04:00
{
stopTimer();
_state = STOPPED;
_level = LOW;
digitalWrite(_pin, _level);
2013-09-30 12:29:52 -04:00
}
2013-09-30 12:32:34 -04:00
bool PulsePattern::isRunning()
2013-09-30 12:29:52 -04:00
{
return (_state == RUNNING);
}
2013-09-30 12:32:34 -04:00
void PulsePattern::worker()
2013-09-30 12:29:52 -04:00
{
if (_state != RUNNING) return;
// set next period & flip signal
2013-09-30 12:29:52 -04:00
_level = !_level;
digitalWrite(_pin, _level);
2013-09-30 12:38:54 -04:00
// TODO: adjustment needed for code overhead when micros?;
// + 5.2 usec for digitalWrite
// + 3 usec for settimer call
2013-09-30 12:38:54 -04:00
OCR1A = (_ar[_cnt]) * (F_CPU/1000000L);
2013-09-30 12:29:52 -04:00
_cnt++;
if (_cnt >= _size) _cnt = 0; // repeat
2013-09-30 12:29:52 -04:00
}
// TIMER code based upon - http://www.gammon.com.au/forum/?id=11504
2013-09-30 12:32:34 -04:00
void PulsePattern::stopTimer()
2013-09-30 12:29:52 -04:00
{
TCCR1A = 0; // reset timer 1
TCCR1B = 0;
}
// TODO: can be optimized?
2013-09-30 12:32:34 -04:00
void PulsePattern::setTimer(uint16_t cc)
2013-09-30 12:29:52 -04:00
{
TCCR1A = 0;
2013-09-30 12:29:52 -04:00
TCCR1B = 0;
2013-09-30 12:38:54 -04:00
TCNT1 = 0; // reset counter
OCR1A = cc*16; // compare A register value;
// *16 makes max period 4095
// min period 12?
2013-09-30 12:29:52 -04:00
// 4: CTC mode, top = OCR1A
TCCR1A = _BV (COM1A1); // clear on compare
2013-09-30 12:34:23 -04:00
TCCR1B = _BV (WGM12) | _prescaler;
2013-09-30 12:29:52 -04:00
TIFR1 |= _BV (OCF1A); // clear interrupt flag
TIMSK1 = _BV (OCIE1A); // interrupt on Compare A Match
}
// END OF FILE