Browse Source

implemented reset detection

pull/5/head
Youen Toupin 10 years ago
parent
commit
03c2f0afd3
  1. 93
      LowLevel.h
  2. 38
      OneWireIO.ino
  3. 44
      OneWireIO.sln
  4. 81
      OneWireIO.vcxproj
  5. 13
      OneWireIO.vcxproj.filters
  6. 102
      Oscilloscope.ino

93
LowLevel.h

@ -0,0 +1,93 @@
#ifndef _LowLevel_h
#define _LowLevel_h
#include <inttypes.h>
#if ARDUINO >= 100
#include "Arduino.h" // for delayMicroseconds, digitalPinToBitMask, etc
#else
#include "WProgram.h" // for delayMicroseconds
#include "pins_arduino.h" // for digitalPinToBitMask, etc
#endif
#if defined(__AVR__)
#define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin)))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define IO_REG_TYPE uint8_t
#define IO_REG_ASM asm("r30")
#define DIRECT_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0)
#define DIRECT_MODE_INPUT(base, mask) ((*((base)+1)) &= ~(mask))
#define DIRECT_MODE_OUTPUT(base, mask) ((*((base)+1)) |= (mask))
#define DIRECT_WRITE_LOW(base, mask) ((*((base)+2)) &= ~(mask))
#define DIRECT_WRITE_HIGH(base, mask) ((*((base)+2)) |= (mask))
#elif defined(__MK20DX128__) || defined(__MK20DX256__)
#define PIN_TO_BASEREG(pin) (portOutputRegister(pin))
#define PIN_TO_BITMASK(pin) (1)
#define IO_REG_TYPE uint8_t
#define IO_REG_ASM
#define DIRECT_READ(base, mask) (*((base)+512))
#define DIRECT_MODE_INPUT(base, mask) (*((base)+640) = 0)
#define DIRECT_MODE_OUTPUT(base, mask) (*((base)+640) = 1)
#define DIRECT_WRITE_LOW(base, mask) (*((base)+256) = 1)
#define DIRECT_WRITE_HIGH(base, mask) (*((base)+128) = 1)
#elif defined(__SAM3X8E__)
// Arduino 1.5.1 may have a bug in delayMicroseconds() on Arduino Due.
// http://arduino.cc/forum/index.php/topic,141030.msg1076268.html#msg1076268
// If you have trouble with OneWire on Arduino Due, please check the
// status of delayMicroseconds() before reporting a bug in OneWire!
#define PIN_TO_BASEREG(pin) (&(digitalPinToPort(pin)->PIO_PER))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define IO_REG_TYPE uint32_t
#define IO_REG_ASM
#define DIRECT_READ(base, mask) (((*((base)+15)) & (mask)) ? 1 : 0)
#define DIRECT_MODE_INPUT(base, mask) ((*((base)+5)) = (mask))
#define DIRECT_MODE_OUTPUT(base, mask) ((*((base)+4)) = (mask))
#define DIRECT_WRITE_LOW(base, mask) ((*((base)+13)) = (mask))
#define DIRECT_WRITE_HIGH(base, mask) ((*((base)+12)) = (mask))
#ifndef PROGMEM
#define PROGMEM
#endif
#ifndef pgm_read_byte
#define pgm_read_byte(addr) (*(const uint8_t *)(addr))
#endif
#elif defined(__PIC32MX__)
#define PIN_TO_BASEREG(pin) (portModeRegister(digitalPinToPort(pin)))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define IO_REG_TYPE uint32_t
#define IO_REG_ASM
#define DIRECT_READ(base, mask) (((*(base+4)) & (mask)) ? 1 : 0) //PORTX + 0x10
#define DIRECT_MODE_INPUT(base, mask) ((*(base+2)) = (mask)) //TRISXSET + 0x08
#define DIRECT_MODE_OUTPUT(base, mask) ((*(base+1)) = (mask)) //TRISXCLR + 0x04
#define DIRECT_WRITE_LOW(base, mask) ((*(base+8+1)) = (mask)) //LATXCLR + 0x24
#define DIRECT_WRITE_HIGH(base, mask) ((*(base+8+2)) = (mask)) //LATXSET + 0x28
#else
#error "Please define I/O register types here"
#endif
class Pin
{
private:
IO_REG_TYPE mask;
volatile IO_REG_TYPE *reg;
public:
inline Pin(uint8_t pin)
{
mask = PIN_TO_BITMASK(pin);
reg = PIN_TO_BASEREG(pin);
}
inline void inputMode() { DIRECT_MODE_INPUT(reg, mask); }
inline void outputMode() { DIRECT_MODE_OUTPUT(reg, mask); }
inline bool read() { return DIRECT_READ(reg, mask); }
inline void writeLow() { DIRECT_WRITE_LOW(reg, mask); }
inline void writeHigh() { DIRECT_WRITE_HIGH(reg, mask); }
inline void write(bool value) { if (value) writeHigh(); else writeLow(); }
};
#endif

