I’ve tinkered and searched for over 2 hours to try and figure this out. I’m porting the following code for a HC-SR04 Rangefinder plugged into @ ransomhall’s MakeBread module. The top code below works on my NetDuino plugged into a breadboard with Echo on D6 and Trigger on D7.
NETMF code:
private static int ticks;
private static InterruptPort EchoPin = new InterruptPort(Pins.GPIO_PIN_D6, true, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);
private static OutputPort TriggerPin = new OutputPort(Pins.GPIO_PIN_D7, false);
public static void Main()
{
EchoPin.OnInterrupt += new NativeEventHandler(port_OnInterrupt);
EchoPin.DisableInterrupt();
while (true)
{
EchoPin.EnableInterrupt();
TriggerPin.Write(false);
Thread.Sleep(2);
TriggerPin.Write(true);
Thread.Sleep(10);
TriggerPin.Write(false);
Thread.Sleep(2);
}
}
private static void port_OnInterrupt(uint port, uint state, DateTime time)
{
if (state == 0) // falling edge, end of pulse
{
int pulseWidth = (int)time.Ticks - ticks;
// valid for 20°C
//int pulseWidthMilliSeconds = pulseWidth * 10 / 582;
//valid for 24°C
int pulseWidthMilliSeconds = (pulseWidth * 10 / (int)578.29);
Debug.Print("Distance = " + pulseWidthMilliSeconds.ToString() + " millimètres.");
}
else
{
ticks = (int)time.Ticks;
}
EchoPin.ClearInterrupt();
}
I’m doing it in a gadgeteer module, which shouldn’t make a difference, but here’s what I’ve got:
Gadgeteer Code:
private static int _ticks;
private GTI.InterruptInput input;
private Socket _socket;
private InterruptInput _input;
private DigitalOutput _output;
private uint _state;
private DateTime _time;
private bool _monitoring = false;
private string _currentDistance = "-1";
/// <summary>bool: Whether the rangefinder is monitoring current distance or not.</summary>
public bool IsMonitoring()
{
return _monitoring;
}
/// <summary>string: Current Distance in millimeters</summary>
public string CurrentDistance()
{
return _currentDistance;
}
/// <summary></summary>
/// <param name="socketNumber">The socket that this module is plugged in to.</param>
public MakeBreadRangeFinder(int socketNumber)
{
_socket = Socket.GetSocket(socketNumber, true, this, null);
// The HC-SR04 Rangefinder uses the following pins on the makebread module:
//
// VCC (5v power): Pin 2 (5V)
// Trig (Input): Pin 6 (P6)
// Echo (Output): Pin 7 (P7)
// GND (Ground): Ping 10 (GND)
//
_input = new GTI.InterruptInput(_socket, GT.Socket.Pin.Six, GTI.GlitchFilterMode.Off, GTI.ResistorMode.Disabled, GTI.InterruptMode.RisingAndFallingEdge, this);
_output = new GTI.DigitalOutput(_socket, GT.Socket.Pin.Seven, false, this);
// This registers a handler for the interrupt event of the interrupt input (which is bereleased)
this.input.Interrupt += new GTI.InterruptInput.InterruptEventHandler(this._input_Interrupt);
if (_monitoring)
{
_output.Write(false);
Thread.Sleep(2);
_output.Write(true);
Thread.Sleep(10);
_output.Write(false);
Thread.Sleep(2);
}
Thread.Sleep(-1);
}
private void _input_Interrupt(GTI.InterruptInput input, bool value)
{
if (_state == 0) // falling edge, end of pulse
{
int pulseWidth = (int)_time.Ticks - _ticks;
// valid for 20°C
//int pulseWidthMilliSeconds = pulseWidth * 10 / 582;
//valid for 24°C
int pulseWidthMilliSeconds = (pulseWidth * 10 / (int)578.29);
_currentDistance = pulseWidthMilliSeconds.ToString();
}
else
{
_ticks = (int)_time.Ticks;
}
}