Browse Source

implemented presence with timer interrupts

timer1
Youen Toupin 10 years ago
parent
commit
8c473f50e4
  1. 96
      OneWireIO.ino
  2. 8
      OneWireIO.vcxproj
  3. 6
      OneWireIO.vcxproj.filters
  4. 25
      SerialChannel.cpp
  5. 8
      SerialChannel.h
  6. 2
      SerialMonitor/SerialMonitor/App.xaml.cs

96
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();
}

8
OneWireIO.vcxproj

@ -44,8 +44,8 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>D:\Outils\Arduino\hardware\arduino\avr\cores\arduino</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);ARDUINO=160;__AVR__</PreprocessorDefinitions>
<AdditionalIncludeDirectories>D:\Outils\Arduino\hardware\arduino\avr\cores\arduino;D:\Outils\Arduino\hardware\tools\avr\avr\include</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);ARDUINO=160;__AVR__;UBRRH;__AVR_ATmega328__</PreprocessorDefinitions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -66,7 +66,9 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="OneWireIO.ino" />
<None Include="OneWireIO.ino">
<FileType>Document</FileType>
</None>
</ItemGroup>
<ItemGroup>
<ClCompile Include="SerialChannel.cpp" />

6
OneWireIO.vcxproj.filters

@ -1,8 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<None Include="OneWireIO.ino" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="SerialChannel.cpp" />
</ItemGroup>
@ -10,4 +7,7 @@
<ClInclude Include="SerialChannel.h" />
<ClInclude Include="LowLevel.h" />
</ItemGroup>
<ItemGroup>
<None Include="OneWireIO.ino" />
</ItemGroup>
</Project>

25
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)

8
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();

2
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;
}

Loading…
Cancel
Save