Sunday, March 16, 2008

Simple IO


Simple IO

This code reads digital data from an IR motion sensor, attached to pin A0.  (pin 40).

It keeps count of the number of motions it has detected ("numberOfPeople") and outputs data to different pins accordingly.


okthx.

Robert

Saturday, March 15, 2008



PWM example for you to download!
(This could be useful to ... say... dim a light...)


kthxbai.

Tuesday, March 4, 2008

makefiles and source for irsensor example


Here are the files for the irsensor example:

irsensor.zip

This zip file contains irsensor.c, global.h, and makefile.


If you download the file, unzip it in your sixcode directory, and type "make" in the directory with the new files, it should compile the irsensor example.


The makefile contains comments that should help describe what it is, how it works, but the most important things are:
  • the target line: TRG = irsensor.
    • To compile a program of your own devising, you should change this to the name of your c file.
  • the source line: SRC = $(AVRLIB)/buffer.c $(AVRLIB)/uart.c $(AVRLIB)/rprintf.c $(AVRLIB)/timer.c $(AVRLIB)/a2d.c $(AVRLIB)/vt100.c $(TRG).c
    • you should make sure that this includes all of the modules that you use in your main program. For instance, if you use a2d functions, $(AVRLIB)/a2d.c should be on this source line.  
    • notice the $(TRG).c at the end of the line. This is what includes the main program you have written, defined in TRG above.
  • any source file you include needs to be described at the bottom of the makefile as well, under the rules to compile.  
    • For the a2d functions, you see that "a2d.o" has its own line at the bottom of the makefile: "a2d.o: a2d.c a2d.h".  
    • This specifies dependencies. This line says that a2d.o (the object file) depends on a2d.c (the source code) and a2d.h (the header) in order to compile.

Wednesday, February 20, 2008

Variable Speed Motor Control

Pulse Width Modulation (PWM) is a way to control the speed of a motor.  The following example program, pwm.c, demonstrates PWM with the Atmega32.  A motor is run in the forward direction from slow-->fast-->slow, and then in the reverse direction from slow-->fast-->slow. 

In order for the program to work, the microprocessor needs to be connected to some circuitry to drive the motor, probably an H-Bridge, which allows bi-directional control of a motor (e.g. you can get it to spin in either direction, by way of sending current forward or backwards through the circuit).

Here are some kinds of motor-driving H-Bridges:


general reference on H-Bridges: http://www.discovercircuits.com/H/hbridge.htm

---------------------

//

// pwm.c

//

// a simple program to control the speed of a DC motor in the forward and reverse directions, using Pulse Width Modulation (PWM).

// This program requires an hbridge motor driver (such as L6203 or LMD18200), a 12-24V DC motor, and a sufficient power supply (12-24V).

//

// rtwomey@ucsd.edu

//



// includes

#include <avr/io.h> // include I/O definitions (port names, pin names, etc)

#include <avr/interrupt.h> // include interrupt support


#include "global.h" // include our global settings

#include "uart.h" // include uart function library

#include "rprintf.h" // include printf function library

#include "timer.h" // include timer function library (timing, PWM, etc)


// function prototypes

int pwmDemo(void);


// program

int main(void)

{

// initialize the UART (serial port)

uartInit();

// set the baud rate of the UART for our debug/reporting output

uartSetBaudRate(57600);

// initialize rprintf system

rprintfInit(uartSendByte);

// initialize the timer system

timerInit();

// initialize pins for PWM

// set OC1B (PD4) to output for PWM

// set OC1A (PD5) to output for PWM

// set PD6 to output for DIR

// set PD7 to output for BRAKE

sbi(DDRD, PD4);

sbi(DDRD, PD5);

sbi(DDRD, PD6);

sbi(DDRD, PD7);


// turn off pull-up resistor on those pins

cbi(PORTD, PD4);

cbi(PORTD, PD5);

cbi(PORTD, PD6);

cbi(PORTD, PD7);

// print a welcome message so we know things are working

rprintf("rnnnWelcome to the PWM demonstration!rn");


// run the demo

while(1) {

pwmDemo();

};

return 0;

}


int pwmDemo(void)

{

// PWM demo cycle

int i=0;

// initialize timer1 for PWM output, 8 bit resolution.

rprintf("Initializing timer1 for PWMrn");

timer1PWMInit(8);


// turn on the channel A PWM output of timer1

// - this signal will come out on the OC1A I/O pin (PD5)

rprintf("Turning on timer1 channel A PWM outputrn");

timer1PWMAOn();


// turn on the channel B PWM output of timer1

// - this signal will come out on the OC1B I/O pin (PD4)

rprintf("Turning on timer1 channel B PWM outputrn");

timer1PWMBOn();


// set direction to 1 (forward);

//rprintf("Setting direction pin (PD6) to forward (1)rn");

//sbi(PORTD, PD6);


// set brake to 0 (no braking)

//rprintf("Setting brake pin (PD7) to no braking (0)rn");

//cbi(PORTD, PD7);


// sweep through range of pwm duty cycles in forward direction. 

for(i=0; i<=255; i++)

{

// set duty cycle;

timer1PWMASet(i);

rprintf("Forward = %drn", i);

    timerPause(10);

}


// wait

rprintf("Pause for 0.5 second...rn");

timerPause(500);


for(i=255; i>=0; i--)

{

// set duty cycle;

timer1PWMASet(i);

rprintf("Forward = %drn", i);

    timerPause(10);

}

// wait

rprintf("Pause for 0.5 second...rn");

timerPause(500);


rprintf("Turning off PWM in forward dir (PWMA)rn");

timer1PWMAOff();


// wait

rprintf("Pause for 0.5 second...rn");

timerPause(500);


// set direction to 0 (reverse);

//rprintf("Setting direction pin (PD6) to reverse (0)rn");

//cbi(PORTD, PD6);


// sweep through range of pwm duty cycles in forward direction. 

for(i=0; i<=255; i++)

{

// set duty cycle;

timer1PWMBSet(i);

rprintf("Reverse = %drn", i);

    timerPause(10);

}

// wait

rprintf("Pause for 0.5 second...rn");

timerPause(500);


for(i=255; i>=0; i--)

{

// set duty cycle;

timer1PWMBSet(i);

rprintf("Reverse = %drn", i);

    timerPause(10);

}

rprintf("Turning off PWM in reverse dir (PWMB)rn");

timer1PWMBOff();


// wait

rprintf("Pause for 0.5 second...rn");

timerPause(500);


// now turn off all PWM on timer1

rprintf("Turning of all PWMrn");

timer1PWMOff();


// wait

rprintf("Pause for 0.5 second...rn");

timerPause(500);


return(0);

}


Code for Reading From a Range Sensor


