Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MIDI Thru changes data on Atmega32U4 #174

Open
CorjanV opened this issue Sep 16, 2020 · 2 comments
Open

MIDI Thru changes data on Atmega32U4 #174

CorjanV opened this issue Sep 16, 2020 · 2 comments

Comments

@CorjanV
Copy link

CorjanV commented Sep 16, 2020

Hi,

I have some trouble with the MIDI Thru function on a custom atmega32U4 based board. The board checks the keys of a keyboard and send a MIDI signal. Incoming messages are also send thru. This way it is possible to daisy-chain multiple boards.

The hardware is not the problem, I think. I've made some other custom boards based on the atmega32U4 and they work great. But I don't use serial communication on those boards.

What I use to debug:
I have 2 of the custom boards: daisy-chained. Those are connected by a MIDI-USB converter to my PC. I use MIDI-OX to debug.

So: [Board 1] -> [Board 2] -> [MIDI-USB converter] -> [PC] -> [MIDI-OX]
...............|..........................|
...[Keyboard 1] [Keyboard 2]

What does work:
When I press a key on [Keyboard 2], on the MIDI-OX monitor I see a proper Note-On message and when I release I see a proper Note-Off message.

What doesn't work:
When I press a key on [Keyboard 1], on the MIDI-OX monitor I see something totally different. Only when I press a key very fast or multiple at ones, some messages are Note-On/Off. The corresponding data (channel, pitch) are then correct.
image

I can reproduce the problem when I switches [Board 1] with [Board 2].
I use the Leonardo bootloader to set the fuses.

I hope that I provided enough information.

Thanks in advance!
Corjan

@franky47
Copy link
Member

That's very odd indeed, can I have a look at the code ?

@CorjanV
Copy link
Author

CorjanV commented Sep 17, 2020

Yes, sure. Here it is:

#include <MIDI.h>
#include <digitalWriteFast.h>

#define KLAVIER_LED_ON PORTE |= 0b00000100;
#define KLAVIER_LED_OFF PORTE &= ~0b00000100;
#define CH_S1 5
#define CH_S2 13
#define CH_S4 A5
#define CH_S8 A4
#define T0 8
#define T1 9
#define T2 10
#define T3 11
#define T4 A3
#define T5 A2
#define T6 A1
#define T7 A0

#define BR0_STATUS (PIND & 0b00000001) >> 0
#define BR1_STATUS (PIND & 0b00000010) >> 1
#define BR2_STATUS (PINB & 0b00000001) >> 0
#define BR3_STATUS (PINE & 0b01000000) >> 6
#define BR4_STATUS (PIND & 0b00010000) >> 4
#define BR5_STATUS (PIND & 0b00100000) >> 5
#define BR6_STATUS (PIND & 0b01000000) >> 6
#define BR7_STATUS (PIND & 0b10000000) >> 7

MIDI_CREATE_DEFAULT_INSTANCE();

int inputNieuw[64] = {0};
int inputOud[64] = {0};
int i,j,k;
int counter = 0;
int offset = 36;
int kanaal = 0;
int toetsActief = 0;

void setup() 
{ 
  WDT_off();
  WDT_Prescaler_Change();

//  pinMode(KLAVIER_ACT, OUTPUT);
  DDRE |= 0b00000100;
  pinMode(CH_S1, INPUT_PULLUP);
  pinMode(CH_S2, INPUT_PULLUP);
  pinMode(CH_S4, INPUT_PULLUP);
  pinMode(CH_S8, INPUT_PULLUP);

  if(digitalRead(CH_S1) == LOW) kanaal |= 0b0001;
  if(digitalRead(CH_S2) == LOW) kanaal |= 0b0010;
  if(digitalRead(CH_S4) == LOW) kanaal |= 0b0100;
  if(digitalRead(CH_S8) == LOW) kanaal |= 0b1000;

  kanaal++;

  pinMode(T0, OUTPUT);
  pinMode(T1, OUTPUT);
  pinMode(T2, OUTPUT);
  pinMode(T3, OUTPUT);
  pinMode(T4, OUTPUT);
  pinMode(T5, OUTPUT);
  pinMode(T6, OUTPUT);
  pinMode(T7, OUTPUT);
  DDRD &= ~0b11110011;
  DDRB &= ~0b00000001;
  DDRE &= ~0b01000000;

  MIDI.begin(MIDI_CHANNEL_OMNI); // Luister op alle kanalen
  MIDI.turnThruOn(); //Alle inkomende berichten doorsturen
}

void loop() 
{ 
  asm("wdr \n"); // reset 
  MIDI.read();
  
  highMode(); // Lees klavier in met hoge aanslaggevoeligheid (lage aanslaggevoeligheid niet beschikbaar)
  
  for(k=0; k<64; k++)
  {
    if(inputNieuw[k] != inputOud[k])  // alleen als de input is veranderd een MIDI transfer doen
    {
      if(inputNieuw[k] == HIGH) MIDI.sendNoteOn(offset+k,127,kanaal);
      else MIDI.sendNoteOff(offset+k,0,kanaal);
    }
  }
  
  MIDI.read();
  
  copy(inputNieuw, inputOud, 64);
}

