Pages: 1 [2] 3   Go Down
Author Topic: Sequencer groove  (Read 1860 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
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?
Logged

Mountain View, CA
Offline Offline
Newbie
*
Karma: 0
Posts: 20
Professional C/C++ programmer available for projects
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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 ??
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 309
Posts: 26496
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Offline Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

how can i check this?
i use the arduino ide
Logged

Mountain View, CA
Offline Offline
Newbie
*
Karma: 0
Posts: 20
Professional C/C++ programmer available for projects
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 309
Posts: 26496
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

...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.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Mountain View, CA
Offline Offline
Newbie
*
Karma: 0
Posts: 20
Professional C/C++ programmer available for projects
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

...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.
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 ?
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
« Last Edit: July 02, 2011, 12:23:27 pm by Flub » Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 309
Posts: 26496
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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?)
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Offline Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

Sweden
Offline Offline
Jr. Member
**
Karma: 0
Posts: 84
Arduino System Go!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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).





Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I now restructured the code like Anders proposed
i uploaded it http://murderers.de/NEu.pde


i want it as efficent as possible
« Last Edit: July 28, 2011, 03:04:15 am by Flub » Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 82
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

this is the loop function:
Code:
    if (play()) {
    } else {
      Button_Check();
      Button_Process();
    }

this is the play function:
Code:
   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
« Last Edit: February 12, 2012, 07:16:04 am by Flub » Logged

Pages: 1 [2] 3   Go Up
Jump to: