Arduino MIDI Controller

Arduino MIDI controller Controlador MIDI basado en Arduino UNO. MIDI controller based on Arduino UNO. sábado, 8 de marzo

Views 109 Downloads 4 File size 776KB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

Arduino MIDI controller Controlador MIDI basado en Arduino UNO. MIDI controller based on Arduino UNO. sábado, 8 de marzo de 2014

"Unexpected end of file" at startup of CvPcb Al cargar los modulos en kicad a veces pasa esto cuando han sido modificados o importados de bibliotecas como por ejemplo Eagle "Unexpected end of file" at startup of CvPcb La solucion que he encontrado es esta, y de momento me ha funcionado. añadir al final del archivo que dá el error $EndLIBRARY.

https://bugs.launchpad.net/kicad/+bug/872315 Salud. Publicado por Pulse en 11:29 No hay comentarios: Enviar por correo electrónicoEscribe un blogCompartir con TwitterCompartir con FacebookCompartir en Pinterest

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 changethings, 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 #include #include #include #include

"avr/pgmspace.h" "potenciometros_y_display.h" "CC_defs.h" "constants.h" "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 //#define //#define //#define //#define //#define //#define //#define

DEBUG_MENU DEBUG_KNOBS DEBUG_MIDI ENCODER ENCODER_PRIMER_PASO ENCODER_SEGUNDO_PASO BOTON_PULSADO 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(¤t_status); } void loop() { static unsigned int clock = 0; const unsigned int period = 100; input_update(¤t_status); if ((clock % period) == 0) // trigger every 'period' (e.g. 1 every 5 times) { input_update(¤t_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(¤t_status); output_update(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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 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 encoder.positions[ControlChangeEncoderNdx]; const char *cc_text = value >= 0 && value encoder.positions[KnobGroupEncoderNdx]; for ( { const const const

int i = 0; i < NUM_KNOBS; i++ ) int midi_channel = cs->knobs[knob_group].channel[i]; int cc = cs->knobs[knob_group].control_change[i]; 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 change to prog_char prog_char prog_char prog_char prog_char prog_char change to prog_char prog_char prog_char prog_char

string_0[] PROGMEM = "00-BankSelMSB"; // "String 0" etc are strings to store suit. string_1[] PROGMEM = "01-Mod Wheel"; string_2[] PROGMEM = "02-Breath Cntrl"; string_3[] PROGMEM = "03-CC 03"; string_4[] PROGMEM = "04-Foot Cntrl"; string_5[] PROGMEM = "05-Porta Time"; string_6[] PROGMEM = "06-Data Entry"; // "String 0" etc are strings to store suit. string_7[] PROGMEM = "07-Volume"; string_8[] PROGMEM = "08-Balance"; string_9[] PROGMEM = "09-CC 09"; string_10[] PROGMEM = "10-Pan";

prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char

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[]

PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

"11-Expression "; "12-fx Cntrl 1"; "13-fx Cntrl 2"; "14-CC 14"; "15-CC 15"; "16-GPCntrl1LSB1"; "17-GPCntrl1LSB2"; "18-GPCntrl1LSB3"; "19-GPCntrl1LSB3"; "20-CC 20"; "21-CC 21"; "22-CC 22"; "23-CC 23"; "24-CC 24"; "25-CC 25"; "26-CC 26"; "27-CC 27"; "28-CC 28"; "29-CC 29"; "30-CC 30"; "31-CC 31"; "32-BankSelLSB"; "33-Mod Wheel LSB"; "34-Breath Cntrl LSB"; "35-CC 35"; "36-Foot Cntrl LSB"; "37-Porta Time LSB"; "38-Data Entry LSB"; "39-Volume LSB"; "40-Balance LSB"; "41-CC 41"; "42-Pan LSB "; "43-Expression LSB"; "44-fx 1 LSB "; "45-fx 2 LSB"; "46-CC 46"; "47-CC 47"; "48-GPCntrl1LSB "; "49-GPCntrl2LSB "; "50-GPCntrl3LSB "; "51-GPCntrl4LSB"; "52-CC 52"; "53-CC 53"; "54-CC 54"; "55-CC 55"; "56-CC 56"; "57-CC 57"; "58-CC 58"; "59-CC 59"; "60-CC 60"; "61-CC 61"; "62-CC 62"; "63-CC 63"; "64-Damper Pedal"; "65-Porta Pedal"; "66-Sostenuto"; "67-Soft Pedal"; "68-Legato Foot Sw"; "69-Hold-2"; "70-Sound Vari"; "71-Timbre/Harmonics"; "72-Realease Time"; "73-Attack Time";

prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char

string_74[] PROGMEM = "74-Brighness"; string_75[] PROGMEM = "75-Decay Time"; string_76[] PROGMEM = "76-Vib.Rate"; string_77[] PROGMEM = "77-Vib.Depth"; string_78[] PROGMEM = "78-Vib.Delay"; string_79[] PROGMEM = "79-Sound Ctrl10"; string_80[] PROGMEM = "80-GeneralPurp10 "; string_81[] PROGMEM = "81-GeneralPurp6"; string_82[] PROGMEM = "82-GeneralPurp7"; string_83[] PROGMEM = "83-GeneralPurp8"; string_84[] PROGMEM = "84-PortaCntrl"; string_85[] PROGMEM = "85-CC 85"; string_86[] PROGMEM = "86-CC 86"; string_87[] PROGMEM = "87-CC 87"; string_88[] PROGMEM = "88-CC 88"; string_89[] PROGMEM = "89-CC 89"; string_90[] PROGMEM = "90-CC 90"; string_91[] PROGMEM = "91-Reverb Depth"; string_92[] PROGMEM = "92-Tremolo Depth"; string_93[] PROGMEM = "93-Chorus Depth"; string_94[] PROGMEM = "94-Detune Depth"; string_95[] PROGMEM = "95-Phaser Depth"; string_96[] PROGMEM = "96-Data Inc"; string_97[] PROGMEM = "97-Data Dec"; string_98[] PROGMEM = "98-NRPN LSB"; string_99[] PROGMEM = "99-NRPN-MSB"; string_100[] PROGMEM = "100-RPN LSB"; string_101[] PROGMEM = "101-RPN MSB"; string_102[] PROGMEM = "102-CC 102"; string_103[] PROGMEM = "103-CC 103"; string_104[] PROGMEM = "104-CC 104"; string_105[] PROGMEM = "105-CC 105"; string_106[] PROGMEM = "106-CC 106"; string_107[] PROGMEM = "107-CC 107"; string_108[] PROGMEM = "108-CC 108"; string_109[] PROGMEM = "109-CC 108"; string_110[] PROGMEM = "110-CC 110 "; string_111[] PROGMEM = "111-CC 111"; string_112[] PROGMEM = "112-CC 112"; string_113[] PROGMEM = "113-CC 113"; string_114[] PROGMEM = "114-CC 114"; string_115[] PROGMEM = "115-CC 115"; string_116[] PROGMEM = "116-CC 116"; string_117[] PROGMEM = "117-CC 117"; string_118[] PROGMEM = "118-CC 118"; string_119[] PROGMEM = "119-CC 119"; string_120[] PROGMEM = "120-All Sound OFF"; string_121[] PROGMEM = "121-RST all Cntrl"; string_122[] PROGMEM = "122-Local Cntrl"; string_123[] PROGMEM = "123-All note Off"; string_124[] PROGMEM = "124-Omni Off"; string_125[] PROGMEM = "125-Omni On"; 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 suit. prog_char prog_char prog_char prog_char prog_char prog_char suit. prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char

strin_0[] PROGMEM = "0"; // "String 0" etc are strings to store // change to strin_1[] strin_2[] strin_3[] strin_4[] strin_5[] strin_6[]

PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM PROGMEM

= = = = = =

"1"; "2"; "3"; "4"; "5"; "6"; // "String 0" etc are strings to store - // change to

