PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Arduino Midi BPM und Midi-stop auslesen



Cysign
24.04.2020, 03:59
Hallo zusammen,
ich versuche grade per Arduino ein Midi-Signal zum synchronisieren auszulesen.

Hierbei kommt es mir nur auf die BPM, start/stop und das Synchronisieren an. Notenwerte und sonstige Controllerwerte können ignoriert werden.


Ich nutze Softserial um den Midiport abzufragen, da ich meinen Arduino Nano per USB zum debuggen/programmieren am Rechner habe.
Sollte der Sketch fertig sein, kann ich auch gerne auf den Hardware-RX-Pin umsatteln (kann per Jumper zwischen D0 und D4 wählen).


#include <MIDI.h>
#include <SoftwareSerial.h>

SoftwareSerial softSerial(4,5); // pin 4 = optocoupler from midi // pin 5 NC
MIDI_CREATE_INSTANCE(SoftwareSerial, softSerial, midiB);

int counter = 0;
int tempZahl = 0;
unsigned long lastMidiMsg = 0;
unsigned long newMidiMsg = 0;
unsigned long midiPeriod = 0;

float teilBar = 0;


void setup()
{
// Initiate MIDI communications, listen to all channels
midiB.begin(MIDI_CHANNEL_OMNI);
// initiate serial connection
Serial.begin(115200);

midiB.read();
//Serial.print(++counter); Serial.print(millis());
lastMidiMsg = newMidiMsg;
newMidiMsg = millis();
midiPeriod = (newMidiMsg - lastMidiMsg);

/*
if (midiB.getType() == 250){
Serial.println(midiB.getType());
Serial.println(midiB.getData1());
Serial.println(midiB.getData2());
Serial.println(midiB.getChannel());
Serial.println(" - - - ");
}
*/

}

void loop(){
if (midiB.read())
tempZahl = midiB.getType();

if (tempZahl == 250){
Serial.println("Midi start");
}

if (tempZahl == 252){
Serial.println("Midi stop");
}
}

Mit dem Code bekomme ich scheinbar zuverlässig ein "Midi start" ausgespuckt.
Der Stop-Befehl wiederholt sich scheinbar immer wieder, während mein Synthie pausiert ist.

Die Ausgabe von 1x Star und 1x stop drücken sieht wie folgt aus:


Midi start
Midi stop
Midi stop
Midi stop
Midi stop
Midi stop
Midi stop
Midi stop
Midi stop
Midi stop
Midi stop
Midi stop
Midi stop
Midi stop
Midi stop
Midi stop
Midi stop
Midi stop


Ich verstehe noch nicht, warum hier mehrfach stop gesendet wird...Auch wenn mein ROland JD Xi eigentlich weiter läuft, wird ein Stop gesendet.

ber viel wichtiger:
Gesucht: Midi BPM
...damit ich das als ClickSync für einen Pocket Operator ausgeben kann (ClickSync = 2,5ms Impulse in doppelter BPM-Rate bei 1V, siehe: https://p0k3t0.wordpress.com/2017/10/18/pocket-operator-signals/).

Ich muss also nun irgendwie die BPM ermitteln und dann ein Click-Sync-Signal für meinen Pocket Operator erstellen.
Allerdings komm ich hier grade nicht weiter.

- - - Aktualisiert - - -

Okay, die BPM bekomme ich nun dank des Quellcodes dieses Beispiels zuverlässig ausgelesen:
https://www.youtube.com/watch?v=Su6NhtEoipg (https://www.youtube.com/watch?v=Su6NhtEoipg)

Ich hau mich in die Falle und nacher muss ich noch das ClickSync-Signal berechnen und zum Midi synchronisieren.
Das sollte aber hoffentlich nicht mehr all zu schwer sein ;)

Siro
24.04.2020, 07:55
Guten Morgen Cysign,
ich glaube Dir sind einfach nur die Klammern verrutscht:
ich habe das mal etwas geschoben, dann leuchtet es Dir auch sicherlich auch ein:


void loop(){
if (midiB.read())
tempZahl = midiB.getType();

if (tempZahl == 250)
{
Serial.println("Midi start");
}

if (tempZahl == 252) // hier kommt er IMMER an, weil das letzte Byte das STOP war......
{
Serial.println("Midi stop");
}
}


// es sollte sicherlich so sein:

void loop()
{
if (midiB.read())
{
tempZahl = midiB.getType();

if (tempZahl == 250)
{
Serial.println("Midi start");
}

if (tempZahl == 252){
Serial.println("Midi stop");
}
}

Cysign
24.04.2020, 15:33
Super, danke für den Hinweis ;)
Wenn man sich die Nacht über an so nem Projekt festbeißt kommt dann doch irgendwann die Müdigkeit ;)

Aber mit dem verlinkten Code oben konnte ich direkt fehlerfrei die BPM angeben lassen.
Jetzt muss ich nur noch den Startzeitpunkt für meine Intervalle abpassen (ich vermute, das ist das 248-Command) und dazu passend mein ClickSync-Signal erzeugen (für nen Pocket Operator, 2,5ms 1V, doppelte BPM als Intervall).

wkrug
25.04.2020, 08:16
Ich hab mal ein MiDi Metronom gebastelt.
Hier nur mal der Quelltext, die Sound Dateien usw. hab ich mal nicht mit hochgeladen - zu groß.
Und das File ist für das ATMEL Studio 7:

/*
* MiDi_Metronom.c
*
* Created: 11.12.2018 17:06:18
* Author : Krug, Wilhelm
* Version: 1.0
*/

/*
ATMEGA 328P Pin Belegung
Pin Name Funktion
1 PC6 Reset
2 PD0 MiDi IN
3 PD1
4 PD2
5 PD3 Test Taster
6 PD4 Sound Auswahl 1
7 VCC
8 GND
9 XTAL1
10 XTAL2
11 PD5 Sound Auswahl 2
12 PD6 PWM Sound Out
13 PD7
14 PB0 Taktauswahl 0
15 PB1 Taktauswahl 1
16 PB2 Taktauswahl 2
17 PB3 Taktauswahl 3
18 PB4 Taktauswahl 4
19 PB5 Taktauswahl 5
20 AVCC
21 AREF
22 GND
23 PC0 LED 1 Ausgang ( Rot )
24 PC1 LED 2 Ausgang ( Gruen )
25 PC2 LED 3 Ausgang ( Gruen )
26 PC3 LED 4 Ausgang ( Gruen )
27 PC4 LED MiDi aktiv LED ( Rot )
28 PC5
*/

#define F_CPU 20000000

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "sound.c"

//Zähler, Counter und Flags
volatile uint8_t midistate = 0; //MiDi Status Metronom Ein / Aus
volatile uint8_t midiclocks = 0; //Zähler für empfangene MiDi Clocks
volatile uint8_t beatcomplete = 0; //24 MiDi Clocks wurden Empfangen ein Takt ist zu Ende
volatile uint8_t beatcounter = 0; //Zähler für die Takte
#define statestop 0
#define staterun 1

//LED Section
#define LED0 PORTC |=0b00000001
#define LED1 PORTC |=0b00000010
#define LED2 PORTC |=0b00000100
#define LED3 PORTC |=0b00001000
#define LED_MIDI PORTC |=0b00010000
#define LED_MIDI_OFF PORTC &=0b11101111
#define LEDOFF PORTC &=0b11110000
volatile uint8_t ledcount = 0;
#define ledlen 12
volatile uint8_t midiled = 0;
#define midiledlen 2

//MiDi Kommandos
#define MIDI_START 0xFA
#define MIDI_STOP 0xFC
#define MIDI_CLOCK 0xF8
#define MIDI_CONTINUE 0xFB

//Schalter und Tasten Definitionen
#define sel_clock0 (PINB & 0b00000001) //Stumm
#define sel_clock1 (PINB & 0b00000010) //Jeder dritte Beat Sound 1
#define sel_clock2 (PINB & 0b00000100) //Jeder vierte Beat Sound 1
#define sel_clock3 (PINB & 0b00001000) //Jeder Beat Sound 1 ( 1/4 )
#define sel_clock4 (PINB & 0b00010000) //Beat1 = Sound 1 Beat2 = Sound 2 ( 2/4 )
#define sel_clock5 (PINB & 0b00100000) //Beat1 = Sound 1 Beat 2 + 3 = Sound 2 ( 3/4 )
#define sel_clock6 (PINB & 0b00111111) //Beat1 = Sound 1 Beat 3 = Sound 2 ( 2/2 = halbe Geschwindigkeit
#define test_switch (PIND & 0b00001000) //Der Test Taster wurde gedrückt PINB3 = 0
#define sel_sound (PIND & 0b00110000) //Beat1 = Sound 1 Beat 2...4 = Sound 2 ( 4/4 )

#define sound0 0b00000000 //Fehler keine gültige Auswahl
#define sound1 0b00010000 //Klassisches Metronom
#define sound2 0b00110000 //Ableton Metronom
#define sound3 0b00100000 //Percussion Metronom

//USART Section
#define FRAMING_ERROR (1<<FE0)
#define PARITY_ERROR (1<<UPE0)
#define DATA_OVERRUN (1<<DOR0)
#define DATA_REGISTER_EMPTY (1<<UDRE0)
#define RX_COMPLETE (1<<RXC0)

// USART Receiver buffer
#define RX_BUFFER_SIZE 255
char rx_buffer[RX_BUFFER_SIZE];

#if RX_BUFFER_SIZE<256
unsigned char rx_wr_index,rx_rd_index,rx_counter;
#else
unsigned int rx_wr_index,rx_rd_index,rx_counter;
#endif

// This flag is set on USART Receiver buffer overflow
volatile uint8_t rx_buffer_overflow;

//Timer 2 Overflow Vektor wird alle 819µs aufgerufen
ISR (TIMER2_OVF_vect)
{
if(ledcount > 0 )
{
ledcount --;
}
else
{
LEDOFF;
}
if(midiled > 0)
{
midiled --;
}
else
{
LED_MIDI_OFF;
}
}

ISR (USART_RX_vect)
{
uint8_t status,data;
status=UCSR0A;
data=UDR0;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
LED_MIDI; //MiDi Datenempfang Status LED
midiled = midiledlen;
switch(data)
{
case MIDI_START:
midiclocks = 0; //Neuer Start, alle Zähler auf 0
beatcounter = 1;
midistate = staterun; //MiDi Status auf running
beatcomplete = 1; //Ein Beat ist komplett -> Aktion ausführen
break;

case MIDI_STOP: //MiDi Clocks wurden gestoppt
midistate = statestop;
break;

case MIDI_CLOCK:
if(midistate > statestop)
{
midiclocks++;
if(midiclocks > 23)
{
beatcomplete = 1; //Ein Beat ist komplett -> Aktion ausführen
beatcounter++; //Beats hochzählen, werden bei der Taktauswahl wieder zurückgesetzt
midiclocks = 0; //Ein neuer Zählzyklus beginnt
}
}

break;

case MIDI_CONTINUE:
midistate = staterun; //Die Metronomausgabe wird fortgesetzt
break;

}
}
}

//Metronomtakt Hauptschlag Metronomsound
void play_metro1 (void)
{
uint16_t i = 0;
for(i=0;i<metro1_wav_len;i++)
{
OCR0A = pgm_read_byte (&metro1_wav[i]);
_delay_us(90);
}
OCR0A = 0x7F;
}

//Metronomtakt Nebenschlag Metronomsound
void play_metro2 (void)
{
uint16_t i = 0;
for(i=0;i<metro2_wav_len;i++)
{
OCR0A = pgm_read_byte (&metro2_wav[i]);
_delay_us(90);
}
OCR0A = 0x7F;
}

//Metronomtakt Hauptschlag ABLETON Metronom Sound
void play_able1 (void)
{
uint16_t i = 0;
for(i=0;i<able1_wav_len;i++)
{
OCR0A = pgm_read_byte (&able1_wav[i]);
_delay_us(90);
}
OCR0A = 0x7F;
}

//Metronomtakt Nebenschlag ABLETON Metronom Sound
void play_able2 (void)
{
uint16_t i = 0;
for(i=0;i<able2_wav_len;i++)
{
OCR0A = pgm_read_byte (&able2_wav[i]);
_delay_us(90);
}
OCR0A = 0x7F;
}

//Metronomtakt Hauptschlag Trommelsound
void play_drum1 (void)
{
uint16_t i = 0;
for(i=0;i<drum1_wav_len;i++)
{
OCR0A = pgm_read_byte (&drum1_wav[i]);
_delay_us(90);
}
OCR0A = 0x7F;
}

//Metronomtakt Nebenschlag Trommelsound
void play_drum2 (void)
{
uint16_t i = 0;
for(i=0;i<drum1_wav_len;i++)
{
OCR0A = pgm_read_byte (&drum2_wav[i]);
_delay_us(90);
}
OCR0A = 0x7F;
}

//Metronomtakt Hauptschlag Beckensound
void play_ride_high (void)
{
uint16_t i = 0;
for(i=0;i<ride_high_wav_len;i++)
{
OCR0A = pgm_read_byte (&ride_high_wav[i]);
_delay_us(90);
}
OCR0A = 0x7F;
}

//Metronomtakt Nebenschlag Beckensound
void play_ride_low (void)
{
uint16_t i = 0;
for(i=0;i<ride_low_wav_len;i++)
{
OCR0A = pgm_read_byte (&ride_low_wav[i]);
_delay_us(90);
}
OCR0A = 0x7F;
}

//LED und Soundausgabe je nach eingestelltem Wunschsound
void setoutput (uint8_t takt)
{
ledcount = ledlen;
switch(takt)
{
case 1: //Erster Takt = Start Sound + LED 1
LED0;
if(sel_sound == sound1){play_metro1();}
if(sel_sound == sound2){play_able1();}
if(sel_sound == sound3){play_drum1();} //Parken!
//if(sel_sound == sound3){play_ride_high();}
break;

case 2: //Zweiter Takt = anderer Sound + LED 2
LED1;
if(sel_sound == sound1){play_metro2();}
if(sel_sound == sound2){play_able2();}
if(sel_sound == sound3){play_drum2();}
//if(sel_sound == sound3){play_ride_low();}
break;

case 3: //Dritter Takt = anderer Sound + LED 3
LED2;
if(sel_sound == sound1){play_metro2();}
if(sel_sound == sound2){play_able2();}
if(sel_sound == sound3){play_drum2();}
//if(sel_sound == sound3){play_ride_low();}
break;

case 4: //Vierter Takt = anderer Sound + LED 4
LED3;
if(sel_sound == sound1){play_metro2();}
if(sel_sound == sound2){play_able2();}
if(sel_sound == sound3){play_drum2();}
//if(sel_sound == sound3){play_ride_low();}
break;

default: //Fehler es wurde einungültiger Wert übergeben
beatcounter = 0;
}
}

//Taktmassabfrage und Verwaltung der Ausgabe
void sel_takt ( void )
{

//Jeder dritte Takt
if(sel_clock0 == 0)
{
if(beatcounter == 1){setoutput(beatcounter);}
if(beatcounter > 2){beatcounter = 0;}
}
//Jeder vierte Takt
if(sel_clock1 == 0)
{
if(beatcounter == 1){setoutput(beatcounter);}
if(beatcounter > 3){beatcounter = 0;}
}
//Jeder Takt
if(sel_clock2 == 0)
{
if(beatcounter > 1){beatcounter = 0;} //Fehler beim Umschalten abfangen
if(beatcounter == 1)
{
setoutput(beatcounter);
beatcounter = 0;

}

}
//2/4 Takt
if(sel_clock3 == 0)
{
if(beatcounter == 1){setoutput(beatcounter);}
if(beatcounter > 1)
{
setoutput(beatcounter);
beatcounter = 0;
}
}
//3/4 Takt
if(sel_clock4 == 0)
{
if(beatcounter == 1){setoutput(beatcounter);}
if(beatcounter == 2){setoutput(beatcounter);}
if(beatcounter > 2)
{
setoutput(beatcounter);
beatcounter = 0;
}
}
//4/4 Takt
if(sel_clock5 == 0)
{
if(beatcounter == 1){setoutput(beatcounter);}
if(beatcounter == 2){setoutput(beatcounter);}
if(beatcounter == 3){setoutput(beatcounter);}
if(beatcounter > 3)
{
setoutput(beatcounter);
beatcounter = 0;
}
}
//Alla Breve Takt 2/2 = Halbe Geschwindigkeit
if(sel_clock6 == 63)
{
if(beatcounter == 1){setoutput(beatcounter);}
//if(beatcounter == 2){setoutput(beatcounter);}
if(beatcounter == 3){setoutput(beatcounter);}
if(beatcounter > 3)
{
//setoutput(beatcounter);
beatcounter = 0;
}
}
}

//Test Taster ist gedrueckt = Testausgabe
void testausgabe ( void )
{
beatcounter = 1;
while (test_switch == 0)
{
sel_takt(); //Ausgabe starten
beatcounter++; //Der Takt wird hochgezählt
LED_MIDI; //MiDi Datenempfang Status LED - Hier für Testzwecke!
midiled = midiledlen;
_delay_ms(425);
}
beatcounter = 0;
}

