Microcontrollers
Micromouse Update
by Martyn on May.10, 2009, under Microcontrollers, Micromouse, Robots
As its exam time I have been carefully avoiding revision with a mix of counterstrike and micromouse work. New PCBs are 95% ready to be ordered and so my focus has turned to the controllers.
After implementing a fixed point maths system for the controller (10.5bits signed for those who care) and ziegler-nichols tuning the PI controller I had a one wheel mouse - putting a bit more effort in I got it to two wheels - yay.
Tuning it was a bit of a chore - so automation is king and I was able to produce this graph (yes, no axis labels, minus 2 marks for me, x is the time, y (going back into the scene) is as the gain increases and z (going up) is the velocity for said gain:
The idea is to find the point where oscillations occur, the above plot was far too noisy so a 16 point moving average was applied:
I got a value of about 1.2, but it is questionable, will compare against some simulated controllers to see if it seems a likely value - it does however work well enough to control the motors!
Now the results:
It is nice having onboard bluetooth for this sort of debugging, anyhow, things look nice - the integral term does push things out of whack when going from zero or getting down to zero - but possibly an artefact of the controller being ill tuned - there is still a large overshoot to a step input which is not what you would expect from a z-n tuned controller…
Video, go to http://www.youtube.com/watch?v=AYmkJvthVJw and click on view in HD at the bottom! or watch it in small size bellow:
Next time it will be slower and have a straight line controller built in, after that its onto cornering!
Buttons - and LEDs :D
by Martyn on Apr.04, 2009, under Microcontrollers, Micromouse, News, Robots
Buttons are cool, so are menu’s. So with the help of a button, a few leds and a dspic I have a menu system (also note that this is blocking, the idea is that its used to start / stop the robot, so the robot does not move while the menu is active), first lets look at the switch circuit and then at the dspic set up (c30 compiler, using a dspic33fj128gp804):
/* Setup the IO Pin Assignment */ __builtin_write_OSCCONL(OSCCON & ~(1<<6)); RPINR7bits.IC1R = 5; // Switch Input Capture __builtin_write_OSCCONL(OSCCON | (1<<6)); /* Switch Input Capture Setup */ IC1CONbits.ICM = 0x02; // Capture on falling edge _IC1IF = 0; _IC1IE = 1; /* CPU Time Clock */ T1CONbits.TCKPS = 0x02; // 40.5504Mhz / 64 TMR1 = 0x00; PR1 = 634*4; // Int at 1.000631313ms*4 _T1IF = 0; _T1IE = 1; T1CONbits.TON = 1;
The code is fairly simple: first attach the switch input to the input capture (ic1) peripheral, set up ic1 to trigger an interrupt on the falling edge and then there is the set up for my main timer loop, this occurs at ~250Hz, and yes I am using a weird value crystal.
Next lets look at the global variables (well global to the scope of the interrupts)
// Switch input vars int sw_counter = 0; int sw_on = 0; // Menu vars int menu_counter = 0; int menu_on = 0; int menu_value = 0;
Next the interrupt for the input capture routine
void __attribute__((__interrupt__)) _NOPSV _IC1Interrupt(void)
{
_IC1IF = 0; // Clear the interrupt
_IC1IE = 0; // Disable the interrupt
_RED = 1; // Show the user the button pressed
sw_on = 1; // Enable the debounce counter
// If the menu is on already, increment the menu value
// Otherwise turn the menu on and set the menu value to
//default
if (menu_on)
{
menu_val ++;
menu_counter = 0;
}
else
{
menu_on = 1;
menu_val = 0;
}
}
And then the interrupt for the timer:
void __attribute__((__interrupt__)) _NOPSV _T1Interrupt(void)
{
// Handle switch
if (sw_on) // If a switch 'event' is ongoing
{
sw_counter ++;
if (sw_counter > 50) // 50x 1/250 = 200ms debounce
{
sw_on = 0; // Switch no longer on
sw_counter = 0; // Counter to zero
_IC1IF = 0; // Clear the bounces
_IC1IE = 1; // Enable more switches
_RED = 0; // Led off
}
}
// Menu
if (menu_on) // If menu is on
{
menu_counter ++; // Increment counter
// Leave menu active for 1s after last click
if (menu_counter > 250)
{
menu_on = 0; // Menu off
menu_counter = 0; // Reset
// Menu complete - do stuff
switch (menu_val)
{
case 0:
_RED = 0;
Nop(); // Required if RED and GREEN
// On same port
_GREEN = 1;
break;
case 1:
_RED = 1;
Nop(); // Required if RED and GREEN
// On same port
_GREEN = 0;
break;
default:
break;
}
}
}
}
And thats it, google _NOPSV to find the macro for that (sometimes required to compile using c30). Also _RED and _GREEN are port bits, so something like #define _RED _RB1 to make _RED = 1 turn Port B pin 1 on. All quite useful, maybe…
Its must have been a good day for someone…
by Martyn on Apr.02, 2009, under Microcontrollers, Micromouse, News, Photoblog, Robots
Today was a very unproductive one. Slept in, managed to do nothing till 2, then spend hours trying to work out why something had broken on my mouse - it was me, it was running 4 times slower because I put the line of code to tell it to run 4 times faster in the wrong place, that followed by a c# bottleneck - c#.net cannot handle 1mbit rs232 too well, its running fine at about 20% capacity, but between there and 50% capacity something goes very wrong. That lead to hours of no progress. And finally I though I may have broken one of my motors, the expensive ones, but it was fine, a bad connector, or maybe a break in the cable (think it was the former as after a lot of wiggling I cant detect a break). It must work - look at the graph bellow
result.

Graph if step input to motor
The ‘rough’ steady state speed of this input is about 2m/s, mwhahaha, lets hope there is some torque at 0.3m/s otherwise testing will be interesting….
Timering with DSPic’s
by Martyn on Mar.22, 2009, under Microcontrollers, Robots
Timers on DSPics are easy - and after helping a few people out with timers at uni I thought I would post a really quick how-to on setting up a timer to interrupt at a set frequency. First lets start with a few bits you need to know:
Fosc = 40000000;
That’s it
Just make sure that this value is the number in Hz on your oscillator (or a multiple of it if using PLL)
Next its important to remember there are different types of timers on a pic, do some research and rtfm before doing any pic / embedded work - will save you hours, I am using timer 1 - as its the first one in the manual :p
Next bits:
-
-
-
T1CONbits.TCKPS = 0×02; // Select the PRESCALER
-
TMR1 = 0×00; // Make sure the timer is starting from zero
-
PR1 = 600; // How long the timer should run before an interrupt (in timer ticks)
-
_T1IF = 0; // Clear the interrupt flag
-
_T1IE = 1; // Enable the interrupt
-
T1CONbits.TON = 1; // Turn the interrupt on
-
-
void __attribute__((__interrupt__)) __attribute__((no_auto_psv)) _T1Interrupt(void)
-
{
-
// Funky interrupt code goes
-
}
-
-
To explain, the prescale waits x many ticks before incrementing the timer counter and is usually a set number like 1,8,32 or 64. To calculate the number for PR1 you then juse a very simple formula:


Where Freq is your desired interrupt frequency. Then just round the value of PR1 to the nearest integer if it is not one already. Simple!
As a side note - more information to why the interrupt function has a no_auto_psv attribute can be found at FlyingPic24.com
Hope this has been useful - please comment if you have any corrections/questions/comments.
Micromouse has shrunk a bit…
by Martyn on Oct.19, 2008, under Microcontrollers, Robots
A bit (lot) late, but I just noticed a video posted on youtube with a 1/2 size micromouse - Its tiny!
Anyhow, I have been working on my mouse as it is also my 4th (and final) year project for my MEng Cybernetics degree. Been working on the motor housing and choosing the components for the hardware, to make sure it all fits I built everything up in Solidworks and got some prototypes made!
Head over to www.shapeways.com to see about their rapid prototyping server - its really fast, easy to use and mighty cheap.
Here are a couple of photos of the prototypes, first one is a ’simplified’ complete model and the second is the actual motor mount.
Unfortunately I had to change motor, so I have redesigned everything… But there was a special offer on at shapeways, so I was able to order more prototypes. This time I have also ordered parts which will be used on the final mouse including skids and sensor mounts.







