Search This Blog

Showing posts with label RS232. Show all posts
Showing posts with label RS232. Show all posts

Sunday, 4 November 2007

Time for some interfacing..

Before I get onto the interfacing adventure, here's an annoying problem I faced yesterday with the CMUcam3..

I picked up a cheap PQi 256MB MMC card for the CMUcam. Got back home and took the turret assembly apart to fit the MMC card. Reassembled the turret and flashed the CMUcam3 with the 'hello-world' example project. No joy trying the initial file write test in that example. Added some printfs into the HAL driver and hello-world example, and reached a 'DOH!' moment. I hadn't formatted the MMC card for FAT :(
Took turret assembly apart, formatted the MMC card for FAT, reassembled the turret, and tried again.. Still no joy :( I had a dig around further in the mmc_driver and mmc_hardware functions. Referencing datasheets on the SPI programming of an SD/MMC card, it looks like the HAL driver has very limited implementation for MMC cards. The CMUCam WIKI and forum also mention that only certain cards work and some others that CMU guys have tried don't work. So something else to add to the todo list..

Onto interfacing fun..


With the double decker chassis built earlier in the week, it was time to have a closer look at the interfacing of the three systems; VC21 stack, CMUCam3, and uDSMC. Interfacing the VC21 and CMUCam3 should be easy. The VC breakout board has UART4 to connect to the UART0 on the CMUCam3. The issue then was how to get serial data to the Pololu uDSMC board, plus the issue of how/where to get a GPIO line to the reset pin of the uDSMC.

Re-reading the CMUCam3 datasheet lead me to a mini-Eureka moment. The LPC2106 has dual UART built in and CMU have sent UART1 through to a second IDC connector on the module (the Expansion port GPIO). It also looked like the CAM RESET (P0.15) GPIO could be used for the uDSMC reset line. The UART1 sent to the expansion port is already at TTL levels, so no need for the MAX232 line driver, freeing up valuable space for the DE-ACCM2G accelerometer board :)

I made a cable to connect the expansion port IDC socket to the breadboard (only need three lines from it, GND, CAM RESET, and TX2). Then onto changing the 'CMUCam2 emulator' example project to handle GPIO changes and UART1.


It took a little bit of work to get the CAM RESET GPIO setup. The below code is now used to initially select P0.15 as a GPIO output, pull it low for 100ms, before turning it high and keeping it high.
// CAM RESET(P0.15) bit selector
#define CAM_RESET 0x00008000
// Make P0.15 a GPIO
REG(PCB_PINSEL0) = REG(PCB_PINSEL0)&0xCFFFFFFF;
// Set P0.15 as output
REG(GPIO_IODIR) = REG(GPIO_IODIR) | CAM_RESET;
// P0.15 low, to reset motor controller
REG(GPIO_IOCLR) = CAM_RESET;
cc3_timer_wait_ms (100);
// Raise P0.15 high
REG(GPIO_IOSET) = CAM_RESET;

The UART1 setup was a lot easier. The cc3 HAL library is already setup to handle the second UART. It was then just a simple case of adding another input command to the example code. The following shows a simple way to send serial commands to the Pololu uDSMC.

cc3_uart_init (1, CC3_UART_RATE_9600, CC3_UART_MODE_8N1, CC3_UART_BINMODE_BINARY);
FILE * fp = cc3_uart_fopen(1,"r+");
if (fp == NULL)
{
printf("UART1 is dead\n");
while(1);
}
unsigned char buf[8];
// Both motors forward at half speed
buf[0] = 0x80; // Start byte
buf[1] = 0x00; // Device type
buf[2] = (0x00<<1) | 0x1; //M1 forward
buf[3] = 0x40;
buf[4] = 0x80; // Start byte
buf[5] = 0x00; // Device type
buf[6] = (0x01<<1) | 0x1; //M2 forward
buf[7] = 0x40;
for(int i = 0; i < 8; i++)
{
while((REG(UART1_LSR) & LSR_THR_EMPTY) == 0);
REG(UART1_THR) = buf[i];
}
fflush(fp);
I don't think the fflush is needed (and might not even be setup properly) because the cc3_uart_init already setups UART1 to flush it's FIFO after 8 bytes have been written to it. I need to have a further look to see if this is the write way to write out serial data via the UART registers, and whether the HAL code is behaving and thourough.

So two extra commands have been added to that CMUCam2 example firmware image. I've hooked up the 'FW' command to send the motor on commands to the uDSMC, and added the 'MR' command to CLR and SET the P0.15 GPIO line to reset the motor controller. These commands can be sent via the CMUCam3 Frame Grabber program.


Issues..
So far this 'almost' works. The uDSMC picks up the serial commands and starts turning the motors/wheels. BUT, and a big one, is that after X milliseconds (over 400ish) the P0.15 GPIO line drops half it's voltage and I guess resets/disables the uDSMC stopping the motors. Hmmmm...

Something to look at in the week.

That's all for now folks..

Sunday, 14 October 2007

Pololu chassis up and running...


Yesterday I had great fun setting up the Pololu chassis and controlling it via serial communication from the laptop :) After trying out my soldering on a test kit from Maplin (two LED flashing unit), I started work on the chassis and breadboard work for this ickle robot.

As recommended I soldered a 0.1uF Cermamic capacitors across the two motors and feed each pair of wires from the motors through the chassis to the breadboard. The USB-RS232 connector fed the four serial lines required through to the breadboard, with a simple transistor (2N2222A, high frequency, low power) and resistor arrangement to bring the RS232 levels down to the levels required by the Pololu micro dual serial motor controller. This could then be sent a serial bit stream that the controller would interpret and drive the internal H-Bridge to control the two chassis motors.

I had some teething trouble at first by making the mistake of driving the motor controller logic levels at too high a voltage. Ending up with a smoking motor controller :S Thankfully I had bought two of them just in case this happened.

To send the control data to the motor controller ended up being very simple. A Win32 console app, built through the free Visual Studio 2005 Express Edition IDE, opened up and setup the appropriate COM port that the USB-RS232 converter had mapped itself too (under WinXP). Configured to 9600bps, no parity, 1 stop bit, DTR/RTS turned off, and FILE_FLAG_WRITE_THROUGH|FILE_FLAG_NO_BUFFERING used in the CreateFile call to make sure device writes were not cached (although I also used FlushFileBuffers after each WriteFile just in case). It was then a simple matter of using WriteFile to send the 4 bytes worth of data to the motor controller to control the motor states. Some additional GetAsyncKeyState monkeyness allowed for forward/back/left/right movement control.

Apart from frying the original controller, and making sure that stalls didn't kick in the motor controller thermal cutoff protection, everything went very smoothly. Although this is just novice entry level experiments to get a chassis built and moving, it's a nice starting point. I can now do some stress testing of the chassis and controller, see how they fair with carrying heavier loads, and work out what improvements/replacements need to be made for the final chassis and motor control. But before that, I'm going to switch back to the JTAG debugging investigation/learning with the COGs, and setting up a decent makefile workspace (either in Eclipse or VS EE, not sure yet).