miércoles, 11 de diciembre de 2013

Código controlador MIDI

Para poder compilar el código debo en primer lugar indicar que utilizo las siguientes librerias:

MIDI: http://playground.arduino.cc/Main/MIDILibrary

U8glib: http://code.google.com/p/u8glib/

M2tklib: http://code.google.com/p/m2tklib/  ( no es imprescindible, pero si alguien se anima a modificar cosas, esta es sin duda una herramienta de gran ayuda )

El código lo hice en diferentes archivos, teneis el principal y a continuación los ".h" que componen el total del código. Podeis añadir con el IDE que viene por defecto en Arduino los archivos .h tal y como se indica aqui:

http://arduino.cc/es/Guide/Environment

To compile the code I must first state that I use the following libraries:

MIDI: http://playground.arduino.cc/Main/MIDILibrary

U8glib: http://code.google.com/p/u8glib/

M2tklib: http://code.google.com/p/m2tklib/ (not required, but if anyone is encouraged to change things, this is definitely a useful tool)

I did the code in different files, you have the main and then. "H" that make up the total code. . IDE you can add to the default one h files in Arduino as shown here:


http://arduino.cc/es/Guide/Environment



                                   Código principal / Main code:



//
//
// Changelog:
// 20120818: fixes
// 20120813: cleanup
// 2012????.Albert: implementation

// http://en.wikipedia.org/wiki/The_C_Programming_Language

#include
#include "avr/pgmspace.h"
#include "potenciometros_y_display.h"
#include "CC_defs.h"
#include "constants.h"
#include "U8glib.h"

U8GLIB_ST7920_128X64 u8g(3, 5, 6, 9, 10, 11, 7, 8, 13, U8G_PIN_NONE, U8G_PIN_NONE, 12, 4); // 8Bit Com: D0..D7: 3, 5, 6, 9, 10, 11, 7, 8 en=13, di=12,rw=4

ControlStatus current_status;

//#define DEBUG_MENU
//#define DEBUG_KNOBS
//#define DEBUG_MIDI
//#define ENCODER
//#define ENCODER_PRIMER_PASO
//#define ENCODER_SEGUNDO_PASO
//#define BOTON_PULSADO
//#define SALIDA

void setup() // -----------------------------------------------------------------------------------------------------------------------------------
{
#if defined(DEBUG_MENU) || defined(DEBUG_MIDI) || defined(ENCODER) || defined(SALIDA) || defined(ENCODER_PRIMER_PASO) || defined(ENCODER_SEGUNDO_PASO) || defined(BOTON_PULSADO) || defined(DEBUG_KNOBS)
Serial.begin(9600);
#else
MIDI.begin(MIDI_CHANNEL_OMNI); // de esta manera recibe os 16 canales
#endif
ControlStatus_Init(&current_status);
}

void loop()
{
static unsigned int clock = 0;
const unsigned int period = 100;

input_update(&current_status);

if ((clock % period) == 0) // trigger every 'period' (e.g. 1 every 5 times)
{
input_update(&current_status);//zz!
// clock: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// clock % period: 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0
screen_update(&current_status);
output_update(&current_status);

}
}

//------------- EMPIEZAN LAS FUNCIONES-------------------------------------------


