Monday 28 October 2013

ADSR Exercises...

The exponential attack curves available will have these different options, in the final version !

I had to try to rethink the ADSR block of my project, as there are some variations that i want to include, and that make it different from other methods more popular often used in synths. Plus, what im building is not your average synth either, so here are some of the results of my tests ! Still need to test it as far as performance goes to be able to decide if ill go with an exponential attack( i am quite confident it can be calculated between interrupts, so as not to weigh too much on the interrupt load, itself !
I tried to make it as readable as possible; There are a lot of short cuts available to make it more efficient and optimize it. Which shall be taken into consideration in the final code . This one was wrote in tutorial style; several of the calculations can be shortened , optimized, for better performance. But then, it wouldn't have been as readable as this, i guess !
So, here it is for now !.


//*    Synth Building blocks 
//*    ATTACK-DECAY-SUSTAIN-RELEASE for Wavetable-based Generator #0.1
//*    Check section "Synth building blocks related" @
//*    http://dubworks.blogspot.co.uk/p/my-self-documented-tutorials.html
//*    Result of my experiences into the ADSR part of my project. Keep in mind that i decided to re-trhink it, 
//*    as what im working on is not your usual synth, but something else slightly(?!) different.
//*    This code was wrote for readability more than anything else ! There are a lot of short cuts available
//*    to make it more efficient and optimize it. Which shall be taken into consideration in the final code 

#define xinc (1.00/param.attack) // Allows an exponential attack
#define sigl 4095 // Despite being a constant here, it should be replaced by the wavetable equivalent
//
uint32_t phaseinc,output;
//
//  Declare the struct for our ADSR
struct ADSR {
  uint16_t period;  // total of the whole period
  uint16_t attack;
  uint16_t decay;
  uint16_t sustain;
  uint16_t rlease;
  float x;  // increment for period, to accum xinc by addition
};
struct ADSR param; // initialize the structure, so it is in scope !
//
//boolean led = false; 
//
void update (){
  if(phaseinc <= param.period){
    //
    if(phaseinc < param.attack){
      float y;
      y= pow(param.x , 0.50);  // Expon. attack-generator. This is where my latest tests been focusing on
      output= sigl * y;  //Ramp up can be achieved by just multiplying it by param.x as well, though 
      //  it would be a waste of computing power, as there are easier and "cheaper" ways to do it !

      //      Serial.print ("attack ");
      //      Serial.println (attack);
      //      Serial.print ("Output ");
      //      Serial.println (output);
    }
    else if(phaseinc >= param.attack && phaseinc <(param.attack + param.decay)){
      //
      output = sigl-((phaseinc - param.attack)*(512.0/param.decay)); //512= 4096 * 1/8
      //      Serial.println ("decay");
      //      Serial.println (param.decay);
      //      Serial.print ("Output ");
      //      Serial.println (output);
    }
    else if(phaseinc >=(param.attack + param.decay) && phaseinc <(param.attack + param.decay + param.sustain)){
      //
      //      Serial.print ("sustain");
      //      Serial.println (param.sustain);
      output = sigl *(7/8.00);
      //      Serial.print ("Output ");
      //      Serial.println (output);
    }
    else if(phaseinc >(param.attack + param.decay + param.sustain) && phaseinc < param.period){
      //
      //      Serial.print ("rlease");
      //      Serial.println (param.rlease);
      output=(param.rlease-(phaseinc-(param.attack+param.decay+param.sustain)))*((sigl*(7/8.00))/param.rlease);
      //      Serial.print ("Output ");
      //      Serial.println (output);  
    }
  }
}
//
void ADSR_calculation()
{ 
  //  There are more exciting ways to calculate division and remainders.
  //  We wrap-up with  a "modulo-like" operator for
  //  the last variable sustain- a "greatest-integer function" of sorts .
  //  This way we can go from decay to release directly. Todo list is to loop inside the sustain
  //  For now im planning using 3 sec/1 as MAXIMUM of the whole period for ADSR.
  uint16_t b    = param.period >> 1;  // These operations help us achieve a cheap aproximation
  param.attack  = param.period >> 2; 
  param.decay   = b/3;
  param.rlease  = param.period >> 2;
  param.sustain = param.period -(param.attack + param.rlease + param.decay); 
  // same as 
  // param.sustain = param.period %(param.attack + param.rlease + param.decay);
  /*if(Serial){
   Serial.print ("attack ");
   Serial.println (param.attack);
   Serial.print ("decay ");
   Serial.println (param.decay);
   Serial.print ("sustain ");
   Serial.println (param.sustain);
   Serial.print ("rlease ");
   Serial.println (param.rlease);
   }*/
}
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  //variable for the period; To be analogous to the analog read/s and should be declared with an initial 
  //value(21504?!), before the buffering of the initial values , at the time of wavetable generation
  param.period=128;  //this value should be the sum of all ADSR values, so we can have variable-lenght 
  //  on each of the individual parameters of the ADSR !It is already in the tODO list !
  //  But for now, ill leave it as it is: weighed proportionally !
  //
  ADSR_calculation();
}

