Send CC Events on pot movements within specific range (Scaling)

We want to send MIDI events on pot movements. In difference to this simple example, the sent value is scaled to the given boundaries, the value range can be specified in a table.

Copy the SDCC skeleton into a new directory, open the main.c file and enhance the AIN_NotifyChange() function like shown below. Thereafter type "make" in the command shell, and upload the new project.hex file to the core.

// this const definition creates a table of 32 bytes in flash memory
// we create a 2-dimensional array with 8 entries
// each entry consists of four bytes: 
//   o one for the first MIDI byte (MIDI status)
//   o a second for the second MIDI byte (here: CC number)
//   o the minimum value
//   o the maximum value
// The meaning of the bytes can be found in the MIDI spec
// (-> http://www.borg.com/~jglatt/tech/midispec.htm)

const unsigned char pot_event_map[8][4] = {
// evt0  evt1   min   max
  {0xb0, 0x10, 0x00, 0x0f}, // Pot #1
  {0xb0, 0x11, 0x00, 0x1f}, // Pot #2
  {0xb0, 0x12, 0x00, 0x2f}, // Pot #3
  {0xb0, 0x13, 0x00, 0x3f}, // Pot #4
  {0xb0, 0x14, 0x00, 0x7f}, // Pot #5
  {0xb0, 0x15, 0x40, 0x7f}, // Pot #6
  {0xb0, 0x16, 0x30, 0x5f}, // Pot #7
  {0xb0, 0x17, 0x20, 0x6f}, // Pot #8
  };


/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS after startup to initialize the 
// application
/////////////////////////////////////////////////////////////////////////////
void Init(void) __wparam
{
  // initialize the AIN driver
  MIOS_AIN_NumberSet(8);   // 8 pots are connected
  MIOS_AIN_UnMuxed();      // the AINX4 modules are *not* used
  MIOS_AIN_DeadbandSet(7); // should be 7 when 7bit resolution is used
}

/////////////////////////////////////////////////////////////////////////////
// This is an assembly optimized function which scales a 7bit value between
// a minimum and maximum value
/////////////////////////////////////////////////////////////////////////////
unsigned char Scale_7bit(unsigned char value, unsigned char min, unsigned char max)
{
  // scaled value is (2*<7bit value> * ) >> 8
  PRODL = value << 1; // 8bit value
  PRODH = max-min+1;  // range
__asm
    movf _PRODL, W
    mulwf _PRODH, 0
__endasm;

  return min + PRODH;
}

/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS when a pot has been moved
/////////////////////////////////////////////////////////////////////////////
void AIN_NotifyChange(unsigned char pin, unsigned int pin_value) __wparam
{
  unsigned char value;

  // scale 7bit value between min and max boundary
  value = Scale_7bit(MIOS_AIN_Pin7bitGet(pin), // converted to 7bit
                     pot_event_map[pin][2],    // min value
                     pot_event_map[pin][3]);   // max value

  // send scaled CC value
  MIOS_MIDI_TxBufferPut(pot_event_map[pin][0]); // first value from table
  MIOS_MIDI_TxBufferPut(pot_event_map[pin][1]); // second value from table
  MIOS_MIDI_TxBufferPut(value);                 // scaled pot value
}

A list of available MIOS functions can be found here.



Last update: 2023-11-04

Copyright © 1998-2023, Thorsten Klose. All rights reserved.