Interrupt triggers randomly (only when i run a motor)

Hi all, i have a slight problem, i am trying to run some motors via my fez panda2. I have 2 limit switches connected to the ends of the tracks of the motors and i am using the motor in PWM mode.

I have setup 2 interrupt routines for the limit switches and some debug LED’s so that i know if the routine run or not. The routine is simply meant to change the direction of the motor direction via a single digital i/o. The uart is used to send simple commands to start/stop or change the direction of the motor.

The code runs properly if the motors are not in operation, and the debug LED’s only change state when i manually touch the limit switches. But as soon as i start up the motors via PWM the interrupts are triggering randomly. I know the interrupts are triggering as i can see that from the debug LED’s.

I have probed the i/o pins of the interrupts and those pins are not changing state - so the interrupts are just randomly triggering. i am also using a schmitt trigger circuit before the interrupt pins to ensure that there is no grey are that may trigger an interrupt.

I have attempted to remove the PWM mode and run the h-bridges of a digital i/o line but this did not change anything.

please advise.

Thanks in advance


// code for the linear

using GHIElectronics.NETMF.Hardware;
using GHIElectronics.NETMF.IO;
using GHIElectronics.NETMF.System;
using GHIElectronics.NETMF.FEZ;

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

using System;
using System.IO;
using System.Threading;
using System.Text;
using System.IO.Ports;
namespace MFConsoleApplication8
{
    public class Program
    {

        static OutputPort LED;
        static OutputPort Debug1;
        static OutputPort Debug2;
        static OutputPort Debug3;
        static OutputPort MotorDirection;
        static PWM PWMMotor;
        static InterruptPort LimitSwitchA;
        static InterruptPort LimitSwitchB;

        // Use UART channel 1
        static SerialPort UART = new SerialPort("COM1", 115200);

        public static void Main()
        {
            LED = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.LED, false);
            Debug1 = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.Di50, false);
            Debug2 = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.Di51, false);
            Debug3 = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.Di52, false);
            MotorDirection = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.Di38, false);
 
            PWMMotor = new PWM((PWM.Pin)FEZ_Pin.PWM.Di5);

            //uart open
            UART.Open();
            UART.DataReceived += new SerialDataReceivedEventHandler(UART_DataReceived);

            TimeSpan ts = new TimeSpan(0, 0, 0, 0, 500);               
            Microsoft.SPOT.Hardware.Cpu.GlitchFilterTime = ts;

            LimitSwitchA = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.Di37, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeHigh);
            LimitSwitchB = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.Di39, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeLow);

            LimitSwitchA.OnInterrupt +=new NativeEventHandler(LimitSwitchA_OnInterrupt);
            LimitSwitchB.OnInterrupt += new NativeEventHandler(LimitSwitchB_OnInterrupt);

            Debug1.Write(true);
            Debug.Print(">>> setup complete <<<");

            while (true)
            {
                LED.Write(!LED.Read());
                Thread.Sleep(200);
            }

        }//end of class

        static void LimitSwitchB_OnInterrupt(uint data1, uint data2, DateTime time)
        {   // setting the pwm
            PWMMotor.Set(200, 0);
            Thread.Sleep(100);
            Debug2.Write(!Debug2.Read());
            MotorDirection.Write(!MotorDirection.Read());
            Thread.Sleep(100);
            // setting the pwm
         PWMMotor.Set(200, 100);
        }

        static void LimitSwitchA_OnInterrupt(uint data1, uint data2, DateTime time)
        {
            // setting the pwm

          PWMMotor.Set(200, 0);
            Thread.Sleep(100);
            Debug3.Write(!Debug3.Read());
            MotorDirection.Write(!MotorDirection.Read());
            Thread.Sleep(100);
            // setting the pwm
         PWMMotor.Set(200, 100);

        }

        static void UART_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {

            Debug2.Write(true);

            byte[] rx_data = new byte[10];
            UART.Read(rx_data, 0, 1);

            if (rx_data[0] != 10)
            {
                String UARTrx = ("UART MESSAGE RECIEVED, data:" + rx_data[0] + "\r\n");
                byte[] UARTrxBuffer = Encoding.UTF8.GetBytes(UARTrx);
                UART.Write(UARTrxBuffer, 0, UARTrxBuffer.Length);

                //97 = char a
                if (rx_data[0] == 97)
                {
                    String msg1 = ("going to START pwm motor" + "\r\n");
                    byte[] msg1Buffer = Encoding.UTF8.GetBytes(msg1);
                    UART.Write(msg1Buffer, 0, msg1Buffer.Length);
                    // setting the pwm
                    PWMMotor.Set(200, 100);
                    PWMLED.Set(200, 100);
                    Debug.Print(">>> PWM set <<<");

                }//end if rx data
                //98 = char b
                else if (rx_data[0] == 98)
                {
                    String msg2 = ("going to STOP pwm motor" + "\r\n");
                    byte[] msg2Buffer = Encoding.UTF8.GetBytes(msg2);
                    UART.Write(msg2Buffer, 0, msg2Buffer.Length);

                    // setting the pwm
                    PWMMotor.Set(200, 0);
                    PWMLED.Set(200, 0);
                    Debug.Print(">>> PWM set <<<");

                }//end else if rx data

                //98 = char c
                else if (rx_data[0] == 99)
                {
                    String msg2 = ("going to change motor direction" + "\r\n");
                    byte[] msg2Buffer = Encoding.UTF8.GetBytes(msg2);
                    UART.Write(msg2Buffer, 0, msg2Buffer.Length);
                    MotorDirection.Write(!MotorDirection.Read());

                }//end else if rx data
            }//end if 

            Debug2.Write(!Debug2.Read());
        }//end of rx data received event

    }//end class
}//end name space


It’s more likely a hardware problem, not softwre. I bet on insuficient or noisy FEZ suply.

motors/relays can generate a lot of noise which can cause input pins to toggle. Even worse, it can damage the processor if inductive noise is too high.

I have same problem. I also get random Interrupt even if motor have no connection with my Cerberus. So motor is connected directly to own power supply, but positioned nearby Cerberus (5-10cm). I guess it is magnetic field from running motor, but not sure. What can I do to prevent running motor effect my board?

Are you using pull-up/pull-down resistors? If yes, you might want to use a stronger one…