r2 - Moving Day!

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!

Chomp!

Ever had an email attachment you want to put on the web, but cant be bothered downloading it to your PC, finding your FTP details, uploading it to a server, fixing the permissions, wondering why it isnt showing up then finding you put it in the wrong folder?

Well, Dan Had the same problem, and decided there must be an easier way, so he created ChompMail!

Just forward your email to hugo the hippo, and he’ll chomp it up, and put it on display for all to see!

Hugo the Hippo

Pandora Partslist

After seeing skeezix’s unboxing of the pandora devkit, i decided to make a parts list of all visible ICs on the board.

U1	8JA98/JWI92	- [Micron RAM Package] atop TI OMAP 3530 SoC
U2	TWL4030CI 	- TI Audio & Power Management Chip
U3
U4
U5
U6
U7
U8
U9
U10
U11
U12	TI 1773		- Low Voltage & Low Power Stereo Audio DAC with Lineout Amplifier - Thanks Moe
U13
U14
U15
U16
U17
U18	ATMega8L	- Atmel ATmega8L Micro Controller
U19	ALVC00		- Low Voltage 2 input NAND Gate
U20	ALVC00		- Low Voltage 2 input NAND Gate
U21	WE245		- TI 8-BIT DUAL-SUPPLY BUS TRANSCEIVER
U22	ATMega8L	- Atmel ATmega8L Micro Controller
U23

Can't see U#
1x WG7210 		- Wireless & BT Module including TI WL1251, WL1251FE and WL1251PM
1x WY245		- TI 32-BIT DUAL-SUPPLY BUS TRANSCEIVE

The ATmega8 sat near the SD cards interests me, it’d be nice to get a code dump of it to see what it’s up to.

If you have any more information, can read any chip markings i can’t, have a pandora devkit and fancy taking some more high res shots for us all, or datasheet links for the above, please leave a comment.

Track bot.

While waiting for the last parts for r2 to arrive, I have been toying with building a bot based on… well… a toy!

I bought this remote control tank off ebay last year, and took off the plastic top.  Today I stripped off the other unnecessary bits of plastic, and mounted a breadboard on top.

Next part of the plan is to either modify the existing drive board to allow direct drive from the microcontroller, or build a replacement based on a single-chip h-bridge device.

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!

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);
	}
}

AVR GCC Bit Manipulation Macros

These are some macros i originally found on avrfreaks for bit manipulation. I have posted them here in case they are useful to anyone.

#define bit_get(p,m) ((p) & (m))
#define bit_set(p,m) ((p) |= (m))
#define bit_clear(p,m) ((p) &= ~(m))
#define bit_flip(p,m) ((p) ^= (m))
#define bit_write(c,p,m) (c ? bit_set(p,m) : bit_clear(p,m))
#define BIT(x) (0x01 < < (x))
#define LONGBIT(x) ((unsigned long)0x00000001 << (x))

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: