From 8c473f50e445cbe1315c2d979ddecc89fea57631 Mon Sep 17 00:00:00 2001 From: Youen Toupin Date: Fri, 24 Apr 2015 10:30:11 +0200 Subject: [PATCH] implemented presence with timer interrupts --- OneWireIO.ino | 96 ++++++++++++++++++++----- OneWireIO.vcxproj | 8 ++- OneWireIO.vcxproj.filters | 6 +- SerialChannel.cpp | 27 ++++++- SerialChannel.h | 8 ++- SerialMonitor/SerialMonitor/App.xaml.cs | 2 +- 6 files changed, 119 insertions(+), 28 deletions(-) diff --git a/OneWireIO.ino b/OneWireIO.ino index 604a01e..46f43ce 100644 --- a/OneWireIO.ino +++ b/OneWireIO.ino @@ -10,39 +10,67 @@ #define ResetMaxDuration 900 #define PresenceWaitDuration 30 -#define PresenceDuration 150 +#define PresenceDuration 300 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(); +} diff --git a/OneWireIO.vcxproj b/OneWireIO.vcxproj index c0bc860..5125aed 100644 --- a/OneWireIO.vcxproj +++ b/OneWireIO.vcxproj @@ -44,8 +44,8 @@ Level3 Disabled true - D:\Outils\Arduino\hardware\arduino\avr\cores\arduino - _MBCS;%(PreprocessorDefinitions);ARDUINO=160;__AVR__ + D:\Outils\Arduino\hardware\arduino\avr\cores\arduino;D:\Outils\Arduino\hardware\tools\avr\avr\include + _MBCS;%(PreprocessorDefinitions);ARDUINO=160;__AVR__;UBRRH;__AVR_ATmega328__ true @@ -66,7 +66,9 @@ - + + Document + diff --git a/OneWireIO.vcxproj.filters b/OneWireIO.vcxproj.filters index f361281..ba1919b 100644 --- a/OneWireIO.vcxproj.filters +++ b/OneWireIO.vcxproj.filters @@ -1,8 +1,5 @@  - - - @@ -10,4 +7,7 @@ + + + \ No newline at end of file diff --git a/SerialChannel.cpp b/SerialChannel.cpp index 73720ae..bcf7346 100644 --- a/SerialChannel.cpp +++ b/SerialChannel.cpp @@ -61,7 +61,7 @@ void SerialChannel::write(const char* text, unsigned long time) write((byte*)text, strlen(text), time); } -void SerialChannel::append(byte* data, short byteCount, unsigned long time) +SerialChannel::Message& SerialChannel::append(byte* data, short byteCount, unsigned long time) { if (time == (unsigned long)-1) time = micros(); @@ -73,6 +73,9 @@ void SerialChannel::append(byte* data, short byteCount, unsigned long time) msg.data = data; msg.byteCount = byteCount; msg.time = time; + msg.longArg0 = 0; + + return msg; } void SerialChannel::append(const char* text, unsigned long time) @@ -80,6 +83,12 @@ void SerialChannel::append(const char* text, unsigned long time) append((byte*)text, strlen(text), time); } +void SerialChannel::appendInt(const char* text, short textLength, int arg0, unsigned long time) +{ + Message& msg = append((byte*)text, textLength, time); + msg.longArg0 = arg0 | 0x40000000; +} + void SerialChannel::swap() { backBuffer = backBuffer == buffer1 ? buffer2 : buffer1; @@ -94,9 +103,21 @@ void SerialChannel::flush() Message* frontBuffer = backBuffer == buffer1 ? buffer2 : buffer1; for (Message* msg = frontBuffer; msg < frontBuffer + frontBufferSize; ++msg) { - beginWriteInChannel(msg->id, msg->byteCount, msg->time); + char params[32]; + params[0] = 0; + + if ((msg->longArg0 & 0x40000000) != 0) + sprintf(params, ";arg0=%ld", msg->longArg0 & ~0x40000000); + + short paramsSize = strlen(params); + + beginWriteInChannel(msg->id, msg->byteCount + paramsSize, msg->time); Serial.write(msg->data, msg->byteCount); + if (paramsSize > 0) + Serial.write(params, paramsSize); } + + Serial.flush(); } void SerialChannel::writeShort(short num) @@ -114,7 +135,7 @@ void SerialChannel::handleConnection() int b = Serial.read(); if(b == (int)'C') { - Serial.write("CONNECTION"); + Serial.write("CONNECTION"); SerialChannel* c = first; while(c) { diff --git a/SerialChannel.h b/SerialChannel.h index 116a53c..0231f24 100644 --- a/SerialChannel.h +++ b/SerialChannel.h @@ -2,6 +2,8 @@ #define _SerialChannel_h_ #define SC_APPEND_STR(str) append((byte*)str, sizeof(str)-1) +#define SC_APPEND_STR_INT(str, arg0) appendInt(str, sizeof(str)-1, arg0) + #define SC_APPEND_STR_TIME(str, time) append((byte*)str, sizeof(str)-1, time) class SerialChannel @@ -11,8 +13,9 @@ private: struct Message { - byte* data; unsigned long time; + long longArg0; + byte* data; short byteCount; byte id; }; @@ -40,8 +43,9 @@ public: void beginWrite(short byteCount, unsigned long time = (unsigned long)-1); void continueWrite(byte* data, short byteCount); - void append(byte* data, short byteCount, unsigned long time = (unsigned long)-1); + Message& append(byte* data, short byteCount, unsigned long time = (unsigned long)-1); void append(const char* text, unsigned long time = (unsigned long)-1); + void appendInt(const char* text, short textLength, int arg0, unsigned long time = (unsigned long)-1); static void swap(); static void flush(); diff --git a/SerialMonitor/SerialMonitor/App.xaml.cs b/SerialMonitor/SerialMonitor/App.xaml.cs index 897717c..b0509e2 100644 --- a/SerialMonitor/SerialMonitor/App.xaml.cs +++ b/SerialMonitor/SerialMonitor/App.xaml.cs @@ -33,13 +33,13 @@ namespace SerialMonitor Serial.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(OnDataReceived); Serial.Open(); + Serial.Write("C"); } private void OnDataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { if (!Connected) { - Serial.Write("C"); Serial.ReadTo("CONNECTION"); Connected = true; }