void loop() {

//  if(Serial){
//    Serial.print ("phaseinc ");
//    Serial.println (phaseinc);
//  }
  //
  update();  
  //This can be done between interrupts, as there is some calculations involved.

  phaseinc++;
  //Serial.println(phaseinc);
  if( phaseinc >= param.period ){
    phaseinc= phaseinc - param.period;
    ADSR_calculation();
  }
  param.x += xinc;
  if (param.x >= 1){
    param.x = 0;
  }
  Serial.println (output);
}


Arduino Decimal to Roman numerals converter- The code for Olimex WPC #30

Ok, here is the story :
Friday i saw the "Olimex WPC #30 Problem" just posted and decide to participate...MORE: I was going to try to be the first one to apply a working project, regardless of the "cost".
So i rushed, cheated, took no notice of programming "rules", and VOILA !
Also, as i rarely(?!) see an "Arduino Language" entry ( if you can call it that) , i decided it was what id be applying with ( and because i had nothing else more to code with, at the time :) ).
Added my good mood to the vibes, and this is what came out !
Will only work up to 9999 numbers... If you do a calendar with it, they will probably think it is the end of the world in the year 9999, due to my laziness !!
It was the fastest, laziest way i could find at the time !
* Dont take this code too serious...

**See the results here !https://github.com/OLIMEX/WPC/tree/master/ISSUE-30


// Enjoy the random names for variables and function at moments. 
// and learn how to write down the year that Olimex was founded in Roman numerals
// For completion, i give you the foundation of their fraction system: A twelfth !
// DISCLAIMER : Any similarities with attempt at comedy is pure coincidence !
//        CHANGE THIS to test other numbers ( up tp 9999
//         | | | | |    
//         V V V V V
char plaintext[]="1991"; // Why a char[] array? More user friendly with both c and c++
// and because i can !! :)

int tocipher[sizeof(plaintext)];
int ciphered[sizeof(tocipher)];

boolean stringComplete = false;  // whether the string is complete
boolean done = false; // no relationship between the name and function ! ;)

void setup() {
  // DO NOT put your code here to run once ?!?!
  Serial.begin(9600);
  Serial.println("Roman Numeral History Lesson with Olimex Pt.1");
}

void loop() 
{ 
  while(Serial){
    if(stringComplete == true)  // How long is a piece of string ?!
    {
      calculate();
      Serial.println("string complete");
      fractions();
      //
    }
    if(stringComplete == false){
      Serial.println("string NOT complete");
      // put your debug code here, to find out where you was going wrong: 
      uint8_t sizeofarray = sizeof(plaintext);
      uint8_t i;
      //
      for(i=0;i<=sizeofarray;i++)
      {
        uint16_t retrieved;
        retrieved=plaintext[i];
        leap(retrieved,i);
        Serial.println(retrieved);

        if(retrieved==0){
          Serial.print(i);
          Serial.println(" characters in the string processed.END OF STRING "); // Thats how long a string is :)
          Serial.println("null CHARACTER");
          stringComplete = true; 
          // The use of goto's is highly frowned upon...
          // ...but can be quite handy as well !
          goto bailout; 
        }
      }
bailout: // " Bloody bankers taken all !"
      delay(1); // As the tradition says:" Rome and Pavia weren't made in one day!
    }  
    while(done==true){
      // Allowing time for Nero to play with fire !
    }
  }
}

int leap(int in,int il){
// tocipher[il]=in; would have been enough
  switch (in) {
  case '0':  
    //
    Serial.println("tocipher- 0 ");
    tocipher[il]=0;
    break;
  case '1':
    Serial.println("tocipher- 1 ");
    tocipher[il]=1;  
    //
    break;
  case '2': 
    Serial.println("tocipher- 2 ");
    tocipher[il]=2;  
    //
    break;
  case '3': 
    Serial.println("tocipher- 3 ");
    tocipher[il]=3;  
    //
    break;
  case '4':
    Serial.println("tocipher- 4 ");
    tocipher[il]=4;  
    //
    break;
  case '5': 
    Serial.println("tocipher- 5 ");
    tocipher[il]=5;  
    //
    break;
  case '6':
    Serial.println("tocipher- 6 ");
    tocipher[il]=6;  
    //
    break;
  case '7':
    Serial.println("tocipher- 7 "); 
    tocipher[il]=7;  
    //
    break;
  case '8':
    Serial.println("tocipher- 8 ");
    tocipher[il]=8;  
    //
    break;
  case '9': 
    Serial.println("tocipher- 9 ");
    tocipher[il]=9;  
    //
    break;
    //
  default:
    //
    break;
    //
  }
}

void calculate(){
  uint16_t sizeofarray = sizeof(tocipher);
  int i;
  //
  for(i=0;i<=sizeofarray;i++)
  {
    int retrieved;
    retrieved=tocipher[i];
    bigjump(retrieved,i);
    //
  }
}

int bigjump(int coming, int il){

  switch (il) { 
  case 0:
    int k;
    Serial.print("Year Olimex was founded in Roman numerals- ");
    for(k=0;k<coming;k++){
      Serial.print("M");
    }
    break;

  case 1:
    if(coming==9){
      Serial.print("CM");
    }
    if (coming==8){
      Serial.print("DCCC");
    }
    if (coming==7){
      Serial.print("DCC");
    }
    if (coming==6){
      Serial.print("DC");
    }
    if (coming==5){
      Serial.print("D");
    }
    if (coming==4){
      Serial.print("CD");
    }
    if (coming==3){
      Serial.print("CCC");
    }
    if (coming==2){
      Serial.print("CC");
    }
    if (coming==1){
      Serial.print("C");
    }
    break;

  case 2:
    if(coming==9){
      Serial.print("XC");
    }
    else if (coming==8){
      Serial.print("LXXX");
    }
    else if (coming==7){
      Serial.print("LXX");
    }
    else if (coming==6){
      Serial.print("LX");
    }
    else if (coming==5){
      Serial.print("L");
    }
    else if (coming==4){
      Serial.print("XL");
    }
    else if (coming==3){
      Serial.print("XXX");
    }
    else if (coming==2){
      Serial.print("XX");
    }
    else if (coming==1){
      Serial.print("X");
    }
    break;

  case 3:
    if(coming==9){
      Serial.print("IX");
    }
    else if (coming==8){
      Serial.print("VIII");
    }
    else if (coming==7){
      Serial.print("VII");
    }
    else if (coming==6){
      Serial.print("VI");
    }
    else if (coming==5){
      Serial.print("V");
    }
    else if (coming==4){
      Serial.print("IV");
    }
    else if (coming==3){
      Serial.print("III");
    }
    else if (coming==2){
      Serial.print("II");
    }
    else if (coming==1){
      Serial.print("I");
    }
    done=true;
    break;

  case 4:
    Serial.println("");
    break;  

  default:
    break;
  }
}


