Help mapping Mackie encoder to linear encoder

I have a control surface encoder that sends B0 0A pp (pp= 0x01 thru 0x7F). I am expected to send this encoder data to a software knob expecting to see Mackie encoder data. Here is the explanation:

Mackie:
B0, 1i, XX

i V-Pot ID (00—07)

XX delta value in the form of ( 0 s v v v v v v )
s direction bit:
0 = clockwise,
1 = counter clockwise
vv number of ticks

Examples:

• B0, 10, 01 = V-Pot Ch. 1 is being turned clockwise by one

tick.
• B0, 17, 47 = V-Pot Ch. 8 is being turned counter-clockwise by 7 ticks.

So basically I’m trying to translate the linear encoder data to this Mackie encoder data and I’m a little stumped on how to do this. Any help is greatly appreciated

Hi, Please find the following example.

I use the global variable ga for the last known value of the incoming absolute encoder.

The example is only for the first encoder, you will need to set up a different global variable for each encoder. I document and initializes global variable used in this project in the rules of translator 0.2

Translator 2.0 is the translator used for conversion.

Here are how I have my aliases set up.

You can learn more about aliases from this tutorial.

Here are the rules with comments.

// Positive Movement
if pp>ga then tt=pp-ga
// Negative Movement
if pp<ga then tt=ga-pp
if pp<ga then tt=tt|64
// lower end
if pp==0 then tt=65
//higher end
if pp==127 then tt=1

//update for next iteration
ga=pp
// no higher than 127
if ga>127 then ga=127
// no lower than 0
if ga<0 then ga=0
Log "Log outgoing value is 0x%02x tt%"

And the project file.

Absolute-to-VPOT-Example-2024-12-22.bmtp (2.1 KB)

Steve Caldwell
Bome Customer Care


Also available for paid consulting services: bome@sniz.biz

2 posts were split to a new topic: Scaling Mackie MCU LED rings back to absolute values

Here is an update after some trial and error for anyone who is looking to map an absolute encoder (1-127) to a Mackie/MCU encoder. I have changed the rules to match the absolute encoder rotation with it’s corresponding 15 LED Ring, so both the absolute encoder and software encoder match throughout the entire scale.

I needed to create 2 translators where each one will ONLY function if it detects either the clockwise OR counter clockwise rotation of the hardware encoder. When the software encoder was rotated to send data back to the hardware encoder, and the hardware encoder was rotated again, there was a random value that made the software encoder skip to an incorrect position.

A third translator for LED return from software is to update the hardware encoder 15 LED Ring position

[x] Preset 5: PANS 1-8

[x] Translator 5.0: Pan 1-8
Options: swallow
Incoming: MIDI yy 0A zb, on port V-Control Midi Mode
Rules:
  
  // Ensure pp is within the valid range
  if zb==0 then zb=1
  // Avoid division by zero issues
  if zb==127 then zb=126
  
  // Scale pp (1-127) to a 0-40 range using integer math
  ga=zb-1
  // Adjust pp to start from 0
  ga=ga*40
  // Scale up to match the target range
  ga=ga/126
  // Scale down to fit within 0–40
  
  // ga now holds the scaled value, use it for scaled_pp
  // Calculate tt based on scaled_pp (stored in ga) and za (previous value)
  if ga>za then tt=ga-za
  if ga<za then tt=za-ga
  if ga<za then tt=tt|64
  // Set direction bit for decrement
  
  // Handle special cases
  if zb==1 then tt=65
  if zb==126 then tt=1
  
  // Update za with the new scaled value
  za=ga
  
  // Ensure za stays within 0–40 range
  if za>40 then za=40
  if za<0 then za=0
  
  if yy==176 then zz=16
  if yy==177 then zz=17
  if yy==178 then zz=18
  if yy==179 then zz=19
  if yy==180 then zz=20
  if yy==181 then zz=21
  if yy==182 then zz=22
  if yy==183 then zz=23
  
  if yy<=175 then exit rules, skip Outgoing Action
  if yy>=184 then exit rules, skip Outgoing Action
  if zz<=15 then exit rules, skip Outgoing Action
  if zz>=24 then exit rules, skip Outgoing Action
  
  //This rule prevents software encoder skipping due to rogue
  //values after adjusting hardware encoder.
  if tt!=65 then exit rules, skip Outgoing Action
  
