R3volution - Time for a fresh start

Well, r2 made it into a maze!  then crashed into the walls of that maze over... and over... and over... anyway, it diddnt work, and looks unlikely to work in the near or far future.

So i've spent some time fiddling with my CAD software, and now have a basic design ready to announce R3volution, my third micromouse!

Its a bit of an... unconventional design, with massive foam rubber wheels that i hope will give me a nice big contact patch, and therefore more traction on the ground.

The Gearbox is made up of 3 parts, a 3d printed 'backbone' and a pair of laser cut 'plates'

They are all designed in OpenSCAD, and set up in a parametric way, so i can adjust things like the angle of the motors and the height of the base plate without having to rebuild the entire cad files from scratch.  

It uses Faulhaber 1524SR motors with integrated encoders and 0.4 mod gearing, giving me a final gear ratio of 1:12.8, slightly higher than most mice (i think), but balanced out by the fact my wheels are HUGE.  The Axle for each side is a m4 bolt, mounted on mf84zz bearings and fixed to a custom wheel mounting system i'll be making on a lathe.

Electronics to follow when i've finished buying parts for & building the gearbox!

r2 - Moving Day!

[youtube=http://www.youtube.com/watch?v=ZImGw8d2ksc]

Finally got some time to work on r2 this weekend, and have movement! He can now move arond, and spin and stuff.

Unfortunately, still need to add some odometry, not quite worked out how thats going to work yet!

r2 update

finally got a gearbox mount that i'm happy with, just need to work out how to add odometry to it, since Plan A had two magnets close and opposite each other.  One wheel turning would turn the other!

R2 Project Log - Motors

After a minor slip up with a probe killed my primary R2 bot (shorted VBATT to 5VCC, bye bye processor and drive chips) I've tonight soldered up another of my spare R2 boards to take over the mantle.

And the motor drive code i was debugging at the time works!

[youtube=http://www.youtube.com/watch?v=tNQfu4DB9lU]

Tomorrow, i add a battery monitor circuit and the sensors, so i'll finally have al the major electronic systems tested and good to go ready for the motor mounts.

#define F_CPU 1000000UL
#include < avr/io.h>#include < util/delay.h>#include < avr/interrupt.h>#include "r2.h"

int main(void) {
// Activate all the LEDs, set their pins to output
bit_set(LED_WHITE_L_DDR, LED_WHITE_L_BIT);
bit_set(LED_WHITE_R_DDR, LED_WHITE_R_BIT);
bit_set(LED_RED_L_DDR, LED_RED_L_BIT);
bit_set(LED_RED_R_DDR, LED_RED_R_BIT);
bit_set(LED_YELLOW_FL_DDR, LED_YELLOW_FL_BIT);
bit_set(LED_YELLOW_FR_DDR, LED_YELLOW_FR_BIT);
bit_set(LED_YELLOW_RL_DDR, LED_YELLOW_RL_BIT);
bit_set(LED_YELLOW_RR_DDR, LED_YELLOW_RR_BIT);

// Activate the motor's control lines
bit_set(MOTOR_R_ENABLE_DDR, MOTOR_R_ENABLE_BIT);
bit_set(MOTOR_R_PHASE_DDR, MOTOR_R_PHASE_BIT);
bit_set(MOTOR_L_ENABLE_DDR, MOTOR_L_ENABLE_BIT);
bit_set(MOTOR_L_PHASE_DDR, MOTOR_L_PHASE_BIT);

// turn on the motors
bit_set(MOTOR_R_ENABLE_PORT, MOTOR_R_ENABLE_BIT);
bit_set(MOTOR_R_PHASE_PORT, MOTOR_R_PHASE_BIT);
bit_set(MOTOR_L_ENABLE_PORT, MOTOR_L_ENABLE_BIT);
bit_set(MOTOR_L_PHASE_PORT, MOTOR_L_PHASE_BIT);

// turn on the white and red LEDs
bit_set(LED_WHITE_L_PORT, LED_WHITE_L_BIT);
bit_set(LED_WHITE_R_PORT, LED_WHITE_R_BIT);
bit_set(LED_RED_L_PORT, LED_RED_L_BIT);
bit_set(LED_RED_R_PORT, LED_RED_R_BIT);

// enable internal pullup on PD0
bit_set(PORTD, BIT(0));
// enable external interrupts
EIMSK = BIT(INT0) | BIT(INT1);
// enable global interrupts
sei();

// loop forever
while (1)
{

delayms(500);
}
return 0;
}

// delay for up to 65k milliseconds
void delayms(uint16_t millis)
{
// loop, delaying 1ms each iteration
while ( millis )
{
_delay_ms(1);
millis--;
}
}

// this catches the Interrupt sent from pin INT0
ISR(INT0_vect)
{
//Turn everything off
bit_clear(LED_WHITE_L_PORT, LED_WHITE_L_BIT);
bit_clear(LED_WHITE_R_PORT, LED_WHITE_R_BIT);
bit_clear(LED_RED_L_PORT, LED_RED_L_BIT);
bit_clear(LED_RED_R_PORT, LED_RED_R_BIT);

bit_clear(MOTOR_R_ENABLE_PORT, MOTOR_R_ENABLE_BIT);
bit_clear(MOTOR_R_PHASE_PORT, MOTOR_R_PHASE_BIT);
bit_clear(MOTOR_L_ENABLE_PORT, MOTOR_L_ENABLE_BIT);
bit_clear(MOTOR_L_PHASE_PORT, MOTOR_L_PHASE_BIT);


// loop forever, flashing our indicators.
while(1)
{
bit_flip(LED_YELLOW_FL_PORT, LED_YELLOW_FL_BIT);
bit_flip(LED_YELLOW_FR_PORT, LED_YELLOW_FR_BIT);
bit_flip(LED_YELLOW_RL_PORT, LED_YELLOW_RL_BIT);
bit_flip(LED_YELLOW_RR_PORT, LED_YELLOW_RR_BIT);
delayms(500);
}
}

R2 Project Log - External Interrupts

I've done some playing, and worked out how to turn on the external interrupts on the atmega128 I am using for R2.

Code:

#define F_CPU 1000000UL
#include < avr/io.h>#include < util/delay.h>#include < avr/interrupt.h>#include "r2.h"

int main(void) {
// Activate all the LEDs, set their pins to output
bit_set(LED_WHITE_L_DDR, LED_WHITE_L_BIT);
bit_set(LED_WHITE_R_DDR, LED_WHITE_R_BIT);
bit_set(LED_RED_L_DDR, LED_RED_L_BIT);
bit_set(LED_RED_R_DDR, LED_RED_R_BIT);
bit_set(LED_YELLOW_FL_DDR, LED_YELLOW_FL_BIT);
bit_set(LED_YELLOW_FR_DDR, LED_YELLOW_FR_BIT);
bit_set(LED_YELLOW_RL_DDR, LED_YELLOW_RL_BIT);
bit_set(LED_YELLOW_RR_DDR, LED_YELLOW_RR_BIT);

// enable internal pullup on PD0
bit_set(PORTD, BIT(0));
// enable external interrupts
EIMSK = BIT(INT0) | BIT(INT1);
// enable global interrupts
sei();

// turn on the white and red LEDs
bit_set(LED_WHITE_L_PORT, LED_WHITE_L_BIT);
bit_set(LED_WHITE_R_PORT, LED_WHITE_R_BIT);
bit_set(LED_RED_L_PORT, LED_RED_L_BIT);
bit_set(LED_RED_R_PORT, LED_RED_R_BIT);

// loop forever
while (1)
{
delayms(500);
}
return 0;
}

// delay for up to 65k milliseconds
void delayms(uint16_t millis)
{
// loop, delaying 1ms each iteration
while ( millis )
{
_delay_ms(1);
millis--;
}
}

// this catches the Interrupt sent from pin INT0
ISR(INT0_vect)
{
//Turn everything off
bit_clear(LED_WHITE_L_PORT, LED_WHITE_L_BIT);
bit_clear(LED_WHITE_R_PORT, LED_WHITE_R_BIT);
bit_clear(LED_RED_L_PORT, LED_RED_L_BIT);
bit_clear(LED_RED_R_PORT, LED_RED_R_BIT);

// loop forever, flashing our indicators.
while(1)
{
bit_flip(LED_YELLOW_FL_PORT, LED_YELLOW_FL_BIT);
bit_flip(LED_YELLOW_FR_PORT, LED_YELLOW_FR_BIT);
bit_flip(LED_YELLOW_RL_PORT, LED_YELLOW_RL_BIT);
bit_flip(LED_YELLOW_RR_PORT, LED_YELLOW_RR_BIT);
delayms(500);
}
}

Changing Trigger Mode:

By default, the interrupt triggers when the pin is brought low. If we want to change this behavior, we need to poke at the External Interrupt Control Registers, EICRA (for INT0 - INT3) and EICRB (for INT4 - INT7).

Each interrupt pin has 2 bits in the EICR Registers, ISCxO and ISCx1. This Gives 4 possible options for triggering:

  • 0 0: Default, Trigger when INTx is held low
  • 0 1: Not Used
  • 1 0: Trigger when INTx changes from 1 to 0
  • 1 1: Trigger when INTx changes from 0 to 1

So, to turn on INT1, and set it to trigger on a rising edge, we,d use the following code:

// enable external interrupt
EIMSK = BIT(INT0);
// set the interrupt to trigger on a rising edge
EICRA |= BIT(ISC00) | BIT(ISC01);

Video:

[youtube=http://www.youtube.com/watch?v=pSuCHiK-Xq4]

 1 2 3 … 5 Next →