Hey there,
I have programmed a sequencer which works with a timer.
This timer is set to have an compare match interrupt and a normal overflow interrupt.
the overflow interrupt sets the outputs of my device to the level i programmed in the sequencer and then 1 ms later all outputs will be set to low again by the compare match interrupt routine.
Now this is all good, when the sequencer plays standalone. But I want it to be Midi synced, so i thought:
just take the midi_clock to trigger outputs. But the trigger pulse length should still be 1ms (or another specific time i set) so i still need some timer actions here.
I want to set the 16bit timer to 65536 then start it, so the overflow function is triggered instantly.
Then when the compare match function is called the timer gets stopped and all outputs will be set to 0 again.
this process should happen on every step. but it just wont work !
the output pulses arent 1 ms long (much shorter) and the compare match function gets called intstantly.
To test when it will be called, i set it so it should react much later, because it is set to a high value.
this is the code :
//TIMER3 EINRICHTEN
noInterrupts();
TIMSK3 = 0;
TCCR3A = 0;
TCCR3B = 0;
ASSR &= ~(1<<AS2);
/* Setze Prescaler auf 64 */
TCCR3B |= ((1<<CS31) | (1<<CS30)); // Setze bit CS32
TCCR3B &= ~(1<<CS32); // Setze Bit CS31 und Bit CS30 auf 0
interrupts();
...
loadByte(); //loads the byte "outputs";
//STARTUP LIGHTSHOW
display_values(1,2,3,active_channel);
display_bars(ProgramSequenceTakt);
setTempo();
setTriggerLength();
TCNT3 = 65536;
OCR3AH = cpmatch_l;
OCR3AL = cpmatch_h;
}
/* TIMER ROUTINEN */
ISR(TIMER3_OVF_vect) {
PORTK = outputs;
if (midi_sync==true) {
TCNT3 = 1;
OCR3AH = cpmatch_h;
OCR3AL = cpmatch_l;
TIMSK3 |= (1<<OCIE3A);
} else {
display_values(9,5,3,3);
TCNT3 = tcnt3;
OCR3AH = cpmatch_h;
OCR3AL = cpmatch_l;
}
clock = true;
}
ISR(TIMER3_COMPA_vect) // Interrupt service run when Timer/Counter2 reaches OCR2A
{
PORTK=0b00000000;
if (midi_sync) {
Timer3(false);
TCNT3=65536;
}
}
/*
------------------------------------------------------------------------------------
LOOP FUNKTION
------------------------------------------------------------------------------------
*/
void loop() {
if (clock == true) {
setLeds();
if (ProgramSequenceTakt == PlaySequenceTakt) {
if(aufloesung == 1) {
if (Step > 15) {
if (first16==false) {
digitalWrite(StepLedPINS[Step-16], !(ReadValue(play_sequence,PlaySequenceTakt,active_channel,Step,false)));
}
} else {
if (first16) {
digitalWrite(StepLedPINS[Step], !(ReadValue(play_sequence,PlaySequenceTakt,active_channel,Step,false)));
}
}
} else {
digitalWrite(StepLedPINS[(Step/aufloesung)], !(ReadValue(play_sequence,PlaySequenceTakt,active_channel,Step,false)));
}
}
loadByte();
clock = false;
if (Step < 31) {
Step++;
} else {
Step=0;
if (PlaySequenceTakt < loopend[play_sequence]) {
PlaySequenceTakt++;
} else {
PlaySequenceTakt = loopstart[play_sequence];
}
}
}
Button_Check();
Button_Process();
if (Serial.available() > 0) {
incomingByte = Serial.read();// read the incoming byte:
if (incomingByte == midi_start){
if (midi_sync == false) {
midi_sync = true;
tcnt3=1;
setTriggerLength();
TCNT3=65536;
OCR3AH = cpmatch_h;
OCR3AL = cpmatch_l;
}
digitalWrite(PlayPauseLedPIN, HIGH);
} else if (incomingByte == midi_stop) {
midi_sync = false;
TIMSK3 &= ~(1<<TOIE3);
digitalWrite(PlayPauseLedPIN, LOW);
} else if (incomingByte == midi_clock) {
if (midi_sync) {
if (midi_clock_count == 0) {
TIMSK3 |= (1<<TOIE3);
}
if (midi_clock_count < 2) {
midi_clock_count++;
} else {
midi_clock_count=0;
}
}
}
}
}
...
void setTriggerLength(void) {
unsigned int x = tcnt3+((1500*16)/64);
cpmatch_l = x & 0xff;
cpmatch_h = (x >> 8);
}
void Timer3 (boolean state) {
//state true = count
//state false = stop
if (state) {
TIMSK3 |= (1<<TOIE3) | (1<<OCIE3A);
} else {
TIMSK3 &= ~((1<<TOIE3) | (1<<OCIE3A));
}
}
Can someone help me? I dont know what to do better now.
regards,
Flo