Welcome, Guest
Username: Password: Remember me

TOPIC: Mounting an OLED screen on my pedalshield

Mounting an OLED screen on my pedalshield 4 years 4 days ago #381

  • llegoff
  • llegoff's Avatar
  • OFFLINE
  • New Member
  • Posts: 4
  • Thank you received: 3
  • Karma: 2
Hi
i mount a oled screen on my pedalshield


20151116_222344_2015-11-17.jpg


it's a SSD1306 I2C 0.96" 128x64 pixels
it may be found on ebay, aliexpress ......
adafruit Monochrome 0.96" 128x64 OLED work but pcb is too big
select I2C or configurable model, not SPI model

wiring:

oled_wire.png

be careful, OLED pinout may be different

my code :

it need U8Glib for Arduino
/*******************************************************************************/
/*  download U8GLib at https://code.google.com/p/u8glib/                       */
/*      SSD1306 128x64 I2C display   -----------> Arduino Due                  */
/*               VCC ------------------------------> 3.3V                      */
/*               GND ------------------------------> GND                       */
/*               SCL ------------------------------> 21 SCL                    */
/*               SDA ------------------------------> 20 SDA                    */
/*******************************************************************************/
#include "U8glib.h"
//U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);  // I2C / TWI 
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_NO_ACK|U8G_I2C_OPT_FAST);  // Fast I2C / TWI 
//U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NO_ACK);  // Display which does not send AC
/*******************************************************************************/
 
   int in_ADC0, in_ADC1;  //variables for 2 ADCs values (ADC0, ADC1)
   int POT0, POT1, POT2, out_DAC0, out_DAC1; //variables for 3 pots (ADC8, ADC9, ADC10)
   int LED = 3;           //pin 3
   int FOOTSWITCH = 7;    //pin 7
   int TOGGLE = 2;        //pin 2
   int toggle_value = 0;  
   int footswitch_value,old_footswitch_value;
   #define N_EFFECT 9  //number of effect
   int effect=0;
   int old_effect=-1;
   int upper_threshold, lower_threshold, adjDelayDepth ;
   #define no_samples 44100
   uint16_t sDelayBuffer0[no_samples];
   unsigned int Delay_Depth , Delay_DepthB, DelayCounter, DelayCounterB = 0;
   #define MAX_DELAY 500
   #define MIN_DELAY 200
   unsigned int count_up=1;
   int p;
   int accumulator, sample, LFO;
   unsigned long DrawMillis=0; // for display timing
 
const unsigned char splashLogo [] U8G_PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0xE0, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0xE0, 0x00, 0x78, 0xF8, 0x30, 0x18, 0xC7, 0xF8, 0xC0, 0x7F, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0xE0, 0x00, 0xF1, 0xFC, 0x30, 0x18, 0xC7, 0xF8, 0xC0, 0x7F, 0xC0,
0x00, 0x00, 0x00, 0x00, 0x01, 0xE0, 0x00, 0xF3, 0x8C, 0x30, 0x18, 0xC7, 0xF8, 0xC0, 0x7F, 0xE0,
0x00, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x00, 0xF3, 0x00, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0xF0,
0x00, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x00, 0xF3, 0x00, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0x70,
0x00, 0x3F, 0xC0, 0x00, 0x3F, 0xC0, 0x00, 0xE3, 0x80, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0x38,
0x00, 0xFF, 0xDF, 0xFC, 0xFF, 0xCF, 0xF9, 0xE3, 0xC0, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0x18,
0x01, 0xE7, 0xDE, 0x3D, 0xE7, 0x80, 0x79, 0xE1, 0xF0, 0x3F, 0xF8, 0xC7, 0xF8, 0xC0, 0x60, 0x18,
0x01, 0xE7, 0x9E, 0x79, 0xE7, 0x80, 0x79, 0xE0, 0xF8, 0x3F, 0xF8, 0xC7, 0xF8, 0xC0, 0x60, 0x18,
0x01, 0xEF, 0xBE, 0x7B, 0xE7, 0x80, 0x79, 0xC0, 0x3C, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0x18,
0x03, 0xCF, 0xBE, 0x7B, 0xE7, 0x80, 0xFB, 0xC0, 0x0E, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0x18,
0x03, 0xCF, 0xBD, 0xFB, 0xCF, 0x3F, 0xFB, 0xC0, 0x06, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0x18,
0x03, 0xCF, 0x7C, 0x03, 0xCF, 0x3C, 0xF3, 0xC0, 0x06, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0x38,
0x03, 0xDF, 0x7C, 0x07, 0xCF, 0x78, 0xF3, 0xC6, 0x06, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0x70,
0x07, 0x9F, 0x7C, 0x07, 0xCF, 0x79, 0xF7, 0x87, 0x06, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0xE0,
0x07, 0x9F, 0x78, 0x07, 0x9E, 0x79, 0xF7, 0x83, 0x8E, 0x30, 0x18, 0xC7, 0xF8, 0xFE, 0x7F, 0xE0,
0x07, 0x9E, 0x78, 0x07, 0x9E, 0x79, 0xE7, 0x81, 0xFC, 0x30, 0x18, 0xC7, 0xF8, 0xFE, 0x7F, 0xC0,
0x07, 0xBE, 0x78, 0x0F, 0xFE, 0x7B, 0xE7, 0x80, 0xF8, 0x30, 0x18, 0xC7, 0xF8, 0xFE, 0x7E, 0x00,
0x0F, 0xF8, 0x7F, 0xCF, 0xFC, 0x7F, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
 
const unsigned char mixOn [] U8G_PROGMEM = {
  0x00, //00000000 ........
  0x00, //00000000 ........
  0x18, //00011000 ...##...
  0x24, //00100100 ..#..#..
  0x42, //01000010 .#....#.
  0x99, //10011001 #..##..#
  0x99, //10011001 #..##..#
  0x5a, //01011010 .#.##.#.
  0x3c, //00111100 ..####..
  0x3c, //00111100 ..####..
  0x3c, //00111100 ..####..
  0x18  //00011000 ...##...
};
 
const unsigned char mixOff [] U8G_PROGMEM = {
  0x18, //00011000 ...##...
  0x3c, //00111100 ..####..
  0x3c, //00111100 ..####..
  0x3c, //00111100 ..####..
  0x5a, //01011010 .#.##.#.
  0x99, //10011001 #..##..#
  0x99, //10011001 #..##..#
  0x42, //01000010 .#....#.
  0x24, //00100100 ..#..#..
  0x18, //00011000 ...##...
  0x00, //00000000 ........
  0x00  //00000000 ........
};
 
 
void setup()
{
  //Oled init
  u8g.setColorIndex(1);         // pixel on
  u8g.firstPage();  
  do {
     drawSplash();
  } while( u8g.nextPage() );
  delay(10000);
 
  /* turn on the timer clock in the power management controller */
  pmc_set_writeprotect(false);
  pmc_enable_periph_clk(ID_TC4);
 
  /* we want wavesel 01 with RC */
  TC_Configure(/* clock */TC1,/* channel */1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC 
  | TC_CMR_TCCLKS_TIMER_CLOCK2);
  TC_SetRC(TC1, 1, 238); // sets <> 44.1 Khz interrupt rate
  //TC_SetRC(TC1, 1, 109); // sets <>   96 Khz interrupt rate
 
  TC_Start(TC1, 1);
 
  // enable timer interrupts on the timer
  TC1->TC_CHANNEL[1].TC_IER=TC_IER_CPCS;
  TC1->TC_CHANNEL[1].TC_IDR=~TC_IER_CPCS;
 
  /* Enable the interrupt in the nested vector interrupt controller */
  /* TC4_IRQn where 4 is the timer number * timer channels (3) + the channel number 
  (=(1*3)+1) for timer1 channel1 */
  NVIC_EnableIRQ(TC4_IRQn);
 
  //ADC Configuration
  ADC->ADC_MR |= 0x80;   // DAC in free running mode.
  ADC->ADC_CR=2;         // Starts ADC conversion.
  ADC->ADC_CHER=0x1CC0;    // Enable ADC channels 0 and 1.  
 
  //DAC Configuration
  analogWrite(DAC0,0);  // Enables DAC0
  analogWrite(DAC1,0);  // Enables DAC0
 
  //configure pin2 as an input and enable the internal pull-up resistor
  pinMode(LED, OUTPUT);
  pinMode(TOGGLE, INPUT_PULLUP);
  toggle_value=digitalRead(TOGGLE);
  attachInterrupt(TOGGLE, switch_handler, CHANGE);
  pinMode(FOOTSWITCH, INPUT_PULLUP);  
}
 
void loop()
{
  //Read the ADCs
  while((ADC->ADC_ISR & 0x1CC0)!=0x1CC0);  // wait for ADC 0, 1, 8, 9, 10 conversion complete.
  in_ADC0=ADC->ADC_CDR[7];             // read data from ADC0
  in_ADC1=ADC->ADC_CDR[6];             // read data from ADC1  
  POT0=ADC->ADC_CDR[10];                   // read data from ADC8        
  POT1=ADC->ADC_CDR[11];                   // read data from ADC9   
  POT2=ADC->ADC_CDR[12];                   // read data from ADC10    
  footswitch_value=digitalRead(FOOTSWITCH);
 
  //create sin tabe for tremolo or sinwave generaor
  if ((effect!=old_effect)&&(effect>=N_EFFECT-1)) 
  {
       u8g.firstPage();  
       do {
         drawSinWait();
       } while( u8g.nextPage() );
       createSineTable();
  }
 
  //lcd refresh on effect change or 
  if ((effect!=old_effect)||(footswitch_value!=old_footswitch_value)||((DrawMillis<millis())&&(footswitch_value==0))) {
    u8g.firstPage();  
    do {
      draw();
    } while( u8g.nextPage() );
    DrawMillis=millis()+100;
    old_effect=effect;
    old_footswitch_value=footswitch_value;
  }
}
 