strin_7[] PROGMEM = "7"; strin_8[] PROGMEM = "8"; strin_9[] PROGMEM = "9"; strin_10[] PROGMEM = "10"; strin_11[] PROGMEM = "11"; strin_12[] PROGMEM = "12"; strin_13[] PROGMEM = "13"; strin_14[] PROGMEM = "14"; strin_15[] PROGMEM = "15"; strin_16[] PROGMEM = "16"; strin_17[] PROGMEM = "17"; strin_18[] PROGMEM = "18"; strin_19[] PROGMEM = "19"; strin_20[] PROGMEM = "20"; strin_21[] PROGMEM = "21"; strin_22[] PROGMEM = "22"; strin_23[] PROGMEM = "23"; strin_24[] PROGMEM = "24"; strin_25[] PROGMEM = "25"; strin_26[] PROGMEM = "26"; strin_27[] PROGMEM = "27"; strin_28[] PROGMEM = "28"; strin_29[] PROGMEM = "29"; strin_30[] PROGMEM = "30"; strin_31[] PROGMEM = "31"; strin_32[] PROGMEM = "32"; strin_33[] PROGMEM = "33"; strin_34[] PROGMEM = "34"; strin_35[] PROGMEM = "35"; strin_36[] PROGMEM = "36"; strin_37[] PROGMEM = "37"; strin_38[] PROGMEM = "38"; strin_39[] PROGMEM = "39";

prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char prog_char

strin_40[] PROGMEM = "40"; strin_41[] PROGMEM = "41"; strin_42[] PROGMEM = "42"; strin_43[] PROGMEM = "43"; strin_44[] PROGMEM = "44"; strin_45[] PROGMEM = "45"; strin_46[] PROGMEM = "46"; strin_47[] PROGMEM = "47"; strin_48[] PROGMEM = "48"; strin_49[] PROGMEM = "49"; strin_50[] PROGMEM = "50"; strin_51[] PROGMEM = "51"; strin_52[] PROGMEM = "52"; strin_53[] PROGMEM = "53"; strin_54[] PROGMEM = "54"; strin_55[] PROGMEM = "55"; strin_56[] PROGMEM = "56"; strin_57[] PROGMEM = "57"; strin_58[] PROGMEM = "58"; strin_59[] PROGMEM = "59"; strin_60[] PROGMEM = "60"; strin_61[] PROGMEM = "61"; strin_62[] PROGMEM = "62"; strin_63[] PROGMEM = "63"; strin_64[] PROGMEM = "64"; strin_65[] PROGMEM = "65"; strin_66[] PROGMEM = "66"; strin_67[] PROGMEM = "67"; strin_68[] PROGMEM = "68"; strin_69[] PROGMEM = "69"; strin_70[] PROGMEM = "70"; strin_71[] PROGMEM = "71"; strin_72[] PROGMEM = "72"; strin_73[] PROGMEM = "73"; strin_74[] PROGMEM = "74"; strin_75[] PROGMEM = "75"; strin_76[] PROGMEM = "76"; strin_77[] PROGMEM = "77"; strin_78[] PROGMEM = "78"; strin_79[] PROGMEM = "79"; strin_80[] PROGMEM = "80"; strin_81[] PROGMEM = "81"; strin_82[] PROGMEM = "82"; strin_83[] PROGMEM = "83"; strin_84[] PROGMEM = "84"; strin_85[] PROGMEM = "85"; strin_86[] PROGMEM = "86"; strin_87[] PROGMEM = "87"; strin_88[] PROGMEM = "88"; strin_89[] PROGMEM = "89"; strin_90[] PROGMEM = "90"; strin_91[] PROGMEM = "91"; strin_92[] PROGMEM = "92"; strin_93[] PROGMEM = "93"; strin_94[] PROGMEM = "94"; strin_95[] PROGMEM = "95"; strin_96[] PROGMEM = "96"; strin_97[] PROGMEM = "97"; strin_98[] PROGMEM = "98"; strin_99[] PROGMEM = "99"; 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.

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.

Publicado por Pulse en 9:06 No hay comentarios: Enviar por correo electrónicoEscribe un blogCompartir con TwitterCompartir con FacebookCompartir en Pinterest

lunes, 9 de diciembre de 2013

Material Este es el listado de material de la última versión que tengo en marcha del controlador que sale en la foto. Hubo una versión anterior con un display de 16×2 y otra versión posterior con un display de 16×4 caracteres, pero debido a que se me quedaba corto decidí implementar un display GLCD de 128X64 píxeles con la posibilidad de añadir gráficos. A continuación describo los elementos que he utilizado en esta última (¿?) versión. This is the list of material that I have latest version of the driver up in the photo. There was an earlier version with a display of 16 × 2 and a later version with a display of 16 × 4 character, but because I fell short I decided to implement a 128X64 GLCD display pixels with the ability to add graphics. Below I describe the items that I have used in the last (?) Version.

Núcleo / Core : Arduino UNO y su IDE.

Medio para visualizar la información: Pantalla 128X64 GLCD ( permite visualizar gráficos ) Means for displaying the information: 128X64 GLCD display (used to display graphics)

Control: 4 potenciómetros ( lineales no importa el valor), un encoder y un pulsador. Control: 4 sliders (linear no matter the value), an encoder and a button.

Esquemático donde se puede apreciar los diferentes módulos MIDI IN, OUT y TRHU que lo conforman y sus componentes. Schematic where you can see the different modules MIDI IN, OUT and THRU comprising it and its components.

Conectores DIN 5 hembra (hay muchos modelos, yo escogí el que NO era aéreo y podia soldarlo en la PCB). 5 female DIN connectors (there are many models, I chose the one that was NO air and I couldsolder on the PCB).

Opto-acoplador Sharp PC-900 o equivalente para el modulo MIDI IN. Optocoupler Sharp PC-900 or equivalent to the MIDI IN module.

HCF4069UBE inversor hexadecimal para el modulo MIDI OUT. HCF4069UBE hex inverter module to the MIDI OUT.

Resistencias de 220 y 280 Ohms y diodo 1N914, tal y como se indica en el esquemático. Pcb con pistas y agujeros para trabajar con mas facilidad a la hora de soldar, evitando pegotes de estaño y por ende falsos contactos. Resistors 220 and 280 Ohms and 1N914 diode, as indicated in the schematic. Pcb with tracks and holes to work more easily when welding, avoiding globs of tin and thereforefalse contacts.

Cable rígido y las herramientas que corresponda. Espadines, para poder hacer las conexiones

Como elemento final, elegí reunir todos estos elementos en una pieza de metacrilato por varios motivos: 

Elegante.



Relativamente fácil de manipular.

Hard wire and tools appropriate. Sprats, to make connections As a final element, I chose to bring all these elements in a piece of acrylic for several reasons:

Elegant. Relatively easy to manipulate.

Pero también caro si lo cortas con laser. But also expensive if you cut with laser.

Edit Publicado por Pulse en 11:26 No hay comentarios: Enviar por correo electrónicoEscribe un blogCompartir con TwitterCompartir con FacebookCompartir en Pinterest

miércoles, 3 de julio de 2013

Controlador MIDI Arduino UNO ( I Presentación ) Después de muchas horas, pruebas y de casi no poder acabarlo, os presento mi primer controlador MIDI basado en Arduino UNO. After many hours of testing and almost unable to finish it, I present my first MIDI controller based on Arduino UNO.

¿ Como funciona ¿ How does it work?  Seleccionamos un grupo de potenciometros, 0, 1, 2, 3... hay 8 grupos, es decir 8 x 4 potenciometros = 32 potenciometros virtuales. 

We selected a group of potentiometers, 0, 1, 2, 3 ... There are 8 groups, i.e 8 x 4 = 32 virtual potentiometers .



Elegimos entre el P0, P1, P2, P3, ( los cuatro potenciometros reales ).



Chose between P0, P1, P2, P3, ( the four real potentiometers ).

 Una vez elegidos, asignamos mediante el pulsador ( manteniendo pulsado ) y el encoder mecánico, uno de los Control Change que aparece en el listado de Control Change que a continuación aparece en el display .  Once selected, assigned by the button (holding down) and mechanical encoder, choose one of the Control Change that appears in the display.

 Habiendo asignado el número de canal al potenciometro, es decir que el canal MIDI no esté en midi = 0. El controlador empezará a enviar mensajes por la salida de MIDI OUT.  Having allocated channel number potentiometer, ie the MIDI channel is not in midi = 0. The controller will start sending out messages for MIDI OUT.

Podéis observar que el funcionamiento es muy sencillo. Este uno de los objetivos mas importantes que quería conseguir, pues como músico electrónico y usuario de hardware me he encontrado con máquinas que no hacen lo que se supone tienen que hacer, y este era el caso de mi controlador Evolution UC-33 You can see that the operation is very simple. This one of the most important goals I wanted to achieve, because as electronic musician and hardware user I found machines that do not do what they are supposed to do, and this was the case of my Evolution UC-33 controller.