void input_update(ControlStatus *cs)
{
// Menu and submenu handling:

#ifdef ENCODER

char btmp[127];
sprintf(btmp, "cs->encoder.encoder_target %i", cs->encoder.encoder_target);
Serial.println(btmp);//zz

#endif

switch ( cs->encoder.encoder_target ) // Vale 0
{
case MenuEncoderNdx:

cs->encoder.positions[cs->encoder.encoder_target] = update_from_encoder(cs, cs->encoder.positions[cs->encoder.encoder_target], NUM_MENUS);//NUM_MENUS

/*
int update_from_encoder(ControlStatus *cs, int enc_pos, int x);

int update_from_encoder = ( Paso de la estructura, parametro del valor de la funcion de encoder, valor maximo que puede alcanzar en este caso NUM_MENUS )

ejemplo:

update_from_encoder(cs, cs->encoder.positions[cs->encoder.encoder_target], NUM_MENUS): 3
cs->encoder.positions[cs->encoder.encoder_target]: 3
Valor de cs->encoder.encoder_target: 0

update_from_encoder(cs, cs->encoder.positions[cs->encoder.encoder_target], NUM_MENUS): 4
cs->encoder.positions[cs->encoder.encoder_target]: 4
Valor de cs->encoder.encoder_target: 0

*/

#ifdef ENCODER_PRIMER_PASO

char btmp[127];
char btmp1[127];
char btmp2[127];
sprintf(btmp, "cs->encoder.positions[cs->encoder.encoder_target]: %i", cs->encoder.positions[cs->encoder.encoder_target]);
sprintf(btmp1, "update_from_encoder(cs, cs->encoder.positions[cs->encoder.encoder_target], NUM_MENUS): %i", update_from_encoder(cs, cs->encoder.positions[cs->encoder.encoder_target], NUM_MENUS));
sprintf(btmp2, "Valor de cs->encoder.encoder_target: %i", cs->encoder.encoder_target );
Serial.println(btmp1);//zz
Serial.println(btmp);
Serial.println(btmp2);
Serial.println("\n");
,
#endif



if (update_from_button(&current_status) == BUTTON_PRESSED)
{
switch (cs->encoder.positions[MenuEncoderNdx]
{
case ME_KnobGroup:
cs->encoder.encoder_target = KnobGroupEncoderNdx;
break;

case ME_Knob:
cs->encoder.encoder_target = KnobEncoderNdx;
break;

case ME_ControlChange:
cs->encoder.encoder_target = ControlChangeEncoderNdx;
break;

case ME_MidiChannel:
cs->encoder.encoder_target = MidiChannelNdx;
break;

case ME_Behavior:
cs->encoder.encoder_target = BehaviorNdx;
break;
}

#ifdef ENCODER_SEGUNDO_PASO

char btmp[127];
char btmp1[127];
char btmp2[127];
sprintf(btmp, "cs->encoder.positions[cs->encoder.encoder_target]: %i", cs->encoder.positions[cs->encoder.encoder_target]);
sprintf(btmp1, "update_from_encoder(cs, cs->encoder.positions[cs->encoder.encoder_target], NUM_MENUS): %i", update_from_encoder(cs, cs->encoder.positions[cs->encoder.encoder_target], NUM_MENUS));
sprintf(btmp2, "Valor de cs->encoder.encoder_target: %i", cs->encoder.encoder_target );
Serial.println(btmp1);//zz
Serial.println(btmp);
Serial.println(btmp2);
Serial.println("\n");

#endif



}
update_encoder_targets(cs);
break;

case KnobGroupEncoderNdx:// ----------------------------------------------------------------------------------Case-0

// Serial.println("Knob group");
cs->encoder.positions[cs->encoder.encoder_target] =
update_from_encoder(&current_status, cs->encoder.positions[cs->encoder.encoder_target], NUM_KNOB_GROUPS);

#ifdef DEBUG_MENU
sprintf(btmp, "KnobGroupEncoderNdx: %i", cs->encoder.positions[cs->encoder.encoder_target]);
Serial.println(btmp);//zz
#endif

if (update_from_button(&current_status) == BUTTON_RELEASED) // pressed
{

cs->encoder.encoder_target = MenuEncoderNdx; // Return to menu.
}
break;

case KnobEncoderNdx: // --------------------------------------------------------------------------------------Case-1

// Serial.println("Knob");
cs->encoder.positions[cs->encoder.encoder_target] =
update_from_encoder(&current_status, cs->encoder.positions[cs->encoder.encoder_target], NUM_KNOBS);

#ifdef DEBUG_MENU
sprintf(btmp, "KnobEncoderNdx: %i", cs->encoder.positions[cs->encoder.encoder_target]);
Serial.println(btmp);//zz
#endif

if (update_from_button(&current_status) == BUTTON_RELEASED) // pressed
{
cs->encoder.encoder_target = MenuEncoderNdx; // Return to menu.
}
break;

case MidiChannelNdx: // --------------------------------------------------------------------------Case-2
// Canal Midi
// #include"canalMIDI.h"

// Serial.println("Canal Midi");
cs->encoder.positions[cs->encoder.encoder_target] =
update_from_encoder(&current_status, cs->encoder.positions[cs->encoder.encoder_target], NUM_MIDI);

#ifdef DEBUG_MENU
sprintf(btmp, "MidiChannelNdx: %i", cs->encoder.positions[cs->encoder.encoder_target]);
Serial.println(btmp);//zz
#endif

if (update_from_button(&current_status) == BUTTON_RELEASED)
{
// Assign midi channel
int group = cs->encoder.positions[KnobGroupEncoderNdx];
int knob = cs->encoder.positions[KnobEncoderNdx];
cs->knobs[group].channel[knob] = cs->encoder.positions[cs->encoder.encoder_target];
// Return to menu:
cs->encoder.encoder_target = MenuEncoderNdx;
}
break;

case ControlChangeEncoderNdx: // -------------------------------------------------------------------------Case-3
// Control Change
// Serial.println("Control Change");

cs->encoder.positions[cs->encoder.encoder_target] =
update_from_encoder(&current_status, cs->encoder.positions[cs->encoder.encoder_target], NUM_CONTROL_CHANGE);

#ifdef DEBUG_MENU
sprintf(btmp, "ControlChangeEncoderNdx: %i", cs->encoder.positions[cs->encoder.encoder_target]);
Serial.println(btmp);//zz
#endif


if (update_from_button(&current_status) == BUTTON_RELEASED) // pressed
{
// Assign control change:
int group = cs->encoder.positions[KnobGroupEncoderNdx];
int knob = cs->encoder.positions[KnobEncoderNdx];
cs->knobs[group].control_change[knob] = cs->encoder.positions[cs->encoder.encoder_target];
// Return to menu:
cs->encoder.encoder_target = MenuEncoderNdx;
}
break;

case BehaviorNdx: // --------------------------------------------------------------------------------------Case-4

#ifdef DEBUG_MENU
sprintf(btmp, "BehaviorNdx: %i", cs->encoder.positions[cs->encoder.encoder_target]);
Serial.println(btmp);//zz
#endif

cs->encoder.encoder_target = MenuEncoderNdx; // Unimplemented:
// return to menu.
break;

}//switch

// Read knob data:
input_update_knobs(cs);

}



void output_update(ControlStatus *cs)
{
// Update MIDI parameters, if required:
output_update_midi(cs);
}



void screen_update(ControlStatus *cs)
{
// Prepare LCD for drawing:
u8g.firstPage();

// Draw frame and constant parts:
do
{
// Draw frame and constant parts:

lcd_draw_header();

// Dynamic data:
lcd_draw_menu(cs);
lcd_draw_knob(cs);
input_update(cs);
}
while (u8g.nextPage());
}




int update_from_button(ControlStatus * cs)
{
// read the pushbutton input pin:
int salida = BUTTON_IDLE; // Initialize, always

if (cs)
{
cs->button.buttonState = digitalRead(PIN_Button); // PIN_Button = 2;

// compare the buttonState to its previous state
if (cs->button.buttonState != cs->button.lastButtonState)
{
// if the state has changed, increment the counter
if (cs->button.buttonState == HIGH)
{
// if the current state is HIGH then the button
// wend from off to on:
cs->button.buttonPushCounter++;

#ifdef BOTON_PULSADO
Serial.println("on");
Serial.print("number of button pushes: ");
Serial.println(cs->button.buttonPushCounter);
#endif
salida = BUTTON_PRESSED;

}
else
{
// if the current state is LOW then the button
// wend from on to off:
#ifdef DEBUG_MENU
Serial.println("off");
#endif
salida = BUTTON_RELEASED;


}
}
// save the current state as the last state,
// for next time through the loop
cs->button.lastButtonState = cs->button.buttonState;

#ifdef SALIDA
Serial.print(salida == BUTTON_PRESSED? "BUTTON_PRESSED" : salida == BUTTON_RELEASED? "BUTTON_RELEASED" : "" );
#endif

}

return salida;
}





int update_from_encoder(ControlStatus *cs, int enc_pos, int x)
{
if (cs)
{
int lecturaPin = digitalRead(PIN_Encoder0A);
if ((cs->encoder.ultimaPosicionPinA == HIGH) && (lecturaPin == LOW))
{
if (digitalRead(PIN_Encoder0B) == HIGH)
{
#ifdef DEBUG_MENU
Serial.println("-");
#endif

enc_pos--;
// lcd.clear();
}
else
{
#ifdef DEBUG_MENU
Serial.println("+");//zz!
#endif
enc_pos++;
// lcd.clear();
}
}
cs->encoder.ultimaPosicionPinA = lecturaPin;
if (enc_pos < 0)
{
#ifdef DEBUG_MENU
Serial.println("- [0]");//zz!
#endif
enc_pos = 0;
}
if (enc_pos > x)
{
enc_pos = x;
}
}
return enc_pos;
}



void input_update_knobs(ControlStatus * cs)
{
const int inputs[NUM_KNOBS] = { A3, A2, A1, A0 };
const int knob_group = cs->encoder.positions[KnobGroupEncoderNdx];

for ( int i = 0; i < NUM_KNOBS; i++ )
{
const int raw_input = analogRead(inputs[i]);
const int ADC_res_bits = 10;
const int meaning_adc_bits = 4; // Use 4 of the 10 ADC bits (e.g. 2**4 = 16 steps instead of 2**10 = 1024)
const int remove_mask = ~(1 << (ADC_res_bits - meaning_adc_bits)) - 1;
const int knob_current_value = raw_input & remove_mask; // = (raw_input / 64) * 64;
if ( cs->knobs[knob_group].knob[i] != knob_current_value ) // knob changed?
{
delay(10);
cs->knobs[knob_group].knob[i] = knob_current_value;
#ifdef DEBUG_KNOBS

char btmp[32];
sprintf(btmp, "knob[%i, %i]: %i",
knob_group, i, knob_current_value);
Serial.println(btmp);//zz!
#endif
}
}
}


void lcd_draw_knob(ControlStatus * cs)
{
const int knob_group = cs->encoder.positions[KnobGroupEncoderNdx];

u8g.setFont(u8g_font_micro);

for ( int i = 0; i < NUM_KNOBS; i++ )
{
const int value = map(cs->knobs[knob_group].knob[i], 0, 1023, 0, 20);
const int pct = map(cs->knobs[knob_group].knob[i], 0, 1023, 0, 107);

// X, Y ; ancho , alto Linea vertical mas estrcha (debajo del restangulo )
// rectangulo que sube o baja

u8g.drawLine(2 + 20 * i, 60, 2 + 20 * i, 40);
u8g.drawBox(1 + 20 * i, (60 - value), 3, 100);

// Knob %
u8g.drawStr(1 + 20 * i + 6, 64 - value, strcpy_P(buzzer, (char *)pgm_read_word(&(strin_table[pct])))); // sample
}
}




void lcd_draw_header()
{
u8g.drawFrame(79, 0, 49, 64); // X, Y ; ancho , alto Recuadro grupo
u8g.drawLine(0, 30, 79, 30); // linea entre el texto y los potes
u8g.drawLine(0, 37, 79, 37); // "" ""
u8g.drawLine(79, 24, 128, 24); // linea separadora grupo y auto
}


void indicador_de_pulsacion(ControlStatus * cs)
{

//u8g.setFont(u8g_font_6x10);
u8g.drawStr( 80, 15,"d" );
}



void lcd_draw_menu(ControlStatus *cs)
{
u8g.setFont(u8g_font_micro);
const int font_width = 4; // 4 point-wide font
const int font_height = 6; // 6 point-tall font
const int menu_pos = cs->encoder.positions[MenuEncoderNdx];

// Draw cursor:
u8g.drawStr(1, 5 + (menu_pos * font_height), ">");

// Draw menu entries:
for ( int i = 0; i < ME_Elems; i++ )
{
// Draw text:



u8g.drawStr(8, 5 + i*font_height, menu_labels[i]);
if ( i != ME_ControlChange ) // Draw all except CC
{

// Draw value:
//const int text_offset = (strlen(menu_labels[i]) ) * font_width;

const int text_offset = (strlen(menu_labels[i]) ) * font_width;



const int value = cs->encoder.positions[i+1];
const char *text = value >= 0 && value <= MAX_strin? (char *)pgm_read_word(&(strin_table[value])) : "???!";
u8g.drawStr(8 + text_offset, 5 + i*font_height, strcpy_P(buzzer, text));
}
}
// Draw extra elements:

const int cc_text_offset = (strlen(menu_labels[ME_ControlChange]) + 1) * font_width;
const int value = cs->encoder.positions[ControlChangeEncoderNdx];
const char *cc_text = value >= 0 && value <= MAX_string? (char *)pgm_read_word(&(string_table[value])) : "???!";
u8g.drawStr(8 + cc_text_offset, 5 + ME_ControlChange*font_height, strcpy_P(buffer, cc_text)); // Muestra el porcentaje que se mueve


}



void output_update_midi(ControlStatus *cs)
{
const int knob_group = cs->encoder.positions[KnobGroupEncoderNdx];

for ( int i = 0; i < NUM_KNOBS; i++ )
{
const int midi_channel = cs->knobs[knob_group].channel[i];
const int cc = cs->knobs[knob_group].control_change[i];
const int value = map(cs->knobs[knob_group].knob[i], 0, 1023, 0, 137);

if ( midi_channel >= 0 && midi_channel < NUM_MIDI && cs->midi_status[midi_channel].cc != cc || cs->midi_status[midi_channel].knob_value != value )
{
cs->midi_status[midi_channel].cc = cc;
cs->midi_status[midi_channel].knob_value = value;
MIDI.sendControlChange(cc,value,midi_channel);
//sendControlChange (byte ControlNumber, byte ControlValue, byte Channel)

}
}
}


void ControlStatus_Init(ControlStatus * cs)
{
memset(cs, 0, sizeof(ControlStatus));

cs->button.buttonPushCounter = 1; // Counter for the number of button presses
cs->button.buttonState = 1; // Current state of the button
cs->button.lastButtonState = 0; // Previous state of the button

cs->encoder.encoder_target = 0;
cs->encoder.ultimaPosicionPinA = LOW;
for ( int i = 0; i < NUM_KNOB_GROUPS; i++ )
{
for ( int j = 0; j < NUM_KNOBS; j++ )
{
cs->knobs[i].knob[j] = 0;
cs->knobs[i].behavior[j] = 0;
cs->knobs[i].control_change[j] = 0;
cs->knobs[i].channel[j] = 0;
}
}
for ( int i = 0; i < NUM_MIDI; i++ )
{
cs->midi_status[i].cc = 0;
cs->midi_status[i].knob_value = 0;
}
}


void update_encoder_targets(ControlStatus *cs)
{
const int knob_group = MAX(0, cs->encoder.positions[KnobGroupEncoderNdx]);
const int knob = MAX(0, cs->encoder.positions[KnobEncoderNdx]);
cs->encoder.positions[ControlChangeEncoderNdx] = MAX(0, cs->knobs[knob_group].control_change[knob]);
cs->encoder.positions[MidiChannelNdx] = MAX(0, cs->knobs[knob_group].channel[knob]);

cs->encoder.positions[BehaviorNdx] = MAX(0, cs->knobs[knob_group].behavior[knob]);
}


------------------------------------------------------------------  CC_defs.h



// Changelog:
// 20120813: cleanup
// 2012????.Albert: implementation


#ifndef CC_defs_h
#define CC_defs_h


char buffer[16];

prog_char string_0[] PROGMEM = "00-BankSelMSB"; // "String 0" etc are strings to store - change to suit.
prog_char string_1[] PROGMEM = "01-Mod Wheel";
prog_char string_2[] PROGMEM = "02-Breath Cntrl";
prog_char string_3[] PROGMEM = "03-CC 03";
prog_char string_4[] PROGMEM = "04-Foot Cntrl";
prog_char string_5[] PROGMEM = "05-Porta Time";
prog_char string_6[] PROGMEM = "06-Data Entry"; // "String 0" etc are strings to store - change to suit.
prog_char string_7[] PROGMEM = "07-Volume";
prog_char string_8[] PROGMEM = "08-Balance";
prog_char string_9[] PROGMEM = "09-CC 09";
prog_char string_10[] PROGMEM = "10-Pan";
prog_char string_11[] PROGMEM = "11-Expression ";
prog_char string_12[] PROGMEM = "12-fx Cntrl 1";
prog_char string_13[] PROGMEM = "13-fx Cntrl 2";
prog_char string_14[] PROGMEM = "14-CC 14";
prog_char string_15[] PROGMEM = "15-CC 15";
prog_char string_16[] PROGMEM = "16-GPCntrl1LSB1";
prog_char string_17[] PROGMEM = "17-GPCntrl1LSB2";
prog_char string_18[] PROGMEM = "18-GPCntrl1LSB3";
prog_char string_19[] PROGMEM = "19-GPCntrl1LSB3";
prog_char string_20[] PROGMEM = "20-CC 20";
prog_char string_21[] PROGMEM = "21-CC 21";
prog_char string_22[] PROGMEM = "22-CC 22";
prog_char string_23[] PROGMEM = "23-CC 23";
prog_char string_24[] PROGMEM = "24-CC 24";
prog_char string_25[] PROGMEM = "25-CC 25";
prog_char string_26[] PROGMEM = "26-CC 26";
prog_char string_27[] PROGMEM = "27-CC 27";
prog_char string_28[] PROGMEM = "28-CC 28";
prog_char string_29[] PROGMEM = "29-CC 29";
prog_char string_30[] PROGMEM = "30-CC 30";
prog_char string_31[] PROGMEM = "31-CC 31";
prog_char string_32[] PROGMEM = "32-BankSelLSB";
prog_char string_33[] PROGMEM = "33-Mod Wheel LSB";
prog_char string_34[] PROGMEM = "34-Breath Cntrl LSB";
prog_char string_35[] PROGMEM = "35-CC 35";
prog_char string_36[] PROGMEM = "36-Foot Cntrl LSB";
prog_char string_37[] PROGMEM = "37-Porta Time LSB";
prog_char string_38[] PROGMEM = "38-Data Entry LSB";
prog_char string_39[] PROGMEM = "39-Volume LSB";
prog_char string_40[] PROGMEM = "40-Balance LSB";
prog_char string_41[] PROGMEM = "41-CC 41";
prog_char string_42[] PROGMEM = "42-Pan LSB ";
prog_char string_43[] PROGMEM = "43-Expression LSB";
prog_char string_44[] PROGMEM = "44-fx 1 LSB ";
prog_char string_45[] PROGMEM = "45-fx 2 LSB";
prog_char string_46[] PROGMEM = "46-CC 46";
prog_char string_47[] PROGMEM = "47-CC 47";
prog_char string_48[] PROGMEM = "48-GPCntrl1LSB ";
prog_char string_49[] PROGMEM = "49-GPCntrl2LSB ";
prog_char string_50[] PROGMEM = "50-GPCntrl3LSB ";
prog_char string_51[] PROGMEM = "51-GPCntrl4LSB";
prog_char string_52[] PROGMEM = "52-CC 52";
prog_char string_53[] PROGMEM = "53-CC 53";
prog_char string_54[] PROGMEM = "54-CC 54";
prog_char string_55[] PROGMEM = "55-CC 55";
prog_char string_56[] PROGMEM = "56-CC 56";
prog_char string_57[] PROGMEM = "57-CC 57";
prog_char string_58[] PROGMEM = "58-CC 58";
prog_char string_59[] PROGMEM = "59-CC 59";
prog_char string_60[] PROGMEM = "60-CC 60";
prog_char string_61[] PROGMEM = "61-CC 61";
prog_char string_62[] PROGMEM = "62-CC 62";
prog_char string_63[] PROGMEM = "63-CC 63";
prog_char string_64[] PROGMEM = "64-Damper Pedal";
prog_char string_65[] PROGMEM = "65-Porta Pedal";
prog_char string_66[] PROGMEM = "66-Sostenuto";
prog_char string_67[] PROGMEM = "67-Soft Pedal";
prog_char string_68[] PROGMEM = "68-Legato Foot Sw";
prog_char string_69[] PROGMEM = "69-Hold-2";
prog_char string_70[] PROGMEM = "70-Sound Vari";
prog_char string_71[] PROGMEM = "71-Timbre/Harmonics";
prog_char string_72[] PROGMEM = "72-Realease Time";
prog_char string_73[] PROGMEM = "73-Attack Time";
prog_char string_74[] PROGMEM = "74-Brighness";
prog_char string_75[] PROGMEM = "75-Decay Time";
prog_char string_76[] PROGMEM = "76-Vib.Rate";
prog_char string_77[] PROGMEM = "77-Vib.Depth";
prog_char string_78[] PROGMEM = "78-Vib.Delay";
prog_char string_79[] PROGMEM = "79-Sound Ctrl10";
prog_char string_80[] PROGMEM = "80-GeneralPurp10 ";
prog_char string_81[] PROGMEM = "81-GeneralPurp6";
prog_char string_82[] PROGMEM = "82-GeneralPurp7";
prog_char string_83[] PROGMEM = "83-GeneralPurp8";
prog_char string_84[] PROGMEM = "84-PortaCntrl";
prog_char string_85[] PROGMEM = "85-CC 85";
prog_char string_86[] PROGMEM = "86-CC 86";
prog_char string_87[] PROGMEM = "87-CC 87";
prog_char string_88[] PROGMEM = "88-CC 88";
prog_char string_89[] PROGMEM = "89-CC 89";
prog_char string_90[] PROGMEM = "90-CC 90";
prog_char string_91[] PROGMEM = "91-Reverb Depth";
prog_char string_92[] PROGMEM = "92-Tremolo Depth";
prog_char string_93[] PROGMEM = "93-Chorus Depth";
prog_char string_94[] PROGMEM = "94-Detune Depth";
prog_char string_95[] PROGMEM = "95-Phaser Depth";
prog_char string_96[] PROGMEM = "96-Data Inc";
prog_char string_97[] PROGMEM = "97-Data Dec";
prog_char string_98[] PROGMEM = "98-NRPN LSB";
prog_char string_99[] PROGMEM = "99-NRPN-MSB";
prog_char string_100[] PROGMEM = "100-RPN LSB";
prog_char string_101[] PROGMEM = "101-RPN MSB";
prog_char string_102[] PROGMEM = "102-CC 102";
prog_char string_103[] PROGMEM = "103-CC 103";
prog_char string_104[] PROGMEM = "104-CC 104";
prog_char string_105[] PROGMEM = "105-CC 105";
prog_char string_106[] PROGMEM = "106-CC 106";
prog_char string_107[] PROGMEM = "107-CC 107";
prog_char string_108[] PROGMEM = "108-CC 108";
prog_char string_109[] PROGMEM = "109-CC 108";
prog_char string_110[] PROGMEM = "110-CC 110 ";
prog_char string_111[] PROGMEM = "111-CC 111";
prog_char string_112[] PROGMEM = "112-CC 112";
prog_char string_113[] PROGMEM = "113-CC 113";
prog_char string_114[] PROGMEM = "114-CC 114";
prog_char string_115[] PROGMEM = "115-CC 115";
prog_char string_116[] PROGMEM = "116-CC 116";
prog_char string_117[] PROGMEM = "117-CC 117";
prog_char string_118[] PROGMEM = "118-CC 118";
prog_char string_119[] PROGMEM = "119-CC 119";
prog_char string_120[] PROGMEM = "120-All Sound OFF";
prog_char string_121[] PROGMEM = "121-RST all Cntrl";
prog_char string_122[] PROGMEM = "122-Local Cntrl";
prog_char string_123[] PROGMEM = "123-All note Off";
prog_char string_124[] PROGMEM = "124-Omni Off";
prog_char string_125[] PROGMEM = "125-Omni On";
prog_char string_126[] PROGMEM = "126-Mono Mode On";

#define MAX_string 126

PROGMEM PGM_P string_table[] = // change "string_table" name to suit
{
string_0,
string_1,
string_2,
string_3,
string_4,
string_5,
string_6,
string_7,
string_8,
string_9,
string_10,
string_11,
string_12,
string_13,
string_14,
string_15,
string_16,
string_17,
string_18,
string_19,
string_20,
string_21,
string_22,
string_23,
string_24,
string_25,
string_26,
string_27,
string_28,
string_29,
string_30,
string_31,
string_32,
string_33,
string_34,
string_35,
string_36,
string_37,
string_38,
string_39,
string_40,
string_41,
string_42,
string_43,
string_44,
string_45,
string_46,
string_47,
string_48,
string_49,
string_50,
string_51,
string_52,
string_53,
string_54,
string_55,
string_56,
string_57,
string_58,
string_59,
string_60,
string_61,
string_62,
string_63,
string_64,
string_65,
string_66,
string_67,
string_68,
string_69,
string_70,
string_71,
string_72,
string_73,
string_74,
string_75,
string_76,
string_77,
string_78,
string_79,
string_80,
string_81,
string_82,
string_83,
string_84,
string_85,
string_86,
string_87,
string_88,
string_89,
string_90,
string_91,
string_92,
string_93,
string_94,
string_95,
string_96,
string_97,
string_98,
string_99,
string_100,
string_101,
string_102,
string_103,
string_104,
string_105,
string_106,
string_107,
string_108,
string_109,
string_110,
string_111,
string_112,
string_113,
string_114,
string_115,
string_116,
string_117,
string_118,
string_119,
string_120,
string_121,
string_122,
string_123,
string_124,
string_125,
string_126,
};




#endif /* #ifndef CC_defs_h */


------------------------------------------------------------------ constants.h


// Changelog:
// 20120813: cleanup
// 2012????.Albert: implementation



#ifndef constants_h
#define constants_h

#include "Arduino.h"


char buzzer[16];

prog_char strin_0[] PROGMEM = "0"; // "String 0" etc are strings to store // change to suit.
prog_char strin_1[] PROGMEM = "1";
prog_char strin_2[] PROGMEM = "2";
prog_char strin_3[] PROGMEM = "3";
prog_char strin_4[] PROGMEM = "4";
prog_char strin_5[] PROGMEM = "5";
prog_char strin_6[] PROGMEM = "6"; // "String 0" etc are strings to store - // change to suit.
prog_char strin_7[] PROGMEM = "7";
prog_char strin_8[] PROGMEM = "8";
prog_char strin_9[] PROGMEM = "9";
prog_char strin_10[] PROGMEM = "10";
prog_char strin_11[] PROGMEM = "11";
prog_char strin_12[] PROGMEM = "12";
prog_char strin_13[] PROGMEM = "13";
prog_char strin_14[] PROGMEM = "14";
prog_char strin_15[] PROGMEM = "15";
prog_char strin_16[] PROGMEM = "16";
prog_char strin_17[] PROGMEM = "17";
prog_char strin_18[] PROGMEM = "18";
prog_char strin_19[] PROGMEM = "19";
prog_char strin_20[] PROGMEM = "20";
prog_char strin_21[] PROGMEM = "21";
prog_char strin_22[] PROGMEM = "22";
prog_char strin_23[] PROGMEM = "23";
prog_char strin_24[] PROGMEM = "24";
prog_char strin_25[] PROGMEM = "25";
prog_char strin_26[] PROGMEM = "26";
prog_char strin_27[] PROGMEM = "27";
prog_char strin_28[] PROGMEM = "28";
prog_char strin_29[] PROGMEM = "29";
prog_char strin_30[] PROGMEM = "30";
prog_char strin_31[] PROGMEM = "31";
prog_char strin_32[] PROGMEM = "32";
prog_char strin_33[] PROGMEM = "33";
prog_char strin_34[] PROGMEM = "34";
prog_char strin_35[] PROGMEM = "35";
prog_char strin_36[] PROGMEM = "36";
prog_char strin_37[] PROGMEM = "37";
prog_char strin_38[] PROGMEM = "38";
prog_char strin_39[] PROGMEM = "39";
prog_char strin_40[] PROGMEM = "40";
prog_char strin_41[] PROGMEM = "41";
prog_char strin_42[] PROGMEM = "42";
prog_char strin_43[] PROGMEM = "43";
prog_char strin_44[] PROGMEM = "44";
prog_char strin_45[] PROGMEM = "45";
prog_char strin_46[] PROGMEM = "46";
prog_char strin_47[] PROGMEM = "47";
prog_char strin_48[] PROGMEM = "48";
prog_char strin_49[] PROGMEM = "49";
prog_char strin_50[] PROGMEM = "50";
prog_char strin_51[] PROGMEM = "51";
prog_char strin_52[] PROGMEM = "52";
prog_char strin_53[] PROGMEM = "53";
prog_char strin_54[] PROGMEM = "54";
prog_char strin_55[] PROGMEM = "55";
prog_char strin_56[] PROGMEM = "56";
prog_char strin_57[] PROGMEM = "57";
prog_char strin_58[] PROGMEM = "58";
prog_char strin_59[] PROGMEM = "59";
prog_char strin_60[] PROGMEM = "60";
prog_char strin_61[] PROGMEM = "61";
prog_char strin_62[] PROGMEM = "62";
prog_char strin_63[] PROGMEM = "63";
prog_char strin_64[] PROGMEM = "64";
prog_char strin_65[] PROGMEM = "65";
prog_char strin_66[] PROGMEM = "66";
prog_char strin_67[] PROGMEM = "67";
prog_char strin_68[] PROGMEM = "68";
prog_char strin_69[] PROGMEM = "69";
prog_char strin_70[] PROGMEM = "70";
prog_char strin_71[] PROGMEM = "71";
prog_char strin_72[] PROGMEM = "72";
prog_char strin_73[] PROGMEM = "73";
prog_char strin_74[] PROGMEM = "74";
prog_char strin_75[] PROGMEM = "75";
prog_char strin_76[] PROGMEM = "76";
prog_char strin_77[] PROGMEM = "77";
prog_char strin_78[] PROGMEM = "78";
prog_char strin_79[] PROGMEM = "79";
prog_char strin_80[] PROGMEM = "80";
prog_char strin_81[] PROGMEM = "81";
prog_char strin_82[] PROGMEM = "82";
prog_char strin_83[] PROGMEM = "83";
prog_char strin_84[] PROGMEM = "84";
prog_char strin_85[] PROGMEM = "85";
prog_char strin_86[] PROGMEM = "86";
prog_char strin_87[] PROGMEM = "87";
prog_char strin_88[] PROGMEM = "88";
prog_char strin_89[] PROGMEM = "89";
prog_char strin_90[] PROGMEM = "90";
prog_char strin_91[] PROGMEM = "91";
prog_char strin_92[] PROGMEM = "92";
prog_char strin_93[] PROGMEM = "93";
prog_char strin_94[] PROGMEM = "94";
prog_char strin_95[] PROGMEM = "95";
prog_char strin_96[] PROGMEM = "96";
prog_char strin_97[] PROGMEM = "97";
prog_char strin_98[] PROGMEM = "98";
prog_char strin_99[] PROGMEM = "99";
prog_char strin_100[] PROGMEM = "100";

#define MAX_strin 100

PROGMEM PGM_P strin_table[] = // change "string_table" name to suit
{
strin_0,
strin_1,
strin_2,
strin_3,
strin_4,
strin_5,
strin_6,
strin_7,
strin_8,
strin_9,
strin_10,
strin_11,
strin_12,
strin_13,
strin_14,
strin_15,
strin_16,
strin_17,
strin_18,
strin_19,
strin_20,
strin_21,
strin_22,
strin_23,
strin_24,
strin_25,
strin_26,
strin_27,
strin_28,
strin_29,
strin_30,
strin_31,
strin_32,
strin_33,
strin_34,
strin_35,
strin_36,
strin_37,
strin_38,
strin_39,
strin_40,
strin_41,
strin_42,
strin_43,
strin_44,
strin_45,
strin_46,
strin_47,
strin_48,
strin_49,
strin_50,
strin_51,
strin_52,
strin_53,
strin_54,
strin_55,
strin_56,
strin_57,
strin_58,
strin_59,
strin_60,
strin_61,
strin_62,
strin_63,
strin_64,
strin_65,
strin_66,
strin_67,
strin_68,
strin_69,
strin_70,
strin_71,
strin_72,
strin_73,
strin_74,
strin_75,
strin_76,
strin_77,
strin_78,
strin_79,
strin_80,
strin_81,
strin_82,
strin_83,
strin_84,
strin_85,
strin_86,
strin_87,
strin_88,
strin_89,
strin_90,
strin_91,
strin_92,
strin_93,
strin_94,
strin_95,
strin_96,
strin_97,
strin_98,
strin_99,
strin_100,

};


#endif // #ifndef constants_h


------------------------------------------------------------- potenciometros_y_display.h


// Changelog:
// 20120813: cleanup
// 2012????.Albert: implementation

#ifndef potenciometros_y_display_h


// Definitions and constants:

#define NUM_KNOB_GROUPS 8
#define NUM_KNOBS 4 // 4 knobs * 4 knobs/bank = 16 total knobs
#define NUM_MENUS 4
#define NUM_MIDI 16
#define NUM_CONTROL_CHANGE 127

#define BUTTON_IDLE 0
#define BUTTON_RELEASED 1
#define BUTTON_PRESSED 2
/*
Version para Mega
const int PIN_Encoder0A = 30;
const int PIN_Encoder0B = 31;
const int PIN_Button = 22;
*/
// version para UNO
/*const int PIN_Encoder0A = 0;
const int PIN_Encoder0B = 2;
*/

const int PIN_Encoder0A = 19;
const int PIN_Encoder0B = 18;
const int PIN_Button = 2;


enum EncoderIndexes
{
MenuEncoderNdx = 0,
KnobGroupEncoderNdx,
KnobEncoderNdx,
ControlChangeEncoderNdx,
MidiChannelNdx,
BehaviorNdx,
KnobEncoderElems
};


enum MenuElems
{
ME_KnobGroup = 0,
ME_Knob,
ME_ControlChange,
ME_MidiChannel,
ME_Behavior,
ME_Elems
};

const char *menu_labels[ME_Elems] = { "K group:", "Knob:", "CC:", "Channel:", "lin/exp/log:" };


// Data structures:

typedef struct
{
int knob[NUM_KNOBS];
int behavior[NUM_KNOBS];
int control_change[NUM_KNOBS];
int channel[NUM_KNOBS];
} KnobStatus;


typedef struct
{
int buttonPushCounter; // counter for the number of button presses
int buttonState; // current state of the button
int lastButtonState; // previous state of the button
} Button;

typedef struct
{
int encoder_target; // it will point to knob_ndx/control_change_ndx/menu_ndx.
int positions[KnobEncoderElems];
int ultimaPosicionPinA;
} Encoder;

typedef struct
{
int cc;
int knob_value;
} MIDI_STATUS;

typedef struct
{
KnobStatus knobs[NUM_KNOB_GROUPS];
Encoder encoder;
Button button;
MIDI_STATUS midi_status[NUM_MIDI];
} ControlStatus;


// Function prototypes:

void input_update(ControlStatus *cs);
void output_update(ControlStatus *cs);
void screen_update(ControlStatus *cs);
int update_from_button(ControlStatus *cs); // pulsador()
int update_from_encoder(ControlStatus *cs, int enc_pos, int x); // Paso de la estructura, retorno del valor de la funcion de encoder, valor maximo que puede alcanzar )
void input_update_knobs(ControlStatus *cs);
void lcd_draw_knob(ControlStatus *cs);
void lcd_draw_header();
void indicador_de_pulsacion(ControlStatus *cs);
void lcd_draw_menu(ControlStatus *cs);
void output_update_midi(ControlStatus *cs);
void ControlStatus_Init(ControlStatus *cs);
void update_encoder_targets(ControlStatus *cs);

// Macros:

#define MAX(x, y) (x > y? x : y)


#endif // potenciometros_y_display_h




Pido de antemano disculpas por cualquier error u omisión que afecte al código, si tenéis alguna duda respecto al código hacédmela saber.

video
Espero que disfrutéis con vuestro nuevo controlador MIDI.

I ask in advance apologies for any errors or omissions affecting the code, if you have any questions regarding hacédmela know code.

I hope you enjoy with your new MIDI Controller.




No hay comentarios:

Publicar un comentario