void draw(void) {
  // graphic commands to redraw the complete screen should be placed here  
  u8g.drawCircle(32,34,5);
  u8g.drawCircle(64,48,5);
  u8g.drawCircle(96,34,5);
  if (footswitch_value==0) {
    u8g.setFont(u8g_font_6x10);
    u8g.setPrintPos(26,50);
    u8g.print(POT0*100/4096); u8g.print('%');
    u8g.setPrintPos(58,64);
    u8g.print(POT1*100/4096); u8g.print('%');
    u8g.setPrintPos(90,50);
    u8g.print(POT2*100/4096); u8g.print('%');
  }
  u8g.setFont(u8g_font_8x13B);
  switch(effect) {
    case 0:  
      u8g.drawStr( 0, 10, " Volume-Booster"); //max 16 char
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 74, 24, " Volume"); //max 8 char
      u8g.drawBitmapP( 4, 42, 1, 12, mixOff);
      u8g.drawStr( 0, 64, "Mix");
      break;
    case 1:  
      u8g.drawStr( 0, 10, "Asym. Distortion");
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 10, 24, "Upp. Th."); //max 8 char
      u8g.drawStr( 42, 38, "Low. Th."); //max 8 char
      u8g.drawStr( 74, 24, " Volume");
      u8g.drawBitmapP( 4, 42, 1, 12, mixOff);
      u8g.drawStr( 0, 64, "Mix");
      break;
    case 2:  
      u8g.drawStr( 0, 10, "      Delay");
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 10, 24, " Delay");
      u8g.drawStr( 74, 24, " Volume");
      u8g.drawBitmapP( 4, 42, 1, 12, mixOn);
      u8g.drawStr( 0, 64, "Mix");
      break;
    case 3:  
      u8g.drawStr( 0, 10, "      Echo");
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 10, 24, " Delay");
      u8g.drawStr( 74, 24, " Volume");
      u8g.drawBitmapP( 4, 42, 1, 12, mixOff);
      u8g.drawStr( 0, 64, "Mix");
      break;
    case 4:  
      u8g.drawStr( 0, 10, " Chorus/Vibrato");
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 10, 24, " Delay");
      u8g.drawStr( 74, 24, " Volume");
      break;
    case 5:  
      u8g.drawStr( 0, 10, "     Octaver");
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 12, 24, " - | +");
      u8g.drawStr( 74, 24, " Volume");
      break;
    case 6:
      u8g.drawStr( 0, 10, "     Reverb");
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 10, 24, "1st Ref");
      u8g.drawStr( 42, 38, "2nd Ref");
      u8g.drawStr( 74, 24, " Volume");
      u8g.drawBitmapP( 4, 42, 1, 12, mixOn);
      u8g.drawStr( 0, 64, "Mix");
     break;
    case 7:
      u8g.drawStr( 0, 10, "  Super-Reverb");
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 10, 24, "1st Ref");
      u8g.drawStr( 42, 38, "2nd Ref");
      u8g.drawStr( 74, 24, " Volume");
      u8g.drawBitmapP( 4, 42, 1, 12, mixOn);
      u8g.drawStr( 0, 64, "Mix");
      break;
    case 8:  
      u8g.drawStr( 0, 10, "     Tremolo");
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 10, 24, "  Freq.");
      u8g.drawStr( 42, 38, "  Depth");
      u8g.drawStr( 74, 24, " Volume");
      u8g.drawBitmapP( 4, 42, 1, 12, mixOff);
      u8g.drawStr( 0, 64, "Mix");
      break;
    case 9:  
      u8g.drawStr( 0, 10, "  SinWave Gen.");
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 10, 24, "  Freq.");
      u8g.drawStr( 74, 24, " Volume");
      u8g.drawBitmapP( 4, 42, 1, 12, mixOff);
      u8g.drawStr( 0, 64, "Mix");
      break;
    default:  
      u8g.drawStr( 0, 10, " Unknown-effect");
      break;
  }
}
 
void drawSinWait()
{
  u8g.setFont(u8g_font_8x13B);
  if (effect==N_EFFECT-1) u8g.drawStr( 0, 10, "    Tremolo");
  if (effect==N_EFFECT) u8g.drawStr( 0, 10, "  SinWave Gen.");
  u8g.drawStr( 0, 32, "     Please");
  u8g.drawStr( 0, 48, "      wait");
}
 
void drawSplash()
{
  u8g.setFont(u8g_font_6x10);
  u8g.drawStr( 0, 46, " Arduino Guitar Pedal");
  u8g.drawStr( 0, 55, "    Multi Effects");
  u8g.drawStr( 0, 64, " www.electrosmash.com");
  u8g.drawBitmapP( 0, 0, 16, 36, splashLogo);
}
 
void createSineTable()
{
  for(uint32_t nIndex=0; nIndex<44100; nIndex++)
  {
    // normalised to 12 bit range 0-4095
    sDelayBuffer0[nIndex] = (uint16_t)  (((1+sin(((2.0*PI)/44100)*nIndex))*4095.0)/2);
  }
}
 
 
void TC4_Handler()
{
   // We need to get the status to clear it and allow the interrupt to fire again
  TC_GetStatus(TC1, 1);
  if (footswitch_value==1) 
  //******************************************************************
  if (effect==0) // EFFECT 0: Volume-Booster    
   {
    digitalWrite(LED, HIGH);  
    //Adjust the volume with POT2
    out_DAC0=map(in_ADC0,0,4095,1,POT2);
    out_DAC1=map(in_ADC1,0,4095,1,POT2);
 
    //Write the DACs
    dacc_set_channel_selection(DACC_INTERFACE, 0);          //select DAC channel 0
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
    dacc_set_channel_selection(DACC_INTERFACE, 1);          //select DAC channel 1
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC1);//write on DAC
   }
  //******************************************************************
  else if (effect==1)  // EFFECT 1: Asymmetric Distortion  
   {
    digitalWrite(LED, LOW); 
    upper_threshold=map(POT0,0,4095,4095,2047);
    lower_threshold=map(POT1,0,4095,0000,2047);
 
    if(in_ADC0>=upper_threshold) in_ADC0=upper_threshold;
    else if(in_ADC0<lower_threshold)  in_ADC0=lower_threshold;
 
    if(in_ADC1>=upper_threshold) in_ADC1=upper_threshold;
    else if(in_ADC1<lower_threshold)  in_ADC1=lower_threshold;
 
    //adjust the volume with POT2
    out_DAC0=map(in_ADC0,0,4095,1,POT2);
    out_DAC1=map(in_ADC1,0,4095,1,POT2);
 
    //Write the DACs
    dacc_set_channel_selection(DACC_INTERFACE, 0);          //select DAC channel 0
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
    dacc_set_channel_selection(DACC_INTERFACE, 1);          //select DAC channel 1
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC1);//write on DAC 
   }
  //******************************************************************
  else if (effect==2) // EFFECT 2: Delay.
   {
    digitalWrite(LED, LOW); 
    //Store current readings  
    sDelayBuffer0[DelayCounter]  = in_ADC0;
 
    //Adjust Delay Depth based in pot0 position.
    Delay_Depth =map(POT0>>2,0,1023,1,MAX_DELAY);
 
    //Increse/reset delay counter.   
    DelayCounter++;
    if(DelayCounter >= Delay_Depth) DelayCounter = 0; 
    out_DAC0 = ((sDelayBuffer0[DelayCounter]));
 
    //Add volume feature based in POT2 position.
    out_DAC0=map(out_DAC0,0,4095,1,POT2);
 
    //Write the DACs
    dacc_set_channel_selection(DACC_INTERFACE, 0);          //select DAC channel 0
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
    dacc_set_channel_selection(DACC_INTERFACE, 1);          //select DAC channel 1
    dacc_write_conversion_data(DACC_INTERFACE, 0);          //write on DAC
   }
  //******************************************************************
  else if (effect==3) // EFFECT 3: Echo.
  {
   digitalWrite(LED, LOW); 
   //Store current readings  
   sDelayBuffer0[DelayCounter]  = (in_ADC0 + (sDelayBuffer0[DelayCounter]))>>1;
 
   //Adjust Delay Depth based in pot0 position.
   Delay_Depth =map(POT0>>2,0,1023,1,MAX_DELAY);
 
   //Increse/reset delay counter.   
   DelayCounter++;
   if(DelayCounter >= Delay_Depth) DelayCounter = 0; 
   out_DAC0 = ((sDelayBuffer0[DelayCounter]));
 
   //Add volume feature based in POT2 position.
   out_DAC0=map(out_DAC0,0,4095,1,POT2);
 
   //Write the DACs
   dacc_set_channel_selection(DACC_INTERFACE, 0);          //select DAC channel 0
   dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
   dacc_set_channel_selection(DACC_INTERFACE, 1);          //select DAC channel 1
   dacc_write_conversion_data(DACC_INTERFACE, 0);          //write on DAC
  }
  //******************************************************************
  else if (effect==4) // EFFECT 4: Chorus
   {
    digitalWrite(LED, LOW); 
    //Store current readings  
    sDelayBuffer0[DelayCounter] = in_ADC0;
 
    //Adjust Delay Depth based in pot0 position.
    adjDelayDepth=map(POT0>>2,0,1023,1,25); //25 empirically chosen
 
    DelayCounter++;
    if(DelayCounter >= Delay_Depth) 
     {
      DelayCounter = 0; 
      if(count_up)
       {
        digitalWrite(LED, HIGH);
        for(p=0;p<adjDelayDepth+1;p++) sDelayBuffer0[Delay_Depth+p]=sDelayBuffer0[Delay_Depth-1]; 
        Delay_Depth=Delay_Depth+adjDelayDepth;
        if (Delay_Depth>=MAX_DELAY)count_up=0;
       }
      else
       {
        digitalWrite(LED, LOW); 
        Delay_Depth=Delay_Depth-adjDelayDepth;
        if (Delay_Depth<=MIN_DELAY)count_up=1;
       }
     }
 
   out_DAC0 = sDelayBuffer0[DelayCounter];
 
   //Add volume control based in POT2
   out_DAC0=map(out_DAC0,0,4095,1,POT2);
 
   //Write the DACs
   dacc_set_channel_selection(DACC_INTERFACE, 0);       //select DAC channel 0
   dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
   dacc_set_channel_selection(DACC_INTERFACE, 1);       //select DAC channel 1
   dacc_write_conversion_data(DACC_INTERFACE, 0);       //write on DAC
  }
  //******************************************************************
  else if (effect==5) // EFFECT 5: Octaver
  {
    sDelayBuffer0[DelayCounter] = in_ADC0;
    sDelayBuffer0[DelayCounter+no_samples/2] = in_ADC1;
 
    //Adjust Delay Depth based in pot2 position.
    Delay_Depth = (no_samples/2) -1;
 
    //Increse/reset delay counter.
    DelayCounter++;
    if(DelayCounter >= Delay_Depth) DelayCounter = 0; 
 
    out_DAC0 = ((sDelayBuffer0[sample]));
    out_DAC1 = ((sDelayBuffer0[sample+no_samples/2]));
 
    if (POT0>2700)
     { 
      sample = sample + 2;
     }
    else if (POT0>1350)
     {
      sample = sample + 1;
     }
    else
     {
     p++;
     if (p>=2)
      {
        sample = sample + 1;
        p=0;
      }
     }
 
    if(sample >= Delay_Depth) sample = 0; 
 
    //Add volume control with POT2
    out_DAC0=map(out_DAC0,0,4095,1,POT2);
    out_DAC1=map(out_DAC1,0,4095,1,POT2);
 
    //Write the DACs
    dacc_set_channel_selection(DACC_INTERFACE, 0);       //select DAC channel 0
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
    dacc_set_channel_selection(DACC_INTERFACE, 1);       //select DAC channel 1
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC1);//write on DAC
  }
  //******************************************************************
  else if (effect==6) // EFFECT 6: Reverb
   {
     //Store current readings in DELAY mode  
     sDelayBuffer0[DelayCounter]  = in_ADC0 ;
     sDelayBuffer0[DelayCounterB+no_samples/2]  = in_ADC1 ;  
 
    //Adjust Delay Depth based in POT0 and POT1 position.
    Delay_Depth =map(POT0>>3,0,512,1,no_samples/2);
    Delay_DepthB =map(POT1>>3,0,512,1,no_samples/2);
 
    //Increse/reset delay counter.   
    DelayCounter++;
    DelayCounterB++;
    if(DelayCounter >= Delay_Depth) DelayCounter = 0; 
    if(DelayCounterB >= Delay_DepthB) DelayCounterB = 0; 
 
    //Calculate the output as the sum of DelayBuffer + DelayBufferB 
    out_DAC0 = (sDelayBuffer0[DelayCounter]);
    out_DAC1 = (sDelayBuffer0[DelayCounterB+no_samples/2]);
 
    //Add volume feature based in pot2 position.
    out_DAC0=map(out_DAC0,0,4095,1,POT2);
    out_DAC1=map(out_DAC1,0,4095,1,POT2);
 
    //Write the DACs
    dacc_set_channel_selection(DACC_INTERFACE, 0);       //select DAC channel 0
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
    dacc_set_channel_selection(DACC_INTERFACE, 1);       //select DAC channel 1
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC1);//write on DAC
   }
  //******************************************************************
  else if (effect==7) // EFFECT 7: Super-Reverb
   {
     //Store current readings in ECHO mode
     sDelayBuffer0[DelayCounter]=(in_ADC0 + (sDelayBuffer0[DelayCounter]))>>1;
     sDelayBuffer0[DelayCounterB+no_samples/2]=(in_ADC1 + (sDelayBuffer0[DelayCounterB+no_samples/2]))>>1; 
    //Adjust Delay Depth based in POT0 and POT1 position.
    Delay_Depth =map(POT0>>3,0,512,1,no_samples/2);
    Delay_DepthB =map(POT1>>3,0,512,1,no_samples/2);
 
    //Increse/reset delay counter.   
    DelayCounter++;
    DelayCounterB++;
    if(DelayCounter >= Delay_Depth) DelayCounter = 0; 
    if(DelayCounterB >= Delay_DepthB) DelayCounterB = 0; 
 
    //Calculate the output as the sum of DelayBuffer + DelayBufferB 
    out_DAC0 = (sDelayBuffer0[DelayCounter]);
    out_DAC1 = (sDelayBuffer0[DelayCounterB+no_samples/2]);
 
    //Add volume feature based in pot2 position.
    out_DAC0=map(out_DAC0,0,4095,1,POT2);
    out_DAC1=map(out_DAC1,0,4095,1,POT2);
 
    //Write the DACs
    dacc_set_channel_selection(DACC_INTERFACE, 0);       //select DAC channel 0
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
    dacc_set_channel_selection(DACC_INTERFACE, 1);       //select DAC channel 1
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC1);//write on DAC
   }
  //******************************************************************
  else if (effect==8) // EFFECT 8: Tremolo
   {
    //Increase the sinewave index and/or reset the value.
    POT0 = POT0>>1; //divide value by 2 (its too big) 
    p++; 
    if (p>=160) //160 chosen empirically
     {
      p=0;
      sample=sample+POT0;
      if(sample>=no_samples) sample=0;
     }
 
    //Create the Low Frequency Oscillator signal with depth control based in POT1.
    LFO=map(sDelayBuffer0[sample],0,4095,(4095-POT1),4095);
 
    //Modulate the output signals based on the sinetable.
    out_DAC0 =map(in_ADC0,1,4095,1, LFO);
    out_DAC1 =map(in_ADC1,1,4095,1, LFO);
 
    //Add volume feature with POT2
    out_DAC0 =map(out_DAC0,1,4095,1, POT2);
    out_DAC1 =map(out_DAC1,1,4095,1, POT2);
 
    //Write the DACs
    dacc_set_channel_selection(DACC_INTERFACE, 0);       //select DAC channel 0
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
    dacc_set_channel_selection(DACC_INTERFACE, 1);       //select DAC channel 1
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC1);//write on DAC
   }
  //******************************************************************
  else if (effect==9) // EFFECT 9: Sinewave generator
   {
    //update the accumulator, from 0 to 511
    accumulator=POT0>>3;
 
    //calculate the sample
    if(sample>=(44100-accumulator)) sample=0;
    sample=sample+accumulator;
 
    //Generate the DAC output
    out_DAC0 = sDelayBuffer0[sample];
    out_DAC1 = 4095 - sDelayBuffer0[sample];
 
    //Add volume feature
    out_DAC0=map(out_DAC0,0,4095,0,POT2);
    out_DAC1=map(out_DAC1,0,4095,0,POT2);
 
    //Write the DACs.
    dacc_set_channel_selection(DACC_INTERFACE, 0);       //select DAC channel 0
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
    dacc_set_channel_selection(DACC_INTERFACE, 1);       //select DAC channel 1
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC1);//write on DAC 
   }
}
 