int main(void)
{
//uint8_t i = 0;
// Input/Output Ports initialization
// Port B initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (0<<DDB0);
// State: Bit7=T Bit6=T Bit5=P Bit4=P Bit3=P Bit2=P Bit1=P Bit0=P
PORTB=(0<<PORTB7) | (0<<PORTB6) | (1<<PORTB5) | (1<<PORTB4) | (1<<PORTB3) | (1<<PORTB2) | (1<<PORTB1) | (1<<PORTB0);

// Port C initialization
// Function: Bit6=In Bit5=In Bit4=In Bit3=Out Bit2=Out Bit1=Out Bit0=Out
DDRC=(0<<DDC6) | (0<<DDC5) | (1<<DDC4) | (1<<DDC3) | (1<<DDC2) | (1<<DDC1) | (1<<DDC0);
// State: Bit6=T Bit5=T Bit4=T Bit3=0 Bit2=0 Bit1=0 Bit0=0
PORTC=(0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);

// Port D initialization
// Function: Bit7=In Bit6=Out Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In
DDRD=(0<<DDD7) | (1<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
// State: Bit7=T Bit6=0 Bit5=P Bit4=P Bit3=P Bit2=T Bit1=T Bit0=T
PORTD=(0<<PORTD7) | (0<<PORTD6) | (1<<PORTD5) | (1<<PORTD4) | (1<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 20000,000 kHz
// Mode: Fast PWM top=0xFF
// OC0A output: Non-Inverted PWM
// OC0B output: Disconnected
// Timer Period: 0,0128 ms
// Output Pulse(s):
// OC0A Period: 0,0128 ms Width: 0 us
TCCR0A=(1<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (1<<WGM01) | (1<<WGM00);
TCCR0B=(0<<WGM02) | (0<<CS02) | (0<<CS01) | (1<<CS00);
TCNT0=0x00;
OCR0A=0x7F;
OCR0B=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Disconnected
// OC1B output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (0<<CS12) | (0<<CS11) | (0<<CS10);
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: 312,500 kHz
// Mode: Normal top=0xFF
// OC2A output: Disconnected
// OC2B output: Disconnected
// Timer Period: 0,8192 ms
ASSR=(0<<EXCLK) | (0<<AS2);
TCCR2A=(0<<COM2A1) | (0<<COM2A0) | (0<<COM2B1) | (0<<COM2B0) | (0<<WGM21) | (0<<WGM20);
TCCR2B=(0<<WGM22) | (1<<CS22) | (0<<CS21) | (0<<CS20);
TCNT2=0x00;
OCR2A=0x00;
OCR2B=0x00;

// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=(0<<OCIE0B) | (0<<OCIE0A) | (0<<TOIE0);

// Timer/Counter 1 Interrupt(s) initialization
TIMSK1=(0<<ICIE1) | (0<<OCIE1B) | (0<<OCIE1A) | (0<<TOIE1);

// Timer/Counter 2 Interrupt(s) initialization
TIMSK2=(0<<OCIE2B) | (0<<OCIE2A) | (1<<TOIE2);

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// Interrupt on any change on pins PCINT0-7: Off
// Interrupt on any change on pins PCINT8-14: Off
// Interrupt on any change on pins PCINT16-23: Off
EICRA=(0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
EIMSK=(0<<INT1) | (0<<INT0);
PCICR=(0<<PCIE2) | (0<<PCIE1) | (0<<PCIE0);

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: Off
// USART0 Mode: Asynchronous
// USART Baud Rate: 31250
UCSR0A=(0<<RXC0) | (0<<TXC0) | (0<<UDRE0) | (0<<FE0) | (0<<DOR0) | (0<<UPE0) | (0<<U2X0) | (0<<MPCM0);
UCSR0B=(1<<RXCIE0) | (0<<TXCIE0) | (0<<UDRIE0) | (1<<RXEN0) | (0<<TXEN0) | (0<<UCSZ02) | (0<<RXB80) | (0<<TXB80);
UCSR0C=(0<<UMSEL01) | (0<<UMSEL00) | (0<<UPM01) | (0<<UPM00) | (0<<USBS0) | (1<<UCSZ01) | (1<<UCSZ00) | (0<<UCPOL0);
UBRR0H=0x00;
UBRR0L=0x27;

// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator's positive input is
// connected to the AIN0 pin
// The Analog Comparator's negative input is
// connected to the AIN1 pin
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);
ADCSRB=(0<<ACME);
// Digital input buffer on AIN0: On
// Digital input buffer on AIN1: On
DIDR1=(0<<AIN0D) | (0<<AIN1D);

// ADC initialization
// ADC disabled
ADCSRA=(0<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) | (0<<ADIE) | (0<<ADPS2) | (0<<ADPS1) | (0<<ADPS0);

// SPI initialization
// SPI disabled
SPCR=(0<<SPIE) | (0<<SPE) | (0<<DORD) | (0<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (0<<SPR0);

// TWI initialization
// TWI disabled
TWCR=(0<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWEN) | (0<<TWIE);

// Globally enable interrupts
sei();

//Main Loop
while (1)
{
//Der Test Taster ist gedrückt = Probeausgabe
if (test_switch == 0)
{
testausgabe();
}

//Ein neuer Metronomtakt muss ausgegeben werden
if ((midistate > 0) && (beatcomplete > 0 ))
{
sel_takt();
beatcomplete = 0;
}

}
}




Über einen Schalter kann die Taktart eingestellt werden über einen 3 Stufen Wechselschalter der Sound.
Anzeige oder sowas ist hier nicht mit drin!

Cysign
04.05.2020, 01:38
So, mein Plan hat funktioniert. Ich kann jetzt per Midi start/stop und BPM auslesen und damit einen Pocket Operator steuern:
https://www.youtube.com/watch?v=RIpqoiIKZzY&feature=youtu.be