Tech Off Thread

2 posts

Forum Read Only

This forum has been made read only by the site admins. No new threads or comments can be added.

Observers leaking down to hardware devices

Back to Forum: Tech Off
  • User profile image
    staceyw

    Hope this makes Eric smile a little. A question on TinyClr NETMF forum prompted this. The question was related to looking at a Cpu.Pin stream for a certain pattern. Right away I thought of Rx. However a 35K+ port of Rx is overkill. But mixing in some of the ideas, I was able to come up with two (very handy I think) extention methods that get the job done in a composable way.  You subscribe to an event pin with an observer and do what you need.  I thought it was cool.

    public delegate bool PinChange(bool state, DateTime time);
    public delegate bool PinChangeSpan(bool state, long tickSpan);
    public static class Extentions
    {
        /// <summary>
        /// This overload passes tick span between pin changes.
        /// </summary>
        public static void Subscribe(this InterruptPort port, PinChangeSpan predicate)
        {
            if (predicate == null) throw new ArgumentNullException("predicate");
            long lastTick = -1;
            port.Subscribe((bool state, DateTime dt) =>
                {
                    if (lastTick < 0)
                    {
                        lastTick = dt.Ticks;
                        // The first "real" pin change has no delta yet.
                        return predicate(state, -1);
                    }
                    long delta = dt.Ticks - lastTick;
                    lastTick = dt.Ticks;
                    return predicate(state, delta);
                }, 1); // Always skip first as dirty because no idea when it was set.
        }
    
        /// <summary>
        /// This overload passes DateTime of current pin state.
        /// </summary>
        /// <param name="predicate">User predicate.</param>
        /// <param name="skipCount">Number of changes to skip.</param>
        public static void Subscribe(this InterruptPort port, PinChange predicate, uint skipCount=0)
        {
            if (predicate == null) throw new ArgumentNullException("predicate");
            NativeEventHandler del = null;
            del = (uint data1, uint data2, DateTime time) =>
            {
                if (skipCount > 0)
                {
                    skipCount--;
                    return;
                }
    
                if (del == null)
                    return; // Already unregisted. Not sure why this needed to avoid extra callback. MF Bug?
    
                bool state = data2 == 0 ? false : true;
                // If user predicate not want more, then unregister.
                if (! predicate(state, time))
                {
                    port.OnInterrupt -= del;
                    del = null;
                }
            };
    
            // Register observer.
            port.OnInterrupt += del;
        }
    }
    

    Usage samples:

     
    InterruptPort inPort = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.Di13, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);
    
    int highCount = 0; // local state var.
    inPort.Subscribe((isHigh, dt) =>
    {
        if (isHigh && ++highCount >= 5)
        {
            Debug.Print("Pin high 5 times. Do something.");
            return false; // unsubscribe.
        }
        return true; // keep subscription active.
    });
    
    // PulseIn sample:
    // Milliseconds span between first low and high.
    inPort.Subscribe((bool isHigh, long ticks) =>
    {
        if (ticks == -1)
            return true; // Skip first, because we have no delta time context yet. 
        if (isHigh)
        {
            Debug.Print("\nDelay between first low and first high: " + ticks / 10000);
            return false; // done.
        }
        else
            return true;
    });
    
    

  • User profile image
    teslaBytes

    Use System.Diagnostics.

Conversation locked

This conversation has been locked by the site admins. No new comments can be made.