void switch_handler()
{
  delayMicroseconds(100000); //debouncing protection
  if (toggle_value!=digitalRead(TOGGLE)) effect++;
  delayMicroseconds(100000); //debouncing protection
  toggle_value=digitalRead(TOGGLE);
  if (effect>N_EFFECT) effect=0;
 
  Delay_Depth=300; //reset the variable.
  Delay_DepthB=300;
}  
Last Edit: 4 years 2 days ago by llegoff.
The administrator has disabled public write access.
The following user(s) said Thank You: Ray, ZagatoZee

Mounting an OLED screen on my pedalshield 4 years 4 days ago #382

  • Ray
  • Ray's Avatar
  • NOW ONLINE
  • Moderator
  • Posts: 695
  • Thank you received: 146
  • Karma: 41
This is awesome, could you upload some more pics and give us some details about which model are you using and the connections?
Thanks for your contribution to the pedalSHIELD project!!
The administrator has disabled public write access.

Mounting an OLED screen on my pedalshield 3 years 11 months ago #387

  • llegoff
  • llegoff's Avatar
  • OFFLINE
  • New Member
  • Posts: 4
  • Thank you received: 3
  • Karma: 2
llegoff wrote:
Hi
i mount a oled screen on my pedalshield


20151116_222344_2015-11-17.jpg


it's a SSD1306 I2C 0.96" 128x64 pixels
it may be found on ebay, aliexpress ......
adafruit Monochrome 0.96" 128x64 OLED work but pcb is too big
select I2C or configurable model, not SPI model

wiring:

oled_wire.png

be careful, OLED pinout may be different

my code :

it need U8Glib for Arduino
/*******************************************************************************/
/*  download U8GLib at https://code.google.com/p/u8glib/                       */
/*      SSD1306 128x64 I2C display   -----------> Arduino Due                  */
/*               VCC ------------------------------> 3.3V                      */
/*               GND ------------------------------> GND                       */
/*               SCL ------------------------------> 21 SCL                    */
/*               SDA ------------------------------> 20 SDA                    */
/*******************************************************************************/
#include "U8glib.h"
//U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);  // I2C / TWI 
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_NO_ACK|U8G_I2C_OPT_FAST);  // Fast I2C / TWI 
//U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NO_ACK);  // Display which does not send AC
/*******************************************************************************/
 
   int in_ADC0, in_ADC1;  //variables for 2 ADCs values (ADC0, ADC1)
   int POT0, POT1, POT2, out_DAC0, out_DAC1; //variables for 3 pots (ADC8, ADC9, ADC10)
   int LED = 3;           //pin 3
   int FOOTSWITCH = 7;    //pin 7
   int TOGGLE = 2;        //pin 2
   int toggle_value = 0;  
   int footswitch_value,old_footswitch_value;
   #define N_EFFECT 9  //number of effect
   int effect=0;
   int old_effect=-1;
   int upper_threshold, lower_threshold, adjDelayDepth ;
   #define no_samples 44100
   uint16_t sDelayBuffer0[no_samples];
   unsigned int Delay_Depth , Delay_DepthB, DelayCounter, DelayCounterB = 0;
   #define MAX_DELAY 500
   #define MIN_DELAY 200
   unsigned int count_up=1;
   int p;
   int accumulator, sample, LFO;
   unsigned long DrawMillis=0; // for display timing
 
const unsigned char splashLogo [] U8G_PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0xE0, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0xE0, 0x00, 0x78, 0xF8, 0x30, 0x18, 0xC7, 0xF8, 0xC0, 0x7F, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0xE0, 0x00, 0xF1, 0xFC, 0x30, 0x18, 0xC7, 0xF8, 0xC0, 0x7F, 0xC0,
0x00, 0x00, 0x00, 0x00, 0x01, 0xE0, 0x00, 0xF3, 0x8C, 0x30, 0x18, 0xC7, 0xF8, 0xC0, 0x7F, 0xE0,
0x00, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x00, 0xF3, 0x00, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0xF0,
0x00, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x00, 0xF3, 0x00, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0x70,
0x00, 0x3F, 0xC0, 0x00, 0x3F, 0xC0, 0x00, 0xE3, 0x80, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0x38,
0x00, 0xFF, 0xDF, 0xFC, 0xFF, 0xCF, 0xF9, 0xE3, 0xC0, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0x18,
0x01, 0xE7, 0xDE, 0x3D, 0xE7, 0x80, 0x79, 0xE1, 0xF0, 0x3F, 0xF8, 0xC7, 0xF8, 0xC0, 0x60, 0x18,
0x01, 0xE7, 0x9E, 0x79, 0xE7, 0x80, 0x79, 0xE0, 0xF8, 0x3F, 0xF8, 0xC7, 0xF8, 0xC0, 0x60, 0x18,
0x01, 0xEF, 0xBE, 0x7B, 0xE7, 0x80, 0x79, 0xC0, 0x3C, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0x18,
0x03, 0xCF, 0xBE, 0x7B, 0xE7, 0x80, 0xFB, 0xC0, 0x0E, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0x18,
0x03, 0xCF, 0xBD, 0xFB, 0xCF, 0x3F, 0xFB, 0xC0, 0x06, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0x18,
0x03, 0xCF, 0x7C, 0x03, 0xCF, 0x3C, 0xF3, 0xC0, 0x06, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0x38,
0x03, 0xDF, 0x7C, 0x07, 0xCF, 0x78, 0xF3, 0xC6, 0x06, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0x70,
0x07, 0x9F, 0x7C, 0x07, 0xCF, 0x79, 0xF7, 0x87, 0x06, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0xE0,
0x07, 0x9F, 0x78, 0x07, 0x9E, 0x79, 0xF7, 0x83, 0x8E, 0x30, 0x18, 0xC7, 0xF8, 0xFE, 0x7F, 0xE0,
0x07, 0x9E, 0x78, 0x07, 0x9E, 0x79, 0xE7, 0x81, 0xFC, 0x30, 0x18, 0xC7, 0xF8, 0xFE, 0x7F, 0xC0,
0x07, 0xBE, 0x78, 0x0F, 0xFE, 0x7B, 0xE7, 0x80, 0xF8, 0x30, 0x18, 0xC7, 0xF8, 0xFE, 0x7E, 0x00,
0x0F, 0xF8, 0x7F, 0xCF, 0xFC, 0x7F, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
 
