Playing around with the Meadow F7

This post refers to an older version of Meadow.  The latest version has something similar to what is described below, and it also makes the below post irrelevant.   I highly recommend that you update your Meadow API to the latest version and focus on using it rather than focusing on the samples below.  However, always keep in mind that you aren't limited to what any manufacture provides to you for development purposes and sometimes it may be worth the time to simplify your development processes by creating reusable 'objects' that can be shared among your projects.   There is nothing wrong with simplifying your development process, but also be careful to fully test anything you create (and intend to use across multiple projects) since shared code that has problems can cause havoc.

Like I said in the previous post, I haven't been doing much with Arduino lately.   Although, I would like to say I really like using Visual Studio Code for Arduino Development.  With the Arduino Extension, it works very well.  You do still have to install the Arduino IDE, but since that installs everything else you need other than the Arduino Extension for Visual Studio Code and, of course Visual Studio Code itself, it seems like a small price to pay.

Note: This has changed a bit from the original posting with the addition of the IMeadowSketch interface and the MeadowRunner class, then I removed the virtual Setup() / Loop() that needed to be overridden (which are now handled by the IMeadowSketch interface).

On to the Meadow F7 conversation.   If you are familiar with Netduinos, and since I have written a number of posts about them you should be, which means you should also be familiar with Wilderness Labs, who also make the Meadow F7 boards.  Unlike the Netduino Boards that you use the .NET Micro Framework for development, with the Meadow F7 boards you use the full-fledged .NET Standard.  As of a short time before this writing, the Meadow Framework was moved from supporting .NET Framework 4.7.2 to supporting .NET Standard 2.1.    

One thing I tend to do when I start using a new board like this is attempt to simplify the learning curve as much as possible.  I like the whole Setup() / Loop() paradigm that Arduino uses. So, when I first started using Netduinos, I wrote some code that my Netduino apps to have the Setup() / Loop() functionality and I have written a class (and interface) to derive from that works similarly for the Meadow F7.  

First the MeadowSketch<T> class just simplifies what you derive from in your app. 

using Meadow;
using Meadow.Devices;

namespace Sketch
{
    public class MeadowSketch<T> : App<F7Micro, T> where T : class, Meadow.IApp
    {
    }
} 

Next is a MeadowRunner class that just has a static Run() function that calls Setup() and Loop() in your apps.  I originally had the Run function in the MeadowSketch<T> class ... but having to call the function with MeadowSketch<T>.Run(new T) just didn't seem like the best thing to do and it looks odd to me too.

namespace Sketch
{
public class MeadowRunner
{
public static void Run(IMeadowSketch sketch)
{
sketch.Setup();
while (true)
sketch.Loop();
}
}
}

And finally, there is the IMeadowSketch interface, that just defines the Setup() and Loop() functions which MeadowRunner.Run() uses as an argument (and any Meadow app class derives from) ... which now has the fully coded Setup() and Loop() functions.

namespace Sketch
{
public interface IMeadowSketch
{
void Setup();
void Loop();
}
}

So, I created a library out of the above and now, if I add Sketch.dll (the library I created) as a dependency in my Meadow Apps, instead of having to derive from App<...>, I can simply derive from MeadowSketch<T> where T is the class name I'm creating and the IMeadowSketch interface. 

So, if we revise the simple LEDApp class and tweaked it to use the Sketch.dll assembly  ... derive as-need and change the structure to use the Setup() and Loop() functions, it should look something like the below code.

using System;
using System.Threading;
using Meadow.Hardware;
using Sketch; // The library that was created above

namespace HelloLED
{
public class LEDApp : MeadowSketch<LEDApp>, IMeadowSketch
{
private IDigitalOutputPort redLed;
private IDigitalOutputPort blueLed;
private IDigitalOutputPort greenLed;
private bool state;

public void Setup()
{
state = false;
redLed = Device.CreateDigitalOutputPort(Device.Pins.OnboardLedRed);
blueLed = Device.CreateDigitalOutputPort(Device.Pins.OnboardLedBlue);
greenLed = Device.CreateDigitalOutputPort(Device.Pins.OnboardLedGreen);
}

public void Loop()
{
state = !state;

Console.WriteLine($"State: {state}");

redLed.State = state;
Thread.Sleep(200);
greenLed.State = state;
Thread.Sleep(200);
blueLed.State = state;
Thread.Sleep(200);
}
}

The MainClass would change a bit too... no longer needing the Thread.Sleep(Timeout.Infinite) calls since the endlessly called Loop() function is taking care of the non-stop Run().   And now, only needing the using Sketch statement, which allows us to get rid of all of the other using statements. And we just call the static Run() function with an argument that instantiates the LEDApp class (which Run() uses to get the Setup() and Loop() function to call thru the IMeadowSketch interface).

using Sketch;

namespace HelloLED
{
class MainClass
{
static void Main(string[] args)
{
// instantiate new meadow app
MeadowRunner.Run(new LEDApp());
}
}
}

This just seems easier and cleaner to me.  Again, the MeadowSketch class handles deriving from the App<F7Micro, T> and all you need to remember to do is derive from both the MeadowSketch<T> (where T is the name of the class you are creating) and the IMeadowSketch interface. The MeadowRunner.Run() function and the IMeadowSketch interface (which will force you to create the Setup() and Loop() functions in the app class) handle the execution of the app.  There is no need to include a using Meadow or using Meadow.Device statement, since again, the Sketch assembly is the only thing that needs them ... at least for this sample.  And, to me, it just doesn't seem so clunky.

Even if you don't want to use the Setup()/Loop() functionality described here, this may give you some ideas of how to simplify Meadow F7 development.

Comments

Popular posts from this blog

Fun with the SolidDigi Color Image LCD Shield

Parallax Smart Card Reader - Revisited

Parallax Smart Card Reader Samples for Arduino