Want to help with Gadgeteer?

I have some modules, but most importantly I did successfully use a couple of Mountaineer ETH boards in some networked projects and I still have some lying around. Tell me if I can help with those.

Here are pins on the cerbuino bee Gadgeteer sockets. Load the Cerberus firmware from the current TinyCLR release then use this class to get to pins on the sockets easily. Now take a look at this and try simple things, like a button.

namespace GHIElectronics.TinyCLR.Pins {
    public static class FEZCerbuinoBee {
        public static class GpioPin {
            public const int DebugLed = (16 + 2);
            public const int SdCardDetect = (32 + 2);

            public static class Socket1 {
                public const int Pin3 = (0 + 14);
                public const int Pin4 = (16 + 10);
                public const int Pin5 = (16 + 11);
                public const int Pin6 = (0 + 13);
                public const int Pin7 = (16 + 5);
                public const int Pin8 = (16 + 4);
                public const int Pin9 = (16 + 3);
            }

            public static class Socket2 {
                public const int Pin3 = (0 + 6);
                public const int Pin4 = (0 + 2);
                public const int Pin5 = (0 + 3);
                public const int Pin6 = (0 + 1);
                public const int Pin7 = (0 + 0);
                public const int Pin8 = (16 + 7);
                public const int Pin9 = (16 + 6);
            }

            public static class Socket3 {
                public const int Pin3 = (32 + 0);
                public const int Pin4 = (32 + 1);
                public const int Pin5 = (0 + 4);
                public const int Pin6 = (32 + 5);
                public const int Pin7 = (16 + 8);
                public const int Pin8 = (0 + 7);
                public const int Pin9 = (16 + 9);
            }
            
        }

        public static class AdcChannel {
            public static class Socket2 {
                public const int Pin3 = 0;
                public const int Pin4 = 1;
                public const int Pin5 = 2;
            }

            public static class Socket3 {
                public const int Pin3 = 3;
                public const int Pin4 = 4;
                public const int Pin5 = 5;
            }
        }
    }
}

Spider II, Raptor and Hydra used in timing control system with RS232 modules, Xbee modules with displays

Hi,
I think it would be good to have some guidance and rules how to write drivers for gadgeteer boards (conventions for namespace labelling, recommendations for parameters in the constructors, tests for using allowed input/output pins) and so on. What will be if different people write different drivers for the same module? Will there be a list of official “GHI approved” driver? Who will test and comment a proposed driver? Who decides whether a driver has sufficient quality and how can this be seen by a potential user? Should there be one person who coordinates the activities for a special driver? There are already several drivers from GadgeteerToTinyCLR/TinyApp/GHIElectronics.TinyCLR.Gadgeteer at master · Gravicode/GadgeteerToTinyCLR · GitHub and others. Should these drivers be taken in a list of “recommended” drivers? I think some of these questions should be solved before it is worth the effort to contribute. I’m willing to help an have several mainboards and modules.
Kind regards
RoSchmi

We have to start somewhere. Do you want to start this effort? On my end, I want to see what GHI needs to provide to make the first step possible. These are all discontinued products and there is no financial reasons for GHI to do it. However, we really care and willing to do what is necessary.

2 Likes

I almost forgot about this. @mifmasterz already started the drivers How to deploy TinyCLR to FEZ Raptor and porting the Gadgeteer modules drivers to TinyCLR

1 Like

I aggree! If there is no better suggestion I would recommend to have a look on the drivers of mifmasterz (e.g. the button module) discuss some points concerning e.g. the namespaces and, if there are no objections, take these drivers as a starting point (may be there are already other drivers which I do not know). I think that I myself have not enough skills to give well-founded recommendations. There are much more qualified people at GHI and in the community. However I think, if we don’t get concrete, we will not proceed.

1 Like

“Bringing back Gadgeteer, sort of” is wonderful news!!! :grinning:

I am trying to install TinyCLR on my Fez Spider II, but the instructions are a little unclear.

On this page (http://docs.ghielectronics.com/hardware/legacy_products/gadgeteer/fez_spider_ii.html), point 9 states:

  • Select the G120 Bootloader v203.ghi (or newer) file. You can find available downloads here

…but there is no link and I cannot find that file anywhere on the GitHub repro or releases.

Please help.

Because this release doesn’t have it. I have an internal firmware I am using. This firmware, plus there pin definition class, will be in the coming release. Maybe this week, fingers crossed.

Yep. For now, no matter what the plan is, we need a TinyCLR firmware and the pin definition class. I am also building some documentation starting point. Then the community can direct the path for how this is to be completed

1 Like

I own a FEZ Raptor mainboard, with the following peripherals:

USB Client DP 1.3
WiFi RS21 1.2
RS485 1.1

I’ve been a .NET developer since first release. I know C++, but I hate it. I’ve been a programmer since the '80’s. I’m a control system engineer, a Metrologist, a turbofan mechanic, and a dedicated free software for all servant.

Let me know where I can help.

yes great work by @mifmasterz !!

First test with Cerberus and button gadgeteer module on pin 6:
**
** * FEZCerberus.cs:**
**

    // ReSharper disable once CheckNamespace
    // ReSharper disable UnusedMember.Global
    namespace GHIElectronics.TinyCLR.Pins
    {
    // ReSharper disable once UnusedMember.Global
    // ReSharper disable once InconsistentNaming
    public static class FEZCerberus
    {
        public static class GpioPin
        {
            public const int DebugLed = (32 + 4);
            public static class Socket2 
            {
                public const int Pin3 = (0 + 6);
                public const int Pin4 = (0 + 2);
                public const int Pin5 = (0 + 3);
                public const int Pin6 = (0 + 1);
                public const int Pin7 = (0 + 0);
                public const int Pin8 = (16 + 7);
                public const int Pin9 = (16 + 6);
            }

            public static class Socket6
            {
                public const int Pin3 = (0 + 14);
                public const int Pin4 = (16 + 10);
                public const int Pin5 = (16 + 11);
                public const int Pin6 = (0 + 13);
                public const int Pin7 = (16 + 5);
                public const int Pin8 = (16 + 4);
                public const int Pin9 = (16 + 3);
            }
        }
    }
}

**
** * Button.cs:**
**
using GHIElectronics.TinyCLR.Devices.Gpio;

namespace TestGadgeteerButton
{
    public class Button
    {
        private readonly GpioPin _input;
        private readonly GpioPin _led;
        private LedMode _currentMode;

        private ButtonEventHandler _onButtonEvent;

        /// <summary>Represents the delegate that is used to handle the <see cref="ButtonReleased" /> and <see cref="ButtonPressed" /> events.</summary>
        /// <param name="sender">The <see cref="Button" /> object that raised the event.</param>
        /// <param name="state">The state of the Button</param>
        public delegate void ButtonEventHandler(Button sender, ButtonState state);

        /// <summary>Raised when the button is released.</summary>
        public event ButtonEventHandler ButtonReleased;

        /// <summary>Raised when the button is pressed.</summary>
        public event ButtonEventHandler ButtonPressed;

        /// <summary>Whether or not the button is pressed.</summary>
        public bool Pressed
        {
            get
            {
                return _input.Read() != GpioPinValue.High;
            }
        }

        /// <summary>Whether or not the LED is currently on or off.</summary>
        public bool IsLedOn
        {
            get
            {
                return _led.Read() == GpioPinValue.High;
            }
        }

        /// <summary>Gets or sets the LED's current mode of operation.</summary>
        public LedMode Mode
        {
            get
            {
                return _currentMode;
            }

            set
            {
                _currentMode = value;

                if (_currentMode == LedMode.On || _currentMode == LedMode.OnWhilePressed && Pressed || _currentMode == LedMode.OnWhileReleased && !Pressed)
                    TurnLedOn();
                else if (_currentMode == LedMode.Off || _currentMode == LedMode.OnWhileReleased && Pressed || _currentMode == LedMode.OnWhilePressed && !Pressed)
                    TurnLedOff();
            }
        }

        /// <summary>The state of the button.</summary>
        public enum ButtonState
        {

            /// <summary>The button is pressed.</summary>
            Pressed = 0,

            /// <summary>The button is released.</summary>
            Released = 1
        }

        /// <summary>The various modes a LED can be set to.</summary>
        public enum LedMode
        {

            /// <summary>The LED is on regardless of the button state.</summary>
            On,

            /// <summary>The LED is off regardless of the button state.</summary>
            Off,

            /// <summary>The LED changes state whenever the button is pressed.</summary>
            ToggleWhenPressed,

            /// <summary>The LED changes state whenever the button is released.</summary>
            ToggleWhenReleased,

            /// <summary>The LED is on while the button is pressed.</summary>
            OnWhilePressed,

            /// <summary>The LED is on except when the button is pressed.</summary>
            OnWhileReleased
        }

        /// <summary>Constructs a new instance.</summary>
        /// <param name="digitalPin3">The mainboard pin that has digital pin.</param>
        /// <param name="digitalPin4">The mainboard pin that has digital pin.</param>
        public Button(int digitalPin3, int digitalPin4)
        {
            //Socket socket = Socket.GetSocket(socketNumber, true, this, null);

            //socket.EnsureTypeIsSupported(new char[] { 'X', 'Y' }, this);

            _currentMode = LedMode.Off;
            var controller = GpioController.GetDefault();
            _led = controller.OpenPin(digitalPin4);
            _led.SetDriveMode(GpioPinDriveMode.Output);

            _input = controller.OpenPin(digitalPin3);//GTI.InterruptInputFactory.Create(socket, GT.Socket.Pin.Three, GTI.GlitchFilterMode.On, GTI.ResistorMode.PullUp, GTI.InterruptMode.RisingAndFallingEdge, this);
            if (_input.IsDriveModeSupported(GpioPinDriveMode.InputPullUp))
                _input.SetDriveMode(GpioPinDriveMode.InputPullUp);
            else
                _input.SetDriveMode(GpioPinDriveMode.Input);

            //this.input.Interrupt += this.OnInterrupt;
            _input.ValueChanged += Input_ValueChanged;
        }

        private void Input_ValueChanged(object sender, GpioPinValueChangedEventArgs e)
        {

            var state = e.Edge == GpioPinEdge.FallingEdge ? ButtonState.Released : ButtonState.Pressed;

            switch (state)
            {
                case ButtonState.Released:
                    if (Mode == LedMode.OnWhilePressed)
                        TurnLedOff();
                    else if (Mode == LedMode.OnWhileReleased)
                        TurnLedOn();
                    else if (Mode == LedMode.ToggleWhenReleased)
                        ToggleLed();

                    break;

                case ButtonState.Pressed:
                    if (Mode == LedMode.OnWhilePressed)
                        TurnLedOn();
                    else if (Mode == LedMode.OnWhileReleased)
                        TurnLedOff();
                    else if (Mode == LedMode.ToggleWhenPressed)
                        ToggleLed();

                    break;
            }

            OnButtonEvent(this, state);
        }


        /// <summary>Turns on the LED.</summary>
        public void TurnLedOn()
        {
            _led.Write(GpioPinValue.High);
        }

        /// <summary>Turns off the LED.</summary>
        public void TurnLedOff()
        {
            _led.Write(GpioPinValue.Low);
        }

        /// <summary>Turns the LED off if it is on and on if it is off.</summary>
        public void ToggleLed()
        {
            if (IsLedOn)
                TurnLedOff();
            else
                TurnLedOn();
        }

        /*
         private void OnInterrupt(GTI.InterruptInput input, bool value)
        {
            var state = value ? ButtonState.Released : ButtonState.Pressed;

            switch (state)
            {
                case ButtonState.Released:
                    if (this.Mode == LedMode.OnWhilePressed)
                        this.TurnLedOff();
                    else if (this.Mode == LedMode.OnWhileReleased)
                        this.TurnLedOn();
                    else if (this.Mode == LedMode.ToggleWhenReleased)
                        this.ToggleLED();

                    break;

                case ButtonState.Pressed:
                    if (this.Mode == LedMode.OnWhilePressed)
                        this.TurnLedOn();
                    else if (this.Mode == LedMode.OnWhileReleased)
                        this.TurnLedOff();
                    else if (this.Mode == LedMode.ToggleWhenPressed)
                        this.ToggleLED();

                    break;
            }

            this.OnButtonEvent(this, state);
        }
        */
        private void OnButtonEvent(Button sender, ButtonState state)
        {
            if (_onButtonEvent == null)
                _onButtonEvent = OnButtonEvent;
            switch (state)
            {
                case ButtonState.Released:
                    ButtonReleased?.Invoke(sender, state);
                    break;
                case ButtonState.Pressed:
                    ButtonPressed?.Invoke(sender, state);
                    break;
            }
            /*
            if (Program.CheckAndInvoke(state == ButtonState.Released ? this.ButtonReleased : this.ButtonPressed, this.onButtonEvent, sender, state))
            {
                switch (state)
                {
                    case ButtonState.Released: this.ButtonReleased(sender, state); break;
                    case ButtonState.Pressed: this.ButtonPressed(sender, state); break;
                }
            }*/
        }
    }
}

**
** * Program.cs:**
**
using System.Threading;
using GHIElectronics.TinyCLR.Devices.Gpio;
using GHIElectronics.TinyCLR.Pins;

namespace TestGadgeteerButton
{
    static class Program
    {
        private static Button _button;
        private static GpioPin _led;
        static void Main()
        {
            Init();
            while (true)
            {
                Loop();
                Thread.Sleep(20);
            }
            // ReSharper disable once FunctionNeverReturns
        }

        private static void Loop()
        {
            _led.Write(_led.Read()==GpioPinValue.Low?GpioPinValue.High : GpioPinValue.Low);
            Thread.Sleep(200);
        }

        private static void Init()
        {
            // Led Mainboard blinking
            _led = GpioController.GetDefault().OpenPin(FEZCerberus.GpioPin.DebugLed);
            _led.SetDriveMode(GpioPinDriveMode.Output);
            _led.Write(GpioPinValue.High);

            // Button
            _button =new Button(FEZCerberus.GpioPin.Socket6.Pin3,FEZCerberus.GpioPin.Socket6.Pin4);
            _button.TurnLedOn();
            _button.ButtonPressed += _button_ButtonPressed;
            _button.ButtonReleased += _button_ButtonReleased;
        }

        private static void _button_ButtonReleased(Button sender, Button.ButtonState state)
        {
            _button.TurnLedOff();
        }

        private static void _button_ButtonPressed(Button sender, Button.ButtonState state)
        {
            _button.TurnLedOn();
        }
    }
}
2 Likes

Hi,
just had a look at the CerbuinoBee Pin Definitions and the drivers for the Gadgeteer Button module.

First of all I noticed a strange behaviour of the CerbuinoBee mainboard. When the button module was plugged into socket 1 the board was not recognized as a USB device by my PC (Windows 10, 64 bit), Socket 2 and Socket 3 worked well.

Then I had a look at the driver of @mifmasterz

The drivers use the Gadgeteer namespaces which should be avoided with TinyCLR (as I think). It would be nice if @mifmaserz would tell us his opinion about this and perhaps use the libraries/namespaces as proposed in the example of @Bauland.

The button driver of @Bauland in this post for the Cerberus mainboard worked without issues on the CerbuinoBee Sockets 1 and 2 as well.

IMO one thing that should be considered is the name of the driver classes. Should it only by e.g. Button or better e.g. Button_TinyCLR to show that it is a driver for TinyCLR?
The next thing is the name of the namespace of the driver. One namespace for all the drivers e.g. GHIElectronics.TinyCLR.GadgeteerDrivers ? or e.g. Community.TinyCLR.GadgeteerDrivers ? Or should there be a separate namespace for each module?
I think GHI should make a suggestion for the labelling to achieve some kind of uniformity.

Perhaps the button driver of @Bauland (with changed namespaces) should be posted as an example for the basic structure of a driver.

I would like to actually try different scenarios with different combinations of modules and mainboards. I will share my findings when I get to it. But I would like to see some more input from the community as well.

1 Like

When I’m started this project, the motivation is how to use gadgeteer modules in TinyCLR without too much changes in the code, so I keep the original namespaces, I just change a couple of implementation inside the module drivers. So, if you compare between gadgeteer and TinyCLR gadgeteer, the differences are only in the visual composer, pin mapping, and the module class constructor. I am really happy to know that GHI guys will continue their support for Gadgeteer with TinyCLR, I’m thinking of doing the same concept with the grove modules from Seeed.

2 Likes

This is top secret news! FEZ Spider (original) is now running TinyCLR OS over serial bus. USB is still in the works. Will this week’s tech talk be about the original FEZ Spider with TinyCLR OS? :nerd:

1 Like

Can you unpack that? Do you mean updated to run TinyCLR OS over serial? Or communicating with VS over serial?

So top secret, it’s on Facebook!

:wink:

I can debug/deploy over serial…but I am sure USB will be working soon. Going from Cortex to ARM7 is a big change, a lot bigger than I thought!