const unsigned char splashWarning [] U8G_PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x03, 0xF8, 0x00,
0x00, 0x01, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0x80, 0x00, 0x07, 0xFE, 0x00,
0x00, 0x03, 0x80, 0xE0, 0x00, 0x03, 0x80, 0xE0, 0x00, 0x03, 0x80, 0x80, 0x00, 0x1C, 0x07, 0x00,
0x00, 0x03, 0x00, 0x70, 0x00, 0x07, 0x00, 0x60, 0x00, 0x03, 0x00, 0x00, 0x00, 0x18, 0xE3, 0x80,
0x00, 0x07, 0x00, 0x70, 0x00, 0x06, 0x00, 0x30, 0x00, 0x06, 0x00, 0x00, 0x00, 0x30, 0xE1, 0x80,
0x00, 0x0F, 0x00, 0x78, 0x00, 0x0C, 0x00, 0x18, 0x00, 0x0C, 0x04, 0x00, 0x00, 0x20, 0xE0, 0xC0,
0x00, 0x0F, 0x80, 0x78, 0x00, 0x0C, 0x00, 0x18, 0x00, 0x0C, 0x1E, 0x00, 0x00, 0x60, 0xE0, 0xC0,
0x00, 0x1F, 0x80, 0xFC, 0x00, 0x0C, 0xFF, 0xDF, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0xE7, 0xFE, 0xC0,
0x00, 0x1F, 0x80, 0xFC, 0x00, 0x0C, 0xFF, 0xDF, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0xE7, 0xFE, 0xC0,
0x00, 0x3F, 0x80, 0xFE, 0x00, 0x0C, 0x00, 0x18, 0x00, 0x0C, 0x1F, 0x00, 0x00, 0x60, 0xE0, 0xC0,
0x00, 0x3F, 0x80, 0xFE, 0x00, 0x0C, 0x00, 0x18, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x60, 0xE0, 0xC0,
0x00, 0x7F, 0x80, 0xFF, 0x00, 0x06, 0x00, 0x30, 0x00, 0x06, 0x00, 0x00, 0x00, 0x30, 0xE0, 0xC0,
0x00, 0xFF, 0x80, 0xFF, 0x80, 0x06, 0x00, 0x30, 0x00, 0x06, 0x00, 0x00, 0x00, 0x30, 0xE1, 0x80,
0x00, 0xFF, 0x80, 0xFF, 0x80, 0x03, 0x00, 0x60, 0x00, 0x03, 0x00, 0x00, 0x00, 0x18, 0x03, 0x00,
0x01, 0xFF, 0x80, 0xFF, 0xC0, 0x01, 0xC1, 0xC0, 0x00, 0x01, 0xC1, 0x80, 0x00, 0x0E, 0x0E, 0x00,
0x01, 0xFF, 0xC1, 0xFF, 0xC0, 0x00, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x07, 0xFC, 0x00,
0x03, 0xFF, 0xC1, 0xFF, 0xE0, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0xF0, 0x00,
0x07, 0xFF, 0xC1, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x07, 0xFF, 0xC1, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0F, 0xFF, 0xE3, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x3F, 0x01, 0xE0, 0x0E, 0x1F, 0x03, 0x0C, 0x01, 0x80, 0x00,
0x1F, 0xFF, 0xC1, 0xFF, 0xFC, 0x00, 0x3F, 0x01, 0xB0, 0x1E, 0x1B, 0x83, 0x8C, 0x01, 0x98, 0x00,
0x3F, 0xFF, 0xC1, 0xFF, 0xFE, 0x00, 0x06, 0x03, 0x18, 0x06, 0x01, 0x81, 0x8C, 0xF1, 0xBE, 0x00,
0x3F, 0xFF, 0xC1, 0xFF, 0xFE, 0x00, 0x06, 0x03, 0x38, 0x06, 0x01, 0x81, 0x99, 0xB9, 0xBE, 0x00,
0x7F, 0xFF, 0xC1, 0xFF, 0xFF, 0x00, 0x0E, 0x79, 0xFB, 0xC6, 0x03, 0x00, 0xD9, 0x99, 0x98, 0x00,
0x7F, 0xFF, 0xE3, 0xFF, 0xFF, 0x00, 0x0C, 0x78, 0xDB, 0xC6, 0x0E, 0x00, 0xDB, 0x99, 0x98, 0x00,
0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x0C, 0x00, 0x30, 0x06, 0x1C, 0x00, 0xF1, 0x99, 0x98, 0x00,
0x3F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x18, 0x01, 0xF0, 0x1F, 0x9F, 0x80, 0x71, 0xF9, 0x9E, 0x00,
0x1F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00,
0x00, 0x08, 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x1C, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x03, 0x01, 0xBF, 0xFE,
0x06, 0x1C, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xE7, 0x83, 0x01, 0xBF, 0xFE,
0x06, 0x1E, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x03, 0x81, 0x83, 0x01, 0x80, 0xC0,
0x06, 0x1E, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0xC3, 0x01, 0x80, 0xC0,
0x06, 0x1B, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x07, 0x00, 0xC3, 0x01, 0x80, 0xC0,
0x06, 0x19, 0x0C, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x06, 0x00, 0x63, 0x01, 0x80, 0xC0,
0x06, 0x19, 0x8C, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x06, 0x00, 0x63, 0x01, 0x80, 0xC0,
0x06, 0x18, 0xCC, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x06, 0x00, 0x63, 0x01, 0x80, 0xC0,
0x06, 0x18, 0xCC, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x06, 0x00, 0x63, 0x01, 0x80, 0xC0,
0x06, 0x18, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x07, 0x00, 0xE3, 0x01, 0x80, 0xC0,
0x06, 0x18, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x03, 0x00, 0xC3, 0x01, 0x80, 0xC0,
0x06, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x03, 0x81, 0xC3, 0x03, 0x00, 0xC0,
0x06, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC3, 0x83, 0x87, 0x00, 0xC0,
0x06, 0x18, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x01, 0xFE, 0x00, 0xC0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x38, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
 
const unsigned char mixOn [] U8G_PROGMEM = {
  0x00, //00000000
  0x00, //00000000
  0x18, //00011000
  0x24, //00100100
  0x42, //01000010
  0x99, //10011001
  0x99, //10011001
  0x5a, //01011010
  0x3c, //00111100
  0x3c, //00111100
  0x3c, //00111100
  0x18  //00011000
};
 
const unsigned char mixOff [] U8G_PROGMEM = {
  0x18, //00011000
  0x3c, //00111100
  0x3c, //00111100
  0x3c, //00111100
  0x5a, //01011010
  0x99, //10011001
  0x99, //10011001
  0x42, //01000010
  0x24, //00100100
  0x18, //00011000
  0x00, //00000000
  0x00  //00000000
};
 
 
void setup()
{
  //Oled init
  u8g.setColorIndex(1);         // pixel on
  u8g.firstPage();  
  do {
     drawSplash();
  } while( u8g.nextPage() );
  delay(7000);
  u8g.firstPage();  
  do {
     u8g.drawBitmapP( 0, 0, 16, 64, splashWarning);
  } while( u8g.nextPage() );
  delay(7000);
 
  /* turn on the timer clock in the power management controller */
  pmc_set_writeprotect(false);
  pmc_enable_periph_clk(ID_TC4);
 
  /* we want wavesel 01 with RC */
  TC_Configure(/* clock */TC1,/* channel */1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC 
  | TC_CMR_TCCLKS_TIMER_CLOCK2);
  TC_SetRC(TC1, 1, 238); // sets <> 44.1 Khz interrupt rate
  //TC_SetRC(TC1, 1, 109); // sets <>   96 Khz interrupt rate
 
  TC_Start(TC1, 1);
 
  // enable timer interrupts on the timer
  TC1->TC_CHANNEL[1].TC_IER=TC_IER_CPCS;
  TC1->TC_CHANNEL[1].TC_IDR=~TC_IER_CPCS;
 
  /* Enable the interrupt in the nested vector interrupt controller */
  /* TC4_IRQn where 4 is the timer number * timer channels (3) + the channel number 
  (=(1*3)+1) for timer1 channel1 */
  NVIC_EnableIRQ(TC4_IRQn);
 
  //ADC Configuration
  ADC->ADC_MR |= 0x80;   // DAC in free running mode.
  ADC->ADC_CR=2;         // Starts ADC conversion.
  ADC->ADC_CHER=0x1CC0;    // Enable ADC channels 0 and 1.  
 
  //DAC Configuration
  analogWrite(DAC0,0);  // Enables DAC0
  analogWrite(DAC1,0);  // Enables DAC0
 
  //configure pin2 as an input and enable the internal pull-up resistor
  pinMode(LED, OUTPUT);
  pinMode(TOGGLE, INPUT_PULLUP);
  toggle_value=digitalRead(TOGGLE);
  attachInterrupt(TOGGLE, switch_handler, CHANGE);
  pinMode(FOOTSWITCH, INPUT_PULLUP);  
}
 
void loop()
{
  //Read the ADCs
  while((ADC->ADC_ISR & 0x1CC0)!=0x1CC0);  // wait for ADC 0, 1, 8, 9, 10 conversion complete.
  in_ADC0=ADC->ADC_CDR[7];             // read data from ADC0
  in_ADC1=ADC->ADC_CDR[6];             // read data from ADC1  
  POT0=ADC->ADC_CDR[10];                   // read data from ADC8        
  POT1=ADC->ADC_CDR[11];                   // read data from ADC9   
  POT2=ADC->ADC_CDR[12];                   // read data from ADC10    
  footswitch_value=digitalRead(FOOTSWITCH);
 
  //create sin tabe for tremolo or sinwave generaor
  if ((effect!=old_effect)&&(effect>=N_EFFECT-1)) 
  {
       u8g.firstPage();  
       do {
         drawSinWait();
       } while( u8g.nextPage() );
       createSineTable();
  }
 
  //lcd refresh on effect change or 
  if ((effect!=old_effect)||(footswitch_value!=old_footswitch_value)||((DrawMillis<millis())&&(footswitch_value==0))) {
    u8g.firstPage();  
    do {
      draw();
    } while( u8g.nextPage() );
    DrawMillis=millis()+100;
    old_effect=effect;
    old_footswitch_value=footswitch_value;
  }
}
 
void draw(void) {
  // graphic commands to redraw the complete screen should be placed here  
  u8g.drawCircle(32,34,5);
  u8g.drawCircle(64,48,5);
  u8g.drawCircle(96,34,5);
  if (footswitch_value==0) {
    u8g.setFont(u8g_font_6x10);
    u8g.setPrintPos(26,50);
    u8g.print(POT0*100/4096); u8g.print('%');
    u8g.setPrintPos(58,64);
    u8g.print(POT1*100/4096); u8g.print('%');
    u8g.setPrintPos(90,50);
    u8g.print(POT2*100/4096); u8g.print('%');
  }
  u8g.setFont(u8g_font_8x13B);
  switch(effect) {
    case 0:  
      u8g.drawStr( 0, 10, " Volume-Booster"); //max 16 char
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 74, 24, " Volume"); //max 8 char
      u8g.drawBitmapP( 4, 42, 1, 12, mixOff);
      u8g.drawStr( 0, 64, "Mix");
      break;
    case 1:  
      u8g.drawStr( 0, 10, "Asym. Distortion");
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 10, 24, "Upp. Th."); //max 8 char
      u8g.drawStr( 42, 38, "Low. Th."); //max 8 char
      u8g.drawStr( 74, 24, " Volume");
      u8g.drawBitmapP( 4, 42, 1, 12, mixOff);
      u8g.drawStr( 0, 64, "Mix");
      break;
    case 2:  
      u8g.drawStr( 0, 10, "      Delay");
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 10, 24, " Delay");
      u8g.drawStr( 74, 24, " Volume");
      u8g.drawBitmapP( 4, 42, 1, 12, mixOn);
      u8g.drawStr( 0, 64, "Mix");
      break;
    case 3:  
      u8g.drawStr( 0, 10, "      Echo");
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 10, 24, " Delay");
      u8g.drawStr( 74, 24, " Volume");
      u8g.drawBitmapP( 4, 42, 1, 12, mixOff);
      u8g.drawStr( 0, 64, "Mix");
      break;
    case 4:  
      u8g.drawStr( 0, 10, " Chorus/Vibrato");
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 10, 24, " Delay");
      u8g.drawStr( 74, 24, " Volume");
      break;
    case 5:  
      u8g.drawStr( 0, 10, "     Octaver");
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 12, 24, " - | +");
      u8g.drawStr( 74, 24, " Volume");
      break;
    case 6:
      u8g.drawStr( 0, 10, "     Reverb");
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 10, 24, "1st Ref");
      u8g.drawStr( 42, 38, "2nd Ref");
      u8g.drawStr( 74, 24, " Volume");
      u8g.drawBitmapP( 4, 42, 1, 12, mixOn);
      u8g.drawStr( 0, 64, "Mix");
     break;
    case 7:
      u8g.drawStr( 0, 10, "  Super-Reverb");
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 10, 24, "1st Ref");
      u8g.drawStr( 42, 38, "2nd Ref");
      u8g.drawStr( 74, 24, " Volume");
      u8g.drawBitmapP( 4, 42, 1, 12, mixOn);
      u8g.drawStr( 0, 64, "Mix");
      break;
    case 8:  
      u8g.drawStr( 0, 10, "     Tremolo");
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 10, 24, "  Freq.");
      u8g.drawStr( 42, 38, "  Depth");
      u8g.drawStr( 74, 24, " Volume");
      u8g.drawBitmapP( 4, 42, 1, 12, mixOff);
      u8g.drawStr( 0, 64, "Mix");
      break;
    case 9:  
      u8g.drawStr( 0, 10, "  SinWave Gen.");
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 10, 24, "  Freq.");
      u8g.drawStr( 74, 24, " Volume");
      u8g.drawBitmapP( 4, 42, 1, 12, mixOff);
      u8g.drawStr( 0, 64, "Mix");
      break;
    default:  
      u8g.drawStr( 0, 10, " Unknown-effect");
      break;
  }
}
 