Here is code (a program called irsensor.c) to read data from an IR range sensor. (Sharp GP20YA02
The sensor is hooked up to pin #40 on the microprocessor.
 
-----------------------

//

// irsensor.c

//

// Simple program to read data from a Sharp 2YOA02 IR distance sensor and send it to the computer.

// Adapted from a2dtest.c from Pascal Stang.

//

// rtwomey@ucsd.edu

//

 

// includes

#include <avr/io.h> // include I/O definitions (port names, pin names, etc)

#include <avr/interrupt.h> // include interrupt support


#include "global.h" // include our global settings

#include "uart.h" // include uart function library

#include "rprintf.h" // include printf function library

#include "timer.h" // include timer function library (timing, PWM, etc)

#include "a2d.h" // include A/D converter function library

#include "vt100.h" // include VT100 terminal support


// constants


// function declarations


// program

int main(void)

{

int readVal=0;


// initialize the UART (serial port)

uartInit();

uartSetBaudRate(57600);

// make all rprintf statements use uart for output

rprintfInit(uartSendByte);

// initialize the timer system

timerInit();

// turn on and initialize A/D converter

a2dInit();


// configure a2d port (PORTA) as input

// so we can receive analog signals

DDRA = 0x00;

// make sure pull-up resistors are turned off

PORTA = 0x00;


// set the a2d prescaler (clock division ratio)

// - a lower prescale setting will make the a2d converter go faster

// - a higher setting will make it go slower but the measurements

//   will be more accurate

// - other allowed prescale values can be found in a2d.h

a2dSetPrescaler(ADC_PRESCALE_DIV32);


// set the a2d reference

// - the reference is the voltage against which a2d measurements are made

// - other allowed reference values can be found in a2d.h

a2dSetReference(ADC_REFERENCE_AVCC);


// use a2dConvert8bit(channel#) to get an 8bit a2d reading

// use a2dConvert10bit(channel#) to get a 10bit a2d reading


// loop, and transmit the A/D value every 10 msecs.

while(1)

{

                readVal=a2dConvert8bit(0);

rprintf("%dn", readVal);

//uartSendByte(readVal);

// wait a 0.1s before reading next value

timerPause(100);

}


return 0;

}



-----------------------

Here is a program for taking the readings from the processor, and rendering them as color on the screen. The program is written in processing, which you can download here.

To get this to program to work, you first need to change the irsensor.c program to switch the program from sending data as text to the terminal window, and instead to send it as data to be read by processing.  Change it as follows:

  1. uncomment uartSendByte(readVal) above (remove the "//" at the beginning of that line)
  2. comment out rprintf("%dn", readVal); (add a "//" at the beginning of that line)
  3. recompile the program.  (make, from the terminal, or [AvrLib] Build All in Programmer's Notepad)

And then run this program in processing, AtoD:

/*

Simple program to demonstrate a2d functionality and IR rangefinding.
A Sharp 2YOA02 distance sensor is connected to an ADC pin on the microprocessor,
and distance data is fed through the serial port to this program. 

*/

import processing.serial.*;

Serial port;  // Create object from Serial class
int val;      // Data received from the serial port

float MULTIPLIER = 1.6;  // Scales readings to full color range.

void setup() 
{
  size(600, 600);

  // Open the port that the board is connected to and use the same speed (57600 bps)
  port = new Serial(this, Serial.list()[0],57600);
  
}

void draw()
{

  if (0 < port.available()) {  // If data is available,
    val = port.read();         // read it and store it in val
  }
 
  background(val*MULTIPLIER, 0, 0);  // color the window proportional to distance reading.
  
}

Tuesday, February 19, 2008

Distance Sensor

Good info on IR distance sensors:
http://www.acroname.com/robotics/info/articles/sharp/sharp.html


The one I am going to show in class tomorrow is this:
http://www.acroname.com/robotics/parts/gp2y0a02_e.pdf

Thursday, January 31, 2008

Communicating with your chip

Communicating with your chip

OS X:

1. Install the driver for the usb adapter: http://www.ftdichip.com/Drivers/VCP.htm

2. Connect the USB adapter to your chip and the computer. 

3. Install zterm http://homepage.mac.com/dalverson/zterm/
Simply double-click the install icon and follow the on screen instructions. 

4.  Start up Z-term, and select the serial port that corresponds to the USB adapter you just installed.  Configure the connection with the following parameters.

In connection settings:
Turn off flow control
Set Data Rate to 57600
Parity: None

In Text Pacing:
0 delay between characters
1/60th seconds delay between lines

You will want to save these settings, otherwise it is tedious to enter them every time you launch Z-Term. Upon quitting, it will ask you if you want to save, click yes.

5. Open Zterm, and power on the chip while holding the reset button.  You should see the cockroach logo appear in the terminal screen.

6. To program your chip, select File—>Send Text.  Under enable, select All Documents.  browse for the .hex file of the program you compiled, click OK.  
The transfer should start automatically.  When the transfer has completed successfully, you can restart the chalkroach and test that it works.


Windows:

1. Install the driver for the usb adapter: http://www.ftdichip.com/Drivers/VCP.htm

2. Connect the USB adapter to your chip and the computer. 

2. Open hyperterminal, make a new connection.  Go to File/Properties/Connect Using --> select the COM port chalkroach is connected to.  This is the COM port assigned to your USB device, after installing the usb driver.

3. Configure the connection as follows.  Click Configure and select:

Bits per second --> 57600
Data bits --> 8
Parity --> None
Stop bits --> 1
Flow control --> None
Click OK.

On to the Settings tab, click on ASCII Setup.

Line delay --> 20 ms,
character delay --> 0 ms
Click OK.

4. Power on the chip while holding the reset button.  You should see the cockroach logo appear in the terminal screen.  

5. From the HyperTerminal Transfer menu, click Send Text File. The Send Text File dialog box appears. Change the file type to All Files, browse for the .hex file of the program you compiled, click OK. The transfer should start automatically. When the transfer has completed, it should notify you of its success, and you can restart the chalkroach and see that it works.