implemented presence with timer interrupts
This commit is contained in:
parent
8fb20ab065
commit
8c473f50e4
100
OneWireIO.ino
100
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);
|
||||||
|
|
||||||
|
void owPullLow()
|
||||||
|
{
|
||||||
|
owPin.outputMode();
|
||||||
|
owPin.writeLow();
|
||||||
|
owOutTestPin.writeLow();
|
||||||
|
}
|
||||||
|
|
||||||
|
void owRelease()
|
||||||
|
{
|
||||||
|
owPin.inputMode();
|
||||||
|
owOutTestPin.writeHigh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void owWrite(bool value)
|
||||||
|
{
|
||||||
|
if (value)
|
||||||
|
owRelease();
|
||||||
|
else
|
||||||
|
owPullLow();
|
||||||
|
}
|
||||||
|
|
||||||
unsigned long resetStart = (unsigned long)-1;
|
unsigned long resetStart = (unsigned long)-1;
|
||||||
|
|
||||||
enum Status
|
|
||||||
{
|
|
||||||
S_WaitReset,
|
|
||||||
S_WaitPresence,
|
|
||||||
S_Presence,
|
|
||||||
};
|
|
||||||
|
|
||||||
Status status = S_WaitReset;
|
|
||||||
unsigned long statusChangeTime = (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();
|
||||||
|
}
|
||||||
|
@ -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" />
|
||||||
|
@ -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>
|
@ -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)
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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…
Reference in New Issue
Block a user