void fractions(){
  // Any similarites with attempt at comedy is pure coincidence !
  uint16_t sizeofarray = sizeof(tocipher);
  int i;
  //
  for(i=0;i<=sizeofarray;i++)
  {
    int retrieved;
    int accum;
    retrieved=tocipher[i];
    int result=0;
    switch (i) {
    case 0:  
      //
      accum=(retrieved*1000);
      Serial.print("result thou ");
      Serial.println(accum);
      break;
    case 1:
      accum+=(retrieved*100); 
      Serial.print("result with hundr");
      Serial.println(accum); 
      //
      break;
    case 2: 
      accum+=(retrieved*10); 
      Serial.print("result with decim ");
      Serial.println(accum); 
      //
      break;
    case 3: 
      accum+=retrieved; 
      Serial.print("total result ");
      Serial.println(accum);
      //
      break;

    case 4:
      Serial.print("Proverbial 1/12 (twelfth) Roman fracction ");
      Serial.print((float)(accum/12));
      break;

    default:
      break;
      //
    } 
  }
}
















Saturday 26 October 2013

Problem : Write a decimal to Roman Numerals Converter


Decided to rush and be the first to enter a solution for Olimex's 30th Weekend Programming Contest (WPC #30).
Problem : Write a decimal to Roman Numerals Converter !
I sacrificed a lot on trying to be the first to apply( time will tell if it worked). But did finish a working converter for Arduino (read cumbersome ) !!
Even included the calculation of a twelfth, which was the backbone of their fraction system.

https://github.com/OLIMEX/WPC

http://olimex.wordpress.com/2013/10/25/weekend-programming-challenge-week-30-roman-numbers/

Thursday 24 October 2013

Project share: "Making" on the making !

Kodjo Afate Gnikou creates a 3d printer from "junk diving".


Richard Feynman, No Ordinary Genius

“Science is like sex: sometimes something useful comes out, but that is not the reason we are doing it. ”
― Richard P. Feynman

Feynman was the anti-thesis of a genius at first glance (highly extrovert, known to work some of his brilliancies in strip club tables, not always a follower of protocols, sassy, and so much more), yet he rubbed shoulders and worked with many of the biggest geniuses of his time.
He also a achieved a Nobel prize ( back in the day where you actually had to earn them, as nowadays they are handing them for your looks and influence to every dick and harry , specially the peace prize!! ), shared with others, for his contributions in light and matter interaction and solved the Space shuttle Challenger explosion in the 80's. All these achievements and other are always epic in proportions by the way he made them happen, adding to the awe of his myth . His extrovert personality only helped to increase the myth around the genius !

There are a few people i could hear lecturing anytime. Herbert Gross, Feynman, Alan V. Oppenheim, Gilbert Strang to mention but a few. Some people do have the gift that makes the difference between learning by memorizing things ( Some seem to spit nothing but book technical terms), and learning by understanding things !





Wednesday 23 October 2013

Some exercises with the "Caesar cipher" Pt 2.

Plaintext    |a |b |c  |d |e |f  |g |h |i   |j | k | l  | m| n| o | p | q  | r  | s | t  | u | v | w | x | y | z |
P-Number  |0 |1 |2 | 3 |4 |5 |6 |7 |8 |9 |10|11|12|13|14|15 |16 |17|18|19|20|21|22 |23|24|25|
Ciphertext |d |e | f | g |h |i  |j  |k |l |m | n | o | p | q | r  | s| t  | u | v | w | x | y | z  | a | b  | c |

In the Caesar cipher, the modulus operator was used to achieve a fast way of computing the result.
The use of an array from 0 to 25 is inherent to the discrete implementation methods widely used. Look-up tables also get this particularity many a times !
If it is not obvious why, wait until one of the next posts on the subject. Other examples will surely make obvious why .
Let's remember  what was said in a previous post :

// Caesar cipher ==> C = (P+s) Mod (Number_of_Characters)
// Number_of_Characters also known as Keyspace = 26 (0 to 25)
// P = numerical equivalent of character plaintext
// C = Numerical equivalent of cipher text character
// s = number of shifts,adds (n_shift)
// Ke = s = 3 ==> (P+s) mod (Number_of_Characters)
// Kd = -s = -3 ==> (C -s)mod (Number_of_Characters) (reverse operation)

From this, we can then adapt this idea into the way the ascii numerical code uses to represent printable characters.

