Browse Source

implemented presence with timer interrupts

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

96
OneWireIO.ino

@ -10,39 +10,67 @@
#define ResetMaxDuration 900 #define ResetMaxDuration 900
#define PresenceWaitDuration 30 #define PresenceWaitDuration 30
#define PresenceDuration 150 #define PresenceDuration 300
SerialChannel debug("debug"); SerialChannel debug("debug");
Pin owPin(OWPin); 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, owPin.inputMode();
S_WaitPresence, owOutTestPin.writeHigh();
S_Presence, }
};
Status status = S_WaitReset; void owWrite(bool value)
unsigned long statusChangeTime = (unsigned long)-1; {
if (value)
owRelease();
else
owPullLow();
}
unsigned long resetStart = (unsigned long)-1;
void setup() void setup()
{ {
ledPin.outputMode(); led.outputMode();
owPin.inputMode(); owPin.inputMode();
owOutTestPin.outputMode();
owOutTestPin.writeHigh();
ledPin.writeLow(); led.writeLow();
cli(); // disable interrupts
attachInterrupt(InterruptNumber,onewireInterrupt,CHANGE); 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); Serial.begin(400000);
} }
//int count = 0;
void loop() void loop()
{ {
//if ((count++) % 1000 == 0)
// led.write(!led.read());
cli();//disable interrupts cli();//disable interrupts
SerialChannel::swap(); SerialChannel::swap();
sei();//enable interrupts sei();//enable interrupts
@ -50,12 +78,26 @@ void loop()
SerialChannel::flush(); 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) void onewireInterrupt(void)
{ {
bool state = owPin.read(); bool state = owPin.read();
unsigned long now = micros(); unsigned long now = micros();
//ledPin.write(state); //led.write(state);
if (!state) if (!state)
resetStart = now; resetStart = now;
@ -67,10 +109,32 @@ void onewireInterrupt(void)
if (resetDuration >= ResetMinDuration && resetDuration <= ResetMaxDuration) if (resetDuration >= ResetMinDuration && resetDuration <= ResetMaxDuration)
{ {
debug.SC_APPEND_STR_TIME("reset", now); //debug.SC_APPEND_STR_TIME("reset", now);
status = S_WaitPresence; setTimerEvent(PresenceWaitDuration - (micros() - now), &beginPresence);
statusChangeTime = now;
return; 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> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>D:\Outils\Arduino\hardware\arduino\avr\cores\arduino</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>D:\Outils\Arduino\hardware\arduino\avr\cores\arduino;D:\Outils\Arduino\hardware\tools\avr\avr\include</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);ARDUINO=160;__AVR__</PreprocessorDefinitions> <PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);ARDUINO=160;__AVR__;UBRRH;__AVR_ATmega328__</PreprocessorDefinitions>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
@ -66,7 +66,9 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<None Include="OneWireIO.ino" /> <None Include="OneWireIO.ino">
<FileType>Document</FileType>
</None>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="SerialChannel.cpp" /> <ClCompile Include="SerialChannel.cpp" />

6
OneWireIO.vcxproj.filters

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

27
SerialChannel.cpp

@ -61,7 +61,7 @@ void SerialChannel::write(const char* text, unsigned long time)
write((byte*)text, strlen(text), 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) if (time == (unsigned long)-1)
time = micros(); time = micros();
@ -73,6 +73,9 @@ void SerialChannel::append(byte* data, short byteCount, unsigned long time)
msg.data = data; msg.data = data;
msg.byteCount = byteCount; msg.byteCount = byteCount;
msg.time = time; msg.time = time;
msg.longArg0 = 0;
return msg;
} }
void SerialChannel::append(const char* text, unsigned long time) 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); 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() void SerialChannel::swap()
{ {
backBuffer = backBuffer == buffer1 ? buffer2 : buffer1; backBuffer = backBuffer == buffer1 ? buffer2 : buffer1;
@ -94,9 +103,21 @@ void SerialChannel::flush()
Message* frontBuffer = backBuffer == buffer1 ? buffer2 : buffer1; Message* frontBuffer = backBuffer == buffer1 ? buffer2 : buffer1;
for (Message* msg = frontBuffer; msg < frontBuffer + frontBufferSize; ++msg) 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); Serial.write(msg->data, msg->byteCount);
if (paramsSize > 0)
Serial.write(params, paramsSize);
} }
Serial.flush();
} }
void SerialChannel::writeShort(short num) void SerialChannel::writeShort(short num)
@ -114,7 +135,7 @@ void SerialChannel::handleConnection()
int b = Serial.read(); int b = Serial.read();
if(b == (int)'C') if(b == (int)'C')
{ {
Serial.write("CONNECTION"); Serial.write("CONNECTION");
SerialChannel* c = first; SerialChannel* c = first;
while(c) while(c)
{ {

8
SerialChannel.h

@ -2,6 +2,8 @@
#define _SerialChannel_h_ #define _SerialChannel_h_
#define SC_APPEND_STR(str) append((byte*)str, sizeof(str)-1) #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) #define SC_APPEND_STR_TIME(str, time) append((byte*)str, sizeof(str)-1, time)
class SerialChannel class SerialChannel
@ -11,8 +13,9 @@ private:
struct Message struct Message
{ {
byte* data;
unsigned long time; unsigned long time;
long longArg0;
byte* data;
short byteCount; short byteCount;
byte id; byte id;
}; };
@ -40,8 +43,9 @@ public:
void beginWrite(short byteCount, unsigned long time = (unsigned long)-1); void beginWrite(short byteCount, unsigned long time = (unsigned long)-1);
void continueWrite(byte* data, short byteCount); 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 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 swap();
static void flush(); static void flush();

2
SerialMonitor/SerialMonitor/App.xaml.cs

@ -33,13 +33,13 @@ namespace SerialMonitor
Serial.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(OnDataReceived); Serial.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(OnDataReceived);
Serial.Open(); Serial.Open();
Serial.Write("C");
} }
private void OnDataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) private void OnDataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{ {
if (!Connected) if (!Connected)
{ {
Serial.Write("C");
Serial.ReadTo("CONNECTION"); Serial.ReadTo("CONNECTION");
Connected = true; Connected = true;
} }

Loading…
Cancel
Save