Posts tagged ‘PIC’

Putting Bluetooth into a flea market toy car

On the flea market here in Ghent a few weeks ago, I bought myself a toy car with a wired remote control. Feeling destructive, I immediately removed the hood of the car, opened up the remote control and measured how the car could be controlled. It turns out there are four wires from the remote to the car. Two of them control the forward / backward motion by setting 5V or -5V across them. The two other wires control the left / right motion of the front wheels, again by setting 5V across them.

Next I soldered header pins to the wires of the car so I can control them through the L293D driver chip of my Dwengo board. Next I added the Bluesmirf module (as explained in a previous post) and taped everything together using Duct tape.

After some programming and some tweaking (putting the battery pack above the steering wheels so they have more grip) I got my car driving across the appartment 🙂

edit: latest version of code is now available via https://github.com/kr3l/rommelrubot

Advertisements

May 29, 2010 at 8:39 pm Leave a comment

Distance scanner using servomotor and distance sensor

In my previous post we got a servomotor doing what we want, so now it is time to put it to use! We will mount a Sharp GP2YOA distance sensor on top of the servo, so we can measure the distance to obstacles at different angles. We can then mount this sensor-servo combination on a robot to give it a good overview of the environment!

cimg5413

The hot glue gun!

I read a lot about robotic projects online, and I have several books about the topic. The coolest tool present in all of those is without competition the hot glue gun :-).. A few months ago I was in a hobby store and came across one by accident so I bought one. Though it is not as spectacular as I had hoped for, it certainly is really handy to glue things together like lego and sensors. 

First I glued a Lego piece on the sensor:

hot glue gun

The hot glue gun, the servo and the lego

The image below shows how the component is glued to the sensor. Note the piece of cardboard to protect the electronics from the glue (though I don’t think it would hurt the electronics, I didn’t want to take the risk :p)

sensor lego cardboard

We will also glue a piece of Lego to the servo:

lego servo

 

Jop, it's a bit messy :)

Jop, it's a bit messy 🙂

Now we can just plug the sensor Lego piece into the servo Lego piece, et voilà!

 

This already looks a bit like a robot..

This already looks a bit like a robot..

The code

The hard bits are already done in past projects:

So now it is just a matter of putting the two together.. I’ve put the code in a file called scanner.c. The scanStep() function will move the sensor one step (in this example 2°) and measure the distance. It will then send the current angle and distance value on the COM port using the format D,[angle],[distance]. 

#include "scanner.h"
#define SCAN_RESOLUTION 2	//measure distance every 2°
short servoDir		= 0;	//0 = clockwise / 1=ccw
int distances[180/SCAN_RESOLUTION+1];
/**
 * Moves the servo from left to right and back (one step per call)
 **/
void moveServo() {
	static short servoAngle	= 90;
	short oldAngle = servoAngle;
	if (servoDir == 0) {			//clockwise
		servoAngle+=SCAN_RESOLUTION;
		if (servoAngle>=180) {
			servoDir = 1;
			//servoAngle = 0;	
		}
	} else if (servoDir == 1) {		//counterclockwise
		servoAngle-=SCAN_RESOLUTION;
		if (servoAngle<=0) {
			servoDir = 0;
		}
	}
	setServoAngle(servoAngle);
	//give servo some time to reach goal angle
	if (oldAngle>servoAngle) {
		Wait_Ms(20*(oldAngle-servoAngle));
	} else {
		Wait_Ms(20*(servoAngle-oldAngle));
	}
}
void scanStep() {
	int distance = 0;
	int angle = 0;
	moveServo();						//move servo 5° further
	angle = getServoAngle();
	distance = readLightSensor(0);		//read distance at this angle
	distances[angle/SCAN_RESOLUTION+1] = distance;
	fprintf (_H_USART, "D,%i,%i\n",angle,distances[angle/SCAN_RESOLUTION+1]);
}