void drawSinWait()
{
  u8g.setFont(u8g_font_8x13B);
  if (effect==N_EFFECT-1) u8g.drawStr( 0, 10, "     Tremolo");
  if (effect==N_EFFECT) u8g.drawStr( 0, 10, "  SinWave Gen.");
  u8g.drawStr( 0, 32, "     Please");
  u8g.drawStr( 0, 48, "      wait");
}
 
void drawSplash()
{
  u8g.setFont(u8g_font_6x10);
  u8g.drawStr( 0, 46, " Arduino Guitar Pedal");
  u8g.drawStr( 0, 55, "    Multi Effects");
  u8g.drawStr( 0, 64, " www.electrosmash.com");
  u8g.drawBitmapP( 0, 0, 16, 36, splashLogo);
}
 
void createSineTable()
{
  for(uint32_t nIndex=0; nIndex<44100; nIndex++)
  {
    // normalised to 12 bit range 0-4095
    sDelayBuffer0[nIndex] = (uint16_t)  (((1+sin(((2.0*PI)/44100)*nIndex))*4095.0)/2);
  }
}
 
 
void TC4_Handler()
{
   // We need to get the status to clear it and allow the interrupt to fire again
  TC_GetStatus(TC1, 1);
  if (footswitch_value==1) 
  //******************************************************************
  if (effect==0) // EFFECT 0: Volume-Booster    
   {
    digitalWrite(LED, HIGH);  
    //Adjust the volume with POT2
    out_DAC0=map(in_ADC0,0,4095,1,POT2);
    out_DAC1=map(in_ADC1,0,4095,1,POT2);
 
    //Write the DACs
    dacc_set_channel_selection(DACC_INTERFACE, 0);          //select DAC channel 0
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
    dacc_set_channel_selection(DACC_INTERFACE, 1);          //select DAC channel 1
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC1);//write on DAC
   }
  //******************************************************************
  else if (effect==1)  // EFFECT 1: Asymmetric Distortion  
   {
    digitalWrite(LED, LOW); 
    upper_threshold=map(POT0,0,4095,4095,2047);
    lower_threshold=map(POT1,0,4095,0000,2047);
 
    if(in_ADC0>=upper_threshold) in_ADC0=upper_threshold;
    else if(in_ADC0<lower_threshold)  in_ADC0=lower_threshold;
 
    if(in_ADC1>=upper_threshold) in_ADC1=upper_threshold;
    else if(in_ADC1<lower_threshold)  in_ADC1=lower_threshold;
 
    //adjust the volume with POT2
    out_DAC0=map(in_ADC0,0,4095,1,POT2);
    out_DAC1=map(in_ADC1,0,4095,1,POT2);
 
    //Write the DACs
    dacc_set_channel_selection(DACC_INTERFACE, 0);          //select DAC channel 0
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
    dacc_set_channel_selection(DACC_INTERFACE, 1);          //select DAC channel 1
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC1);//write on DAC 
   }
  //******************************************************************
  else if (effect==2) // EFFECT 2: Delay.
   {
    digitalWrite(LED, LOW); 
    //Store current readings  
    sDelayBuffer0[DelayCounter]  = in_ADC0;
 
    //Adjust Delay Depth based in pot0 position.
    Delay_Depth =map(POT0>>2,0,1023,1,MAX_DELAY);
 
    //Increse/reset delay counter.   
    DelayCounter++;
    if(DelayCounter >= Delay_Depth) DelayCounter = 0; 
    out_DAC0 = ((sDelayBuffer0[DelayCounter]));
 
    //Add volume feature based in POT2 position.
    out_DAC0=map(out_DAC0,0,4095,1,POT2);
 
    //Write the DACs
    dacc_set_channel_selection(DACC_INTERFACE, 0);          //select DAC channel 0
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
    dacc_set_channel_selection(DACC_INTERFACE, 1);          //select DAC channel 1
    dacc_write_conversion_data(DACC_INTERFACE, 0);          //write on DAC
   }
  //******************************************************************
  else if (effect==3) // EFFECT 3: Echo.
  {
   digitalWrite(LED, LOW); 
   //Store current readings  
   sDelayBuffer0[DelayCounter]  = (in_ADC0 + (sDelayBuffer0[DelayCounter]))>>1;
 
   //Adjust Delay Depth based in pot0 position.
   Delay_Depth =map(POT0>>2,0,1023,1,MAX_DELAY);
 
   //Increse/reset delay counter.   
   DelayCounter++;
   if(DelayCounter >= Delay_Depth) DelayCounter = 0; 
   out_DAC0 = ((sDelayBuffer0[DelayCounter]));
 
   //Add volume feature based in POT2 position.
   out_DAC0=map(out_DAC0,0,4095,1,POT2);
 
   //Write the DACs
   dacc_set_channel_selection(DACC_INTERFACE, 0);          //select DAC channel 0
   dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
   dacc_set_channel_selection(DACC_INTERFACE, 1);          //select DAC channel 1
   dacc_write_conversion_data(DACC_INTERFACE, 0);          //write on DAC
  }
  //******************************************************************
  else if (effect==4) // EFFECT 4: Chorus
   {
    digitalWrite(LED, LOW); 
    //Store current readings  
    sDelayBuffer0[DelayCounter] = in_ADC0;
 
    //Adjust Delay Depth based in pot0 position.
    adjDelayDepth=map(POT0>>2,0,1023,1,25); //25 empirically chosen
 
    DelayCounter++;
    if(DelayCounter >= Delay_Depth) 
     {
      DelayCounter = 0; 
      if(count_up)
       {
        digitalWrite(LED, HIGH);
        for(p=0;p<adjDelayDepth+1;p++) sDelayBuffer0[Delay_Depth+p]=sDelayBuffer0[Delay_Depth-1]; 
        Delay_Depth=Delay_Depth+adjDelayDepth;
        if (Delay_Depth>=MAX_DELAY)count_up=0;
       }
      else
       {
        digitalWrite(LED, LOW); 
        Delay_Depth=Delay_Depth-adjDelayDepth;
        if (Delay_Depth<=MIN_DELAY)count_up=1;
       }
     }
 
   out_DAC0 = sDelayBuffer0[DelayCounter];
 
   //Add volume control based in POT2
   out_DAC0=map(out_DAC0,0,4095,1,POT2);
 
   //Write the DACs
   dacc_set_channel_selection(DACC_INTERFACE, 0);       //select DAC channel 0
   dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
   dacc_set_channel_selection(DACC_INTERFACE, 1);       //select DAC channel 1
   dacc_write_conversion_data(DACC_INTERFACE, 0);       //write on DAC
  }
  //******************************************************************
  else if (effect==5) // EFFECT 5: Octaver
  {
    sDelayBuffer0[DelayCounter] = in_ADC0;
    sDelayBuffer0[DelayCounter+no_samples/2] = in_ADC1;
 
    //Adjust Delay Depth based in pot2 position.
    Delay_Depth = (no_samples/2) -1;
 
    //Increse/reset delay counter.
    DelayCounter++;
    if(DelayCounter >= Delay_Depth) DelayCounter = 0; 
 
    out_DAC0 = ((sDelayBuffer0[sample]));
    out_DAC1 = ((sDelayBuffer0[sample+no_samples/2]));
 
    if (POT0>2700)
     { 
      sample = sample + 2;
     }
    else if (POT0>1350)
     {
      sample = sample + 1;
     }
    else
     {
     p++;
     if (p>=2)
      {
        sample = sample + 1;
        p=0;
      }
     }
 
    if(sample >= Delay_Depth) sample = 0; 
 
    //Add volume control with POT2
    out_DAC0=map(out_DAC0,0,4095,1,POT2);
    out_DAC1=map(out_DAC1,0,4095,1,POT2);
 
    //Write the DACs
    dacc_set_channel_selection(DACC_INTERFACE, 0);       //select DAC channel 0
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
    dacc_set_channel_selection(DACC_INTERFACE, 1);       //select DAC channel 1
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC1);//write on DAC
  }
  //******************************************************************
  else if (effect==6) // EFFECT 6: Reverb
   {
     //Store current readings in DELAY mode  
     sDelayBuffer0[DelayCounter]  = in_ADC0 ;
     sDelayBuffer0[DelayCounterB+no_samples/2]  = in_ADC1 ;  
 
    //Adjust Delay Depth based in POT0 and POT1 position.
    Delay_Depth =map(POT0>>3,0,512,1,no_samples/2);
    Delay_DepthB =map(POT1>>3,0,512,1,no_samples/2);
 
    //Increse/reset delay counter.   
    DelayCounter++;
    DelayCounterB++;
    if(DelayCounter >= Delay_Depth) DelayCounter = 0; 
    if(DelayCounterB >= Delay_DepthB) DelayCounterB = 0; 
 
    //Calculate the output as the sum of DelayBuffer + DelayBufferB 
    out_DAC0 = (sDelayBuffer0[DelayCounter]);
    out_DAC1 = (sDelayBuffer0[DelayCounterB+no_samples/2]);
 
    //Add volume feature based in pot2 position.
    out_DAC0=map(out_DAC0,0,4095,1,POT2);
    out_DAC1=map(out_DAC1,0,4095,1,POT2);
 
    //Write the DACs
    dacc_set_channel_selection(DACC_INTERFACE, 0);       //select DAC channel 0
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
    dacc_set_channel_selection(DACC_INTERFACE, 1);       //select DAC channel 1
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC1);//write on DAC
   }
  //******************************************************************
  else if (effect==7) // EFFECT 7: Super-Reverb
   {
     //Store current readings in ECHO mode
     sDelayBuffer0[DelayCounter]=(in_ADC0 + (sDelayBuffer0[DelayCounter]))>>1;
     sDelayBuffer0[DelayCounterB+no_samples/2]=(in_ADC1 + (sDelayBuffer0[DelayCounterB+no_samples/2]))>>1; 
    //Adjust Delay Depth based in POT0 and POT1 position.
    Delay_Depth =map(POT0>>3,0,512,1,no_samples/2);
    Delay_DepthB =map(POT1>>3,0,512,1,no_samples/2);
 
    //Increse/reset delay counter.   
    DelayCounter++;
    DelayCounterB++;
    if(DelayCounter >= Delay_Depth) DelayCounter = 0; 
    if(DelayCounterB >= Delay_DepthB) DelayCounterB = 0; 
 
    //Calculate the output as the sum of DelayBuffer + DelayBufferB 
    out_DAC0 = (sDelayBuffer0[DelayCounter]);
    out_DAC1 = (sDelayBuffer0[DelayCounterB+no_samples/2]);
 
    //Add volume feature based in pot2 position.
    out_DAC0=map(out_DAC0,0,4095,1,POT2);
    out_DAC1=map(out_DAC1,0,4095,1,POT2);
 
    //Write the DACs
    dacc_set_channel_selection(DACC_INTERFACE, 0);       //select DAC channel 0
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
    dacc_set_channel_selection(DACC_INTERFACE, 1);       //select DAC channel 1
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC1);//write on DAC
   }
  //******************************************************************
  else if (effect==8) // EFFECT 8: Tremolo
   {
    //Increase the sinewave index and/or reset the value.
    POT0 = POT0>>1; //divide value by 2 (its too big) 
    p++; 
    if (p>=160) //160 chosen empirically
     {
      p=0;
      sample=sample+POT0;
      if(sample>=no_samples) sample=0;
     }
 
    //Create the Low Frequency Oscillator signal with depth control based in POT1.
    LFO=map(sDelayBuffer0[sample],0,4095,(4095-POT1),4095);
 
    //Modulate the output signals based on the sinetable.
    out_DAC0 =map(in_ADC0,1,4095,1, LFO);
    out_DAC1 =map(in_ADC1,1,4095,1, LFO);
 
    //Add volume feature with POT2
    out_DAC0 =map(out_DAC0,1,4095,1, POT2);
    out_DAC1 =map(out_DAC1,1,4095,1, POT2);
 
    //Write the DACs
    dacc_set_channel_selection(DACC_INTERFACE, 0);       //select DAC channel 0
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
    dacc_set_channel_selection(DACC_INTERFACE, 1);       //select DAC channel 1
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC1);//write on DAC
   }
  //******************************************************************
  else if (effect==9) // EFFECT 9: Sinewave generator
   {
    //update the accumulator, from 0 to 511
    accumulator=POT0>>3;
 
    //calculate the sample
    if(sample>=(44100-accumulator)) sample=0;
    sample=sample+accumulator;
 
    //Generate the DAC output
    out_DAC0 = sDelayBuffer0[sample];
    out_DAC1 = 4095 - sDelayBuffer0[sample];
 
    //Add volume feature
    out_DAC0=map(out_DAC0,0,4095,0,POT2);
    out_DAC1=map(out_DAC1,0,4095,0,POT2);
 
    //Write the DACs.
    dacc_set_channel_selection(DACC_INTERFACE, 0);       //select DAC channel 0
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
    dacc_set_channel_selection(DACC_INTERFACE, 1);       //select DAC channel 1
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC1);//write on DAC 
   }
}
 
