Main Site Documentation

Two PWM channels interfering with each other? FEZ Panda II based controller


#1

Hi,
I have declared two PWM channels, and have one of them hooked up to the dimming input on an LED controller.

            // Set PWM pins low
            PWM1.Set(true);
            PWM2.Set(true);

When the code runs the first one, it sets the value to 3.3V, as expected. When the second one is set, the second PWM goes up to 3.3V as expected, but the first PWM goes back down to 0V. What is going on here?
Thanks,
Tom


#2

Can you provide the PINS you use for PWM1 and PWM2 ?


#3

Hi,
The pins are:
PWM2 = PWM1/IO35
PWM1 = PWM2/IO25

Thanks,
Tom


#4

@ tommyvdp - Unfortunately, I am unable to replicate your issue using the latest 4.1 SDK and the following code:


using System;
using System.Threading;
using System.IO;

using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;

using GHIElectronics.NETMF.FEZ;
using GHIElectronics.NETMF.Hardware;

namespace _113827
{
    public class Program
    {
        public static void Main()
        {
            PWM PWM1 = new PWM(PWM.Pin.PWM2);
            PWM PWM2 = new PWM(PWM.Pin.PWM1);

            PWM1.Set(true);
            PWM2.Set(true);
        }

    }
}

#5

Hi,
It seems like this problem is only happening when there is a device hooked up to PWM1 (there is none on PWM2). I will have to do some further testing.
Thanks for the help,
Tom


#6

That would not be possible, unless you are overloading the pin, which is also drawing too much power, which is not sufficient, which in turn causing problems.


#7

@ James :

Little mistake in your declaration (PWM1 defined using Pin.PWM2 and PWM2 using Pin.PWM1) which does not generate border effect in this case…

@ tommyvdp :

Did you not something like defining PWM1 and PWM2 using Pin.PWM1 or something like that…


#8

Hi,
I had them defined just like James’s example. Then cross between PWM1 and PWM2 is due to the circuit board layout. This is a custom industrial controller based on the 100 pin module GHI sells and defined as a Panda II for pinout and software purposes. The full code is here:

using System;
using System.Threading;
using System.IO.Ports;

using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;

using GHIElectronics.NETMF.FEZ;
using GHIElectronics.NETMF.Hardware;
namespace IndustrialIO
{
    public class Program
    {
        /// <summary>
        /// Shows if there is data available
        /// </summary>
        static bool isData = false;

        /// <summary>
        /// Stores serial buffer data
        /// </summary>
        static string bufferString = String.Empty;

        /// <summary>
        /// Store PWM duty cycles
        /// </summary>
        static int pwm1Duty = 100;
        static int pwm2Duty = 100;

        /// <summary>
        /// Stores Emergency Trip
        /// </summary>
        static bool emergencyBit = false;

        /// <summary>
        /// Sets up COM1 on the FEZ mini as the PC communication port
        /// </summary>
        static SerialPort COM1 = new SerialPort("COM1", 115000);
        
        /// <summary>
        /// Stores I2C device
        /// </summary>
        static I2CDevice myI2C;

        /// <summary>
        /// Create ADS1115 A/D Converter configuration
        /// </summary>
        static I2CDevice.Configuration ADS1115 = new I2CDevice.Configuration(0x48, 400);