Now we want to plot these values in Matlab. This is done using the following code. First we open the COM port and wait for data to arrive. We then put the data in an array B, where the position in B determines the angle the measurement was made at. We then plot these values so our plot resembles the directions the measurements where made at.

function [B] = sensorPlot2()
COMPORT             = 4;
SCAN_RESOLUTION     = 2;    %make sure this matches SCAN_RESOLUTION in embedded code!

%open com port
s2 = serial(['COM' num2str(COMPORT)],'BaudRate',19200);
fopen(s2);
s2.ReadAsyncMode = 'continuous';

%open plot window
colordef none
h=figure('Color',[0.3 0.3 0.3]);

%init values
quit=0;
paused=0;
B = zeros(180/SCAN_RESOLUTION+1,1);
theAngles = (1:length(B))*SCAN_RESOLUTION*pi/180; %we will plot values on these angles

try
    while 1
        while ~s2.BytesAvailable    %wait for samples to become available
            pause(0.02);
        end
        if s2.BytesAvailable
            try
                res1 = dataFromResult(fscanf(s2)); %read the angle and distance value into res1 = [angle, distanceValue]
                res = res1(2);    resAngle = res1(1);
            catch
                res=[];
                display('something went wrong!');
            end
            samplesRead = size(res,1);
            if samplesRead>0
                indexB = resAngle/SCAN_RESOLUTION+1;
                if indexB>0 && indexB<=180/SCAN_RESOLUTION+1
                    B(round(indexB)) = res;
                    plotVals = [(1000-B).*cos(theAngles') (1000-B).*sin(theAngles')];
                    plot(plotVals(:,1),plotVals(:,2),'-.');
                    hold on;
                    plot(plotVals(round(indexB),1),plotVals(round(indexB),2),'-gO');
                    hold off;
                    xlim([-1000 1000]); ylim([-100 1000]);
                    pause(0.000002);    %so the plot is updated
                end
            end
        end
    end
catch ME1
    ME1.message,ME1.stack,ME1.cause,fclose(s2);delete(s2);
end
try
    fclose(s2);delete(s2);clear s2
end
colordef white;
%% converts the result to a numeric row(kabraeck)
    function [ data ] = dataFromResult( result )
        remain = result;
        index=1;
        tokens=[];
        while (~isempty(remain))
            [token,remain] = strtok(remain, ',');
            if (index>1)
                tokens(index-1)=strread(token);
            end
            index=index+1;
        end
        data = tokens;
    end
end

The image below shows an example plot Matlab generates:

The green dot indicates the current measurement

The green dot indicates the current measurement

 You can see that there is an obstacle on the left of the robot. 

Below are two videos that are perhaps more illustrative:

Code download

You can download the complete code here. This is an Eclipse project (see my other article on how to use Eclipse for PIC development), but you can import the .c and .h files into MPlab if you like. Note that this project assumes to be loaded onto the PIC with an USB bootloader (see this article for details)!

May 9, 2009 at 5:49 pm Leave a comment

PIC servocontroller (in C)

In this article I’ll explain how to control a simple servo motor from a PIC18F4455 microcontroller. I am using a real cheap servo (an ES-30, see Conrad site), but it should be enough for hobby (read: robot) purposes.

Servo Controller

A DC motor is controlled using a DC voltage, but a servo motor requires some more work as it is controlled using pulses. By varying the width of a pulse you can set the angle the servo motor has to turn to. A servo motor can usually turn from -90 degrees to +90 degrees, but my ES-30 seems to be limited to -70 to +70 degrees or so.. 

Connections

The servo motor has three connections: ground (black), supply voltage (red) and the connection for the input pulses (usually yellow). We will connect the black wire to ground, the red one to our PIC supply voltage (5V) and the yellow wire to the D3 output (PORTDbits.RD3). So D3 will be the PIC output pin that controls the servo.

servo

Pulses

The servo expects a pulse every 20ms. The width of this pulse varies in the range 1.0 – 2.2ms, this range could be different with your specific servo so consult the datasheet (or just try some values)! A pulse width of 1.0ms sets the servo to the far left, a pulse of 2.2ms to the far right, and everything in between should map on an angle somewhere in between. 

Timing with the PIC uC

We are going to use interrupts to ensure our pulses appear every 20ms. A timer interrupt happens when the timer register overflows. The timer register (can be configured as 8bit or 16bit) is increased on every clock tick. If the prescaler is set it happens less than every clock tick. A spreadsheet with my calculations is available at http://spreadsheets.google.com/pub?key=p9YPS93eEHH3W7dx5fxQEMQ&output=xls, you can see the interrupt rate for various settings of the prescaler value. 

You can enable the interrupts like this:

OpenTimer0(TIMER_INT_ON & T0_SOURCE_INT & T0_16BIT & T0_PS_1_4);	//enable TMR0, 16bit, CLK0 src, low-to-high trans, prescale on, prescale 1:4 

So your servo initialization will look like this:

void startServo(void) {		//initialize TIMER0 + enable interrupts
	TRISD				=	0;	//D is output
	PORTD				=	0;
	INTCONbits.RBIF		=	0;
	INTCONbits.TMR0IE	=	0;
	RCONbits.IPEN		=	0;
	OpenTimer0(TIMER_INT_ON & T0_SOURCE_INT & T0_16BIT & T0_PS_1_4);	//enable TMR0, 16bit, CLK0 src, low-to-high trans, prescale on, prescale 1:4 
	INTCONbits.GIE 		= 	1;	//enable global interrupts
	INTCONbits.PEIE 	= 	1;	// enable peripheral interrupts
}

Define the interrupt function like this:

 

 

#pragma interruptlow timerFtie
void 
timerFtie(void)  {
	if (INTCONbits.TMR0IF) {	//interrupt timer 0
		INTCONbits.TMR0IF = 0;	//interrupt flag off
		servoInterrupt();
	}
}

 

Now we only need to define what will happen inside the servoInterrup() function, i.e. the function that is called every time TIMER0 overflows. We will set D3 to the correct value (1 or 0) depending on whether the pulse is starting or ending. We will also initialize TMR0H and TMR0L to values so that the next overflow appears when a pulse needs to start/stop. This is explained in the following note:

servo1

This results in the following code:

void servoInterrupt(void) {	//called on overflow of TIMER0
	//create pulse (begin or end of pulse)
	PORTDbits.RD3 = (pulseOn == 1);
	//set new TIMER0 value
	if (pulseOn == 1) {
		pulseOn = 0;
		TMR0H = 0xFF & (pulseOnLoad >> 8);
		TMR0L = 0xFF & pulseOnLoad ;
	} else {
		pulseOn = 1;
		TMR0H = 0xFF & (pulseOffLoad >> 8);
		TMR0L = 0xFF & pulseOffLoad;
	}
}

PulseOnLoad and PulseOffLoad are set according to the servo angle:

void setServoAngle(short angle) {	//set new servo value (called from external code)
	short loadTimer0BeginPulse 	= 0;
	short loadTimer0EndPulse 	= 0;
	short usPulse;
	short timerCount;	// [2727,6363] =~ [900,2100]*3
	servoAngle = angle;
	usPulse = MIN_PULSE_DURATION + angle*((MAX_PULSE_DURATION-MIN_PULSE_DURATION)/180);
	timerCount = usPulse * 3;	//0.33us = 1/3 us per tick
	pulseOnLoad = 65534 - timerCount+2;
	pulseOffLoad = 5538 + timerCount +2;
}

Code download

You can download the complete code here. This is an Eclipse project (see my other article on how to use Eclipse for PIC development), but you can import the .c and .h files into MPlab if you like. Note that this project assumes to be loaded onto the PIC with an USB bootloader (see this article for details)!

References

 

  • This site gives a very thorough introduction to using a servo with a PIC12F675, though all code is not freely available. My logic is also a bit different: I don’t wait inside the interrupt routine untill the end of the pulse but I set it low using a second interrupt. 
  • http://www.mcmanis.com/chuck/robotics/projects/servo.html gives another introduction to using the servo with a PIC, the code is in assembler.
  • The PIC datasheet, chapter about TIMER0. 

May 2, 2009 at 4:38 pm 1 comment

Poor man’s virtualization (a rich experience!)

As computers are becoming more and more powerful, a mere laptop is able to virtualize complete computer systems. With technology like VMWare and Sun’s Virtualbox one can create so-called virtual machines that have an entirely different setup (hardware / operating system) than the host system. As I am finding myself using virtualization more and more, I decided to write an article about it. I won’t be giving an in depth overview of all available technologies and setup tricks, but an overview of how I am using it today. Furthermore, this article will only focus on freely available virtualization software.

A microcontroller development station (Virtualbox)

When looking for a free solution, Virtualbox is the obvious choice as it is available as open source software (GNU GPL) . Just download it from their site (it is available for a myriad of host systems: Win/Linux/Mac/Solaris) and install it to your computer.

virtualbox

I have recently formated my laptop and I am intending to keep it clean and uncluttered for a while. That’s why I decided to put all software and tools needed for my microcontroller activities in a dedicated virtual machine.

The setup:

The host system is my personal laptop I bought a year ago (core 2 duo 2GHz, 2GB RAM, Windows Vista). The guest operating system is a Windows XP machine. I chose XP because it runs faster than Vista and I didn’t need any of the Vista features. Make sure you install the Virtualbox guest tools on your guest system for optimal performance.

The bright side:

  • No polluting of my host environment by all the software needed for my PIC (that’s the microcontroller) programming, as it is contained in the virtual machine: compiler, two IDE’s (Eclipse and MPLAB), programming tools, …
  • All my projects and documentation (datasheets, user guides, …) are available in the virtual machine.
  • I can backup the virtual machine so the software setup and my projects are safe.
  • When I have to format my host environment again, I won’t have to reinstall all the microcontroller software and find my projects back. I’ll just have to reinstall Virtualbox and put the virtual machine back.
  • I only have time in my weekends for this microcontroller hobby. At the end of my weekend I just save the state of my virtual machine (I just leave all windows open) and at the beginning of the next weekend I can pick up exactly where I left off!
  • I usually work with a dual monitor setup (laptop screen + external monitor). It is possible to put the Virtual machine on one monitor and on the other monitor just work in the host operating system.
  • A shared folder allows to share files between the host and guest system.
  • My host is a Vista machine, but it could as well have been a Linux OS, thus giving a solution to hardcore Linux users wanting to program PICs (the Microchip compiler is not available on Linux).

The dark side:

  • As everything is virtualized, things tend to run a tad slower. I don’t find this annoying while developing (it doesn’t require a fast PC), but you wouldn’t want to run games in a virtual machine!
  • For the actual programming of a PIC microcontroller, I use a USB device. It is possible to forward the USB device to the virtual machine so it is recognized over there, but I found this to be rather buggy in Virtualbox (it crashed a few times). So for the actual programming I still use the host system.

Conclusion:

Virtualbox is really, really cool software. I almost can’t believe something like this is just available as open source software. It is ideal for quickly testing some new software / platform or for separating a certain environment from the rest of your system (as I did for my microcontroller environment).

A research platform (VMWare server)

At work we are constantly testing new setups and trying out new technologies. We also have some powerfull servers, but we prefer to do our tests in a vacuum environment (not influenced by other installed components we might not have thought about). That’s why we decided to put VMWare on our server and run our little test setups inside Virtual Machines.

vmware-logo

VMWare offers a lot of products, most of which are paying solutions. They do however offer a free player and a free server virtualization product: VMware Server. The player can be used to run an existing virtual machine on your desktop machine. Vmware Server is a very powerfull solution for creating / managing / running virtual machines on the server. Creating virtual machines is done in a browser application which is really handy. By installing the VMware console plugin one can remotely take over the screen of a virtual machine and run it as you would run a local virtual machine.