void switch_handler()
{
  delayMicroseconds(100000); //debouncing protection
  if (toggle_value!=digitalRead(TOGGLE)) effect++;
  delayMicroseconds(100000); //debouncing protection
  toggle_value=digitalRead(TOGGLE);
  if (effect>N_EFFECT) effect=0;
 
  Delay_Depth=300; //reset the variable.
  Delay_DepthB=300;
} 
 
The administrator has disabled public write access.
The following user(s) said Thank You: Ray

Mounting an OLED screen on my pedalshield 3 years 11 months ago #388

  • llegoff
  • llegoff's Avatar
  • OFFLINE
  • New Member
  • Posts: 4
  • Thank you received: 3
  • Karma: 2
llegoff wrote:
Hi
i mount a oled screen on my pedalshield


20151116_222344_2015-11-17.jpg


it's a SSD1306 I2C 0.96" 128x64 pixels
it may be found on ebay, aliexpress ......
adafruit Monochrome 0.96" 128x64 OLED work but pcb is too big
select I2C or configurable model, not SPI model

wiring:

oled_wire.png

be careful, OLED pinout may be different

my code :

it need U8Glib for Arduino
/*******************************************************************************/
/*  download U8GLib at https://code.google.com/p/u8glib/                       */
/*      SSD1306 128x64 I2C display   -----------> Arduino Due                  */
/*               VCC ------------------------------> 3.3V                      */
/*               GND ------------------------------> GND                       */
/*               SCL ------------------------------> 21 SCL                    */
/*               SDA ------------------------------> 20 SDA                    */
/*******************************************************************************/
#include "U8glib.h"
//U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);  // I2C / TWI 
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_NO_ACK|U8G_I2C_OPT_FAST);  // Fast I2C / TWI 
//U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NO_ACK);  // Display which does not send AC
/*******************************************************************************/
 
   int in_ADC0, in_ADC1;  //variables for 2 ADCs values (ADC0, ADC1)
   int POT0, POT1, POT2, out_DAC0, out_DAC1; //variables for 3 pots (ADC8, ADC9, ADC10)
   int LED = 3;           //pin 3
   int FOOTSWITCH = 7;    //pin 7
   int TOGGLE = 2;        //pin 2
   int toggle_value = 0;  
   int footswitch_value,old_footswitch_value;
   #define N_EFFECT 9  //number of effect
   int effect=0;
   int old_effect=-1;
   int upper_threshold, lower_threshold, adjDelayDepth ;
   #define no_samples 44100
   uint16_t sDelayBuffer0[no_samples];
   unsigned int Delay_Depth , Delay_DepthB, DelayCounter, DelayCounterB = 0;
   #define MAX_DELAY 500
   #define MIN_DELAY 200
   unsigned int count_up=1;
   int p;
   int accumulator, sample, LFO;
   unsigned long DrawMillis=0; // for display timing
 
const unsigned char splashLogo [] U8G_PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0xE0, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0xE0, 0x00, 0x78, 0xF8, 0x30, 0x18, 0xC7, 0xF8, 0xC0, 0x7F, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0xE0, 0x00, 0xF1, 0xFC, 0x30, 0x18, 0xC7, 0xF8, 0xC0, 0x7F, 0xC0,
0x00, 0x00, 0x00, 0x00, 0x01, 0xE0, 0x00, 0xF3, 0x8C, 0x30, 0x18, 0xC7, 0xF8, 0xC0, 0x7F, 0xE0,
0x00, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x00, 0xF3, 0x00, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0xF0,
0x00, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x00, 0xF3, 0x00, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0x70,
0x00, 0x3F, 0xC0, 0x00, 0x3F, 0xC0, 0x00, 0xE3, 0x80, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0x38,
0x00, 0xFF, 0xDF, 0xFC, 0xFF, 0xCF, 0xF9, 0xE3, 0xC0, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0x18,
0x01, 0xE7, 0xDE, 0x3D, 0xE7, 0x80, 0x79, 0xE1, 0xF0, 0x3F, 0xF8, 0xC7, 0xF8, 0xC0, 0x60, 0x18,
0x01, 0xE7, 0x9E, 0x79, 0xE7, 0x80, 0x79, 0xE0, 0xF8, 0x3F, 0xF8, 0xC7, 0xF8, 0xC0, 0x60, 0x18,
0x01, 0xEF, 0xBE, 0x7B, 0xE7, 0x80, 0x79, 0xC0, 0x3C, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0x18,
0x03, 0xCF, 0xBE, 0x7B, 0xE7, 0x80, 0xFB, 0xC0, 0x0E, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0x18,
0x03, 0xCF, 0xBD, 0xFB, 0xCF, 0x3F, 0xFB, 0xC0, 0x06, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0x18,
0x03, 0xCF, 0x7C, 0x03, 0xCF, 0x3C, 0xF3, 0xC0, 0x06, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0x38,
0x03, 0xDF, 0x7C, 0x07, 0xCF, 0x78, 0xF3, 0xC6, 0x06, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0x70,
0x07, 0x9F, 0x7C, 0x07, 0xCF, 0x79, 0xF7, 0x87, 0x06, 0x30, 0x18, 0xC6, 0x00, 0xC0, 0x60, 0xE0,
0x07, 0x9F, 0x78, 0x07, 0x9E, 0x79, 0xF7, 0x83, 0x8E, 0x30, 0x18, 0xC7, 0xF8, 0xFE, 0x7F, 0xE0,
0x07, 0x9E, 0x78, 0x07, 0x9E, 0x79, 0xE7, 0x81, 0xFC, 0x30, 0x18, 0xC7, 0xF8, 0xFE, 0x7F, 0xC0,
0x07, 0xBE, 0x78, 0x0F, 0xFE, 0x7B, 0xE7, 0x80, 0xF8, 0x30, 0x18, 0xC7, 0xF8, 0xFE, 0x7E, 0x00,
0x0F, 0xF8, 0x7F, 0xCF, 0xFC, 0x7F, 0xEF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
 
const unsigned char splashWarning [] U8G_PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0xFF, 0xC0, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x03, 0xF8, 0x00,
0x00, 0x01, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0xC0, 0x00, 0x01, 0xFF, 0x80, 0x00, 0x07, 0xFE, 0x00,
0x00, 0x03, 0x80, 0xE0, 0x00, 0x03, 0x80, 0xE0, 0x00, 0x03, 0x80, 0x80, 0x00, 0x1C, 0x07, 0x00,
0x00, 0x03, 0x00, 0x70, 0x00, 0x07, 0x00, 0x60, 0x00, 0x03, 0x00, 0x00, 0x00, 0x18, 0xE3, 0x80,
0x00, 0x07, 0x00, 0x70, 0x00, 0x06, 0x00, 0x30, 0x00, 0x06, 0x00, 0x00, 0x00, 0x30, 0xE1, 0x80,
0x00, 0x0F, 0x00, 0x78, 0x00, 0x0C, 0x00, 0x18, 0x00, 0x0C, 0x04, 0x00, 0x00, 0x20, 0xE0, 0xC0,
0x00, 0x0F, 0x80, 0x78, 0x00, 0x0C, 0x00, 0x18, 0x00, 0x0C, 0x1E, 0x00, 0x00, 0x60, 0xE0, 0xC0,
0x00, 0x1F, 0x80, 0xFC, 0x00, 0x0C, 0xFF, 0xDF, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0xE7, 0xFE, 0xC0,
0x00, 0x1F, 0x80, 0xFC, 0x00, 0x0C, 0xFF, 0xDF, 0xFF, 0xFC, 0x1F, 0xFF, 0xFF, 0xE7, 0xFE, 0xC0,
0x00, 0x3F, 0x80, 0xFE, 0x00, 0x0C, 0x00, 0x18, 0x00, 0x0C, 0x1F, 0x00, 0x00, 0x60, 0xE0, 0xC0,
0x00, 0x3F, 0x80, 0xFE, 0x00, 0x0C, 0x00, 0x18, 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x60, 0xE0, 0xC0,
0x00, 0x7F, 0x80, 0xFF, 0x00, 0x06, 0x00, 0x30, 0x00, 0x06, 0x00, 0x00, 0x00, 0x30, 0xE0, 0xC0,
0x00, 0xFF, 0x80, 0xFF, 0x80, 0x06, 0x00, 0x30, 0x00, 0x06, 0x00, 0x00, 0x00, 0x30, 0xE1, 0x80,
0x00, 0xFF, 0x80, 0xFF, 0x80, 0x03, 0x00, 0x60, 0x00, 0x03, 0x00, 0x00, 0x00, 0x18, 0x03, 0x00,
0x01, 0xFF, 0x80, 0xFF, 0xC0, 0x01, 0xC1, 0xC0, 0x00, 0x01, 0xC1, 0x80, 0x00, 0x0E, 0x0E, 0x00,
0x01, 0xFF, 0xC1, 0xFF, 0xC0, 0x00, 0xFF, 0x80, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x07, 0xFC, 0x00,
0x03, 0xFF, 0xC1, 0xFF, 0xE0, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0xF0, 0x00,
0x07, 0xFF, 0xC1, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x07, 0xFF, 0xC1, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0F, 0xFF, 0xE3, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0F, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x1F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x3F, 0x01, 0xE0, 0x0E, 0x1F, 0x03, 0x0C, 0x01, 0x80, 0x00,
0x1F, 0xFF, 0xC1, 0xFF, 0xFC, 0x00, 0x3F, 0x01, 0xB0, 0x1E, 0x1B, 0x83, 0x8C, 0x01, 0x98, 0x00,
0x3F, 0xFF, 0xC1, 0xFF, 0xFE, 0x00, 0x06, 0x03, 0x18, 0x06, 0x01, 0x81, 0x8C, 0xF1, 0xBE, 0x00,
0x3F, 0xFF, 0xC1, 0xFF, 0xFE, 0x00, 0x06, 0x03, 0x38, 0x06, 0x01, 0x81, 0x99, 0xB9, 0xBE, 0x00,
0x7F, 0xFF, 0xC1, 0xFF, 0xFF, 0x00, 0x0E, 0x79, 0xFB, 0xC6, 0x03, 0x00, 0xD9, 0x99, 0x98, 0x00,
0x7F, 0xFF, 0xE3, 0xFF, 0xFF, 0x00, 0x0C, 0x78, 0xDB, 0xC6, 0x0E, 0x00, 0xDB, 0x99, 0x98, 0x00,
0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x0C, 0x00, 0x30, 0x06, 0x1C, 0x00, 0xF1, 0x99, 0x98, 0x00,
0x3F, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x18, 0x01, 0xF0, 0x1F, 0x9F, 0x80, 0x71, 0xF9, 0x9E, 0x00,
0x1F, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00,
0x00, 0x08, 0x7F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x1C, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x03, 0x01, 0xBF, 0xFE,
0x06, 0x1C, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xE7, 0x83, 0x01, 0xBF, 0xFE,
0x06, 0x1E, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x03, 0x81, 0x83, 0x01, 0x80, 0xC0,
0x06, 0x1E, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x03, 0x00, 0xC3, 0x01, 0x80, 0xC0,
0x06, 0x1B, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x07, 0x00, 0xC3, 0x01, 0x80, 0xC0,
0x06, 0x19, 0x0C, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x06, 0x00, 0x63, 0x01, 0x80, 0xC0,
0x06, 0x19, 0x8C, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x06, 0x00, 0x63, 0x01, 0x80, 0xC0,
0x06, 0x18, 0xCC, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x06, 0x00, 0x63, 0x01, 0x80, 0xC0,
0x06, 0x18, 0xCC, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x06, 0x00, 0x63, 0x01, 0x80, 0xC0,
0x06, 0x18, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x80, 0x07, 0x00, 0xE3, 0x01, 0x80, 0xC0,
0x06, 0x18, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x03, 0x00, 0xC3, 0x01, 0x80, 0xC0,
0x06, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x03, 0x81, 0xC3, 0x03, 0x00, 0xC0,
0x06, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC3, 0x83, 0x87, 0x00, 0xC0,
0x06, 0x18, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x01, 0xFE, 0x00, 0xC0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x38, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
 
const unsigned char mixOn [] U8G_PROGMEM = {
  0x00, //00000000
  0x00, //00000000
  0x18, //00011000
  0x24, //00100100
  0x42, //01000010
  0x99, //10011001
  0x99, //10011001
  0x5a, //01011010
  0x3c, //00111100
  0x3c, //00111100
  0x3c, //00111100
  0x18  //00011000
};
 
const unsigned char mixOff [] U8G_PROGMEM = {
  0x18, //00011000
  0x3c, //00111100
  0x3c, //00111100
  0x3c, //00111100
  0x5a, //01011010
  0x99, //10011001
  0x99, //10011001
  0x42, //01000010
  0x24, //00100100
  0x18, //00011000
  0x00, //00000000
  0x00  //00000000
};
 
 
void setup()
{
  //Oled init
  u8g.setColorIndex(1);         // pixel on
  u8g.firstPage();  
  do {
     drawSplash();
  } while( u8g.nextPage() );
  delay(7000);
  u8g.firstPage();  
  do {
     u8g.drawBitmapP( 0, 0, 16, 64, splashWarning);
  } while( u8g.nextPage() );
  delay(7000);
 
  /* turn on the timer clock in the power management controller */
  pmc_set_writeprotect(false);
  pmc_enable_periph_clk(ID_TC4);
 
  /* we want wavesel 01 with RC */
  TC_Configure(/* clock */TC1,/* channel */1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC 
  | TC_CMR_TCCLKS_TIMER_CLOCK2);
  TC_SetRC(TC1, 1, 238); // sets <> 44.1 Khz interrupt rate
  //TC_SetRC(TC1, 1, 109); // sets <>   96 Khz interrupt rate
 
  TC_Start(TC1, 1);
 
  // enable timer interrupts on the timer
  TC1->TC_CHANNEL[1].TC_IER=TC_IER_CPCS;
  TC1->TC_CHANNEL[1].TC_IDR=~TC_IER_CPCS;
 
  /* Enable the interrupt in the nested vector interrupt controller */
  /* TC4_IRQn where 4 is the timer number * timer channels (3) + the channel number 
  (=(1*3)+1) for timer1 channel1 */
  NVIC_EnableIRQ(TC4_IRQn);
 
  //ADC Configuration
  ADC->ADC_MR |= 0x80;   // DAC in free running mode.
  ADC->ADC_CR=2;         // Starts ADC conversion.
  ADC->ADC_CHER=0x1CC0;    // Enable ADC channels 0 and 1.  
 
  //DAC Configuration
  analogWrite(DAC0,0);  // Enables DAC0
  analogWrite(DAC1,0);  // Enables DAC0
 
  //configure pin2 as an input and enable the internal pull-up resistor
  pinMode(LED, OUTPUT);
  pinMode(TOGGLE, INPUT_PULLUP);
  toggle_value=digitalRead(TOGGLE);
  attachInterrupt(TOGGLE, switch_handler, CHANGE);
  pinMode(FOOTSWITCH, INPUT_PULLUP);  
}
 
void loop()
{
  //Read the ADCs
  while((ADC->ADC_ISR & 0x1CC0)!=0x1CC0);  // wait for ADC 0, 1, 8, 9, 10 conversion complete.
  in_ADC0=ADC->ADC_CDR[7];             // read data from ADC0
  in_ADC1=ADC->ADC_CDR[6];             // read data from ADC1  
  POT0=ADC->ADC_CDR[10];                   // read data from ADC8        
  POT1=ADC->ADC_CDR[11];                   // read data from ADC9   
  POT2=ADC->ADC_CDR[12];                   // read data from ADC10    
  footswitch_value=digitalRead(FOOTSWITCH);
 
  //create sin tabe for tremolo or sinwave generaor
  if ((effect!=old_effect)&&(effect>=N_EFFECT-1)) 
  {
       u8g.firstPage();  
       do {
         drawSinWait();
       } while( u8g.nextPage() );
       createSineTable();
  }
 
  //lcd refresh on effect change or 
  if ((effect!=old_effect)||(footswitch_value!=old_footswitch_value)||((DrawMillis<millis())&&(footswitch_value==0))) {
    u8g.firstPage();  
    do {
      draw();
    } while( u8g.nextPage() );
    DrawMillis=millis()+100;
    old_effect=effect;
    old_footswitch_value=footswitch_value;
  }
}
 
void draw(void) {
  // graphic commands to redraw the complete screen should be placed here  
  u8g.drawCircle(32,34,5);
  u8g.drawCircle(64,48,5);
  u8g.drawCircle(96,34,5);
  if (footswitch_value==0) {
    u8g.setFont(u8g_font_6x10);
    u8g.setPrintPos(26,50);
    u8g.print(POT0*100/4096); u8g.print('%');
    u8g.setPrintPos(58,64);
    u8g.print(POT1*100/4096); u8g.print('%');
    u8g.setPrintPos(90,50);
    u8g.print(POT2*100/4096); u8g.print('%');
  }
  u8g.setFont(u8g_font_8x13B);
  switch(effect) {
    case 0:  
      u8g.drawStr( 0, 10, " Volume-Booster"); //max 16 char
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 74, 24, " Volume"); //max 8 char
      u8g.drawBitmapP( 4, 42, 1, 12, mixOff);
      u8g.drawStr( 0, 64, "Mix");
      break;
    case 1:  
      u8g.drawStr( 0, 10, "Asym. Distortion");
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 10, 24, "Upp. Th."); //max 8 char
      u8g.drawStr( 42, 38, "Low. Th."); //max 8 char
      u8g.drawStr( 74, 24, " Volume");
      u8g.drawBitmapP( 4, 42, 1, 12, mixOff);
      u8g.drawStr( 0, 64, "Mix");
      break;
    case 2:  
      u8g.drawStr( 0, 10, "      Delay");
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 10, 24, " Delay");
      u8g.drawStr( 74, 24, " Volume");
      u8g.drawBitmapP( 4, 42, 1, 12, mixOn);
      u8g.drawStr( 0, 64, "Mix");
      break;
    case 3:  
      u8g.drawStr( 0, 10, "      Echo");
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 10, 24, " Delay");
      u8g.drawStr( 74, 24, " Volume");
      u8g.drawBitmapP( 4, 42, 1, 12, mixOff);
      u8g.drawStr( 0, 64, "Mix");
      break;
    case 4:  
      u8g.drawStr( 0, 10, " Chorus/Vibrato");
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 10, 24, " Delay");
      u8g.drawStr( 74, 24, " Volume");
      break;
    case 5:  
      u8g.drawStr( 0, 10, "     Octaver");
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 12, 24, " - | +");
      u8g.drawStr( 74, 24, " Volume");
      break;
    case 6:
      u8g.drawStr( 0, 10, "     Reverb");
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 10, 24, "1st Ref");
      u8g.drawStr( 42, 38, "2nd Ref");
      u8g.drawStr( 74, 24, " Volume");
      u8g.drawBitmapP( 4, 42, 1, 12, mixOn);
      u8g.drawStr( 0, 64, "Mix");
     break;
    case 7:
      u8g.drawStr( 0, 10, "  Super-Reverb");
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 10, 24, "1st Ref");
      u8g.drawStr( 42, 38, "2nd Ref");
      u8g.drawStr( 74, 24, " Volume");
      u8g.drawBitmapP( 4, 42, 1, 12, mixOn);
      u8g.drawStr( 0, 64, "Mix");
      break;
    case 8:  
      u8g.drawStr( 0, 10, "     Tremolo");
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 10, 24, "  Freq.");
      u8g.drawStr( 42, 38, "  Depth");
      u8g.drawStr( 74, 24, " Volume");
      u8g.drawBitmapP( 4, 42, 1, 12, mixOff);
      u8g.drawStr( 0, 64, "Mix");
      break;
    case 9:  
      u8g.drawStr( 0, 10, "  SinWave Gen.");
      u8g.setFont(u8g_font_6x10);
      u8g.drawStr( 10, 24, "  Freq.");
      u8g.drawStr( 74, 24, " Volume");
      u8g.drawBitmapP( 4, 42, 1, 12, mixOff);
      u8g.drawStr( 0, 64, "Mix");
      break;
    default:  
      u8g.drawStr( 0, 10, " Unknown-effect");
      break;
  }
}
 
void drawSinWait()
{
  u8g.setFont(u8g_font_8x13B);
  if (effect==N_EFFECT-1) u8g.drawStr( 0, 10, "     Tremolo");
  if (effect==N_EFFECT) u8g.drawStr( 0, 10, "  SinWave Gen.");
  u8g.drawStr( 0, 32, "     Please");
  u8g.drawStr( 0, 48, "      wait");
}
 
void drawSplash()
{
  u8g.setFont(u8g_font_6x10);
  u8g.drawStr( 0, 46, " Arduino Guitar Pedal");
  u8g.drawStr( 0, 55, "    Multi Effects");
  u8g.drawStr( 0, 64, " www.electrosmash.com");
  u8g.drawBitmapP( 0, 0, 16, 36, splashLogo);
}
 