No es que sea una mala máquina, pero es que ( yo creo ) que no es práctico tener 24 potenciometros, 8 deslizadores además de pulsadores y que la única información que obtienes de su bonito display azul sea tan criptico como esto: It's not a bad machine, but is that (I believe) it is not practical to have 24 potentiometers, 8 sliders and buttons as well as the only information you get from her pretty blue display is as cryptic as this:

Obligándote de esta manera a introducir un elemento más en tu "set-up"... la cinta de pintor para poder saber que has asignado en cada potenciometros. Thus forcing you to introduce another element in your "set-up" ... masking tape to know that you assigned in each potentiometers. . . . ¿Os imagináis hacer una actuación y que perdáis la cinta para anotar adonde asignasteis cada función? Can you imagine doing a show and you miss the tape to record where each function was asigned ?

Descripción de la información en el menú:

Description information in the menu:

K group: Grupo de potenciometros K group: Group potentiometers Knob: Potenciometro Knob: Potentiometer CC: Control Change CC: Control Change Channel: Canal MIDI que estamos asignando. Channel: MIDI channel that we are assigning

Lin/exp/log: Respuesta de los potenciometros lineal / exponencial y logarítmica ( no implementado ). Lin / exp / log: linear potentiometers Response / exponential and logarithmic (not implemented).

Los niveles indican la posición absoluta del potenciometro, esto va muy bien para ver a simple vista doce tienes el potenciometro. The levels indicate the absolute position of the potentiometer, this is nice to see at a glance twelve have the potentiometer.

El controlador se basa completamente en un Arduino UNO, utilizando todas las entradas menos el pin número 0 ( de momento ) ya que en en breve quiero implementar un par de cosas más, y entre ellas estrá la capacidad de poder sumar una señal MIDI externa ( MIDI Merge ) y tendré que utilizar el que me queda como entrada serie. The controller is based on an Arduino UNO copmpletamente, using all entries but the pin number 0 (for now) and that soon I want to implement a few more things, including stress and the ability to add external MIDI signal ( MIDI Merge) and I have to use the one I have as input series.

El controlador solo maneja CC ( Control Change ), el motivo por el cual elegí esta particularidad antes de abordar temás como el Program Change o el Play / Stop es que pueden emplearse para modificar cualquier parámetro y para mi E-MU 5000 me vá de perlas, así que si el sintetizador que queremos gobernar permite manejar CC, no habrá problemas para comunicarse con él. The controller only handles CC (Control Change), the reason why I chose this feature before boarding issues as Program Change or the Play / Stop is that they can be used to modify any parameter of my E-MU 5000, so if the synthesizer you want to handle CC rule, there will be no problem communicating with it. Por otra parte al no ser una de las partes estandarizadas en el protocolo MIDI, copié uno a uno los 127 parámetros que reconocía mi AKAI MPC 1000 con su sistema operativo actualizado al JJOS2XL http://www7a.biglobe.ne.jp/~mpc1000/os2xl/ así que haciendo esto me aseguraba que los parámetros que copiaba por lo menos estaban "actualizados" como mi AKAI. On the other hand not being a party in the MIDI standard, I copied one by one the 127 parameters that recognized my AKAI MPC 1000 with its updated operating system to JJOS2XL http://www7a.biglobe.ne.jp/ ~ MPC1000 / os2xl / so doing that I made sure that the parameters were copied at least "updated" as my AKAI.

El material que he empleado ha sido este: The material I have used has been this:

GLCD display 128X64 link

Podéis observar que este montaje no corresponde a la placa del Arduino UNO, pero para haceros rápidamente una idea de como va el conexionado creo que ya sirve. You can see that this show is not for the Arduino UNO board, but to make you a quick idea of how the wiring goes I think it serves.

Por cierto el programa que hace estos graficos tan chulos se llama Fritzing y es Open Software. Certainly the graphics program that makes these so cool is called Fritzing and Open Software.

Una de las pruebas con el display de 128x6. One of the early tests with the display 128x64.



Libreria u8glib, del Señor Oliver, una gran tipo: link