Outgoing: MIDI B0 zz tt, to port Bome Virtual Port 1

[x] Translator 5.1: Pan 1-8
Options: swallow
Incoming: MIDI yy 0A zb, on port V-Control Midi Mode
Rules:
  
  // Ensure pp is within the valid range
  if zb==0 then zb=1
  // Avoid division by zero issues
  if zb==127 then zb=126
  
  // Scale pp (1-127) to a 0-40 range using integer math
  ga=zb-1
  // Adjust pp to start from 0
  ga=ga*40
  // Scale up to match the target range
  ga=ga/126
  // Scale down to fit within 0–40
  
  // ga now holds the scaled value, use it for scaled_pp
  // Calculate tt based on scaled_pp (stored in ga) and za (previous value)
  if ga>za then tt=ga-za
  if ga<za then tt=za-ga
  if ga<za then tt=tt|64
  // Set direction bit for decrement
  
  // Handle special cases
  if zb==1 then tt=65
  if zb==126 then tt=1
  
  // Update za with the new scaled value
  za=ga
  
  // Ensure za stays within 0–40 range
  if za>40 then za=40
  if za<0 then za=0
  
  if yy==176 then zz=16
  if yy==177 then zz=17
  if yy==178 then zz=18
  if yy==179 then zz=19
  if yy==180 then zz=20
  if yy==181 then zz=21
  if yy==182 then zz=22
  if yy==183 then zz=23
  
  if yy<=175 then exit rules, skip Outgoing Action
  if yy>=184 then exit rules, skip Outgoing Action
  if zz<=15 then exit rules, skip Outgoing Action
  if zz>=24 then exit rules, skip Outgoing Action
  
  //This rule prevents software encoder skipping due to rogue
  //values after adjusting hardware encoder.
  if tt!=1 then exit rules, skip Outgoing Action
  
Outgoing: MIDI B0 zz tt, to port Bome Virtual Port 1

[x] Translator 5.2: Pan 1-8 LED
Options: swallow
Incoming: MIDI B0 yy pp, on port Bome Virtual Port 1
Rules:
  
  //zc is the output value
  qq=pp-1
  zc=qq*12
  if zc>127 then zc=127
  
  if yy==48 then zz=176
  if yy==49 then zz=177
  if yy==50 then zz=178
  if yy==51 then zz=179
  if yy==52 then zz=180
  if yy==53 then zz=181
  if yy==54 then zz=182
  if yy==55 then zz=183
  
  if yy<=47 then exit rules, skip Outgoing Action
  if yy>=56 then exit rules, skip Outgoing Action
  if zz<=175 then exit rules, skip Outgoing Action
  if zz>=184 then exit rules, skip Outgoing Action
Outgoing: MIDI zz 0A zc, to port V-Control Midi Mode, delay:500 millisec


Well as long as it works that his good!

I recommend, however, you use local variables for any time you don’t need globals. In this case, moving two encoders at the same time will cause havoc because you are using mostly global variables.

Steve Caldwell
Bome Customer Care


Also available for paid consulting services: bome@sniz.biz

Here is the approach I took with my APC40-MK2

I set a busy timer to disable feedback while moving the physical encoders. They have local feedback so that works. Then I simply do scaling when I move the V-POTs on the DAW.

If your controller does not have local feedback, then enable translator 2.3 and it will provide local feedback for you.

Here are how my aliases are set up.

I use the global variables g0-g7 to hold their current value and ga for the busy flag. When ga==1 then feedback is disabled from the DAW. I set it back to 0 after stopping any encoder for 500ms.

APC-40-VPOT-2025-01-04.bmtp (4.0 KB)

Steve Caldwell
Bome Customer Care


Also available for paid consulting services: bome@sniz.biz