38
OneWireIO.ino

@ -1,18 +1,27 @@
#include "Arduino.h" #include "Arduino.h"
#include "LowLevel.h"
#include "SerialChannel.h" #include "SerialChannel.h"
#define LEDPin 13 #define LEDPin 13
#define OWPin 2 #define OWPin 2
#define InterruptNumber 0 // Must correspond to the OWPin to correctly detect state changes. On Arduino Uno, interrupt 0 is for digital pin 2 #define InterruptNumber 0 // Must correspond to the OWPin to correctly detect state changes. On Arduino Uno, interrupt 0 is for digital pin 2
#define ResetMinDuration 360
#define ResetMaxDuration 900
SerialChannel debug("debug"); SerialChannel debug("debug");
Pin owPin(OWPin);
Pin ledPin(LEDPin);
unsigned long resetStart = (unsigned long)-1;
void setup() void setup()
{ {
pinMode(LEDPin, OUTPUT); ledPin.outputMode();
pinMode(OWPin, INPUT); owPin.inputMode();
digitalWrite(LEDPin, LOW); ledPin.writeLow();
attachInterrupt(InterruptNumber,onewireInterrupt,CHANGE); attachInterrupt(InterruptNumber,onewireInterrupt,CHANGE);
@ -23,11 +32,28 @@ void loop()
{ {
cli();//disable interrupts cli();//disable interrupts
sei();//enable interrupts sei();//enable interrupts
} }
void onewireInterrupt(void) void onewireInterrupt(void)
{ {
digitalWrite(LEDPin, digitalRead(OWPin)); bool state = owPin.read();
unsigned long now = micros();
//ledPin.write(state);
if (!state)
resetStart = now;
if (state)
{
unsigned long resetDuration = now - resetStart;
if (resetStart != (unsigned long)-1 && resetDuration >= ResetMinDuration && resetDuration <= ResetMaxDuration)
{
debug.write("reset");
ledPin.writeHigh();
}
resetStart = (unsigned long)-1;
}
} }

44
OneWireIO.sln

@ -0,0 +1,44 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OneWireIO", "OneWireIO.vcxproj", "{3B500971-1570-460F-81C3-22AC3B7764B9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SerialMonitor", "SerialMonitor\SerialMonitor\SerialMonitor.csproj", "{97704F53-6CA1-4155-9E8F-AEBFEEC20A8B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|Win32 = Debug|Win32
Release|Any CPU = Release|Any CPU
Release|Mixed Platforms = Release|Mixed Platforms
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3B500971-1570-460F-81C3-22AC3B7764B9}.Debug|Any CPU.ActiveCfg = Debug|Win32
{3B500971-1570-460F-81C3-22AC3B7764B9}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{3B500971-1570-460F-81C3-22AC3B7764B9}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{3B500971-1570-460F-81C3-22AC3B7764B9}.Debug|Win32.ActiveCfg = Debug|Win32
{3B500971-1570-460F-81C3-22AC3B7764B9}.Debug|Win32.Build.0 = Debug|Win32
{3B500971-1570-460F-81C3-22AC3B7764B9}.Release|Any CPU.ActiveCfg = Release|Win32
{3B500971-1570-460F-81C3-22AC3B7764B9}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{3B500971-1570-460F-81C3-22AC3B7764B9}.Release|Mixed Platforms.Build.0 = Release|Win32
{3B500971-1570-460F-81C3-22AC3B7764B9}.Release|Win32.ActiveCfg = Release|Win32
{3B500971-1570-460F-81C3-22AC3B7764B9}.Release|Win32.Build.0 = Release|Win32
{97704F53-6CA1-4155-9E8F-AEBFEEC20A8B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{97704F53-6CA1-4155-9E8F-AEBFEEC20A8B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{97704F53-6CA1-4155-9E8F-AEBFEEC20A8B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{97704F53-6CA1-4155-9E8F-AEBFEEC20A8B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{97704F53-6CA1-4155-9E8F-AEBFEEC20A8B}.Debug|Win32.ActiveCfg = Debug|Any CPU
{97704F53-6CA1-4155-9E8F-AEBFEEC20A8B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{97704F53-6CA1-4155-9E8F-AEBFEEC20A8B}.Release|Any CPU.Build.0 = Release|Any CPU
{97704F53-6CA1-4155-9E8F-AEBFEEC20A8B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{97704F53-6CA1-4155-9E8F-AEBFEEC20A8B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{97704F53-6CA1-4155-9E8F-AEBFEEC20A8B}.Release|Win32.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

81
OneWireIO.vcxproj

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{3B500971-1570-460F-81C3-22AC3B7764B9}</ProjectGuid>
<RootNamespace>OneWireIO</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<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>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="OneWireIO.ino" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="SerialChannel.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="LowLevel.h" />
<ClInclude Include="SerialChannel.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

13
OneWireIO.vcxproj.filters

@ -0,0 +1,13 @@
<?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>
<ItemGroup>
<ClInclude Include="SerialChannel.h" />
<ClInclude Include="LowLevel.h" />
</ItemGroup>
</Project>

102
Oscilloscope.ino

@ -1,102 +0,0 @@
#include "Arduino.h"
#include "SerialChannel.h"
#define LEDPin 13
#define OWPin 2
#define InterruptNumber 0 // Must correspond to the OWPin to correctly detect state changes. On Arduino Uno, interrupt 0 is for digital pin 2
// how many samples we want to skip between two samples we keep (can be used to lower the sampling frequency)
#define SkipSamples 0
byte regularEncodedFrequency;
const int BufferSize = 512;
byte buffer1[BufferSize];
byte buffer2[BufferSize];
byte* backBuffer = buffer1;
volatile short backBufferPos = 0;
byte samplesSkipped = SkipSamples;
unsigned long backBufferStartTime = micros();
SerialChannel oscilloscope("oscilloscope");
SerialChannel debug("debug");
void setup()
{
pinMode(LEDPin, OUTPUT);
pinMode(OWPin, INPUT);
digitalWrite(LEDPin, LOW);
//attachInterrupt(InterruptNumber,onewireInterrupt,CHANGE);
cli();//disable interrupts
//set up continuous sampling of analog pin 0
//clear ADCSRA and ADCSRB registers
ADCSRA = 0;
ADCSRB = 0;
ADMUX |= (1 << REFS0); //set reference voltage
ADMUX |= (1 << ADLAR); //left align the ADC value- so we can read highest 8 bits from ADCH register only
int ADPS = (1 << ADPS2) | (0 << ADPS1) | (1 << ADPS0);
ADCSRA |= ADPS; //set ADC clock with 32 prescaler- 16mHz/32=500KHz ; 13 cycles for a conversion which means 38000 samples per second
ADCSRA |= (1 << ADATE); //enabble auto trigger
ADCSRA |= (1 << ADIE); //enable interrupts when measurement complete
ADCSRA |= (1 << ADEN); //enable ADC
ADCSRA |= (1 << ADSC); //start ADC measurements
regularEncodedFrequency = (byte)ADPS;
byte skipSamples = 0;
#if SkipSamples > 0
skipSamples = SkipSamples;
#endif
regularEncodedFrequency |= skipSamples << 3;
sei();//enable interrupts
Serial.begin(400000);
}
void loop()
{
while(backBufferPos < BufferSize / 2) ;
cli();//disable interrupts
byte* currentBuffer = backBuffer;
short currentBufferSize = backBufferPos;
backBuffer = (backBuffer == buffer1 ? buffer2 : buffer1);
backBufferPos = 0;
sei();//enable interrupts
unsigned long currentBufferStartTime = backBufferStartTime;
backBufferStartTime = micros();
digitalWrite(LEDPin, LOW);
//Serial.write(currentBuffer, currentBufferSize);
oscilloscope.beginWrite(currentBufferSize + 1, currentBufferStartTime);
oscilloscope.continueWrite(&regularEncodedFrequency, 1);
oscilloscope.continueWrite(currentBuffer, currentBufferSize);
}
ISR(ADC_vect) {//when new ADC value ready
byte sample = ADCH; //store 8 bit value from analog pin 0
#if SkipSamples > 0
if(samplesSkipped++ < SkipSamples)
return;
samplesSkipped = 0;
#endif
backBuffer[backBufferPos++] = sample;
if(backBufferPos >= BufferSize)
{
// overflow of back buffer, we loose the current sample
digitalWrite(LEDPin, HIGH);
backBufferPos = BufferSize - 1;
}
}
void onewireInterrupt(void)
{
//digitalWrite(LEDPin, digitalRead(OWPin));
}
Loading…
Cancel
Save