chipKIT® Development Platform

Inspired by Arduino™

Max32 Interrupts

Created Tue, 14 Jun 2011 13:48:23 +0000 by edge87


edge87

Tue, 14 Jun 2011 13:48:23 +0000

Hello everybody,

I'm new from the Arduino side of things and this is my first Pic processor. I couldn't find a interrupt library to handle setting an interrupt, and searching the forum seems to yield a result that it has yet to be written.

Could anybody lead me in the right direction to begin putting together something to accomplish a simple timed interrupt. I have a block of code that needs to keep repeating but at a very steady rate.

Thanks in advance for any direction.


KM6VV

Tue, 14 Jun 2011 17:21:25 +0000

What you might be looking for is the MsTimer LIB (on Arduino UNO). It hasn't been ported to the UNO32 yet. I need it as well, but haven't had the time to do it myself.

And if you want to run R/C servos, you need interrupts driven by timers as well. The Servo LIB isn't ported over yet either.

Alan KM6VV


Trev

Wed, 15 Jun 2011 11:01:32 +0000

And if you want to run R/C servos, you need interrupts driven by timers as well.

The servo library might be nice, but I've had no problem controlling a servo without using it or interrupts on a Uno32.

/*
 Ensure RB-421 servo earth is connected to Uno32 board earth or
 it won't work, duh!

            +6v ----------o Red RB-421 servo wire (+ve)
                  
 Pin 9 >>>>----v^v^v^------o Orange RB-421 servo wire (signal)
               220R

             0v ----------o Brown RB-421 servo wire (-ve)

 */

int servoPin = 9;   // servo connected to digital pin 9
int myAngle;        // angle of the servo 0-180 (servo dependant)
int pulseWidth;     // servoPulse function variable
int minAngle = 0;   // Value for RB-421 servo
int maxAngle = 180; //   "    "    "      "
int pw1 = 11;       //   "    "    "      "
int pw2 = 500;      //   "    "    "      "
int deadband = 20;  //   "    "    "      "

void setup()
{
  pinMode(servoPin, OUTPUT);    // sets pin 9 as output
}

void servoPulse(int servoPin, int myAngle)
{
  pulseWidth = (myAngle * pw1) + pw2; // determines delay 
  digitalWrite(servoPin, HIGH);       // sets servo signal high
  delayMicroseconds(pulseWidth);      // delay 
  digitalWrite(servoPin, LOW);        // sets servo signal low
  delay(deadband);                    // refresh cycle
} 

void loop()  
{
  // delay before continuing
  delay(2000);

  // servo starts at minAngle and rotates to maxAngle
  for (myAngle=minAngle; myAngle<=maxAngle; myAngle++) 
  {
    servoPulse(servoPin, myAngle);
  }  

  // delay before continuing
  delay(2000);

  // servo starts at maxAngle and rotates to minAngle 
  for (myAngle=maxAngle; myAngle>=minAngle; myAngle--) 
  {
    servoPulse(servoPin, myAngle);
  }
}

edge87

Wed, 15 Jun 2011 14:40:30 +0000

The interrupt isn't for directly controlling the servos but it has to do with catching an event from a switch matrix and executing servo motions based on that switch event.

The switch matrix needs to be polled at a regular interval and that was what I was hoping to build into a internal interrupt.


KM6VV

Wed, 15 Jun 2011 17:24:15 +0000

OK, you've got a servo connected up to pin 9, but what code are you using to drive it? I don't want to just sit on a single servo loop.

I know what you mean about checking the switches on an interrupt driven routine.

You've probably already seen it, but I use this code for an Arduino UNO:

MsTimer2::set(1, ItsAlive); // 1ms period
  MsTimer2::start();

/*-----------------------------------------------------------------
 * INTERRUPT ROUTINE
 *
 * 1 mS interrupt rate
 * set up by MsTimer2
 *
 * heartbeat    1sec blink shows life
 * TICK         100uS Sensor timing
 * SystemTick2  1mS time delay counter
 */

void ItsAlive(void)
  {
  static int Tickcount = 100;
  static int Alive = 500;
  static boolean output = HIGH;

  /* flash Alive Led at 1 Sec rate) */
  if(--Alive == 0)
    {
    digitalWrite(LED_HEART, output);
    output = !output;
    Alive = FastFlash;
    }

  ++SystemTick2;	/* 1mS timer for delays */

  if(--Tickcount == 0)
    {
    Tick = TRUE;    /* Tick rate 100mS */
    Tickcount = 100;
    }

  }

In the main program loop I check for Tick, and call the sensors() routine.

If I can get this running on the UNO32, I can add code to update a servo as well.

/* 2500 uS interrupt */
  if(TMR0IF && TMR0IE)				/* TMR0 mask enabled and an interrupt */
    {
    TMR0IF	= 0;	/* clear the interrupt flag on 18F4620 18F452, 16F877 */
    TMR0	= (const)PRELOAD_TMR0;		/* preload timer 0 */

    PORTB = 0;		/* servo0 - servo7  ALL SERVOS OFF (only one active anyway) */

		/* Load the 1's complement of the selected servo into timer 1 */
    TMR1L	= (0xFF ^ servos_low[ServoIndex]);
    TMR1H	= (0xFF ^ servos_high[ServoIndex]);

		// Turn on the appropriate servo:
  switch(ServoIndex)
    {
    case 0:
      {
      if(ServoEnables & 0x01)
        servo0 = 1;

      ServoIndex++;
      }
    break;

    case 1:
      {
      if(ServoEnables & 0x02)
        servo1 = 1;

      ServoIndex++;
      }
    break;

     /* up to 8 servos here... */
    }
  }

I've used the above code on an 18F4620, should be adaptable to the new PIC32. I haven't had time to try it!

Alan KM6VV