        /// <summary>
        /// Set up Input Ports
        /// </summary>
        public static InputPort LDR = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.LDR, false, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeLow);
        public static InputPort DIN1 = new InputPort((Cpu.Pin)FEZ_Pin.Digital.An0, false, Port.ResistorMode.PullDown);
        public static InputPort DIN2 = new InputPort((Cpu.Pin)FEZ_Pin.Digital.An1, false, Port.ResistorMode.PullDown);
        public static InputPort DIN3 = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.An2, false, Port.ResistorMode.PullDown, Port.InterruptMode.InterruptEdgeHigh);
        public static InputPort DIN4 = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.Di12, false, Port.ResistorMode.PullDown, Port.InterruptMode.InterruptEdgeHigh);
        public static InputPort DIN5 = new InputPort((Cpu.Pin)FEZ_Pin.Digital.Di11, false, Port.ResistorMode.PullDown);
        public static InputPort DIN6 = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.Di13, false, Port.ResistorMode.PullDown, Port.InterruptMode.InterruptEdgeBoth);
        public static InputPort DIN7 = new InputPort((Cpu.Pin)FEZ_Pin.Digital.Di5, false, Port.ResistorMode.PullDown);
        public static InputPort DIN8 = new InputPort((Cpu.Pin)FEZ_Pin.Digital.Di6, false, Port.ResistorMode.PullDown);

        public static InputPort[] inputPorts = new InputPort[] {DIN1,DIN2,DIN3,DIN4,DIN5,DIN6,DIN7,DIN8};

        /// <summary>
        /// Set up output ports
        /// </summary>
        public static OutputPort DOUT1 = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.Di21, false);
        public static OutputPort DOUT2 = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.Di20, false);
        public static OutputPort DOUT3 = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.Di23, false);
        public static OutputPort DOUT4 = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.Di22, false);
        public static OutputPort DOUT5 = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.Di25, false);
        public static OutputPort DOUT6 = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.Di24, false);
        public static OutputPort DOUT7 = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.Di27, false);
        public static OutputPort DOUT8 = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.Di26, false);
        public static OutputPort LED = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.LED, false);

        public static OutputPort[] outputPorts = new OutputPort[] { DOUT1, DOUT2, DOUT3, DOUT4, DOUT5, DOUT6, DOUT7, DOUT8 };

        /// <summary>
        /// Sets up PWM pins
        /// </summary>
        public static PWM PWM1 = new PWM(PWM.Pin.PWM2);
        public static PWM PWM2 = new PWM(PWM.Pin.PWM1);

        /// <summary>
        ///  Create LCD
        /// </summary>
        public static AF10216A myLCD = new AF10216A("COM4");

        /// <summary>
        /// Set up dSpin items
        /// </summary>
        // Initialize flag and busy ports for all dSpin controllers
        public static InputPort flagPort = new InputPort((Cpu.Pin)FEZ_Pin.Digital.Di50, false, Port.ResistorMode.Disabled);
        public static InputPort busyPort = new InputPort((Cpu.Pin)FEZ_Pin.Digital.Di47, false, Port.ResistorMode.Disabled);

        public static UInt32 dSPIN_rx_data = 0;

        public static dSPIN_RegsStruct_TypeDef dSPIN_RegsStruct;

        public static dSpin myL6472 = null;

        /// <summary>
        /// X Axis configuration
        /// </summary>
        public static SPI.Configuration xAxisConfig = new SPI.Configuration((Cpu.Pin)FEZ_Pin.Digital.Di49,
            false, // Chip Select, active-low
            1000, // 1000 (nanoseconds?) setup time
            1000, // 1000 (nanoseconds?) hold time
            true, // Clock low on idle
            true, // Data valid on falling edge
            5000, // 5Mhz Clock Rate
            SPI.SPI_module.SPI2); //SPI device 2

        /// <summary>
        /// Y Axis configuration
        /// </summary>
        public static SPI.Configuration yAxisConfig = new SPI.Configuration((Cpu.Pin)FEZ_Pin.Digital.Di48,
            false, // Chip Select, active-low
            1000, // 1000 (nanoseconds?) setup time
            1000, // 1000 (nanoseconds?) hold time
            true, // Clock low on idle
            true, // Data valid on falling edge
            5000, // 5Mhz Clock Rate
            SPI.SPI_module.SPI2); //SPI device 2

        /// <summary>
        /// R Axis configuration
        /// </summary>
        public static SPI.Configuration rAxisConfig = new SPI.Configuration((Cpu.Pin)FEZ_Pin.Digital.Di51,
            false, // Chip Select, active-low
            1000, // 1000 (nanoseconds?) setup time
            1000, // 1000 (nanoseconds?) hold time
            true, // Clock low on idle
            true, // Data valid on falling edge
            5000, // 5Mhz Clock Rate
            SPI.SPI_module.SPI2); //SPI device 2

        /// <summary>
        /// Default method
        /// </summary>
        public static void Main()
        {
            // Initializes Motor Controllers
            InitializeMotors();

            // Write to LCD
            myLCD.SendCommand(AF10216A.Commands.FormFeed);
            Thread.Sleep(50);
            myLCD.Print("600-0061-2");
            Thread.Sleep(50);
            myLCD.SendCommand(AF10216A.Commands.CR);
            Thread.Sleep(50);
            myLCD.Print("Optics Placement");

            // Attach Event Handler to 'COM1'
            COM1.DataReceived += new SerialDataReceivedEventHandler(COM1_DataReceived);

            // Open Com port
            COM1.Open();

            // Attach events to Estop & LC Inputs
            DIN3.OnInterrupt += new NativeEventHandler(DIN3_OnInterrupt);
            DIN4.OnInterrupt += new NativeEventHandler(DIN4_OnInterrupt);
            DIN6.OnInterrupt += new NativeEventHandler(DIN6_OnInterrupt);

            // Set PWM pins low
            PWM1.Set(true);
            PWM2.Set(true);

            // Set outputs low
            WriteDigitalOutputs(0);

            //Turn on LED
            LED.Write(true);

            // LED int
            int i = 0;

            while (true)
            {
                // Check to see if there is data available, then process
                if (isData)
                {
                    ProcessData();
                }

                // If 500 ms have passed, blink LED
                if (i > 50)
                {
                    LED.Write(!LED.Read());
                    i = 0;
                }

                Thread.Sleep(10);

                i++;
            }
        }

Thanks,
Tom


#9

@ tommyvdp - oooo multiple axis on spi…what does it do?


#10

Let me guess. CNC or engraver controller?


#11

@ Justin - It runs an automated robotic system that places two parts together in concert with a PC running some machine vision software. The controller drives three STI L6472 stepper drivers in X, Y, and R axes. I use this controller for this and a number of other pieces of test equipment at work. It is sort of a Programmagle Logic Controller on steroids. The PWM drivers were to control the machine vision lighting level through software, but I am having issues…
Tom


#12

@ tommyvdp - sounds very interesting :slight_smile:
What sort of accuracy do you need on the steppers and how much current etc do you need on the lighting?


#13

The motors are all in one stepper actuators from Haydon Kerk. They are at 16 microsteps, which gives them accuracy in the 100ths of a millimeter (theoretically at least).

The lights are 700mA max. The lighting controller has a PWM input, but it may be demanding too much from the FEZ controller. I could do a transistor output from the FEZ controller to handle a heavier PWM current and voltage level.
Tom


#14

A user on here is building a 700ma LED controller using SPI (i think), will be interesting to see if something like that would suit…