U8glib Library of Mr. Oliver, a great guy.



Libreria MIDI aquí: link



MIDI Library



Potenciometros valor de 10K lineales, se encuentran en cualquier tienda electronica.



Linear Potentiometers 10K value, found in any electronics store.



Módulo MIDI: Lo hice siguiendo este esquema: link



MIDI Module: I did following this scheme

 Módulo encoder: A partir de un dibujo que encontré, ya que al inicio estaba completamente perdido, no puedo poner el enlace porque no lo tengo, mil gracias al creador del boceto me fue de perlas.  Encoder module: From a drawing I found, since at the beginning was completely lost, I can not put the link because I have not, thank the creator of the sketch.

Es un divisor de tensión un poco particular con un par de condensadores para evitar rebotes.

Is a curious voltage divider with a pair of capacitors to avoid rebounds.

Debo señalar que controlarlo por soft junto con el pulsador fue un infierno. Ya que al montarlo en la protoboard y con el juego que a veces tienen los cables me daban falsas señales y me pasé días en busca de la falla. I should note that for soft control with the push was hell. Since when mounted on the breadboard and the game that sometimes have the cables gave me false signs and I spent days looking for the fault.

Aquí os adjunto un vídeo ( calidad teléfono móvil ) del funcionamiento de la primera versión del controlador conectado a la MPC 1000. Here I attached a video (mobile phone quality) performance of the first version of MPC 1000connected to the controller.

Sugerencias: Suggestions:

C/C++ Curso de programacion Fco Javier ceballos Sierra A mi me ha servido y me sigue sirviendo de mucho este libro, encuentro que es una joya, y su autor es espectacular el como explica las cosas.

C / C + + programming course ceballos Fco Javier Sierra To me has served and continues to serve me this book a lot, I find it a gem, and its author is spectacular explains things.

Arduino Internals Muy interesante. Very interesting.

Programming And Customizing The AVR Microcontroller Super interesante una vez te ha picado el mundo de los microcontroladores. Super interesting once you've been bitten by the world of microcontrollers.

Nos vemos en la siguiente entrega. See you in the next installment.

Publicado por Pulse en 13:01 6 comentarios: Enviar por correo electrónicoEscribe un blogCompartir con TwitterCompartir con FacebookCompartir en Pinterest Etiquetas: Arduino, controlador, electronica, MIDI, open hardware, open software, sintetizador

lunes, 8 de octubre de 2012

Primer paso: Editor de texto para trabajar. Actualización: He encontrado este enlace: http://www.mupuf.org/project/arduide.html De una forma muy sencilla podéis instalaros un IDE mucho más completo con respecto a la información que ofrece, rápido y agradable a la hora de compilar.

Primer paso: Un editor de texto para trabajar. Después de la experiencia con el entorno de desarrollo que viene por defecto con el paquete de Arduino, he decidido cambiar y aprovechar para aprender a utilizar Vim. Ahora mismo tal y como lo estoy utilizando es probablemente una de las maneras menos eficientes de utilizarlo,

pero después de un día entero de búsqueda, y con decenas de pruebas fallidas, doy por finalizada la "cacería" hasta otro momento. La configuración y el modo de empleo son relativamente sencillos; En primer lugar se trata de abrir el archivo que vayamos a editar/crear con el editor Vim. Una vez hayamos abierto el archivo, el siguiente paso es abrir el IDE del Arduino y en las preferencias elegir "Usar editor externo".

De esta manera al editar o crear el texto que nos convenga, y una vez hayamos hechas las correcciones pertinentes en nuestro archivo, cuando salvemos el archivo debemos recordar que la extensión que utilizará el IDE de Arduino es .ino. Así que lo salvamos como; 'nombre'.ino Ahora vamos al IDE de Arduino, abrimos el mismo archivo y podremos compilarlo y subirlo a nuestra placa siempre que esté bien. Una de las pequeñas ventajas que de cierta manera nos ofrece esta configuración, es que una vez editemos el archivo y lo guardemos al tener el modo "usar editor externo", el IDE de Arduino nos mostrará los cambios que hayamos realizados en Vim o en el editor que hayamos elegido.

También es cierto que estamos obligados a hacer un paso mas a la hora de trabajar, pero eso ya depende de cada cual.