|
|
View previous topic :: View next topic |
Author |
Message |
zutta1
Joined: 16 Jan 2009 Posts: 3
|
MIDI Controller Message fires INT_RDA only 1 time |
Posted: Fri Jan 16, 2009 10:18 am |
|
|
I'm using a PIC18F4620 for a MIDI-sequenzer project.
I have a very strange problem:
The INT_RDA is fired only the first time when a stream of MIDI controller messages were received (when i turn a potentiometer on my keyboard, it sends continuous packages with the 3 Bytes statebyte+controllernumberbyte+controllerdatabyte). After that, RDA_INT will not be fired again until another message than a controller message (for example midi on: statebyte+note+velocity) is received.
Code: |
#include "18f4620.h"
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=31250, xmit= pin_C6, rcv= pin_C7, ERRORS)
#define LED PIN_A1
#INT_RDA // UART DATA Received
receive_isr(){
int rcv0;
output_bit(LED,!input(LED)); //invert LED
rcv0=getc(); // Byte
} // end start_stop_isr
main(){
set_tris_A(0b11111101);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
while(1){
}// end main loop
}// end main |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jan 16, 2009 1:49 pm |
|
|
If it's not working it's possibly because:
1. The signals may be current loop compatible and not compatible with
the voltage levels required by a PIC UART input pin. They may
require an external circuit to convert them to the proper levels.
2. The input signal levels may be inverted from what you expect to see,
and may require an external circuit to invert them.
3. The input signals may not conform exactly to asynchronous serial
timing standards (start bit, number of stop bits, parity, etc).
4. The baud rate of the signals coming from the keyboard may not
really be 31250.
You need to look at the signals with an oscilloscope.
Or find the documentation for the keyboard's midi output interface
(and post a link to it). |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Jan 16, 2009 4:02 pm |
|
|
Also try changing the line: Code: | output_bit(LED,!input(LED)); //invert LED | to: Code: | output_toggle(LED); //invert LED |
Problem with the original code is that it temporarily changes the output to an input. Reading the voltage at your LED is a more or less random operation, depending on board capacitance, etc. The new code will use the value of the output latch instead. |
|
|
zutta1
Joined: 16 Jan 2009 Posts: 3
|
|
Posted: Tue Jan 20, 2009 3:37 am |
|
|
Thank you for your answer!
I think the failure is somewhere else.
1. I use the standard circuit with optocoupler (schematic: http://www.ucapps.de/mbhp/mbhp_core_v3.pdf)
2./3. I only have the failure when the pic receives continous controller messages (3 bytes: 0xB1, controller number 0-127, controller value 0-127) or when it receives contiuous pitchbend messages (3 bytes: 0xB1, 2nd byte=0, 3rd byte=pitchbendvalue 0-127)
When i receive only note on or note off messages (3 bytes: 0xE1, note nr 0-127, velocity value 0-127) i have no problems, the sequenzer works fine.
For example the scenario n=note message, c=controller message, p=pitchbend message:
the Keyboard sends:
nnnccccccnccccc [waiting 5s] ccccccnnnppppppnccccccppppp
the pic fires the int_rda (i=int_rda) and receives the message:
in in in ic in ic in in in ip in ic ip
the pic waits till an other type of message?!
4. when i connect the keyboard over a midi interface to my computer an use a midi-monitor tool it works fine, it shows every message.
5. I have the same when i use output_toggle(LED) instead of output_bit(LED,!input(LED))
Here is the manual of the keyboard http://www.novationmusic.com/support/files/bass_station_keyboard/94/Bass_Station_keyboard_User_Guide.pdf (on page 14).
I've tried it also with a PIC18F458. |
|
|
yerpa
Joined: 19 Feb 2004 Posts: 58 Location: Wisconsin
|
|
Posted: Tue Jan 20, 2009 11:40 am |
|
|
It doesn't look like all of your code is represented above, but I wonder if there is a problem relating to your definition of "int rcv0" having scope only in the interrupt routine itself. Maybe it should be defined as a global or static variable. Without the rest of the code, it is hard to tell. |
|
|
zutta1
Joined: 16 Jan 2009 Posts: 3
|
|
Posted: Tue Jan 20, 2009 1:14 pm |
|
|
I use the code above only to check when the int_rda is fired. Anyway, the int_rda must be fired each time a byte was received.
Here is the full sequenzer code:
Code: |
//#fuses HS,NOWDT,NOPROTECT,NOLVP
#include "18f4620.h"
//#include "18F458.h"
#fuses HS,NOWDT,NOPROTECT,NOLVP
//#device *=16
#use delay(clock=20000000)
#use rs232(baud=31250, xmit= pin_C6, rcv= pin_C7, ERRORS)
#include "em6125.c"
// DEFINITIONEN #######################################################################
#define DATE "27.12.08"
#define VERSION "0.00"
#define DEBUG // change to RELEASE
#define ENDLESS 1
#define BPMFACT 36621 // 60/(Tclk*8*256*4)
#define TAPFACT 904 // BPMFACT/4
#define TXDELAY 25 // Transmit Delay [ms]
#define BTNDELAY 20 // Entprellzeit Taster
#define INCDELAY 170 // Inkremental Delay
#define TAPDELAY 235 // Entprellzeit Tap-Taster
// 60/BPMmax = 60/256
// Display Konstanten
#define VERTICAL_SPACE 12
#define VALUE_X 72
#define STARTUP_VALUE_X 45
#define RADIX_RUN 3
#define RADIX_MENU 2
#ifndef EEPROM_SDA
#define EEPROM_SDA PIN_B4
#define EEPROM_SCL PIN_B5
#endif
#define EEPROM_ADDRESS long int
#define EEPROM_SIZE 32768
#define START_STOP PIN_B0 // start/stop button
#define TAP PIN_B1
#define BPM_DOWN PIN_D4
#define BPM_UP PIN_D5
#define STEP_DOWN PIN_D6
#define STEP_UP PIN_D7
// #define MENU PIN_B2 //compiler erzeigt fehler wenn sie nicht kommentar sind?!*/
#define COPY_BTN PIN_B3
#define GLIDE_BTN PIN_C2
// #define SET_DOWN PIN_D0
// #define SET_UP PIN_D1
#define PATTERN_DOWN PIN_D2
#define PATTERN_UP PIN_D3
// LED
#define LED PIN_A1
#use i2c(master,sda=EEPROM_SDA, scl=EEPROM_SCL)
// ENUM / TYPE / STRUCT #######################################################################33
enum DISPLAY_MODE{
// STARTUP,
RUN,
MENU/*,
TERMINAL*/
};
enum VALUE_UPDATE{
BPM_V,
SET_V,
PATTERN_V,
STEP_V,
ALL_RUN_V,
MIDI_RX_V,
MIDI_TX_V,
ALL_MENU_V,
CURSET_V
};
// struct
struct VALUE_WINDOW{
int y_pos;
int x_pos;
char name[9];
}
bpm_str={0, 0,"BPM:"},
set_str = {VERTICAL_SPACE,0,"SET:"},
pattern_str = {2*VERTICAL_SPACE,0,"PATTERN:"},
step_str = {3*VERTICAL_SPACE,0,"STEP:"},
midi_rx_str = {0,0,"MIDI RX:",},
midi_tx_str = {VERTICAL_SPACE,0,"MIDI TX:"},
curset_str = {4*VERTICAL_SPACE,0,"CURSET:"};
struct step_struct{ // Struktur für einen Step
int note;
int velocity;
int pitchbend;
int ctrnr;
int ctrdata;
short glide;
};
// Globale Variablen ####################################################################
long time, tapcount;
int clkcount;
char temp_value_string[4];
int mode;
int bpm = 80; // 1-255
int pattern = 0;
int step = 0; // 0-15
int midichrx = 1; // 0-15
int midichtx = 1; // 0-15
short read_flag = 0;
int rcv1, cnt = 0; // Empfangsbuffer
int set = 0;
short seqrun = 0;
short tapstate = 0;
short curset = 0; // Current Set - Zum laden aus dem EEProm kann die eine überschrieben werden während die andere läuft
struct step_struct steps[2][16]; //curset 0 liegt im Speicher vor curset 1
char ready[10]= "Ready... ";
char write[10]= "Writing ";
char copy[10] = "Copying ";
char read[10]= "Reading ";
// DISPLAY FUNKTIONEN ####################################################################
/*******************************************************************************
Convert an Integer to String
*******************************************************************************/
char* IntToStr(int value, int radix){
int i;
int z = 0;
static char temp_string[20];
for(i=0;i<radix;i++){
temp_string[radix-1-i]= (int) (value%10+'0');
value = (int) (value/10);
}// end for
for(i=0;i<radix-1;i++){
if(temp_string[i] =='0' && z==0){ // führende nullen löschen
temp_string[i] = ' ';
} else{
z=1;
}
} // end for
temp_string[radix]='\0';
return temp_string;
} // end getStrFromValue
/*******************************************************************************
clear whole display
*******************************************************************************/
void display_clear(void){
int i;
char temp_string[14]=" ";
for(i=0;i<=5;i++){
em6125_dispString(0,i*16,temp_string,OVERWRITE,BIG);
}
} // end display_clear
/*******************************************************************************
update values in display
*******************************************************************************/
void display_update_value(VALUE_UPDATE vu){
switch(mode){
case(RUN):
switch (vu){
case BPM_V:
em6125_dispString(VALUE_X,bpm_str.y_pos,IntToStr(bpm,RADIX_RUN),OVERWRITE,BIG);
break;
case SET_V:
em6125_dispString(VALUE_X,set_str.y_pos,IntToStr(set,RADIX_RUN),OVERWRITE,BIG);
break;
case PATTERN_V:
em6125_dispString(VALUE_X,pattern_str.y_pos,IntToStr(pattern,RADIX_RUN),OVERWRITE,BIG);
break;
case STEP_V:
em6125_dispString(VALUE_X,step_str.y_pos,IntToStr(step,RADIX_RUN),OVERWRITE,BIG);
break;
case CURSET_V:
em6125_dispString(VALUE_X,curset_str.y_pos,IntToStr(curset,RADIX_RUN),OVERWRITE,BIG);
break;
case ALL_RUN_V:
em6125_dispString(VALUE_X,bpm_str.y_pos,IntToStr(bpm,RADIX_RUN),OVERWRITE,BIG);
em6125_dispString(VALUE_X,set_str.y_pos,IntToStr(set,RADIX_RUN),OVERWRITE,BIG);
em6125_dispString(VALUE_X,pattern_str.y_pos,IntToStr(pattern,RADIX_RUN),OVERWRITE,BIG);
em6125_dispString(VALUE_X,step_str.y_pos,IntToStr(step,RADIX_RUN),OVERWRITE,BIG);
em6125_dispString(VALUE_X,curset_str.y_pos,IntToStr(curset,RADIX_RUN),OVERWRITE,BIG);
break;
default:
break;
}// end switch (vu)
break;
case(MENU):
switch(vu){
case MIDI_RX_V:
em6125_dispString(VALUE_X,midi_rx_str.y_pos,IntToStr(midichrx,RADIX_MENU),OVERWRITE,BIG);
break;
case MIDI_TX_V:
em6125_dispString(VALUE_X,midi_tx_str.y_pos,IntToStr(midichtx,RADIX_MENU),OVERWRITE,BIG);
break;
case ALL_MENU_V:
em6125_dispString(VALUE_X,midi_rx_str.y_pos,IntToStr(midichrx,RADIX_MENU),OVERWRITE,BIG);
em6125_dispString(VALUE_X,midi_tx_str.y_pos,IntToStr(midichtx,RADIX_MENU),OVERWRITE,BIG);
break;
default:
break;
}// end switch(vu)
default:
break;
} // end switch (menu)
} // display_update_value
/*******************************************************************************
Change in other display mode
*******************************************************************************/
void display_set_mode(DISPLAY_MODE disp_mode){
display_clear();
switch(disp_mode){
/* case STARTUP:
mode = disp_mode;
em6125_dispString(title_str.x_pos,title_str.y_pos,title_str.name,OVERWRITE,BIG);
em6125_dispString(date_str.x_pos,date_str.y_pos,date_str.name,OVERWRITE,BIG);
em6125_dispString(date_str.x_pos+STARTUP_VALUE_X,date_str.y_pos,date_str.value,OVERWRITE,BIG);
em6125_dispString(ver_str.x_pos,ver_str.y_pos,ver_str.name,OVERWRITE,BIG);
em6125_dispString(ver_str.x_pos+STARTUP_VALUE_X,ver_str.y_pos,ver_str.value,OVERWRITE,BIG);
#ifdef DEBUG
delay_ms(500);
#else
delay_ms(2000);
#endif
break;
*/
case RUN:
mode = disp_mode;
em6125_dispString(bpm_str.x_pos,bpm_str.y_pos,bpm_str.name,OVERWRITE,BIG);
em6125_dispString(set_str.x_pos,set_str.y_pos,set_str.name,OVERWRITE,BIG);
em6125_dispString(pattern_str.x_pos,pattern_str.y_pos,pattern_str.name,OVERWRITE,BIG);
em6125_dispString(step_str.x_pos,step_str.y_pos,step_str.name,OVERWRITE,BIG);
em6125_dispString(curset_str.x_pos,curset_str.y_pos,curset_str.name,OVERWRITE,BIG);
display_update_value(ALL_RUN_V);
break;
case MENU:
mode = disp_mode;
em6125_dispString(midi_rx_str.x_pos,midi_rx_str.y_pos,midi_rx_str.name,OVERWRITE,BIG);
em6125_dispString(midi_tx_str.x_pos,midi_tx_str.y_pos,midi_tx_str.name,OVERWRITE,BIG);
display_update_value(ALL_MENU_V);
break;
/* case TERMINAL:
#ifdef DEBUG
mode = disp_mode;
// display_terminal_window();
#endif
break;*/
default:
break;
}// end switch
}// end display_set_mode
// EEPROM FUNKTIONEN ####################################################################
void init_ext_eeprom()
{
output_float(EEPROM_SCL);
output_float(EEPROM_SDA);
}
void write_ext_eeprom(long int address, byte data)
{
short int status;
i2c_start();
i2c_write(0xa0);
i2c_write(address>>8);
i2c_write(address);
i2c_write(data);
i2c_stop();
i2c_start();
status=i2c_write(0xa0);
while(status==1){
i2c_start();
status=i2c_write(0xa0);
}
}
byte read_ext_eeprom(long int address) {
byte data;
i2c_start();
i2c_write(0xa0);
i2c_write(address>>8);
i2c_write(address);
i2c_start();
i2c_write(0xa1);
data=i2c_read(0);
i2c_stop();
return(data);
}
// maximale Adresse: 7FFF respektive 32767
void savePattern(int pattern, int1 curpat){
int8 i;
em6125_dispString(5,60,write,OVERWRITE,BIG);
read_flag=1;
for(i=0;i<16;i++){
write_ext_eeprom(i*6+0+pattern*100,steps[curpat][i].note);
write_ext_eeprom(i*6+1+pattern*100,steps[curpat][i].velocity);
write_ext_eeprom(i*6+2+pattern*100,steps[curpat][i].pitchbend);
write_ext_eeprom(i*6+3+pattern*100,steps[curpat][i].ctrnr);
write_ext_eeprom(i*6+4+pattern*100,steps[curpat][i].ctrdata);
write_ext_eeprom(i*6+5+pattern*100,steps[curpat][i].glide);
}
read_flag=0;
em6125_dispString(5,60,ready,OVERWRITE,BIG);
}
void getPattern(int pattern, int1 curpat){
int8 i;
em6125_dispString(5,60,read,OVERWRITE,BIG);
read_flag=1;
for(i=0;i<16;i++){
steps[~curpat][i].note=read_ext_eeprom(i*6+0+pattern*100);
steps[~curpat][i].velocity=read_ext_eeprom(i*6+1+pattern*100);
steps[~curpat][i].pitchbend=read_ext_eeprom(i*6+2+pattern*100);
steps[~curpat][i].ctrnr=read_ext_eeprom(i*6+3+pattern*100);
steps[~curpat][i].ctrdata=read_ext_eeprom(i*6+4+pattern*100);
steps[~curpat][i].glide=read_ext_eeprom(i*6+5+pattern*100);
}
em6125_dispString(5,60,ready,OVERWRITE,BIG);
read_flag=0;
}
// INTERRUPT FUNKTIONEN ####################################################################
#INT_RDA // UART DATA Received
receive_isr(){
int rcv0, step0;
//output_bit(LED,!input(LED)); //invert LED
//static int rcv1, cnt = 0; // 1 = note on/off, 2 = note second byte, 3 = note third byte
// 4 = pitchbend, 5 = pitch second byte, 6 = pitch third byte
// 7 = controller, 8 = cntr second byte, 9 = cntr third byte
rcv0=getc(); // Byte 1 MIDI-Statusbyte
step0=step;
if(rcv0==0x90+midichrx){ // note on/off
cnt=1;
}else if(rcv0==0xE0+midichrx){ // pitchbend
cnt=4;
}else if(rcv0==0xB0+midichrx){ // controller
cnt=8;
}else{
switch(cnt){
case 1: rcv1=rcv0; // note second byte
cnt=2;
break;
case 2: if(rcv0!=0){ // note third byte nur speichern wenn nicht note off
steps[curset][step0].note=rcv1;
steps[curset][step0].velocity=rcv0;
cnt=0;
}else{
cnt=0;
}
break;
case 4: cnt=5; // Pitchbend - second byte immer 0
break;
case 5: steps[curset][step0].pitchbend=rcv0; // Pitchbend third byte
cnt=0;
break;
case 8: steps[curset][step0].ctrnr=rcv0; // Controller second byte
cnt=9;
break;
case 9: steps[curset][step0].ctrdata=rcv0; // controller third byte
cnt=0;
break;
default: break;
} // end switch
} //end else
} // end start_stop_isr
#INT_EXT //INT0 on B0 start/stop
start_stop_isr(){
seqrun=!seqrun;
while(input(START_STOP)==1){
delay_ms(BTNDELAY);
}
delay_ms(BTNDELAY);
} // end start_stop_isr
#INT_EXT1 //INT0 on B0 start/stop
taptaste_isr(){
if(tapstate==0){
tapcount=0;
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8); //=> T= 1.6 us
set_timer1(65536-255);
tapstate=1;
}else{
if(tapcount>576){ //max BPM=255
time=65536-(long)(tapcount/4);
BPM= (int)(TAPFACT/tapcount);
display_update_value(BPM_V); // Display BPM aktualisieren
tapstate=0;
tapcount=0;
}
}
} // end tap_isr
#INT_TIMER1 // has to be in front of isr
tap_isr() { // TAP Timer
set_timer1(65536-255); // reload timer overflow after 409.6us
if(++tapcount==7320){ //min BPM=20
tapstate=0;
tapcount=0;
setup_timer_1(T1_DISABLED);
}
}
#INT_TIMER3 // has to be in front of isr
bpm_isr() { // isr bpm (mit doppelter bpm geschwindigkeit)
static short flag=1;
set_timer3(time); // reload timer for 1ms
if(--clkcount==0){
clkcount = 255;
if(flag==1){
flag=0;
output_bit(LED,!input(LED)); //invert LED on every 2nd clk;
}else{
flag=1;
}
if(seqrun==1){
if(step>=16){
step = 0;
putc(0x90 + midichtx); // Byte 1, Note Off
putc(steps[curset][15].note); // Byte 2, Note
putc(0); // Byte 3, 0 für NoteOFF
if(read_flag==1){
curset=~curset;
}
}else{
putc(0x90 + midichtx); // Byte 1, Note Off
putc(steps[curset][step-1].note); // Byte 2, Note
putc(0); // Byte 3, 0 für NoteOFF
}
putc(0x90 + midichtx); // Byte 1, Note On
putc(steps[curset][step].note); // Byte 2, Note
putc(steps[curset][step].velocity); // Byte 3, Anschlagsdynamik
if(steps[curset][step].pitchbend<128){ // nur ausgeben wenn daten vorhanden
putc(0xE0 + midichtx); // Byte 1, Note On
putc(0); // Byte 2, Wert
putc(steps[curset][step].pitchbend); // Byte 3, Wert
}
if(steps[curset][step].ctrnr<128){ // nur ausgeben wenn daten vorhanden
putc(0xB0 + midichtx); // Byte 1, Note On
putc(steps[curset][step].ctrnr); // Byte 2, Ctr.Nr.
putc(steps[curset][step].ctrdata); // Byte 3, Ctr.Data
}
display_update_value(STEP_V); // Display STEP aktualisieren
++step;
}else{
putc(0x90 + midichtx); // Byte 1, Note Off
putc(steps[curset][step-1].note); // Byte 2, Note
putc(0); // Byte 3, 0 für NoteOFF
}
}
}
// DIVERSE FUNKTIONEN ####################################################################
// Directions
void port_init(void){ // set IN, BI, and OPEN PORTS as INPUT, OUT as OUTPUT
set_tris_A(0b11111101);
set_tris_B(0b11011111);
set_tris_C(0b10100101);
set_tris_D(0b11111111);
}
void init_interrupts(void){
time = 65536 - (long)(BPMFACT/bpm);
setup_timer_3(T3_INTERNAL | T3_DIV_BY_8); //=> T= 1.6 us
setup_timer_1(T1_DISABLED);
ext_int_edge(0,L_TO_H); // START/STOP interrupt
ext_int_edge(1,L_TO_H); // TAP interrupt
set_timer3(time);
enable_interrupts(INT_EXT);
enable_interrupts(INT_EXT1);
enable_interrupts(INT_TIMER3); // enable Timer3 interrupt
enable_interrupts(INT_TIMER1); // enable Timer3 interrupt
enable_interrupts(INT_RDA); // enable UART Receive interrupt
enable_interrupts(GLOBAL); // allows previously enabled interrupt
}
void actbpm(){
time = 65536 - (long)(BPMFACT/bpm);
}
void copyPattern(int1 curpat){
int8 i;
em6125_dispString(5,60,copy,OVERWRITE,BIG);
for(i=0;i<16;i++){
steps[~curpat][i].note = steps[curpat][i].note;
steps[~curpat][i].velocity = steps[curpat][i].velocity;
steps[~curpat][i].pitchbend = steps[curpat][i].pitchbend;
steps[~curpat][i].ctrnr = steps[curpat][i].ctrnr;
steps[~curpat][i].ctrdata = steps[curpat][i].ctrdata;
steps[~curpat][i].glide = steps[curpat][i].glide;
}
em6125_dispString(5,60,ready,OVERWRITE,BIG);
}
void reset_steps(){
int i,j;
for(i=0; i<16; i++){
for(j=0; j<2; j++){
steps[j][i].note=50+i;;
steps[j][i].velocity=127;
steps[j][i].pitchbend=255;
steps[j][i].ctrnr=255;
}
}
}
// MAIN ####################################################################
main(){
int s;
port_init(); // ports initialisieren
reset_steps();
init_interrupts(); // start/stop button + timer 0 for bpm
em6125_init(); // Display initialisieren
init_ext_eeprom();
//display_set_mode(STARTUP); // Startup picture (500ms @DEBUG, 3s @RELEASE)
display_set_mode(MENU); // MENU Window with default values for(midichrx, midichtx)
delay_ms(1000); //3 s delay
//midi rx nicht verstellen!!!!!!!!
display_set_mode(RUN); // RUN Window with default values for(bpm,pattern, step, set)
while(1){
if(input(STEP_UP)==1){
if(step==15){
step=0;
}else{
step++;
}
delay_ms(BTNDELAY);
while(input(STEP_UP)==1){
delay_ms(BTNDELAY);
}
display_update_value(STEP_V); // Display STEP aktualisieren
}
if(input(STEP_DOWN)==1){
if(step==0){
step=15;
}else{
step--;
}
delay_ms(BTNDELAY);
while(input(STEP_DOWN)==1){
delay_ms(BTNDELAY);
}
display_update_value(STEP_V); // Display STEP aktualisieren
}
if(input(BPM_UP)==1){
while(input(BPM_UP)==1){
BPM++;
display_update_value(BPM_V); // Display BPM aktualisieren
delay_ms(INCDELAY);
}
actbpm();
}
if(input(BPM_DOWN)==1){
while(input(BPM_DOWN)==1){
BPM--;
display_update_value(BPM_V); // Display BPM aktualisieren
delay_ms(INCDELAY);
}
actbpm();
}
if(input(PATTERN_DOWN)==1){
pattern--;
display_update_value(PATTERN_V); // Display BPM aktualisieren
delay_ms(INCDELAY);
}
if(input(PATTERN_UP)==1){
pattern++;
display_update_value(PATTERN_V); // Display BPM aktualisieren
delay_ms(INCDELAY);
}
if(input(COPY_BTN)==0){
savePattern(pattern,curset);
delay_ms(INCDELAY);
}
if(input(GLIDE_BTN)==0){
getPattern(pattern,curset);
curset=~curset;
delay_ms(INCDELAY);
}
}// end main loop
}// end main
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jan 20, 2009 2:22 pm |
|
|
Strip the program down to a test program. Use Ex_Sisr.c as the basis
of the test program. Incoming bytes from the Midi keyboard will be
put in a buffer. In a while() loop in main(), poll to see if byte is in the
buffer. If so, get it from the buffer by using bgetc(), and display it in
ASCII hex format on your terminal program, by using "%X" in printf.
Now send some messages from the keyboard. Look at the displayed
hex bytes on the terminal window. See if they are correct. This simple
test will tell you if you can successfully do basic communication with the
keyboard. Once you have that part working, then you can do the rest
of your program. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|