MIDI Harp: ADC Settings

One challenging aspect of our project was configuration of the analog-to-digital converter (ADC) for maximum stability and playability. Taking inspiration from Atmel Software Framework example projects, various Atmel publications, and a vast chorus of AVR-forum participants, we included the following ADC initialization function in our final project:

//initialize free running ADC sweep
void adc_init(void)
	// Initialize configuration structures.
	struct adc_config         adc_conf;
	struct adc_channel_config adcch_conf;
	adc_read_configuration(&ADCB, &adc_conf);
	adcch_read_configuration(&ADCB, ADC_CH0, &adcch_conf);

	adc_set_conversion_parameters(&adc_conf, ADC_SIGN_ON, ADC_RES_12, ADC_REF_AREFB) ;
	adc_set_clock_rate(&adc_conf, 5000UL);
	adc_set_conversion_trigger(&adc_conf, ADC_TRIG_FREERUN_SWEEP, 3, 0);
	adc_set_callback(&ADCB, &adc_handler);
	adc_write_configuration(&ADCB, &adc_conf);


	adcch_set_input(&adcch_conf, ADCCH_POS_PIN1, ADCCH_NEG_NONE, 1);
	adcch_write_configuration(&ADCB, ADC_CH0, &adcch_conf);
	adcch_set_input(&adcch_conf, ADCCH_POS_PIN2, ADCCH_NEG_NONE, 1);
	adcch_write_configuration(&ADCB, ADC_CH1, &adcch_conf);

	adcch_set_input(&adcch_conf, ADCCH_POS_PIN3, ADCCH_NEG_NONE, 1);
	adcch_write_configuration(&ADCB, ADC_CH2, &adcch_conf);

This code utilizes ASF to allow for human readable (and Intellisense-aided!) modification, without requiring the bit by bit setting of appropriate AVR registers. Our project was configured for a free-running, single-ended, 12-bit, interrupt-triggering sweep of 3 ADC channels, referenced against an external 2.5V source, at the modest frequency of 5 kHz. Once the ADC is enabled, each finished conversion calls a function that averages the most recent 15 values, and translates this result into a “state” (from which is derived a tone) and volume (from height within the trigger range).