Archive for March, 2010

TestBox

Sunday, March 14th, 2010

The testbox is an LCD/Dorkboard based arduino clone with two buttons and a pair of potentiometers. The switches, power and 4 io pins are made avaliable via screw terminals on the ouside of the testbox.


#include
/*--------------------------------------------------------------
pulse generator for test box

Depending on the setting of left dial send send pulses out on digital ouput pin 2
at between 1 and 122 hz when left button is pressed.
the lcd should show the hz and the number of pulses sent.

*/

//defines for analog "dial" pins.
#define D1PIN 0
#define D2PIN 1
//defines for switches
#define S1PIN 17
#define S2PIN 16
// other pins avaliable for testbox 2, 3, 4, 13
#define PULSEPIN 2

// defines for smooting (nsamples) and debounce (milliseconds)
#define SMOOTHING 16
#define DEBOUNCE 50

//defines to map pins to lcd
#define D4 7
#define D5 8
#define D6 9
#define D7 10
#define RW 11
#define E 6
#define RS 12
#define BL 5

LiquidCrystal lcd(RS, RW, E, D4, D5, D6, D7);

int d1 = 0, d2 = 0, s1=0, s2=0;

/* variables for debouncing switches and knobs */
int s1reading = 0 , s1previous = 0;
long int d1sum = 0, d2sum = 0, s1time=0;
int samples = 0;

volatile int overflowcount;
volatile int pulsecount;
volatile int pinstate=HIGH;

ISR(TIMER2_OVF_vect) {
if (s1) {
if (++overflowcount > d1) {
overflowcount=0;
pinstate=!pinstate;
digitalWrite(PULSEPIN,pinstate);
if ( pinstate ) {
pulsecount++;
}
}
}
}

void setup()
{ overflowcount = 0;
pulsecount = 0;

delay(1000);

lcd.begin(2,16); // Print a message to the LCD.
pinMode(S1PIN, INPUT);
digitalWrite(S1PIN, HIGH);
pinMode(S2PIN, INPUT);
digitalWrite(S2PIN, HIGH);
lcd.setCursor(0,0);
lcd.print(" ");

TCCR2A = 0; //freerunning timer 2
TCCR2B = (CS21|CS22); //divide clock by 256
TIMSK2 = TOIE1; //enable timer2 terrupt

}

void loop()
{

s2 = !digitalRead(S2PIN); //read s2 for grins or DEBOUNCE as below.

//DEBOUNCE s1
s1reading = digitalRead(S1PIN);

// If the switch changed, due to bounce or pressing...
if (s1reading != s1previous) {
// reset the debouncing timer
s1time = millis();
}

if ((millis() - s1time) > DEBOUNCE) {
if (s1 == s1reading) { // if DEBOUNCEd reading is a change
s1=!s1reading;
if (s1) {
pulsecount=0;
}
}
}
s1previous = s1reading;

d1sum += analogRead(D1PIN);
d2sum += analogRead(D2PIN);
if (++samples > SMOOTHING) { //when i have SMOOTHING samples then average them.
d1sum /= SMOOTHING;
d2sum /= SMOOTHING;

d1=map(d1sum,0,1023,0,122); //map dial to what you want values to be
d2=map(d2sum,0,1023,0,300);

samples=0;
d1sum = 0;
d2sum = 0;
}

lcd.setCursor(0,0);
lcd.print("Rate: ");
lcd.setCursor(6,0);
lcd.print(122-d1);
lcd.print("Hz ");

lcd.setCursor(0,1);
if (s1) {
lcd.print("ON ");
} else {
lcd.print("OFF");
}
lcd.setCursor(6,1);
lcd.print("# ");
lcd.setCursor(8,1);
lcd.print(pulsecount);
}

Reprogramming your avr-usb device using atmel’s built in bootloader

Friday, March 5th, 2010

Getting code onto the MidiMonster or Benito device.

Midi Monster Button Locations.

Midi Monster Button Locations.

Benito 7g Switch Positions.

Benito 7g Switch Positions.

Benito 2010 Switch Locations

Benito 2010 Switch Locations

Benito Without Buttons.

Benito Without Buttons.

All of the code on the Benito and MidiMonster devices is open source and references an open source library called the Lightweight Usb For Avr (lufa). Getting the code compiled and onto the device requires a few other open source tools.

AVR-GCC

The most current and stable release of the toochain for the AVR has untill recently been maintained by Eric Wedddington and released as WinAvr (http://sourceforge.net/projects/winavr/) Winaver integrates nicely into atmels avr studio http://www.atmel.com/dyn/Products/tools_card.asp?tool_id=2725 and I reccomend that you get both if you are running windows. Each Winavr Release is closely followed by objective developments CrossPack for avr http://www.obdev.at/products/crosspack/index.html and a script for building the current toolchain on linux which is hosted by AvrFreaks at present there is also a debian package that was put out last month http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=90172

HWB? DFU?

Most Atmel “atmega” devices have a pin dedicated to determining weather or not the device goes into the bootloader depending on the devices flag settings. This pin is labled HWB (for hardware boot) on most of  the datasheets. The usb avr family has this mode set up by default. When you hold the hwb pin low and reset the device it goes into the bootloader. On these devices the built in bootloader uses a usb device class called the Device Firmware Uploader (DFU). Atmel provides a tool called flip for programming DFU devices on  windows and linux. There is an open source programmer called dfu-programmer http://dfu-programmer.sourceforge.net/

That other guys stuff.

Those of you who have worked with the teensy boards from paul stoffregon will notice some subtle differences. Paul wrote his own (closed source) bootloader rather than use the bootloader tha comes installed on the chips. Then he uses a hardware trick similar to the auto reset hack to make a single button manipulate both the reset and the hwb pins to put his boards into the bootloader. I didnt feel that either the two button arrangement or the builtin bootloaders were broken so I like most people working with these chips dont fix them.

Using the dfu-programmer

All of the programs in Dean Cameras Lightweight Usb for Avr have a “dfu” target. Once you have the target into the DFU mode you can simply

$make dfu

This will cause the dfu-programmer to erase the flash reprogramm it with a new hex file and restart the chip. You can also do this manually with the following commands

$dfu-programmer atmega32u2 erase
$dfu-programmer atmega32u2 flash mycode.hex
$dfu-programmer atmega32u2 start

This will cause the dfu-programmer to erase the flash reprogramm it with a new hex file and restart the chip.