void createSineTable()
{
  for(uint32_t nIndex=0; nIndex<44100; nIndex++)
  {
    // normalised to 12 bit range 0-4095
    sDelayBuffer0[nIndex] = (uint16_t)  (((1+sin(((2.0*PI)/44100)*nIndex))*4095.0)/2);
  }
}
 
 
void TC4_Handler()
{
   // We need to get the status to clear it and allow the interrupt to fire again
  TC_GetStatus(TC1, 1);
  if (footswitch_value==1) 
  //******************************************************************
  if (effect==0) // EFFECT 0: Volume-Booster    
   {
    digitalWrite(LED, HIGH);  
    //Adjust the volume with POT2
    out_DAC0=map(in_ADC0,0,4095,1,POT2);
    out_DAC1=map(in_ADC1,0,4095,1,POT2);
 
    //Write the DACs
    dacc_set_channel_selection(DACC_INTERFACE, 0);          //select DAC channel 0
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
    dacc_set_channel_selection(DACC_INTERFACE, 1);          //select DAC channel 1
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC1);//write on DAC
   }
  //******************************************************************
  else if (effect==1)  // EFFECT 1: Asymmetric Distortion  
   {
    digitalWrite(LED, LOW); 
    upper_threshold=map(POT0,0,4095,4095,2047);
    lower_threshold=map(POT1,0,4095,0000,2047);
 
    if(in_ADC0>=upper_threshold) in_ADC0=upper_threshold;
    else if(in_ADC0<lower_threshold)  in_ADC0=lower_threshold;
 
    if(in_ADC1>=upper_threshold) in_ADC1=upper_threshold;
    else if(in_ADC1<lower_threshold)  in_ADC1=lower_threshold;
 
    //adjust the volume with POT2
    out_DAC0=map(in_ADC0,0,4095,1,POT2);
    out_DAC1=map(in_ADC1,0,4095,1,POT2);
 
    //Write the DACs
    dacc_set_channel_selection(DACC_INTERFACE, 0);          //select DAC channel 0
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
    dacc_set_channel_selection(DACC_INTERFACE, 1);          //select DAC channel 1
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC1);//write on DAC 
   }
  //******************************************************************
  else if (effect==2) // EFFECT 2: Delay.
   {
    digitalWrite(LED, LOW); 
    //Store current readings  
    sDelayBuffer0[DelayCounter]  = in_ADC0;
 
    //Adjust Delay Depth based in pot0 position.
    Delay_Depth =map(POT0>>2,0,1023,1,MAX_DELAY);
 
    //Increse/reset delay counter.   
    DelayCounter++;
    if(DelayCounter >= Delay_Depth) DelayCounter = 0; 
    out_DAC0 = ((sDelayBuffer0[DelayCounter]));
 
    //Add volume feature based in POT2 position.
    out_DAC0=map(out_DAC0,0,4095,1,POT2);
 
    //Write the DACs
    dacc_set_channel_selection(DACC_INTERFACE, 0);          //select DAC channel 0
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
    dacc_set_channel_selection(DACC_INTERFACE, 1);          //select DAC channel 1
    dacc_write_conversion_data(DACC_INTERFACE, 0);          //write on DAC
   }
  //******************************************************************
  else if (effect==3) // EFFECT 3: Echo.
  {
   digitalWrite(LED, LOW); 
   //Store current readings  
   sDelayBuffer0[DelayCounter]  = (in_ADC0 + (sDelayBuffer0[DelayCounter]))>>1;
 
   //Adjust Delay Depth based in pot0 position.
   Delay_Depth =map(POT0>>2,0,1023,1,MAX_DELAY);
 
   //Increse/reset delay counter.   
   DelayCounter++;
   if(DelayCounter >= Delay_Depth) DelayCounter = 0; 
   out_DAC0 = ((sDelayBuffer0[DelayCounter]));
 
   //Add volume feature based in POT2 position.
   out_DAC0=map(out_DAC0,0,4095,1,POT2);
 
   //Write the DACs
   dacc_set_channel_selection(DACC_INTERFACE, 0);          //select DAC channel 0
   dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
   dacc_set_channel_selection(DACC_INTERFACE, 1);          //select DAC channel 1
   dacc_write_conversion_data(DACC_INTERFACE, 0);          //write on DAC
  }
  //******************************************************************
  else if (effect==4) // EFFECT 4: Chorus
   {
    digitalWrite(LED, LOW); 
    //Store current readings  
    sDelayBuffer0[DelayCounter] = in_ADC0;
 
    //Adjust Delay Depth based in pot0 position.
    adjDelayDepth=map(POT0>>2,0,1023,1,25); //25 empirically chosen
 
    DelayCounter++;
    if(DelayCounter >= Delay_Depth) 
     {
      DelayCounter = 0; 
      if(count_up)
       {
        digitalWrite(LED, HIGH);
        for(p=0;p<adjDelayDepth+1;p++) sDelayBuffer0[Delay_Depth+p]=sDelayBuffer0[Delay_Depth-1]; 
        Delay_Depth=Delay_Depth+adjDelayDepth;
        if (Delay_Depth>=MAX_DELAY)count_up=0;
       }
      else
       {
        digitalWrite(LED, LOW); 
        Delay_Depth=Delay_Depth-adjDelayDepth;
        if (Delay_Depth<=MIN_DELAY)count_up=1;
       }
     }
 
   out_DAC0 = sDelayBuffer0[DelayCounter];
 
   //Add volume control based in POT2
   out_DAC0=map(out_DAC0,0,4095,1,POT2);
 
   //Write the DACs
   dacc_set_channel_selection(DACC_INTERFACE, 0);       //select DAC channel 0
   dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
   dacc_set_channel_selection(DACC_INTERFACE, 1);       //select DAC channel 1
   dacc_write_conversion_data(DACC_INTERFACE, 0);       //write on DAC
  }
  //******************************************************************
  else if (effect==5) // EFFECT 5: Octaver
  {
    sDelayBuffer0[DelayCounter] = in_ADC0;
    sDelayBuffer0[DelayCounter+no_samples/2] = in_ADC1;
 
    //Adjust Delay Depth based in pot2 position.
    Delay_Depth = (no_samples/2) -1;
 
    //Increse/reset delay counter.
    DelayCounter++;
    if(DelayCounter >= Delay_Depth) DelayCounter = 0; 
 
    out_DAC0 = ((sDelayBuffer0[sample]));
    out_DAC1 = ((sDelayBuffer0[sample+no_samples/2]));
 
    if (POT0>2700)
     { 
      sample = sample + 2;
     }
    else if (POT0>1350)
     {
      sample = sample + 1;
     }
    else
     {
     p++;
     if (p>=2)
      {
        sample = sample + 1;
        p=0;
      }
     }
 
    if(sample >= Delay_Depth) sample = 0; 
 
    //Add volume control with POT2
    out_DAC0=map(out_DAC0,0,4095,1,POT2);
    out_DAC1=map(out_DAC1,0,4095,1,POT2);
 
    //Write the DACs
    dacc_set_channel_selection(DACC_INTERFACE, 0);       //select DAC channel 0
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
    dacc_set_channel_selection(DACC_INTERFACE, 1);       //select DAC channel 1
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC1);//write on DAC
  }
  //******************************************************************
  else if (effect==6) // EFFECT 6: Reverb
   {
     //Store current readings in DELAY mode  
     sDelayBuffer0[DelayCounter]  = in_ADC0 ;
     sDelayBuffer0[DelayCounterB+no_samples/2]  = in_ADC1 ;  
 
    //Adjust Delay Depth based in POT0 and POT1 position.
    Delay_Depth =map(POT0>>3,0,512,1,no_samples/2);
    Delay_DepthB =map(POT1>>3,0,512,1,no_samples/2);
 
    //Increse/reset delay counter.   
    DelayCounter++;
    DelayCounterB++;
    if(DelayCounter >= Delay_Depth) DelayCounter = 0; 
    if(DelayCounterB >= Delay_DepthB) DelayCounterB = 0; 
 
    //Calculate the output as the sum of DelayBuffer + DelayBufferB 
    out_DAC0 = (sDelayBuffer0[DelayCounter]);
    out_DAC1 = (sDelayBuffer0[DelayCounterB+no_samples/2]);
 
    //Add volume feature based in pot2 position.
    out_DAC0=map(out_DAC0,0,4095,1,POT2);
    out_DAC1=map(out_DAC1,0,4095,1,POT2);
 
    //Write the DACs
    dacc_set_channel_selection(DACC_INTERFACE, 0);       //select DAC channel 0
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
    dacc_set_channel_selection(DACC_INTERFACE, 1);       //select DAC channel 1
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC1);//write on DAC
   }
  //******************************************************************
  else if (effect==7) // EFFECT 7: Super-Reverb
   {
     //Store current readings in ECHO mode
     sDelayBuffer0[DelayCounter]=(in_ADC0 + (sDelayBuffer0[DelayCounter]))>>1;
     sDelayBuffer0[DelayCounterB+no_samples/2]=(in_ADC1 + (sDelayBuffer0[DelayCounterB+no_samples/2]))>>1; 
    //Adjust Delay Depth based in POT0 and POT1 position.
    Delay_Depth =map(POT0>>3,0,512,1,no_samples/2);
    Delay_DepthB =map(POT1>>3,0,512,1,no_samples/2);
 
    //Increse/reset delay counter.   
    DelayCounter++;
    DelayCounterB++;
    if(DelayCounter >= Delay_Depth) DelayCounter = 0; 
    if(DelayCounterB >= Delay_DepthB) DelayCounterB = 0; 
 
    //Calculate the output as the sum of DelayBuffer + DelayBufferB 
    out_DAC0 = (sDelayBuffer0[DelayCounter]);
    out_DAC1 = (sDelayBuffer0[DelayCounterB+no_samples/2]);
 
    //Add volume feature based in pot2 position.
    out_DAC0=map(out_DAC0,0,4095,1,POT2);
    out_DAC1=map(out_DAC1,0,4095,1,POT2);
 
    //Write the DACs
    dacc_set_channel_selection(DACC_INTERFACE, 0);       //select DAC channel 0
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
    dacc_set_channel_selection(DACC_INTERFACE, 1);       //select DAC channel 1
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC1);//write on DAC
   }
  //******************************************************************
  else if (effect==8) // EFFECT 8: Tremolo
   {
    //Increase the sinewave index and/or reset the value.
    POT0 = POT0>>1; //divide value by 2 (its too big) 
    p++; 
    if (p>=160) //160 chosen empirically
     {
      p=0;
      sample=sample+POT0;
      if(sample>=no_samples) sample=0;
     }
 
    //Create the Low Frequency Oscillator signal with depth control based in POT1.
    LFO=map(sDelayBuffer0[sample],0,4095,(4095-POT1),4095);
 
    //Modulate the output signals based on the sinetable.
    out_DAC0 =map(in_ADC0,1,4095,1, LFO);
    out_DAC1 =map(in_ADC1,1,4095,1, LFO);
 
    //Add volume feature with POT2
    out_DAC0 =map(out_DAC0,1,4095,1, POT2);
    out_DAC1 =map(out_DAC1,1,4095,1, POT2);
 
    //Write the DACs
    dacc_set_channel_selection(DACC_INTERFACE, 0);       //select DAC channel 0
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
    dacc_set_channel_selection(DACC_INTERFACE, 1);       //select DAC channel 1
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC1);//write on DAC
   }
  //******************************************************************
  else if (effect==9) // EFFECT 9: Sinewave generator
   {
    //update the accumulator, from 0 to 511
    accumulator=POT0>>3;
 
    //calculate the sample
    if(sample>=(44100-accumulator)) sample=0;
    sample=sample+accumulator;
 
    //Generate the DAC output
    out_DAC0 = sDelayBuffer0[sample];
    out_DAC1 = 4095 - sDelayBuffer0[sample];
 
    //Add volume feature
    out_DAC0=map(out_DAC0,0,4095,0,POT2);
    out_DAC1=map(out_DAC1,0,4095,0,POT2);
 
    //Write the DACs.
    dacc_set_channel_selection(DACC_INTERFACE, 0);       //select DAC channel 0
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC0);//write on DAC
    dacc_set_channel_selection(DACC_INTERFACE, 1);       //select DAC channel 1
    dacc_write_conversion_data(DACC_INTERFACE, out_DAC1);//write on DAC 
   }
}
 
void switch_handler()
{
  delayMicroseconds(100000); //debouncing protection
  if (toggle_value!=digitalRead(TOGGLE)) effect++;
  delayMicroseconds(100000); //debouncing protection
  toggle_value=digitalRead(TOGGLE);
  if (effect>N_EFFECT) effect=0;
 
  Delay_Depth=300; //reset the variable.
  Delay_DepthB=300;
}   
The administrator has disabled public write access.
Time to create page: 0.639 seconds
Powered by Kunena Forum
Joomla SEF URLs by Artio