Need help cleaning up my code

I’ve got a block of Gadgeteer code that works but doesn’t look right to me. Is there a way to use the original context of the ledStrip generated without re-initializing it?


    public class myLED 
    {
        private Gadgeteer.Modules.GHIElectronics.LEDStrip ledStrip;
        public myLED()
        {
            this.ledStrip = new GTM.GHIElectronics.LEDStrip(7);
        }

        private int ii = 0 ;
        private bool myState = true; 
        public void next()
        {
            if(ii == 7){myState = false;}
            if(ii == 0){myState = true;} 
            if(myState){
                ledStrip.SetLed(ii, myState);
                ii++;
            }
            else{ledStrip.SetLed(ii-1, myState );
                ii--;
            }
        }
    }


I would pass it in as a constructor parameter.

1 Like

Ian is right, you can pass it as a constructor arg, which works well if you don’t have too much to pass, otherwise it gets messy.

You can also make your devices accessible to other classes by exposing them like this:

using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Presentation.Shapes;
using Microsoft.SPOT.Touch;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;

namespace GadgeteerApp1
{
    public partial class Program
    {
        private static Program _instance;

        void ProgramStarted()
        {
            _instance = this;

            Debug.Print("Program Started");
        }

        public static LEDStrip LEDStrip { get { return _instance.ledStrip; } }
    }
}


Then use them anywhere in your project like this:



In general though, I tend to use a lightweight inversion-of-control (IoC) mechanism, which allows using the same code in different environments (e.g., the emulator) for unit testing. IoC lets you define interfaces at design time and bind the actual implementation at runtime. There's a simple implementation in the Radius project. It is probably too much to bother with for small projects, but it can be a real boon in larger projects with higher quality bars.
3 Likes

@ mcalsyn - I like this approach, but has a problem in regard to multiple access to the device at the same time??

1 Like

If you are developing a multi-threaded app, then one of these must be true for every resource (hardware or data resource) in your program :

a) The resource is accessed from only one thread. For instance, a thread reading from a temp sensor should be the only thread directly accessing the temp sensor. Use get accessors, messages or queues to provide readings to other threads.

b) The resource is inherently thread-safe. That is, it must be harmless when the resource is accessed from multiple threads.

c) You have provided a resource-control mechanism like a lock or mutex around the object. And, to avoid deadlocks, you must always claim nested locks in the same order in every pathway of your program.

So, the method I showed assumes that one of a, b, or c is true in your program (or that your program is single-threaded, which seems to rarely be true in NETMF).

1 Like

Thank you all for the replies. From the code sample I was able to reach my goal. I’ve even been able to create a simple class to display simple messages. Great progress, for me.

@ mcalsyn - I appreciate your extra information about resources for multi-threaded apps. A couple of questions when you have a moment.
You mention ‘get accessors’ . Is that this line:

  or do I need to add the get to my class? 

I did some research and testing with queues and I like the concept.  Problem is I haven't yet figured out how to pass the component of an object.  I need to pass  myLED.next  but it seems to only want to pass myLED.    I've got some more reading to do on this. 

I tried to research messages but kept getting lead down the road for MSMQ and that seemed like way too much overhead even if it would work in NETMF.  

Thank you all again for the assistance,  you have sparked lots of new ideas and a lot of new avenues to pursue.

Yes, that is the ‘get accessor’ that I was talking about. To be really pedantic, “LEDStrip” is a property and the get and set portions are called accessors, and there is no set accessor on this particular property.

I am not sure I follow what you mean by passing a component of an object.

Messaging and queues are actually two names for the same thing … MSMQ is just one big fat fancy implementation of a messaging queue. Generally a queue becomes a messaging construct when one end of it is in one thread and the other end is being used in another thread. Then, items flowing through the queue can be thought of as messages flowing from one thread to the other.

The use of _responseQueue in this code :
https://github.com/DotNetOpenAutomation/serialwifi/blob/master/src/PervasiveDigital.Hardware.ESP8266/Esp8266Serial.cs
is an example of a messaging queue that is being used to pass lines of text from a producer thread to a consumer thread. The producer thread has to be very efficient so that it does not drop characters as they come in from the hardware. The consumer thread processes each line of received characters, but with delays that would not be tolerable on the producer thread. Using two threads and a messaging queue between them solved this performance requirement, keeping the producer thread responsive.

2 Likes

@ mcalsyn - I really appreciate the extent of your replies. They are very helpful.

I did a little testing using the queue method but it appeared that it would only let me pass the object - myLED when I think I need to pass myLED.next. But then I didn’t have much time to fully explore the options. I’ll spend some more time on the example you referenced, I’m sure that will get me in the right direction.

The queue example I pointed you to is mostly relevant for pushing data around.
If you are pushing functions or lambdas into a messaging queue, then perhaps you should use a threadpool…
ThreadPool source : https://github.com/DotNetOpenAutomation/serialwifi/blob/master/src/PervasiveDigital.Utility/ThreadPool.cs
Usage : serialwifi/Esp8266WifiDevice.cs at e88c9008d1bb8d3f40a762782ae980afd6a99e3d · PervasiveDigital/serialwifi · GitHub
at lines 109,801, 825

The threadpool lets you queue up tasks for execution by a pool of threads, rather than having a fixed set of threads or risking thrashing by creating too many threads. This sounds more like what you are trying to do, though offloading the setting/clearing of an led on the gadgeteer led strip seems excessive - the offloading of that work to another thread will take orders of magnitude more time than just setting the led. Why does this need to happen on another thread?

If you just want to access the LED from the class you originally posted, then all you need are the changes to Program that I showed (adding _instance and a property with a get accessor) and to use Program.LEDstrip in your class instead of the object you were creating in the myLED constructor.

1 Like

Someone else recently stated that blinking an LED is the universal metric. I suspect it’s the universal output of much of the conceptual testing done . In this case blinking the LED was just something to do. My main goal was to understand the basic concepts and make sure my approach to was on the right track. This has certainly helped.

Thought I was going to get some other work done today but now it looks like I’ll spend the time learning lambda expressions. :slight_smile:

1 Like

@ dft277 - Ah, that makes sense then!

1 Like