Browse Source

implemented reset detection

timer1
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