The setup:

The actual installation is described over here by my colleague. We installed VMware Server on a Linux host system (2 quad cores and 32GB RAM) [sidenote: I think VMWare Server can only be installed on a Linux host]. Once installed you can open up Firefox on your client computer and point it to port 8333 of your host computer. You should see a login screen. I advise you to use Firefox2 Portable because the console plugin doesn’t work too good with Firefox3. Below are some screenshots of the browser application:

Overview of the available virtual machines and used resources

Overview of the available virtual machines and details of one of them

Creating a new virtual machine

Creating a new virtual machine

Remotely taking over a virtual machine

Remotely taking over a virtual machine

More setup goodness:

I’m not going into details about the actual setup but I’ll give some pointers to what is possible:

  • Configure the dhcp to asssign static IP adresses to your virtual machines. Put an apache http server on your host machine and use proxypass / proxypassreverse / virtualhost to forward a browser to a virtual machine. I.e., we can point the client browser to a url like http://hudson.dunamis, our client host file says that hudson.dunamis is found at the IP adress of our host system so our call is forwarded to the host. The apache http server on the host system has a configuration that says that hudson.dunamis  is to be forwarded to the local IP of the virtual machine to a certain port. So the client is immediately forwarded to the virtual machine, as if it is connected to the actual network.
    [sidenote: you could also use the bridged network setup of VMware for this, but this wasn’t possible in our setup]
  • In this way you can also forward your ssh access: checkout jedi.

The bright side:

  • Once set up, it becomes very easy to create new machines. By copying the vmdk (=virtual harddrive) of another machine you can skip the installation of the operating system and focus on what you really want to test.
  • The different machines can access each other via the network so complex setups are possible.
  • It is possible to copy and paste virtual machines. E.g. you can also create virtual machines locally using VMware Desktop (this is a paying solution) and copy them later to the server. You can also grab a machine from the server and play it locally using VMware player.
  • You can make a snapshot (or just copy) virtual machines so you can return to a certain state later.

The dark side:

  • Because we have to work with the NAT networking setup, it is sometimes difficult to get things running that have to communicate with machines outside the virtual domain..

Conclusion:

This is ideal for a research environment where you have to test all sorts of different setups. Creating and deleting virtual machines is really easy and succesful setups can be copied so you can always return to them.

April 24, 2009 at 8:44 am Leave a comment

Serial com-port communication with autoIt

This weekend I found out how to read from / write to a com port with autoIt code. I created a file with some functions that read/write single characters or lines. To communicate with a com port, I use the CreateFile function from Kernel32.dll.

Continue Reading December 7, 2008 at 5:12 pm 13 comments

PIC18F4455 USB Bootloader

This week I’ve put the USB Bootloader on my PIC experimental board. A bootloader allows you to program the PIC uC without a programmer. More info about using the bootloader can be found on this site. This post addresses some problems I had with the bootloader.

Continue Reading November 29, 2008 at 8:57 am 2 comments

Using Eclipse for PIC development

I’m a fan of the Eclipse environment and I try to use it as much as possible for as many programming languages as possible. There’s the default JAVA environment, but you can also download the CDT plug-in to handle your C / C++ needs, PDT for writing PHP, Aptana for Javascript and so on.. But I hadn’t used it before to write code for my PIC microcontroller. I liked the idea though, because the MPLAB environment of Eclipse (in which you normally write the code) is a bit old-fashioned..

Continue Reading November 2, 2008 at 1:23 pm 5 comments

Older Posts


Feeds

Articles to be written…

Twitter – kr3l

my del.icio.us

RSS Google Reader Shared Stuff

  • An error has occurred; the feed is probably down. Try again later.

RSS Listening to..

  • An error has occurred; the feed is probably down. Try again later.