void copy(int* src, int* dst, int len) {
    memcpy(dst, src, sizeof(src[0])*len);
}

void maakTPinHoog(int T) {
  if(T==0) {digitalWriteFast(T0, HIGH); digitalWriteFast(T1, LOW); digitalWriteFast(T2, LOW); digitalWriteFast(T3, LOW); digitalWriteFast(T4, LOW); digitalWriteFast(T5, LOW); digitalWriteFast(T6, LOW); digitalWriteFast(T7, LOW);}
  else if(T==1) {digitalWriteFast(T0, LOW); digitalWriteFast(T1, HIGH); digitalWriteFast(T2, LOW); digitalWriteFast(T3, LOW); digitalWriteFast(T4, LOW); digitalWriteFast(T5, LOW); digitalWriteFast(T6, LOW); digitalWriteFast(T7, LOW);}  
  else if(T==2) {digitalWriteFast(T0, LOW); digitalWriteFast(T1, LOW); digitalWriteFast(T2, HIGH); digitalWriteFast(T3, LOW); digitalWriteFast(T4, LOW); digitalWriteFast(T5, LOW); digitalWriteFast(T6, LOW); digitalWriteFast(T7, LOW);}  
  else if(T==3) {digitalWriteFast(T0, LOW); digitalWriteFast(T1, LOW); digitalWriteFast(T2, LOW); digitalWriteFast(T3, HIGH); digitalWriteFast(T4, LOW); digitalWriteFast(T5, LOW); digitalWriteFast(T6, LOW); digitalWriteFast(T7, LOW);}  
  else if(T==4) {digitalWriteFast(T0, LOW); digitalWriteFast(T1, LOW); digitalWriteFast(T2, LOW); digitalWriteFast(T3, LOW); digitalWriteFast(T4, HIGH); digitalWriteFast(T5, LOW); digitalWriteFast(T6, LOW); digitalWriteFast(T7, LOW);}  
  else if(T==5) {digitalWriteFast(T0, LOW); digitalWriteFast(T1, LOW); digitalWriteFast(T2, LOW); digitalWriteFast(T3, LOW); digitalWriteFast(T4, LOW); digitalWriteFast(T5, HIGH); digitalWriteFast(T6, LOW); digitalWriteFast(T7, LOW);}  
  else if(T==6) {digitalWriteFast(T0, LOW); digitalWriteFast(T1, LOW); digitalWriteFast(T2, LOW); digitalWriteFast(T3, LOW); digitalWriteFast(T4, LOW); digitalWriteFast(T5, LOW); digitalWriteFast(T6, HIGH); digitalWriteFast(T7, LOW);}  
  else if(T==7) {digitalWriteFast(T0, LOW); digitalWriteFast(T1, LOW); digitalWriteFast(T2, LOW); digitalWriteFast(T3, LOW); digitalWriteFast(T4, LOW); digitalWriteFast(T5, LOW); digitalWriteFast(T6, LOW); digitalWriteFast(T7, HIGH);}
}

int leesIngangStatus(int BR) {
  if(BR==0) return BR0_STATUS;
  else if(BR==1) return BR1_STATUS;
  else if(BR==2) return BR2_STATUS;
  else if(BR==3) return BR3_STATUS;
  else if(BR==4) return BR4_STATUS;
  else if(BR==5) return BR5_STATUS;
  else if(BR==6) return BR6_STATUS;
  else if(BR==7) return BR7_STATUS;
  else return 0;
}

void highMode(void) {
  toetsActief = 0;
  for(i=0; i<=7; i++)
  {
    MIDI.read();
    maakTPinHoog(i);
    for(j=0; j<=7; j++)
    {
      toetsActief |= leesIngangStatus(j);
      inputNieuw[j*8+i] = leesIngangStatus(j);
    }
  }

  if(toetsActief != 0) KLAVIER_LED_ON
  else KLAVIER_LED_OFF
}

void WDT_off(void)
{
  asm("cli \n"); // turn off global interrupt
  asm("wdr \n"); // reset WDT
  /* Clear WDRF in MCUSR */
  MCUSR &= ~(1<<WDRF);
  /* Write logical one to WDCE and WDE */
  /* Keep old prescaler setting to prevent unintentional time-out
  */
  WDTCSR |= (1<<WDCE) | (1<<WDE);
  /* Turn off WDT */
  WDTCSR = 0x00;
  asm("sei \n"); // turn on global interrupt
}

void WDT_Prescaler_Change(void)
{
  asm("cli \n"); // turn off global interrupt
  asm("wdr \n"); // reset WDT
  /* Start timed equence */
  WDTCSR |= (1<<WDCE) | (1<<WDE);
  /* Set new prescaler(time-out) value = 256K cycles (~2.0 s) */
  WDTCSR = (1<<WDE) | (1<<WDP2) | (1<<WDP1) | (1<<WDP0);
  asm("sei \n"); // turn on global interrupt
}

Sorry for the dunglish language ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants