Plain NETMF on Cerb40

Hi guys,

Just wondering if anyone can help me with syntax examples for plain NETMF on Gadeteer? I’m a hardware guy so my programming isn’t very good…
I’m just trying to get some PWM and input buttons working on my Cerb40, I have some Panda II code but not sure how to get it working on the Cerb40.

Panda II code:

InterruptPort LeftTurn = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.Di43, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeHigh);
LeftTurn.OnInterrupt += new NativeEventHandler(LeftTurn_OnInterrupt);
static PWM Red = new PWM((PWM.Pin)FEZ_Pin.PWM.Di6);

Am I on the right track with this?
InterruptPort LeftTurn = new InterruptPort((Cpu.Pin)FEZCerberus.Interrupt.PA2, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeHigh);
PWM LeftRed = new PWM((PWM.Pin)FEZCerberus.PWM.PB9);

Yep, you’re on the right track. It should be VERY similar to Panda II programming, except Panda II is 4.1, and Cerb40 is 4.2. The PWM, for instance, is significantly changed.

Ok…

Where could I learn about these changes? There was plenty of sample code for the Panda there doesn’t seem to be any for the Cerb stuff.

The best place to find out the new stuff in 4.2 is the netmf reference API Reference for .NET Micro Framework | Microsoft Learn

The PWM page is PWM Class | Microsoft Learn

Thanks Brett, but I need syntax examples…

something like this:

PWM MyFader = new PWM(Cpu.PWMChannel.PWM_3,10000,0.1,false);

There doesn’t seem to be any examples from the OSHW yet…

yep, it’s pretty much all new… heck, it’s still only a release candidate not even prime-time! That does mean there are limited examples, sorry; but your code looks good, what is wrong? (I have a recollection of PWM in 4.2 having an issue, but can’t remember details at the moment; I might be back after a quick search)

something like this?

       Microsoft.SPOT.Hardware.PWM pwm = new Microsoft.SPOT.Hardware.PWM((Cpu.PWMChannel)GHI.OSHW.Hardware.FEZCerberus.Pin.PC6, 20000, 1500, PWM.ScaleFactor.Microseconds, false);
            pwm.Start();

            pwm.Duration = 2000;

This thread - http://www.tinyclr.com/forum/topic?id=8616 - leads you to this codeplex tracked bug - https://netmf.codeplex.com/workitem/1749

[quote]Changing PWM frequency should handle duty cycle as well

In 4.2 PWM support, a change to frequency will corrupt dutycycle. This can’t be fixed by vendors as they do not have access to frequency and duty cycle, only period and pulse.

Example:
PWM.Frequency = 1000;
PWM.Duty =0.5;
// everything is working now with 1Khz at 50%
PWM.Frequency = 10000;
// PWM now is not working as the C# drivers didn’t readjust
PWM.Duty = 0.5;
// things are now working again.

Seeing duty after frequency will fix it but will always cause this unacceptable glitch.

The other work around for user to not use frequency and duty and only use pulse and period instead.[/quote]

Simply awesome, thanks Justin.

Any chance you have something like that for the inputs/interrupt handler?

@ Youraagh - No worries :slight_smile:


using System;
using Microsoft.SPOT.Hardware;

namespace MFConsoleApplication2
{
    public class Program
    {
        private static Microsoft.SPOT.Hardware.InterruptPort _interruptPort;
        public static void Main()
        {
            _interruptPort = new InterruptPort(GHI.OSHW.Hardware.FEZCerberus.Pin.PC6,true,Port.ResistorMode.PullUp,Port.InterruptMode.InterruptEdgeHigh);
            _interruptPort.OnInterrupt += new NativeEventHandler(interruptPort_OnInterrupt);
        }
        static void interruptPort_OnInterrupt(uint data1, uint data2, DateTime time)
        {
            // do magic here
        }
    }
}

This will turn PC6 on and off (Blink a LED etc) every second.


using System.Threading;
using Microsoft.SPOT.Hardware;

namespace MFConsoleApplication2
{
    public class Program
    {
        private static Microsoft.SPOT.Hardware.OutputPort _outputPort;
        public static void Main()
        {
            _outputPort = new OutputPort(GHI.OSHW.Hardware.FEZCerberus.Pin.PC6,false);
            Timer myTimer = new Timer(new TimerCallback(Blinkie), null, 1000, 1000);
            Thread.Sleep(Timeout.Infinite);
        }
        static void Blinkie(object o)
        {
            _outputPort.Write(!_outputPort.Read());
        }
    }
}

Still having trouble with PWM:

