Sequencer groove

Well, I'd change any datatype that didn't need to be an "int" to be a "byte" or "char".
I'd hope that the compiler was smart enough to perform strength-reduction on the " / 8" and "% 8" operations, and hope that the bitRead and bitWrite were inlined.

I'd hope that the compiler was smart enough to perform strength-reduction on the " / 8" and "% 8" operations, and hope that the bitRead and bitWrite were inlined.

how can i check if they're inlined?

I didnt understand the first point about strength-reduction, can you explain it?

-Flo

Flub:

I'd hope that the compiler was smart enough to perform strength-reduction on the " / 8" and "% 8" operations, and hope that the bitRead and bitWrite were inlined.

how can i check if they're inlined?

I didnt understand the first point about strength-reduction, can you explain it?

-Flo

Since you dividing by a power of 2 and performing modulus by a power of 2 and count is positive, you can replace

int x = count % 8;
int x2 = (count-x)/8;
count=-1;

with

int x = count & 0x7;
int x2 = (count-x) >> 3;

Why are you setting count = -1 after the computation of x and x2 ??

Edit: Some compilers may do this optimization for you. I don't have my Arduino in front of me so I can't verify if this happens or not. Another compiler I tried does make this optimization automatically. It's still a good trick to know if the compiler will not do it automatically.

void loop() {
  if (Play) {
    if (play()) {
      Button_Check();
    }
  }
}

////////////////////////////////////////////////////////////////////////////////////
//FUNKTIONEN                               
////////////////////////////////////////////////////////////////////////////////////

//________________________________________________________________________SETLEDS()
void setLeds() {
 /* if (Mode==false) {*/
    for (unsigned int i = 0; i<=15; i=i+1) {
   //   if (second) {
      /*  if (ReadValue(program_sequence,ProgramSequenceTakt,active_channel,((i*Faktor)+16), false) == 0) {
          digitalWrite((StepLedPINS[i]), LOW);
        } else {
          digitalWrite((StepLedPINS[i]), HIGH);
        }*/
     // } else {
        if (ReadValue(program_sequence,ProgramSequenceTakt,active_channel,(i*Faktor), false) == 0) {
          digitalWrite((StepLedPINS[i]), LOW);
        } else {
          digitalWrite((StepLedPINS[i]), HIGH);
        }
     // }
    }
  /*} else {    
    for (int i = 0; i <= 15; i++) {
      if (i==program_sequence || i == (Paste-1)) {
        digitalWrite((StepLedPINS[i]), HIGH);
      } else {
        if (i != play_sequence) {
          digitalWrite((StepLedPINS[i]), LOW);
        }
      }
    }
  }*/
}
//________________________________________________________________________DISPLAY_BARS()
void display_bars(unsigned int count) {
  for (unsigned int i = 0; i < 4; i = i + 1) {
    if ( i == (count-1)) {
      if (count == 1) {
        digitalWrite(TaktPINS[i],HIGH);
      } else {
        analogWrite(TaktPINS[i],100);
      }
    } else {
      digitalWrite(TaktPINS[i],LOW);
    }
  }
}
//________________________________________________________________________DISPLAY_VALUES()
void display_values(unsigned int a, unsigned int b, unsigned int c, unsigned int d) {
  digitalWrite(14, HIGH);
  for (unsigned int i = 0; i < 4; i = i+1) {
    digitalWrite(DisplayDataPIN,numbers[b][i]);
    digitalWrite(DisplayClockPIN, HIGH);
    digitalWrite(DisplayDataPIN,LOW);
    digitalWrite(DisplayClockPIN, LOW);
  }
  for (unsigned int i = 0; i < 4; i = i+1) {
    digitalWrite(DisplayDataPIN,numbers[a][i]);
    digitalWrite(DisplayClockPIN, HIGH);
    digitalWrite(DisplayDataPIN,LOW);
    digitalWrite(DisplayClockPIN, LOW);
  }
  for (unsigned int i = 0; i < 4; i = i+1) {
    digitalWrite(DisplayDataPIN,numbers[d][i]);
    digitalWrite(DisplayClockPIN, HIGH);
    digitalWrite(DisplayDataPIN,LOW);
    digitalWrite(DisplayClockPIN, LOW);
  }
  for (unsigned int i = 0; i < 4; i = i+1) {
    digitalWrite(DisplayDataPIN,numbers[c][i]);
    digitalWrite(DisplayClockPIN, HIGH);
    digitalWrite(DisplayDataPIN,LOW);
    digitalWrite(DisplayClockPIN, LOW);
  }
} 
//________________________________________________________________________READVALUE()
inline boolean ReadValue(int seq, int takt, int channel, int p, boolean Switch) {
  takt--;
  int count = (seq*4*10*32)+(takt*10*32)+(channel*32)+p;
  int x = count % 8;
  int x2 = (count-x)/8;
  count=-1;
  boolean BIT = bitRead(sequenzen[x2],x);
  if (Switch) {
    bitWrite(sequenzen[x2],x,inv(BIT)); 
  } else {
    return BIT;
  }
}
//________________________________________________________________________WRITEVALUE()
void WriteValue(int seq, int takt, int channel, int p, boolean value) {
  takt--;
  int count = (seq*4*10*32)+(takt*10*32)+(channel*32)+p;  
  int x = count % 8;
  int x2 = (count-x)/8;
  count=-1;
  bitWrite(sequenzen[x2],x,value); 
}
//________________________________________________________________________inv()
inline boolean inv(boolean x) {
  if (x==HIGH) {
    return LOW;  
  } else {
    return HIGH;
  }
}
boolean play () {
  if ((micros() - Timer) > 66000) {
    for (int i = 0; i<10; i++) {
      channelvals[i]=ReadValue(play_sequence,PlaySequenceTakt,i,Step,false);
    }
    for (int i = 0; i<10; i++) {
      digitalWrite(55+i,channelvals[i]);
    }
    Step++;
    Timer = micros();
    lastOut = micros();
    if ((micros()-lastOut) > 50) {
      for (int i = 0; i<10; i++) {
        digitalWrite(55+i,LOW);
      }
    }
    if (Step > 31) {
      Step = 0;
    } else {
      Step = Step;
    }
    if (PlaySequenceTakt == ProgramSequenceTakt) {      
        if (Faktor == 2) {
          digitalWrite(SetStepsLedPINS[3], stepper[Step/Faktor][0]);
          digitalWrite(SetStepsLedPINS[2], stepper[Step/Faktor][1]);
          digitalWrite(SetStepsLedPINS[1], stepper[Step/Faktor][2]);
          digitalWrite(SetStepsLedPINS[0], stepper[Step/Faktor][3]); 
        } else {
          if (Step > 15) {
            StepSize=Step-16;         
          } else { 
            StepSize = Step; 
          }
            digitalWrite(SetStepsLedPINS[3], HIGH);
            digitalWrite(SetStepsLedPINS[2], HIGH);
            digitalWrite(SetStepsLedPINS[1], HIGH);
            digitalWrite(SetStepsLedPINS[0], HIGH);
        }
      } else {
        digitalWrite(SetStepsLedPINS[3], HIGH);
        digitalWrite(SetStepsLedPINS[2], HIGH);
        digitalWrite(SetStepsLedPINS[1], HIGH);
        digitalWrite(SetStepsLedPINS[0], HIGH);
      }
    return false;
  } else {
    return true;
  }  
}
//________________________________________________________________________Button_Check()
boolean Button_Check() {
  for (unsigned int i = 0; i < 16; i++) {
    button_state=digitalRead(ProgramButtonPINS[i]);  
    if (button_state==LOW) {
      if (button_ok[i]) {
        button_ok[i]= false;
        button_last = millis();
        ReadValue(program_sequence,ProgramSequenceTakt,active_channel,(i*Faktor), true);
        setLeds();
      }
    } else if ((button_ok[i]) == false) {
      if ((millis()-button_last) > 100) {
        button_ok[i] = true;
      }
    }
  }
  //________________________________________________________________ButtonA
  button_state=digitalRead(ButtonAPIN);
  if (button_state==LOW) {
    if (ButtonA_ok) {
      ButtonA_ok = false;
      button_last=millis();
      active_channel--;
      setLeds();
      display_values(0,0,0,active_channel);
    }
  } else if ((ButtonA_ok) == false) {
    if ((millis()-button_last) > 200) {
    ButtonA_ok = true;
    }
  } 
  //________________________________________________________________ButtonB  
  button_state=digitalRead(ButtonBPIN);
  if (button_state==LOW) {
    if (ButtonB_ok) {
      ButtonB_ok = false;
      button_last=millis();
      active_channel++;
      setLeds();
      display_values(0,0,0,active_channel);
    }
  } else if ((ButtonB_ok) == false) {
    if ((millis()-button_last) > 200) {
    ButtonB_ok = true;
    }
  }  
}

Thank you for the modulo stuff !
I now started to rearrange and improve the code. Thats what ive got yet. Do you see anything to improve?

Flub:
Thank you for the modulo stuff !
I now started to rearrange and improve the code. Thats what ive got yet. Do you see anything to improve?

What actually are your goals ?? Are you trying to reduce the amount of C code you have to write/debug/maintain, trying to reduce final program size, trying to have the code run faster, or something else ??

I want the code to go faster, because the sequenzer triggers a Drumsynth I built and when the code was still basic to test if it worked, the rhythm had much more groove then it had after I added all the functions, display options and button combinations That I want the sequencer to have. This is the reason why I want to be as effiecient as possible to keep the beat tight. ( the difference is not really big tecnically but the whole feel is very different, when it is fast you feel your body wants to move, when it is slow it just doesnt make you feel like that.

It is very important that the trigger pulses come at the same point in time and this in a very strict time interval , so the generated sounds really clash together if you know what i mean. Perhaps I could try to set all trigger voltages up right connected to a 4066 analog switch which is later opened by a slightly delayed clock pulse from the sequencer so the trigger pulses really come out at the same time.

sorry for my bad english, if it is bad
-Flo

If you want to squeeze some more cycles, you could look at replacing the "digitalWrite"s with direct port manipulation.
I'd check what the compiler is doing with the division and modulo ops, then if it really is doing division, replace them with mask and shift operations.

how can i check this?
i use the arduino ide

Flub:
how can i check this?
i use the arduino ide

I haven't analyzed your program in detail, I will try to do this and I'll comment later if I see anything.

However, It may be useful to look at disassembled output of your program to see the exact assembly language instructions being generated to see if your division/modulus is being done efficiently by the compiler. You can generate that output by (IIRC) by the compiler option -S. I don't know how to change compiler options using the Arduino IDE.

I am building my sketches the old fashion way via command-line 'make' commands. There is a good article on how to do this:

http://pragprog.com/magazines/2011-04/advanced-arduino-hacking

and here

http://bleaklow.com/2010/06/04/a_makefile_for_arduino_sketches.html

The latter article has a link to a google code project where you can download his examples.

Additionally, IIRC, the Arduino IDE uses compiler optimization flag -O0. This optimizes for program size. If you want to have the compiler optimize for speed you can try -O1 or -O2 or -O3. However, these optimizations may be at the expense of increasing program size.

...or you can run "avr-objdump" with a "-d" option on your compiled code to get a disassembly listing.
To find where the IDE leaves your compiled code, hold down the "shift" key when compiling.

AWOL:
...or you can run "avr-objdump" with a "-d" option on your compiled code to get a disassembly listing.

I did not know about this. Good to know. Thanks.

Am i right that running avrobjdump works like this:

open the console
avrobjdump -d PATH TO FILE

I am using windows xp right now, is it possible to run this program on windows ?

I now did it with the ubuntu on my netbook:

this is the commands output :
http://www.murderers.de/file.txt

if the function readfile goes to the hexnumber bc which is 188 in the decimal system does it mean that the time the function takes is

(1/16000000)*188 = 0,01175 milliseconds

if the function readfile goes to the hexnumber bc which is 188 in the decimal system does it mean that the time the function takes is

(1/16000000)*188 = 0,01175 milliseconds

No, some instructions take more than one cycle,.
(I can't see "readfile" anywhere on that page - what is the source?)

i meant readvalue instead of readfile. it is the the last code i posted here. what can i see in this assembler code? do i have to learn assembler first?

I think you need to restructure and break up your code first. When that is done, you can go into more advanced optimizations if needed.

As mentioned early on in this thread, you should restructure your code so that reading inputs is a separate step from acting on the inputs. This way you can easily gain cycles just by skipping some actions and performing them only every N:th loop, or every N:th millis (better).

I now restructured the code like Anders proposed
i uploaded it murderers.de is available for purchase - Sedo.com

i want it as efficent as possible

Hey there,
I began to work again on the sequencer :

this is the loop function:

    if (play()) {
    } else {
      Button_Check();
      Button_Process();
    }

this is the play function:

    Time = micros()-lastOut;
    if (Time >= 4000 && clock == true) {    
      PORTK = 0b00000000;
      clock = false;
    } else if (Time >= step_intervall) {
      for (int i = 0; i<8; i++) {
        bitWrite(outputs,i,ReadValue(play_sequence,PlaySequenceTakt,i,Step,false));
      }
      PORTK = outputs;
  clock = true;
  lastOut = micros();   
      if (Step < 31) {
        Step++;
      } else {
        Step=0;
      }
      return true;
    } else {
      return false;    
    }
  }

Now it seems like the step_intervall isnt constant, so perhaps the board (Mega 1280) gets interuppted because i used almost every Pin on it and there are more interuppting pins i readed some where.

What can I do to create the Outputsignal in a very constant time intervall (my variable for this intervall in micro seconds is "step_intervall")

Please help me = )

-Flo

isnt it possible to have an action in a very exact time intervall?