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. 

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.

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.




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 could solder 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 therefore false 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
 

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 1000 connected 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.







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.