// Keyspace = 96 ( Nchars; )
// P = retrieved
// s =  n_shift
// [ from "ascii'" character number 32-decimal; 040-OCT; 20-HEX; 00100000-BIN ==> "SPACE" 
// to "ascii'" character number 126 decimal; 176-OCT; 7E-HEX; 01111110-BIN; ==> "~" Equivalence sign - tilde

The way i found was to first subtract  an ascii_offset (retrieved -=32;) compute the algorithm ( uint16_t c =(retrieved + n_shift)% Nchars; ) and then re-add the ascii_offset (retrieved +=32;).

C = (P+s) Mod ( Keyspace )

I should probably note the fact that it should not be confused with the remainder.
Let us see why...

If in C = A modulus B ,  A=13 and B=5 , then C=3 ;
If    C = A remainder B, then it is also C=3.

BUT (and there are always but's) what if we give A=13 and B= -5 ?!
Then, we would get A Modulus B ==> C= -2; In turn, A Remainder B ==> C=3 !!

Oh, yeah !! The art of the Modulus operator in itself  ( specially with only the use of a hand calculator), and its relationship with cryptography, is an art in itself , and can easy allow for a series of posts elaborating on it !
As an example, check the table below (created with Gnumeric) .



Code here
https://docs.google.com/document/d/1CbK-v1OaQIhbr0ao5EY8CrGZ71M9-t4cav4bK4JBwo0/edit?usp=sharing

Tuesday 22 October 2013

Some exercises with the "Caesar cipher"

The Caesar cipher is an example of character or monographic substitution cipher., as it enciphers by substituting a single (mono) character for other single ones.

in the previous related post, the plaintext gives us :

plaintext to encipher- Arduino to cipher this#
Ciphered_array- Dugxlqr#wr#flskhu#wklv&

* you can use the ascii table link for reference.

The Caesar cipher is named after Julius Caesar, who, according to Suetonius, used it with a shift of three to protect messages of military significance.It is unknown how effective the Caesar cipher was at the time, but it is likely to have been reasonably secure, not least because most of Caesar's enemies would have been illiterate and others would have assumed that the messages were written in an unknown foreign language(1)

Of course we can use other shifts; Hal in Arthur C. Clarke's "2001: A Space Odyssey" was chosen as the name for the computer, as it reads 'IBM' with a forward shift of 25 or a back shift of 1 !! Done in a normal 26 letter-only alphabet characters (basic original form)(2).
*There are other funny facts about Hal, actually: the fact that Kubrick is said to have had problems with the initial  use of IBM logos, who decided to withdraw them, due to their disapproval of a computer killing people and how that would look like for them, in terms of publicity !

Polemics aside...
In cryptography the use of modulus operator is essential. An operation not so easy ( read quick) to do with a calculator I intend to do a whole post on that, as "i love me some maths" !
Not much to say about the Caesar cipher, as most of us tried it as kids at some point. Another widely spread use of it was creating a paper set of double wheels( see below pic).

It is as easy as A becomes D( 3 shifts to the right).

Of course this number of shifts can be increased/decreased, and do all sorts of variations in the enciphering key! 
So an implementation of the Caesar cipher algorithm would have to be described as :

C=(P+s) Mod (Number_of_Characters) 
Number_of_Characters= 26 (also known as keyspace; 26 in the case of low case alphabet only)
 P = numerical equivalent of character plaintext  
 C = Numerical equivalent of ciphertext character
 s = number of shifts/adds 
Ke== Enciphering Key
Kd==Deciphering Key
*The last two are termed the keys of a cryptosystem.
Kerchoffs' principle enunciates that the security of a cryptosystem must not depend on keeping the cryptographic algorithm secret, but only in keeping the KEYS secret.
 Ke= s = 3 ==> (P+s) mod (Number_of_Characters)
 Kd = -s = -3 ==> (C -s)mod (Number_of_Characters)


Check Arduino Implementation post here 

Monday 21 October 2013

Some exercises with the "Caesar cipher" and Arduino Pt.1



First instalment of the first cryptographic cipher - The Caesar Cipher.

I will be making a more in-depth explanation of how it all works, as well as adapt the code for a Serial.read ( ) for better usage as proof of concept for this specific project !

For now, here is the code !


//              "CAESAR CIPHER"
//   A simple "CAESAR CIPHER"ing project - http://dubworks.blogspot.co.uk/2013/10/some-exercises-with-caesar-cipher-with_22.html
//  Number_of_Characters = 96 also known as Keyspace
//  [ from "ascii'" character number 32-decimal; 040-OCT; 20-HEX; 00100000-BIN ==> "SPACE"
//  to "ascii'" character number 126 decimal;  176-OCT;  7E-HEX;  01111110-BIN; ==> "~" Equivalency sign - tilde
//
//  Caesar cipher ==> C=(P+s) Mod (Number_of_Characters)
//  P = numerical equivalent of character plaintext
//  C = Numerical equivalent of ciphertext character
//  s = number of shifts/adds
// 
//  Ke= s = 3 ==> (P+s) mod (Number_of_Characters)
//  Kd = -s = -3 ==> (C  -s)mod (Number_of_Characters)
//
//
// 
//   For more on Caesar cipher - http://en.wikipedia.org/wiki/Caesar_cipher
// 
#define Nchars 96  //  starting at 32 up to 126 in the ascii table 
#define n_shift 3  //  shift desired
//
char plaintext[]=
{   
  'A','r','d','u','i','n','o',' ', 't','o',' ','c','i','p','h','e','r',' ','t','h','i','s', '#'};
//
char ciphered[sizeof(plaintext)];
//

boolean stringComplete = true;  // whether the string is complete

void setup() {
  // Insert your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  uint8_t i;
  //   Serial.println(sizeof(plaintext)); 
  //   Insert your main code here, to run repeatedly:  

  while(Serial)
  {
    if(stringComplete==true){
      Serial.println ("Arduino Caesar Cipher v1");
      Serial.println ("");
      cphr();
      //
      //
      Serial.println(" ");
      //
    }
  }
}

void cphr()
{
  uint8_t sizeofarray = sizeof(plaintext);
  uint8_t i;
  //
  for(i=0;i<sizeofarray;i++)
  {
    uint16_t retrieved;
    retrieved=plaintext[i];
    //    Serial.print(" P original- - ");
    //    Serial.println(retrieved);
    retrieved -=32; // Subract Ascii_offset
    //    Serial.print(" P - Offset = ");
    //    Serial.println(retrieved);
    uint16_t c =(retrieved + n_shift)% Nchars; // check blog post for more info on this   
    //    Serial.print("C original - ");
    //    Serial.println(c);
    c +=32; // add the Ascii_offset
    //    Serial.print("C + Offset = ");
    //    Serial.println(c);
    ciphered[i]=c;
    //
    //    Serial.println(" ");
    //    Serial.print("i- ");
    //    Serial.println(i);
    //    Serial.print("c- ");
    //    Serial.println(c);
    //    Serial.print("C_array- ");
    //    Serial.println(ciphered[i]);
    //    Serial.print("Alphaarray- ");
    //    Serial.println(plaintext[i]);
    delay(50);
  }
  displayResults();
  stringComplete = false;
}

void displayResults(){
  //
  uint8_t i;
  uint8_t sizeofarray = sizeof(plaintext);
  Serial.print("plaintext to encipher- ");
  for(i=0;i<sizeofarray;i++)
  {
    Serial.print(plaintext[i]);
    delay(10);
  }
  Serial.println(" ");
  Serial.print("Ciphered_array- ");
  for(i=0;i<sizeofarray;i++)
  {
    Serial.print(ciphered[i]);
    delay(50);
  }
}




A slight different sketch here, easier to test other examples
http://forum.arduino.cc//index.php?topic=194628.msg1437373#msg1437373


Or a more readable version of the code here https://docs.google.com/document/d/1CbK-v1OaQIhbr0ao5EY8CrGZ71M9-t4cav4bK4JBwo0/edit?usp=sharing




-More insight into it !
http://dubworks.blogspot.co.uk/2013/10/some-exercises-with-caesar-cipher-with_22.html

http://dubworks.blogspot.co.uk/2013/10/some-exercises-with-caesar-cipher-pt-2.html

Friday 18 October 2013

Prime number generator with arduino

Prime number 1,370,795 from Wolfram Alpha's list

I had to share this Project !
Nick Gammon is a very helpful member on the Arduino forum , and always ready to share his knowledge and help/time .

http://www.gammon.com.au/forum/?id=12168&page=999
http://forum.arduino.cc//index.php?topic=192209.0



Saturday 12 October 2013

options to attack envelope


Ill keep it simple and share the graphic of the differences and options. Ramp legend is a linear ramp-up attack.
Following the example of period 128, we'd get : attack=32; decay=22; sustain=42; rlease=32.
the picture below is related to the ATTACK stage only.

More soon to come !



void adsr_calculation()
{
  uint16_t b = period >> 1;  // These operations help us achieve a cheap aproximation
  uint16_t a = b >> 3;  // of division by 3 (?!) with a loss of bits/precision, but weighed 
  //  enough for what we need, regarding the fact we wrap-up with  a modulo operator for
  //   the last variable sustain- a "greatest-integer function" of sorts .
 
 /*
 By combining the terms in an obvious manner we can reduce the number of operations:
   
   a = (period >> 2) + (period >> 4) 
   b += (b >> 4)
   b += (b >> 8)
   b += (b >> 16)
   There are more exciting ways to calculate division and remainders.
       b * 3 = shift left 1 bit and then add b
*/

  attack  = period >> 2; 
  decay   = (a <<1)+(a>>1)+(a>>2);
  rlease  = period >> 2;
  sustain = period -(attack + rlease + decay);
  // roughly the same as 
  // sustain = period %(attack + rlease + decay);
  led =!led;    //toggle led
  /* Serial.println ("a");
   Serial.println (a);
   Serial.println ("b");
   Serial.println (b);
   Serial.println ("attack");
   Serial.println (attack);
   Serial.println ("decay");
   Serial.println (decay);
   Serial.println ("sustain");
   Serial.println (sustain);
   Serial.println ("rlease");
   Serial.println (rlease);
   */
}

Regarding REAL division by three



// Crazy as this might sound, but the method below indeed does divide by 3. 
// All it needs for doing so is a single 64 bit multiplication and a shift 
// (multiplications might be 3 to 4 times faster than divisions 
// on your CPU). In a 64 bit application this code will be a lot faster than 
// in a 32 bit application (in a 32 bit application multiplying two 64 bit 
// numbers take 3 multiplications and 3 additions on 32 bit values) 
// - however, it might be still faster than a division on a 32 bit machine.
// It only works for constant numbers. Why ?!
// You always need to know the magic number (here 0xaaaaaaab, 
// 0b1010 1010 1010 1010 1010 1010 1010 1011 ; 2,863,311,531 decimal
// and the correct operations after the multiplication (shifts and/or additions 
// in most cases)and both is different depending on the number you want to divide// by (and to calculate both take too much CPU time, on the fly (that would be 
// slower than  hardware division). However, it's easy for a compiler to 
// calculate these during compile time 
static inline uint32_t div3 (
uint32_t bdivided
) {
  return (uint32_t)(((uint64_t)0xaaaaaaabULL * bdivided) >> 33);
}
void setup() {
  // put your setup code here, to run once:
  Serial.begin (115200);
}

void loop() {
  // put your main code here, to run repeatedly: 
  uint32_t test=1000;
  uint32_t avar=div3(test);
  Serial.println(avar);
  delay(500);
}

Thursday 3 October 2013

Blindspots in code programming

Not news that we all got stuck with silly typos or "mistakes" while debugging some code: Big endianess? N-1 Ring-Buffer ?! Wrong datatype conversion/interaction?! hmmm...
As "developing some blindspots" its something that affects us all from time to time, when writing code, i decided to share some nice examples usually referenced as main examples( though, tbh, there are journalistic column entitled "IT Hiccups of the week", which speaks for itself :).

1- The Ariane 5 rocket, who got confused and got lost

On 4 June 1996 the maiden flight of the Ariane 5 launch ended in a failure, about 40 seconds after initiation of the flight sequence. At an altitude of about 3700 m, the launcher veered off its flight path, broke up and exploded. The failure was caused by "complete loss of guidance and attitude information" 30 seconds after liftoff.
A program segment for converting a floating-point-number to a signed 16-bit integer was executed with an input data value outside the range representable by a signed 16-bit integer. This run time error (out of range, overflow), which arose in both the main and backup computers at about the same time, was detected and both computers shut themselves down. This resulted in the total loss of altitude control. The Ariane 5 turned uncontrollably and aerodynamic forces broke it apart. This was detected by an on-board monitor which ignited the explosive charges to destroy the vehicle in the air. 

* Funny enough, the result of this conversion was no longer needed after, lift off.

reference: http://en.wikipedia.org/wiki/Ariane_5
http://www.rvs.uni-bielefeld.de/publications/Incidents/DOCS/Research/Rvs/Misc/Additional/Reports/ariane.html



2- The Patriot Missile who was late...

On February 25, 1991, during the Gulf War, an American Patriot Missile battery in Dharan, Saudi Arabia, failed to track and intercept an incoming Iraqi Scud missile. The Scud struck an American Army barracks, killing 28 soldiers and injuring around 100 other people. A report of the General Accounting office, GAO/IMTEC-92-26, entitled Patriot Missile Defense: Software Problem Led to System Failure at Dhahran, Saudi Arabia reported on the cause of the failure.

The bug occurs in the calculation of the next location of the incoming target by the range gate. The prediction is calculated based on the target’s velocity and the time of the last radar detection.
Velocity is stored as a whole number and a decimal, and time is a continuous integer or whole number (i.e. the longer the system has been running, the larger the value) measured in tenths of a second.
The algorithm used to predict the next air space to scan by the radar requires that both velocity and time be expressed as real numbers. However, the Patriot’s computer only has 24 bit fixed-point registers. Because time was measured as the number of tenth-seconds, the value 1/10, which has a non-terminating binary expansion, was chopped at 24 bits after the radix point.5 The error in precision grows as the time value increases, and the inaccuracy resulting from this is directly proportional to the target’s velocity.
When the Patriot system was first designed, the primary targets were Soviet aircraft and cruise missiles travelling at speeds around MACH 2, and only operating at a few hours at a time. However, in Operation Desert Storm, they were deployed as static defences (operating continuously), tracking and intercepting Scud missiles travelling at speeds of approximately MACH 5

"It turns out that the cause was an inaccurate calculation of the time since boot due to computer arithmetic errors.
Specifically, the time in tenths of second as measured by the system's internal clock was multiplied by 1/10 to produce the time in seconds. This calculation was performed using a 24-bit fixed-point register. In particular, the value 1/10, which has a non-terminating binary expansion, was chopped at 24 -bits after the radix point.
The small chopping error, when multiplied by the large number giving the time in tenths of a second, led to a significant error. 
Indeed, the Patriot battery had been up around 100 hours, and an easy calculation shows that the resulting time error due to the magnified chopping error was about 0.34 seconds. (The number 1/10 equals 1/24+1/25+1/28+1/29+1/212+1/213+.... In other words, the binary expansion of 1/10 is 0.0001100110011001100110011001100.... Now the 24 bit register in the Patriot stored instead 0.00011001100110011001100 introducing an error of 0.0000000000000000000000011001100... binary, or about 0.000000095 decimal. Multiplying by the number of tenths of a second in 100 hours gives 0.000000095×100×60×60×10=0.34.) 
A Scud travels at about 1,676 meters per second, and so travels more than half a kilometer in this time. This was far enough that the incoming Scud was outside the "range gate" that the Patriot tracked.
Ironically, the fact that the bad time calculation had been improved in some parts of the code, but not all, contributed to the problem, since it meant that the inaccuracies did not cancel."

Reference- "Failure at Dhahran " http://en.wikipedia.org/wiki/MIM-104_Patriot

3- Therac-25 : At a costly price ...

It is hard to reference this one, as it was the most costly, specially as the victims thought that the same device would be the one that would help improve their health, instead of the end result!