Saturday, April 18, 2009
Sensors module
Hardwork on springbreak
Our team seized the awaited spring "break" to work day and night on the project.
Some of the things achieved during this week were the development of the sensors and obstacle detection system.
We decided to get a new infrarred sensor, to make our system more complete.
The system to program the movement and trajectory was finished, as well as a wireless module, so now it is not even necessary to make the connection to a PC to program the path to follow.
Talking about the transmission design, considerable achievements were made, this will be shown in the following entries of our blog.
The structure suffered several modifications for our team's convenience. We will follow a similar structure to the one of the EOS robot. This structure is still on process.
Tuesday, April 7, 2009
Control System.
The wheels direction is also controlled by the microcontroller using a DC motors driver (L293) which has the capability of controlling the direction of two motors. Then, a power stage is placed to avoid that the driver burns and feed the current necessary to move the engines.
Structure, Traction System and Trajectory Control
There are going to be two levels inside the structure. On those levels the battery and the robot control circuitry will be stored.
The traction system will be conformed by two DC motors of 12V. They will give traction to the robot with a crazy wheel to give stability and facility of movement to it.
The aproximated weight of the robot is 5.5 Kg and for this reason a reductive transmission will be located to reduce the motors revolutions and increase the torque that will be transmitted to the traction wheels of the robot.
At the beginning we propose to use a transmission made from polyethylene and composed by bands and pulleys to make the revolutions reduction, but we found that in some cases at the moment of taking the transmission to forced jobs and find break points or skid of the material, the robot stoped moving or the plastic bands blow out. This is why we decided to implement a transmission composed by gears to avoid shuffles between components inside it.
The first transmission tests were done with transmissions that contained three gears with the purpose of having one gear that was the product of the movement, which goes directly to the rotor´s DC motor. The second gear is conected to the rotation axis of the wheels. The third gear is located between the other two and it has the function of transmitting energy and it´s also a fuse gear which aviods that the motor overheating burns the motor or the circuitry.
Due to the complexity of this system we decided to make a simple two-gear transmission with a ratio of 3 to 1. The final system will be a gear on the rotation axis of the wheel and another on the DC motor´s rotor. This means that the gear that goes into the axle of the wheels is approximately 3 times bigger than the one that goes on the motor´s rotor.
The transmissions´ gears were molded with resistant plastic to prevent fractures caused by friction when the robot is moving. Since the gears will be interacting directly with each other, the rotor´s gear of the DC motor is made of heat resistant plastic, with a total of 19 teeth on its circumference, the gear that is placed on the axis of the rim is made of lightweight plastic to make it easier to spin the wheels with a total of 60 teeth on its circumference. The robot´s wheels diameter is 2.5 inches and they are made of hard plastic and coated with soft plastic to cushion the bounce that is caused by the irregularities of the terrain.
Monday, April 6, 2009
Interface for the Record of the Trajectory
User Interface
This second code is the interface code. On it, the user can predefined the trajectory and send the signal to the microcontroller so it can play it. This program is made in LabWindows CVI.
Code
#include "Trayectoria.h"static int panelHandle;
int SendAsciiString (int comport, char *send_ASCII);
int GetSerialMessage (int comport, char *readdata);
char readBuffer[256];
int main (int argc, char *argv[])
{
if (InitCVIRTE (0, argv, 0) == 0)
return -1; /* out of memory */
if ((panelHandle = LoadPanel (0, "Trayectoria.uir", PANEL)) <
loopexit =" 0;" x="0;" error =" -1;" x="0;" begin =" Timer();"
seconds =" 0.003;" inbuffer =" GetInQLen"> 2) {
ComRd (comport, readdata, InBuffer);
LoopExit = 1;
error = 0;
break;
}
SyncWait (Begin, Seconds);
}
if (x == 500)
break;
} while (LoopExit == 0);
return error;
}
First Phase of the Trajectory Planning Program
/*********************************************************************/
/* Project Name: Treyectory */
/* Source fle name: RTC.c */
/*********************************************************************/
/* Robotecnicos */
/*********************************************************************/
/*********************************************************************/
/* Code for QE128 MCU's */
/* Module: Trayectory */
/* The code was developed and tested on CodeWarrior 6.0 version */
/* */
/* Description: To learn the trayecory to be followed */
/* */
/*********************************************************************/
/* */
/* Date: 07/03/2009 */
/* Robotecnicos */
/* ITESM */
/*********************************************************************/
#include /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
/*********************************************************************/
/* Globals */
/*********************************************************************/
#define RECORDING 1
#define LOOP 2
#define RESET 3
#define UP 1
#define DOWN 2
#define RIGHT 4
#define LEFT 8
#define PHOTO 16
typedef unsigned char UINT8;
unsigned char edo_past = 0;
unsigned char begin= 0;
unsigned char finish = 0;
unsigned char in = 0;
unsigned int count = 0;
unsigned int direction = 0;
unsigned int elements = 0;
unsigned int i = 0;
unsigned char state = RECORDING;
unsigned int trayectory[5][2];
/*********************************************************************/
/* Function declarations */
/*********************************************************************/
void MCU_Init(void) {
SOPT1 = 0x23; /* Watchdog disable. Stop Mode Enable. Background Pin enable. RESET pin enable */
SCGC1 = 0x01; /* Bus Clock to the SCI1 module is enable */
SCGC2 = 0x04; /* Bus Clock to the RTC module is enable */
}
void GPIO(void) {
PTAPE = 0x0C;
PTADD = 0x00; // Configure Port A as inputs
PTDPE = 0x0C;
PTDDD = 0x00; // Configure Port D as inputs
PTCDD = (PTCD 0x3F); /* Configure PTC0-PTC5 as outputs */
PTEDD = (PTED 0xC0); /* Configure PTE6 and PTE7 pins as outputs */
PTCD = 0x3F; /* Put 1's in port C in order to turn off the LEDs */
PTED = 0xC0; /* Put 1's in port E port in order to turn off the LEDs */
}
// To print data in the LEDs of DEMOQE
void display(byte x){ /* LEDS low power active */
x = ~x;
PTED = (x & 0xC0); /* Move the adquired ADC value to port E */
PTCD = (x & 0x3F); /* Move the adquired ADC value to port C */
}
void RTC_configuration (void) {
RTCSC = 0x08; /* RTCPS configure prescaler period every 1s */
RTCMOD = 0x00; /* RTCMOD configure to interrupt every 1s */
}
void SCI_configuration (void) {
SCI1C1 = 0x00; /* 8-bit mode. Normal operation */
SCI1C2 = 0x2C; /* Receiver interrupt enable. Transmitter and receiver enable */
SCI1C3 = 0x00; /* Disable all errors interrupts */
SCI1BDL = 0x1A; /* This register and the SCI1BDH are used to configure the SCI baud rate */
SCI1BDH = 0x00; /* BUSCLK 4MHz */
/* Baud rate = -------------------- = ------------ = 9600bps */
} /* [SBR12:SBR0] x 16 26 x 16 */
/*********************************************************************
* Main Function *
*********************************************************************/
void main(void) {
MCU_Init(); /* Function that initializes the MCU */
GPIO(); /* Function that initializes the Ports of the MCU */
RTC_configuration(); /* Function that initializes the RTC module */
SCI_configuration();
EnableInterrupts; /* enable interrupts */
/* Enable RTC interrupt */
for(;;) {
// in = ((~PTAD) & 0x0C);
// in = in >> 2;
// in = in ((~PTDD) & 0x0C);
switch (state){
case RECORDING:
if (finish == 0x01){
finish = 0x00;
begin = 0x00;
trayectory[elements][0] = direction;
trayectory[elements][1] = count;
count = 0;
elements ++;
//if (elements == 5) state = LOOP;
}
if(begin == 0x00) {
edo_past = in;
switch(in){
case 1 : PTCD_PTCD0 =0; RTCSC_RTIE = 1; begin = 0x01; direction = UP; break;
case 2 : PTCD_PTCD1 =0; RTCSC_RTIE = 1; begin = 0x01; direction = DOWN; break;
case 4 : PTCD_PTCD2 =0; RTCSC_RTIE = 1; begin = 0x01; direction = RIGHT; break;
case 8 : PTCD_PTCD3 =0; RTCSC_RTIE = 1; begin = 0x01; direction = LEFT; break;
case 16: PTCD_PTCD4 =1; RTCSC_RTIE = 1; begin = 0x01; direction = PHOTO; break;
default: PTCD = 0xEF; RTCSC_RTIE = 0;
}
}
break;
case LOOP:
PTED_PTED6 = 0;
RTCSC_RTIE = 1;
break;
case RESET:
elements = 0;
PTCD_PTCD0 =1;
PTCD_PTCD1 =1;
PTCD_PTCD2 =1;
PTCD_PTCD3 =1;
PTCD_PTCD4 = 0;
break;
}
} /* loop forever */
/* please make sure that you never leave this function */
}
/*********************************************************************
* Interrupt Service Routines *
*********************************************************************/
void interrupt VectorNumber_Vsci1rx SCI_RX_ISR(void) {
SCI1S1_RDRF = 0; /* Receive interrupt disable */
// display (SCI1D); /* Display on PTE the received data from SCI */
switch (SCI1D){
case '0': in = 0; break;
case '1': state = RECORDING; break;
case '2': state = LOOP; break;
case '3': in = 1; break;
case '4': in = 2; break;
case '5': in = 4; break;
case '6': in = 8; break;
case '7': in = 16; break;
case '8': state = RESET; break;
}
while (SCI1S1_TDRE == 0); /* Wait for the transmitter to be empty */
//SCI1D = '1'; /* Send a character by SCI */
}
void interrupt VectorNumber_Vrtc RTC_ISR(void) {
RTCSC = RTCSC 0x80; /* Clear the RTC flag */
PTED_PTED7 ^= 1; /* Toggles PTE7 pin */
// in = ((~PTAD) & 0x0C);
// in = in >> 2;
// in = in ((~PTDD) & 0x0C);
switch(state){
case RECORDING:
count++;
if(edo_past != in){
finish = 0x01;
RTCSC_RTIE = 0;
}
break;
case LOOP:
if (count == trayectory[i][1]){ PTCD_PTCD0 =1; PTCD_PTCD1 =1; PTCD_PTCD2 =1; PTCD_PTCD3 =1; PTCD_PTCD4 = 0; i++; count = 0;}
count ++;
if(i == elements) i = 0;
direction = trayectory[i][0];
switch(direction) {
case UP : PTCD_PTCD0 =0; break;
case DOWN : PTCD_PTCD1 =0; break;
case RIGHT : PTCD_PTCD2 =0; break;
case LEFT : PTCD_PTCD3 =0; break;
case PHOTO : PTCD_PTCD4 =1; break;
default: PTCD = 0xFF;
}
break;
}
}
Tuesday, March 10, 2009
External trigger CHDK
The diagram to use is really simple.

A USB mini B port is needed to connect it to the camera, while the other side can be connected to a female port connected to the microcontroller or we can cut directly the cable and apply the voltage difference right there.
The program we used to detect the usb port is really simple
@title Remote button
while 1
wait_click 1
if is_key "remote" then shoot
wend
end
It is an infinite cycle (while 1) that waits for some button to be pushed (wait_click 1). If the "button" is in reality the voltage difference in the usb (remote) then it triggers itself and repeats the cycle, if it is any other button then it repeats the cycle without triggering.
The voltage applied to the camera depends on the model. In our case it is enough with 3.75V, however other models require more voltage while others require less.
The CHDK notices the USB port as another button, which means that you can use it to modify the behavior of the program and not just to trigger the camera., today in class we will try to make the camera take pictures in certain time intervals, and when it gets a signal from the microcontroller it will take pictures when it senses movement.
