Source
Introduction | Video | Photo | Music | Source
Firmware (for HiCu)
[ccnw_php width=”880″ theme=”mac-classic”]
#include
#include
#include
#include
#include
#include
#include “usbdrv.h”
#include “description.h”
#include “touch.h”
#include “atmega-adc.h”
#define F_CPU 16000000UL
#define COUNTER_BITS 11
#define ASIZE (1<
Actual tuning
64.2172
68.0357
72.0814
76.3675
80.9086
85.7197
90.8168
96.2171
101.938
108.000
114.422
121.226
Tested but too tight
48 == 128.434 == 87 – 5 – C >>>>> 4 – 0.71mm nw028
49 == 136.071 == 82 – 5 – C# >>>>> 4 .
50 == 144.163 == 77 – 4 – D >>>>> 4
51 == 152.735 == 73 – 4 – D# >>>>> 3 – 0.56mm nw022
52 == 161.817 == 69 – 4 – E >>>>> 3 .
53 == 171.439 == 65 – 4 – F >>>>> 3
54 == 181.634 == 62 – 3 – F# >>>>> 3
56 == 192.434 == 58 – 3 – G >>>>> 3 –broke switch to 2
55 == 203.877 == 55 – 3 – G# >>>>> 2 – 0.36mm pl014
57 == 216.000 == 52 – 2 – A >>>>> 2 .
58 == 228.844 == 49 – 2 – A# >>>>> 2
59 == 242.452 == 46 – 2 – B >>>>> 2
*/
//121.226hz to 64.2172hz
unsigned int f[12] = { 91, 97, 103, 110, 115, 122, 129, 137, 145, 153, 163, 172 }; //(12 high – 1 low)
////////////////////////////////////////////////////////////////////////
// IO
////////////////////////////////////////////////////////////////////////
/*
——– PWM ———
1 – PB0
2 – PB1
3 – PB2
4 – PB3
5 – PB4
6 – PB5
7 – PB6
8 – PB7
9 – PE0
10 – PE1
11 – PE2
12 – PE3
——–LEDS———
1 – PJ7
2 – PJ6
3 – PJ5
4 – PJ4
5 – PJ3
6 – PJ2
7 – PJ1
8 – PJ0
9 – PC7
10 – PC6
11 – PC5
12 – PC4
——–MOSFET———
1 – PH0
2 – PH1
3 – PH2
4 – PH3
5 – PH4
6 – PH5
7 – PH6
8 – PH7
9 – PE4
10 – PE5
11 – PE6
12 – PE7
——–PIANO (SCREW) ADC / TOUCH———
1 – PF0
2 – PF1
3 – PF2
4 – PF3
5 – PF4
6 – PF5
7 – PF6
8 – PF7
9 – PK0
10 – PK1
11 – PK2
12 – PK3
————————SLIDER VHS————————-
PK4 – VHS
—————————SWITCH————————–
PL0 – standalone
*/
////////////////////////////////////////////////////////////////////////
// INIT
////////////////////////////////////////////////////////////////////////
static void USBConf(void)
{
uchar i, j;
/* activate pull-ups except on USB lines */
USB_CFG_IOPORT =
(uchar) ~ ((1 << USB_CFG_DMINUS_BIT) |
(1 << USB_CFG_DPLUS_BIT));
/* all pins input except USB (-> USB reset) */
#ifdef USB_CFG_PULLUP_IOPORT /* use usbDeviceConnect()/usbDeviceDisconnect() if available */
USBDDR = 0; /* we do RESET by deactivating pullup */
usbDeviceDisconnect();
#else
USBDDR = (1 << USB_CFG_DMINUS_BIT) | (1 << USB_CFG_DPLUS_BIT);
#endif
j = 0;
while (--j) { /* USB Reset by device only required on Watchdog Reset */
i = 0;
while (--i); /* delay >10ms for USB reset */
}
#ifdef USB_CFG_PULLUP_IOPORT
usbDeviceConnect();
#else
USBDDR = 0; /* remove USB reset condition */
#endif
DDRD = 0b11010000; // set debug led
}
////////////////////////////////////////////////////////////////////////
// IO CONFIGURATION
////////////////////////////////////////////////////////////////////////
void IOConf()
{
// PWM / MOSFET – output
DDRB = 0xFF;
DDRH = 0xFF;
DDRE = 0xFF;
// LED – output
DDRJ = 0xFF;
DDRC = 0xFF;
// SWITCH – input
DDRL = 0x00;
PORTL = 0xFF; // pull-up enable
// ANALOG – input
DDRF = 0x00;
DDRK = 0x00;
}
////////////////////////////////////////////////////////////////////////
// VHS – CC throttle
////////////////////////////////////////////////////////////////////////
void timerCC_init() {
TCCR0A |= (1<
PORTE ^= (1 << (i - 8));
} else {
PORTB ^= (1 << i);
}
x[(p+f[i])&MASK] |= mask;
}
mask <<= 1;
}
/*
// this should be quicker
PORTE ^= z >> 8;
PORTB ^= z; // assumes 8-bit CPU
for (i = 0; i <12; i++) {
if (z&mask) {
x[(p+f[i])&MASK] |= mask;
}
mask <<= 1;
}
*/
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// CAPACITIVE TOUCH on ADC
// this is causing noise in the pick-up / ground even if the string are isolated
/////////////////////////////////////////////////////////////////////////////////////////////////
// min 780 or higher if unstable
// play with touch.c _delay_us(100)
// play with threshold in main()
static touch_channel_t btn11 = { .mux = 11, .port = &PORTK, .portmask = (1<
parseMidiMessage(data+4, len-4);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// USB<->MIDI
/////////////////////////////////////////////////////////////////////////////////////////////////
uchar usbFunctionDescriptor(usbRequest_t * rq)
{
if (rq->wValue.bytes[1] == USBDESCR_DEVICE) {
usbMsgPtr = (uchar *) deviceDescrMIDI;
return sizeof(deviceDescrMIDI);
} else {
usbMsgPtr = (uchar *) configDescrMIDI;
return sizeof(configDescrMIDI);
}
}
uchar usbFunctionSetup(uchar data[8])
{
usbRequest_t *rq = (void *) data;
if ((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS) {
if ((rq->bmRequestType & USBRQ_DIR_MASK) ==
USBRQ_DIR_HOST_TO_DEVICE)
sendEmptyFrame = 1;
}
return 0xff;
}
void usbFunctionWriteOut(uchar * data, uchar len) // from computer
{
parseMidiMessage(data, len);
}
uchar usbFunctionWrite(uchar * data, uchar len)
{
return 1;
}
uchar usbFunctionRead(uchar * data, uchar len)
{
return 7;
}
////////////////////////////////////////////////////////////////////////
// BOOTLOADER
////////////////////////////////////////////////////////////////////////
// ——————————————————————————
// – Write to EEPROM
// ——————————————————————————
void eepromWrite(unsigned int uiAddress, unsigned char ucData) {
while(EECR & (1<
currentNoteBuffer[0] = 1;
} else {
currentNoteBuffer[0] = 0;
}
} else if(i == 200) {
if(touch_measure(&btn1) > 340) {
currentNoteBuffer[1] = 1;
} else {
currentNoteBuffer[1] = 0;
}
} else if(i == 300) {
if(touch_measure(&btn2) > 340) {
currentNoteBuffer[2] = 1;
} else {
currentNoteBuffer[2] = 0;
}
} else if(i == 400) {
if(touch_measure(&btn3) > 340) {
currentNoteBuffer[3] = 1;
} else {
currentNoteBuffer[3] = 0;
}
} else if(i == 500) {
if(touch_measure(&btn4) > 340) {
currentNoteBuffer[4] = 1;
} else {
currentNoteBuffer[4] = 0;
}
} else if(i == 600) {
if(touch_measure(&btn5) > 340) {
currentNoteBuffer[5] = 1;
} else {
currentNoteBuffer[5] = 0;
}
} else if(i == 700) {
if(touch_measure(&btn6) > 340) {
currentNoteBuffer[6] = 1;
} else {
currentNoteBuffer[6] = 0;
}
} else if(i == 800) {
if(touch_measure(&btn7) > 340) {
currentNoteBuffer[7] = 1;
} else {
currentNoteBuffer[7] = 0;
}
} else if(i == 900) {
if(touch_measure(&btn8) > 340) {
currentNoteBuffer[8] = 1;
} else {
currentNoteBuffer[8] = 0;
}
} else if(i == 1000) {
if(touch_measure(&btn9) > 340) {
currentNoteBuffer[9] = 1;
} else {
currentNoteBuffer[9] = 0;
}
} else if(i == 1200) {
if(touch_measure(&btn10) > 340) {
currentNoteBuffer[10] = 1;
} else {
currentNoteBuffer[10] = 0;
}
} else if(i == 1300) {
if(touch_measure(&btn11) > 340) {
currentNoteBuffer[11] = 1;
} else {
currentNoteBuffer[11] = 0;
}
} else if(i > 1400) {
PORTD ^= (1 << PIND6);
i = 0;
}
// CAPACITIVE TOUCH -> PC via MIDI NOTE
for(j = 0; j < 12; j++) {
// blue led monitor bandwidth
PORTD ^= (1 << PIND7);
if(currentNoteBuffer[j] != lastNoteBuffer[j]) {
lastNoteBuffer[j] = currentNoteBuffer[j];
if(currentNoteBuffer[j] == 1) { // NOTE ON
if(j < 8) {
PORTJ |= (1 << j + 7 - ((j * 2))); // led
PORTH |= (1 << j); // mosfet
} else {
if(j == 8) {
PORTC |= (1 << 7);
} else if(j == 9) {
PORTC |= (1 << 6);
} else if(j == 10) {
PORTC |= (1 << 5);
} else if(j == 11) {
PORTC |= (1 << 4);
}
PORTE |= (1 << (j - 4));
}
midiMsg[0] = 0x09;
midiMsg[1] = 0x90;
midiMsg[3] = 0x7f;
} else { // NOTE OFF
if(j < 8) {
PORTJ &= ~(1 << j + 7 - ((j * 2))); // led
PORTH &= ~(1 << j); // mosfet
} else {
if(j == 8) {
PORTC &= ~(1 << 7);
} else if(j == 9) {
PORTC &= ~(1 << 6);
} else if(j == 10) {
PORTC &= ~(1 << 5);
} else if(j == 11) {
PORTC &= ~(1 << 4);
}
PORTE &= ~(1 << (j - 4));
}
midiMsg[0] = 0x08;
midiMsg[1] = 0x80;
midiMsg[3] = 0x00;
}
midiMsg[2] = j + 59 - (j * 2);
sendEmptyFrame = 0;
if(!standalone) {
while (!usbInterruptIsReady()) {
usbPoll();
}
usbSetInterrupt(midiMsg, 4);
}
}
}
// VHS -> PC via MIDI CC
if(sendCC) {
sendCC = 0;
midiMsg[0] = 0x0b;
midiMsg[1] = 0xb0;
midiMsg[2] = 70;
midiMsg[3] = adc_read(ADC_PRESCALER_128, ADC_VREF_AVCC, 12) >> 3; // vhs slider
sendEmptyFrame = 0;
if(!standalone) {
while (!usbInterruptIsReady()) {
usbPoll();
}
usbSetInterrupt(midiMsg, 4);
}
if(midiMsg[3] > 0 && midiMsg[3] < 10) { AllOff(); PORTC |= (1 << PINC4); PORTE |= (1 << PINE7); PORTC |= (1 << PINC6); PORTE |= (1 << PINE5); PORTJ |= (1 << PINJ0); PORTH |= (1 << PINH7); } else if(midiMsg[3] > 10 && midiMsg[3] < 20) { AllOff(); PORTC |= (1 << PINC5); PORTE |= (1 << PINE6); PORTC |= (1 << PINC7); PORTE |= (1 << PINE4); } else if(midiMsg[3] > 20 && midiMsg[3] < 30) { AllOff(); PORTJ |= (1 << PINJ0); PORTH |= (1 << PINH7); } else if(midiMsg[3] > 30 && midiMsg[3] < 40) { AllOff(); PORTJ |= (1 << PINJ1); PORTH |= (1 << PINH6); } else if(midiMsg[3] > 40 && midiMsg[3] < 50) { AllOff(); PORTJ |= (1 << PINJ2); PORTH |= (1 << PINH5); } else if(midiMsg[3] > 50 && midiMsg[3] < 60) { AllOff(); PORTJ |= (1 << PINJ3); PORTH |= (1 << PINH4); } else if(midiMsg[3] > 60 && midiMsg[3] < 70) { AllOff(); PORTJ |= (1 << PINJ4); PORTH |= (1 << PINH3); } else if(midiMsg[3] > 70 && midiMsg[3] < 80) { AllOff(); PORTJ |= (1 << PINJ5); PORTH |= (1 << PINH2); } else if(midiMsg[3] > 80 && midiMsg[3] < 90) { AllOff(); PORTJ |= (1 << PINJ6); PORTH |= (1 << PINH1); } else if(midiMsg[3] > 90 && midiMsg[3] < 100) { AllOff(); PORTJ |= (1 << PINJ7); PORTH |= (1 << PINH0); } else if(midiMsg[3] > 100 && midiMsg[3] < 116) { AllOff(); } // above 118 == not touching the vsh } } return 0; } [/ccnw_php]
Schematic (Kicad)
PCB (Kicad)
CAD (Sketchup)
BOM
Description | Price | Quantity | Links / infos | |
Peg | 8.49 $ | 6 | http://www.amazon.ca/gp/product/B00CIQL0VM/ref=oh_details_o01_s00_i00?ie=UTF8&psc=1 | |
Peg | 8.49 $ | 6 | http://www.amazon.ca/gp/product/B00CIQL0VM/ref=oh_details_o01_s00_i00?ie=UTF8&psc=1 | |
Planche | 30.18 $ | 1 | Langevins – Érables blanc – 40″, 0.6″, 71/4″ | |
Strings | 27.68 $ | 12 | 12x (6x 6, 6x 5) | |
Vises / bolt | 9 $ | 24 | 10-24 / 1-1/2 | |
Screw | 7.92 $ | 36 | #3 (22$ for 100) http://www.ebay.com/itm/3-x-1-2-Slotted-Round-Head-Solid-Brass-Wood-Screw-Qty-100-/331132452725? | |
Coils | 10 $ | 12 | Adisson 12v http://addison-electronique.com/catalog/product/view/id/6304/s/090146-electro-magnet-from-6-to-12-vdc/ | |
PCB Hicu | 1.5 $ | 1 | $13.80 USD | |
PCB ebarn | 2.5 $ | 1 | $20.49 USD | |
pickup | 9 $ | 2 | http://www.ebay.ca/itm/251268897417 | |
Hicu kit | 20 $ | |||
bague | ||||
magnet | ||||
phone wire | ||||
wiring | average… wire | |||
237-1409-ND | 24 $ | 1 | powersupply 15v | |
839-1204-ND | 0.87 | 1 | connector power supply 8mm circular | |
shipping | 8 $ | |||
SC2014-ND | 7.2 $ | 2 | phono connector | |
493-12772-1-ND | 1.69 $ | 13 | 10uf | |
493-12562-1-ND | 2.64 $ | 12 | 220uf | |
493-12560-1-ND | 0.23 $ | 1 | 100uf | |
399-7931-1-ND | 0.48 $ | 12 | 0.047uf 1608 | |
811-2196-5-ND | 5.13 $ | 1 | murata 36v to 5v | |
160-1721-1-ND | 5.88 $ | 12 | smd led white 1608 (1.60mmx0.80) | |
RHM470DCT-ND | 1.2 $ | 12 | smd resistor 470 for led (1608) | |
RHM10.0AFCT-ND | 1.92 $ | 12 | smd resistor 10 for lm387 (1206) | |
RMCF1206JT10K0CT-ND | 0.6 $ | 12 | smd resistor 10k for mosfet | |
vhs resistor | ||||
LM386N-4/NOPB-ND | 1.07 $ | 12 | lm386-4 | |
785-1185-5-ND | 0.64 $ | 12 | mosfet n-channel (for 25) | |
732-3831-5-ND | 0.89 $ | 1 | switch fibownacci | |
CW181-ND | 0.84 $ | 1 | switch fibownacci |