@ -10,39 +10,67 @@
# define ResetMaxDuration 900
# define PresenceWaitDuration 30
# define PresenceDuration 15 0
# define PresenceDuration 30 0
SerialChannel debug ( " debug " ) ;
Pin owPin ( OWPin ) ;
Pin ledPin ( LEDPin ) ;
Pin owOutTestPin ( 3 ) ;
Pin led ( LEDPin ) ;
unsigned long resetStart = ( unsigned long ) - 1 ;
void owPullLow ( )
{
owPin . outputMode ( ) ;
owPin . writeLow ( ) ;
owOutTestPin . writeLow ( ) ;
}
enum Status
void owRelease ( )
{
S_WaitReset ,
S_WaitPresence ,
S_Presence ,
} ;
owPin . inputMode ( ) ;
owOutTestPin . writeHigh ( ) ;
}
Status status = S_WaitReset ;
unsigned long statusChangeTime = ( unsigned long ) - 1 ;
void owWrite ( bool value )
{
if ( value )
owRelease ( ) ;
else
owPullLow ( ) ;
}
unsigned long resetStart = ( unsigned long ) - 1 ;
void setup ( )
{
ledPin . outputMode ( ) ;
led . outputMode ( ) ;
owPin . inputMode ( ) ;
owOutTestPin . outputMode ( ) ;
owOutTestPin . writeHigh ( ) ;
ledPin . writeLow ( ) ;
led . writeLow ( ) ;
cli ( ) ; // disable interrupts
attachInterrupt ( InterruptNumber , onewireInterrupt , CHANGE ) ;
// set timer0 interrupt at 250KHz (actually depends on compare match register OCR0A)
// 4us between each tick
TCCR1A = 0 ;
TCCR1B = 0 ;
TCNT1 = 0 ; // initialize counter value to 0
//TCCR1B |= (1 << WGM12); // turn on CTC mode
//TCCR1B |= (1 << CS11) | (1 << CS10); // Set 64 prescaler
TIMSK1 | = ( 1 < < OCIE1A ) ; // enable timer compare interrupt
sei ( ) ; // enable interrupts
Serial . begin ( 400000 ) ;
}
//int count = 0;
void loop ( )
{
//if ((count++) % 1000 == 0)
// led.write(!led.read());
cli ( ) ; //disable interrupts
SerialChannel : : swap ( ) ;
sei ( ) ; //enable interrupts
@ -50,12 +78,26 @@ void loop()
SerialChannel : : flush ( ) ;
}
void ( * timerEvent ) ( ) = 0 ;
void setTimerEvent ( short microSecondsDelay , void ( * event ) ( ) )
{
microSecondsDelay - = 10 ; // this seems to be the typical time taken to initialize the timer on Arduino Uno
short skipTicks = ( microSecondsDelay - 3 ) / 4 ; // round the micro seconds delay to a number of ticks to skip (4us per tick, so 4us must skip 0 tick, 8us must skip 1 tick, etc.)
if ( skipTicks < 1 ) skipTicks = 1 ;
//debug.SC_APPEND_STR_INT("setTimerEvent", (long)skipTicks);
TCNT1 = 0 ;
OCR1A = skipTicks ;
timerEvent = event ;
TCCR1B = ( 1 < < WGM12 ) | ( 1 < < CS11 ) | ( 1 < < CS10 ) ; // turn on CTC mode with 64 prescaler
}
void onewireInterrupt ( void )
{
bool state = owPin . read ( ) ;
unsigned long now = micros ( ) ;
//ledPin.write(state);
//led.write(state);
if ( ! state )
resetStart = now ;
@ -67,10 +109,32 @@ void onewireInterrupt(void)
if ( resetDuration > = ResetMinDuration & & resetDuration < = ResetMaxDuration )
{
debug . SC_APPEND_STR_TIME ( " reset " , now ) ;
status = S_WaitPresence ;
statusChangeTime = now ;
//debug.SC_APPEND_STR_TIME("reset", now);
setTimerEvent ( PresenceWaitDuration - ( micros ( ) - now ) , & beginPresence ) ;
return ;
}
}
}
void beginPresence ( )
{
//debug.SC_APPEND_STR("beginPresence");
owPullLow ( ) ;
owOutTestPin . writeLow ( ) ;
setTimerEvent ( PresenceDuration , & endPresence ) ;
}
void endPresence ( )
{
//debug.SC_APPEND_STR("endPresence");
owRelease ( ) ;
}
ISR ( TIMER1_COMPA_vect ) // timer1 interrupt
{
TCCR1B = 0 ; // disable clock
void ( * event ) ( ) = timerEvent ;
timerEvent = 0 ;
if ( event ! = 0 )
event ( ) ;
}