Microsoft.SPOT.Hardware.PWM RearRed = new Microsoft.SPOT.Hardware.PWM((Cpu.PWMChannel)GHI.OSHW.Hardware.FEZCerberus.Pin.PB8, 100, 0, false);
RearRed.Start();
RearRed.Duration = 25;

I get “an unhandled exception of type ‘System.InvalidOperationException’ occurred in Microsoft.SPOT.Hardware.dll” when debugging.
I know I can ignore the "first chance exception, but the unhandled one is causing trouble.

@ Youraagh - Post your entire code and wrap it with the Code tag and lets see if we can track the issue down.

@ Justin - tested the below with a Cerb Bee just now, moves a servo back and forward every 2 secs.


using System.Threading;
using Microsoft.SPOT.Hardware;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;

namespace GadgeteerApp1
{
    public partial class Program
    {
        private Microsoft.SPOT.Hardware.PWM _pwm;
        private GT.Timer _timer;

        void ProgramStarted()
        {
            _pwm = new PWM((Cpu.PWMChannel)GHI.OSHW.Hardware.FEZCerbuino.Pin.PWM.D5, 20000, 1500, PWM.ScaleFactor.Microseconds, false);
            _pwm.Start();
            _timer = new GT.Timer(2000);
            _timer.Tick += new GT.Timer.TickEventHandler(TimerTick);
            _timer.Start();
            
        }

        void TimerTick(GT.Timer timer)
        {
            _timer.Stop();
            _pwm.Duration = 1000;
            Thread.Sleep(500);
            _pwm.Duration = 2000;
            _timer.Start();
        }
    }
}


You are using the wrong pin enum?

Hi Youraagh,

When it comes to Microsoft’s NetMF implementation of PWM they use channels instead of pins. You would only need to typecast the PWM pin if it is out of the range of the pre-enumerated pins. Microsoft goes up to about 7. The Cerb-Famly has about 16 (Depending of course which board you are using). If you are needing a PWM for a board other than Cerbuino you would have to look up the pin to the Channel to get the right PWM Channel as Cerbuino has the PWM channels already enumerated.


//                         C6,A7,C7,A8,B0,B1,B5,B4,B3,B11,B10,A10,A9,A15, B8, B9
 #define STM32F4_PWM_TIMER { 8,14, 8, 1, 3, 3, 3, 3, 2,  2,  2,  1, 1,  2,  4,  4}
 #define STM32F4_PWM_CHNL  { 0, 0, 1, 0, 2, 3, 1, 0, 1,  3,  2,  2, 1,  0,  2,  3}
 #define STM32F4_PWM_PINS  {38, 7,39, 8,16,17,21,20,19, 27, 26, 10, 9, 15, 24, 25}

where channel 0 is C6 and channel 15 is B9

In your case you would want channel 14 so you would need to use this: (Cpu.PWMChannel)14

Typecasting GHI.OSHW.Hardware.FEZCerberus.Pin.PB8 is in essence setting the channel to 24 ((1 * 16) + 8)

Thanks Aron, but changing the Enumeration type doesn’t make any difference, I still get:
“An unhandled exception of type ‘System.InvalidOperationException’ occurred in Microsoft.SPOT.Hardware.dll”

Justin’s example compiles but, then I get:
"Warning: socket 3 is not compliant with Gadgeteer : Socket of type O must support analog output functionality
Warning: socket 4 is not compliant with Gadgeteer : Socket of type O must support analog output functionality

So what should I do next? Try and use Justin’s code by trying to figure out the equivalence pin names on the Cerb40?

The processor is the same on the Cerb40 as it is on all of the Cerb-Family boards. The list that I gave you would match the pins on the Cerb40 as well. What I mean by this is on the Cerb40 there is a pin out silkscreen on the back. Find the right pin on the Cerb40 and use the proper channel enumeration to access the PWM on Cerb40.

I think I’m still not understanding can anyone help?

I’m trying to compile this:
Microsoft.SPOT.Hardware.PWM LeftRed = new Microsoft.SPOT.Hardware.PWM((Cpu.PWMChannel)25, 100, 0, PWM.ScaleFactor.Milliseconds, false);
Which I’m hoping is a PWM on Pin B5 running at 10Khz with 0us duration.

I get this error:
An unhandled exception of type ‘System.InvalidOperationException’ occurred in Microsoft.SPOT.Hardware.dll

Because there is no PWM on channel 25. As Aron said, you should be using 14, not 25.

[quote=“Aron”]where channel 0 is C6 and channel 15 is B9

In your case you would want channel 14 so you would need to use this: (Cpu.PWMChannel)14[/quote]