Introduction: NeckCrusher ( Guitar Mounted Effect Pedal )
Dale Rosen, Carlos Reyes and Rob Koch
DATT 2000
Step 1: Problem
Guitar pedals restrict the musician to the pedal platform. Solution: Build and embed a guitar pedals functionality into the guitar itself. This allows the musician to freely move across the stage, using the guitar neck as an interface instead of being restricted to the location of the pedalboard. We will be exploring this concept by creating a bitcrusher/sample rate effect device.
Step 2: Project Context
There are many guitar pedals used by musicians to manipulate the sound of their guitars. Most of these are usually in rack-based or stomp box units, therefore restricting the control of the effects to the location of the effects unit. Mounting the device on the guitar enables players to control the parameters of the effect anywhere on the stage. This means they will not be restricted and can have the freedom to move around for their performance.
Since Arduino is only capable of 8 bit audio, it is impossible to do high fidelity signal processing. This is why we chose the effects we did, as they are based on creating a low fidelity, distorted sound. These are the only effects that are reasonably possible with an Arduino.
Step 3: Parts / Tools Required
● Impact Drill
● Wire Cutters
● Wire Strippers
● Soldering Iron
● Hot Glue Gun
● Desoldering Pump
● Guitar
● Enclosure
● Solder
● Hot Glue
● Arduino
● Proto Board
● Coated Wire
● Audio Jacks (x2)
● Potentiometers (x3)
● Capacitors: 2.2 uF (x2)
● Exposed Copper Wire
● Screws (M3.5 *8)
● Resistors: 1 k, 10 k, 1.2 k, 1.5 k, 390 k
● * Op Amp (LM358) / * Transistor ( 2N3442)
Step 4: Technical Strategy
Internal Circuitry
Input/Output
We need to convert the audio signal coming from a guitar to something the arduino can use & modify. We will then need to convert the signal coming from the arduino back into an audio signal. Arduino reads voltages from 0V to 5V, audio signals are from -1V to 1V. These conversions are done using resistors. The signal will be converted in the output circuit as well.
Arduino Library: ArduinoDSP
Project Description (Interface)
Knobs Knob 1 : Sample Rate
Knob 2 : Bit Crusher
Knob 3 : Bit Shifter
Step 5: Code
#include "dsp.h"
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
boolean div32; boolean div16;
volatile boolean f_sample; volatile byte badc0; volatile byte badc1; volatile byte ibb;
int fx1; int fx2; int fx3; int fx4;
int cnta; int icnt; int icnt1; int icnt2; int cnt2; int iw; int iw1; int iw2; byte bb;
byte dd[512]; // Audio Memory Array 8-Bit
void setup() { setupIO();
// reload wave after 1 second fill_sinewave();
// set adc prescaler to 64 for 19kHz sampling frequency cbi(ADCSRA, ADPS2); sbi(ADCSRA, ADPS1); sbi(ADCSRA, ADPS0); // 8-Bit ADC in ADCH Register sbi(ADMUX, ADLAR); sbi(ADMUX, REFS0); cbi(ADMUX, REFS1); cbi(ADMUX, MUX0); cbi(ADMUX, MUX1); cbi(ADMUX, MUX2); cbi(ADMUX, MUX3); // Timer2 PWM Mode set to fast PWM cbi (TCCR2A, COM2A0); sbi (TCCR2A, COM2A1); sbi (TCCR2A, WGM20); sbi (TCCR2A, WGM21); //Setup for Timer2 cbi (TCCR2B, WGM22); // Timer2 Clock Prescaler to : 1 sbi (TCCR2B, CS20); cbi (TCCR2B, CS21); cbi (TCCR2B, CS22); // Timer2 PWM Port Enable sbi(DDRB, 3); //cli(); cbi (TIMSK0, TOIE0); sbi (TIMSK2, TOIE2); iw1 = badc1;
}
void loop() {
//check status of the effect potentiometer and rotary switch readKnobs();
// ************* // ***Normal*** // *************
if (fx1 == 0 && fx2 == 0 && fx3 == 0 && fx4 == 0 ) { byte input = analogRead(left); output(left, input); }
// ************* // ***Phasor*** // *************
if (fx4 > 100) {
fx1 = 0; fx2 = 0; fx3 = 0;
while (!f_sample) { // wait for Sample Value from ADC } // Cycle 15625 KHz = 64uSec PORTD = PORTD | 128; f_sample = false; bb = badc1; dd[icnt1] = bb; // write to buffer fx4 = iw * badc0 / 255; // scale delayed sample with potentiometer iw1 = dd[icnt2] ; // read the delay buffer badc0 = badc0 / 20; // limit value to 512 icnt1++; icnt2 = icnt1 - badc0; icnt2 = icnt2 & 511; // limit index 0.. icnt1 = icnt1 & 511; // limit index 0..511 iw2 = iw1 + bb; iw2 = iw2 / 2; bb = iw2; OCR2A = bb; // Sample Value to PWM Output
PORTD = PORTD ^ 128; output(left, PORTD); // Output }
// ************* // ***Flanger*** // ************* if (fx3 > 100) {
fx1 = 0; fx2 = 0; fx4 = 0;
while (!f_sample) { // wait for Sample Value from ADC } // Cycle 15625 KHz = 64uSec
PORTD = PORTD | 128; f_sample = false; bb = dd[icnt] ; // read the delay buffer iw = 127 - bb ; // substract offset fx3 = iw * badc0 / 255; // scale delayed sample with potentiometer iw1 = 127 - badc1; // substract offset from new sample iw1 = iw1 + iw; // add delayed sample and new sample if (iw1 < -127) iw1 = -127; // Audio limiter if (iw1 > 127) iw1 = 127; // Audio limiter bb = 127 + iw1; // add offset dd[icnt] = bb; // store sample in audio buffer icnt++; icnt = icnt & 511; // limit bufferindex 0..511 OCR2A = bb; // Sample Value to PWM Output
PORTD = PORTD ^ 128; output(left, PORTD); // Output
} }
void readKnobs() { fx1 = analogRead(1); fx2 = analogRead(2); fx3 = analogRead(3); fx4 = analogRead(4);
}
void fill_sinewave() { float pi = 3.141592; float dx ; float fd ; float fcnt; dx = 2 * pi / 512; // fill the 512 byte bufferarry for (iw = 0; iw <= 511; iw++) { // with 50 periods sinewawe fd = 127 * sin(fcnt); // fundamental tone fcnt = fcnt + dx; // in the range of 0 to 2xpi and 1/512 increments bb = 127 + fd; // add dc offset to sinewawe dd[iw] = bb; // write value into array
} }
//****************************************************************** // Timer2 Interrupt Service at 62.5 KHz // here the audio and pot signal is sampled in a rate of: 16Mhz / 256 / 2 / 2 = 15625 Hz ISR(TIMER2_OVF_vect) {
PORTB = PORTB | 1 ;
div32 = !div32; // divide timer2 frequency / 2 to 31.25kHz if (div32) { div16 = !div16; if (div16) { // sample channel 0 and 1 alternately so each channel is sampled with 15.6kHz badc0 = ADCH; // get ADC channel 0 sbi(ADMUX, MUX0); // set multiplexer to channel 1 } else { badc1 = ADCH; // get ADC channel 1 cbi(ADMUX, MUX0); // set multiplexer to channel 0 f_sample = true; } ibb++; ibb--; ibb++; ibb--; // short delay before start conversion sbi(ADCSRA, ADSC); // start next conversion }
}
Step 6: Video
Potential Problems ● Pickup is a little too weak to power circuit - need an op amp. - In the video we used a signal booster. ( The grey box lying on the table. )

Participated in the
Audio Contest 2017
Comments