From 5f79fb05184c0f925671672483b9b61cb947eb9d Mon Sep 17 00:00:00 2001 From: Tucker Johnson Date: Thu, 15 May 2025 08:47:25 -0400 Subject: [PATCH 1/1] init --- .gitigonre | 3 ++ Makefile | 28 +++++++++++++++ multiFader.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++ multiFader.hex | 42 +++++++++++++++++++++++ multiFader.o | Bin 0 -> 2804 bytes readme.txt | 1 + 6 files changed, 164 insertions(+) create mode 100644 .gitigonre create mode 100644 Makefile create mode 100644 multiFader.c create mode 100644 multiFader.hex create mode 100644 multiFader.o create mode 100644 readme.txt diff --git a/.gitigonre b/.gitigonre new file mode 100644 index 0000000..a39790f --- /dev/null +++ b/.gitigonre @@ -0,0 +1,3 @@ +*.o +*.elf +*.hex diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c86ec49 --- /dev/null +++ b/Makefile @@ -0,0 +1,28 @@ +MCU = atmega328p +F_CPU = 16000000UL +BAUD = 115200 +PROGRAMMER = arduino +PORT = /dev/ttyACM0 # Change to your COM port if on Windows +TARGET = multiFader + +CC = avr-gcc +OBJCOPY = avr-objcopy +AVRDUDE = avrdude + +CFLAGS = -Os -DF_CPU=$(F_CPU) -mmcu=$(MCU) + +all: $(TARGET).hex + +$(TARGET).o: $(TARGET).c + $(CC) $(CFLAGS) -c -o $@ $< + +$(TARGET).hex: $(TARGET).o + $(CC) $(CFLAGS) -o temp.elf $< + $(OBJCOPY) -O ihex -R .eeprom temp.elf $@ + rm -f temp.elf + +flash: $(TARGET).hex + $(AVRDUDE) -c $(PROGRAMMER) -p $(MCU) -P $(PORT) -b $(BAUD) -U flash:w:$(TARGET).hex + +clean: + rm -f *.o *.hex diff --git a/multiFader.c b/multiFader.c new file mode 100644 index 0000000..de9022a --- /dev/null +++ b/multiFader.c @@ -0,0 +1,90 @@ +#include +#include +#include +#include + +#define BAUD 31250 +#define MYUBRR ((F_CPU / (16UL * BAUD)) - 1) +#define MIDI_CHANNEL 0 +#define NUM_CONTROLS 5 +#define BASE_CC 1 // Start at CC 1, increment for each + +const uint8_t pot_channels[NUM_CONTROLS] = {0, 1, 2, 3, 4}; // ADC0–ADC4 +const uint8_t mute_pins[NUM_CONTROLS] = {PD2, PD3, PD4, PD5, PD6}; // Digital mute pins + +uint8_t last_values[NUM_CONTROLS] = {255, 255, 255, 255, 255}; +bool muted[NUM_CONTROLS] = {false, false, false, false, false}; + +void uart_init(unsigned int ubrr) { + UBRR0H = (unsigned char)(ubrr >> 8); + UBRR0L = (unsigned char)ubrr; + UCSR0B = (1 << TXEN0); + UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); +} + +void uart_send(uint8_t data) { + while (!(UCSR0A & (1 << UDRE0))); + UDR0 = data; +} + +void send_midi_cc(uint8_t channel, uint8_t controller, uint8_t value) { + uart_send(0xB0 | (channel & 0x0F)); + uart_send(controller); + uart_send(value); +} + +void adc_init(void) { + ADMUX = (1 << REFS0); // AVcc + ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1); // Prescaler 64 +} + +uint16_t adc_read_channel(uint8_t channel) { + ADMUX = (ADMUX & 0xF0) | (channel & 0x0F); // Select ADCx + ADCSRA |= (1 << ADSC); + while (ADCSRA & (1 << ADSC)); + return ADC; +} + +void io_init(void) { + for (uint8_t i = 0; i < NUM_CONTROLS; i++) { + DDRD &= ~(1 << mute_pins[i]); // Input + PORTD |= (1 << mute_pins[i]); // Internal pull-up + } +} + +int main(void) { + uart_init(MYUBRR); + adc_init(); + io_init(); + + _delay_ms(500); + + while (1) { + for (uint8_t i = 0; i < NUM_CONTROLS; i++) { + bool switch_state = !(PIND & (1 << mute_pins[i])); // Active LOW + + if (switch_state && !muted[i]) { + // Mute just engaged + muted[i] = true; + send_midi_cc(MIDI_CHANNEL, BASE_CC + i, 0); + } else if (!switch_state && muted[i]) { + // Mute just released — send current value + muted[i] = false; + uint8_t val = adc_read_channel(pot_channels[i]) >> 3; + send_midi_cc(MIDI_CHANNEL, BASE_CC + i, val); + last_values[i] = val; + } + + if (!muted[i]) { + uint8_t val = adc_read_channel(pot_channels[i]) >> 3; + if (abs((int)val - (int)last_values[i]) >= 2) { + send_midi_cc(MIDI_CHANNEL, BASE_CC + i, val); + last_values[i] = val; + } + } + } + + _delay_ms(20); // Delay for debounce + noise filtering + } +} + diff --git a/multiFader.hex b/multiFader.hex new file mode 100644 index 0000000..c1f5bcc --- /dev/null +++ b/multiFader.hex @@ -0,0 +1,42 @@ +:100000000C9434000C9451000C9451000C94510049 +:100010000C9451000C9451000C9451000C9451001C +:100020000C9451000C9451000C9451000C9451000C +:100030000C9451000C9451000C9451000C945100FC +:100040000C9451000C9451000C9451000C945100EC +:100050000C9451000C9451000C9451000C945100DC +:100060000C9451000C94510011241FBECFEFD8E026 +:10007000DEBFCDBF11E0A0E0B1E0E8E7F2E002C0F2 +:1000800005900D92A031B107D9F721E0A0E1B1E0D0 +:1000900001C01D92A531B207E1F70E94B1000C9496 +:1000A0003A010C9400009093C5008093C40088E04E +:1000B0008093C10086E08093C20008959091C000B3 +:1000C00095FFFCCF8093C6000895CF93DF93D62F82 +:1000D000C42F8F70806B0E945E008D2F0E945E0087 +:1000E0008C2FDF91CF910C945E0080E480937C0094 +:1000F00086E880937A00089590917C008F70907FBD +:10010000892B80937C0080917A00806480937A00B0 +:1001100080917A0086FDFCCF8091780090917900E3 +:100120000895E5E0F1E041E050E02AB18191BA01A3 +:1001300002C0660F771F8A95E2F7CB018095822374 +:100140008AB98BB1DF012E91BA0102C0660F771F09 +:100150002A95E2F7862B8BB971E0EA30F70729F789 +:1001600008958FE190E00E9453000E9475000E9464 +:1001700091002FEF69E678E1215060407040E1F78F +:1001800000C00000D1E025E0822E21E0922E30E177 +:10019000C32E31E0D32E40E0E42E41E0F42E5AE0AD +:1001A000A52E51E0B52EC0E089B1F40131914F0187 +:1001B000F60121916F01CF5F90E002C09595879580 +:1001C0003A95E2F780FD1EC021110AC0D29340E0AB +:1001D0006C2F80E00E946500F60182918115A1F0EC +:1001E000FFEFEF1AFF0A2FEFA21AB20AC530E1F6AD +:1001F0006FEF79EF80E0615070408040E1F700C020 +:100200000000C1CF211123C0F50180810E947C0034 +:100210008C0193E0169507959A95E1F7980133279D +:10022000F7018081482F50E0602F681B770BCB01CE +:1002300077FF03C0CA01821B930B02978CF2402FF9 +:100240006C2F80E00E946500F7010083C9CF1292F5 +:10025000F50180810E947C008C0183E01695079552 +:100260008A95E1F7402F6C2F80E00E946500F7012E +:080270000083B2CFF894FFCF28 +:10027800FFFFFFFFFF02030405060001020304005D +:00000001FF diff --git a/multiFader.o b/multiFader.o new file mode 100644 index 0000000000000000000000000000000000000000..9cec3cc1fb19c25bd336e8c03444dacf4099bb64 GIT binary patch literal 2804 zcma);U2GIp6vxlZ>~;$!(5`?=Rkm8CfX;SH`H=Xr3KU`*Y(Ns@gVUkA*p+T~-Q7}3 zstiSo6b!qp8wepr34Vn50?{ajheg2$dBBgv7+;tgVvI3qAq5f>v;NQAx!ZyG;7QKC zzyCe=SqaMfo+= zmhy!%l`2%Wir+$AE?z1A9KH}fl(x3dewXN-Fqa3zR|=O4vq08Wt2j)fe^|v`&e&l( zl+N$ozm!|8!Y;C69AO&$2Xhv7Qob;Rp0+({KVx^B) zwZ}O$rD)GD1xm+C%G6P1*`ix$-w^JyyTiSWgLRjbK^*#b%1C3ePCeqAjE3cUw-nk- z<>2AzdGQKx2jawFnBJFyc-YTC)wf4RbA6=_d0|4!| z*TY)#hM{~k8!b;&Td!5_20!W1A@I{4y|~H@*DA|VPUmpv`hI#A@eo{?(C&x1nco5HOQ<=YkgIvEwQw092XBHefph=ssE6TE zSIb=ZW*cyyJ_P^^q7GtzGh8j=KALlz)~FGhV{&|p8|OLd;VbXZlpN^GB|6MlJfruJ zVQlU)HW-G0P63OBg*p zWX5_#oFNl8V@6M}+20@UqeMysk^{N8kxukyDQPD9aSpk7jQY%M&e&o04aBpQPUYmF zEDj`=GI~R!e*l$MCzyxHJX^pr&qukP3mES`;Bq^-<}q$1S_Kcd`~xQfRV+xDGwR;?-UgmoRXHW$n5zJ?(E)aZ>xl!;jX5J9&I9!|MAid9g zzu=S1yiwRGc#t;-bIxs{;O|jsA;G_*Qr#SW1Irx#1k2p6bGthaK66r=&;Y9i%l`FX z?LpB_dUhz8Gqsj&$eo>HOsMYAZ(IYZyqQDJ9}Psbn(VpL1va zUsVXbkPg+jz4`9Wxy%*E*!Wm|@F<*Z7y~{*jeo72J{;pC=4;_G@-OBjnBSr_IUhfj zTDa_Y1N>k8_&f6E$Nl&>QJTaE8oc>62Z)X$$ocWSGQYK89;3q90)UwUol?%%3B}Cs znymr-+|SL?9Fs2R;y^P*JvPO2Hp6+{dN}7H_X?zTB-J4ogO<$p8QV literal 0 HcmV?d00001 diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..dbf57a2 --- /dev/null +++ b/readme.txt @@ -0,0 +1 @@ +5-fader board -- 2.39.5