Created Tue, 14 Jun 2011 13:48:23 +0000 by 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.
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
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);
}
}
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.
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