Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PB and CC encoder #76

Closed
rogerarends opened this issue Dec 17, 2019 · 43 comments
Closed

PB and CC encoder #76

rogerarends opened this issue Dec 17, 2019 · 43 comments

Comments

@rogerarends
Copy link

I'm using your pichbend encoder example for 8 volume encoders, on teensy 4. Is it possible to have a "switch" or "bank" to change the function from pitchbend to control change so that I can control either volume and pan per channel... when you have a moment.

@tttapa
Copy link
Owner

tttapa commented Dec 17, 2019

Do you mean encoders or potentiometers? If the latter, would something like this work?

@rogerarends
Copy link
Author

rogerarends commented Dec 17, 2019 via email

@tttapa
Copy link
Owner

tttapa commented Dec 18, 2019

In that case, I don't think I understand your question, as I'm not aware of any standard way to use pitch bend message for incremental information like rotary encoders. Do you want to use the encoder in absolute mode?

@rogerarends
Copy link
Author

rogerarends commented Dec 18, 2019 via email

@tttapa
Copy link
Owner

tttapa commented Dec 18, 2019

So when choosing bank 1 the encoders Will send pitch bend messages.
(VOLUME_ 1 to 8) on the first 8 channels.

Choosing the second bank the encoders Will send cc messages (V_POT_ 1 to 8)
for the first 8 channels.

I see. There's a difference between how rotary encoder information and volume information is transmitted. Rotary encoders use an incremental mode, if you turn the encoder 4 ticks to the left, a message "-4" is sent to the computer, not the absolute position of the knob.
Pitch bend is different, it sends the absolute position of the knob/fader. This means that if you want to use a rotary encoder, the Arduino will have to keep track of the position.

I just added a new class that does exactly that. Example

The big problem here is that each encoder keeps track of its own position. So, if you switch from "volume" mode to "pan" mode, turn the encoder to change the pan, and then change back to "volume" mode, the volume will have changed as well.
I have some ideas about how to get around this, but I don't know if they're going to work.

Is there an io expander that could handle rotary encoders.
If yes. Which one and how would I implement it?

You need interrupts for the encoders to work reliably. There are IO expanders with interrupt capability, but it's not trivial to implement. Using I²C in an ISR context is tricky, for example.

connecting 4 mcp23017 on the i2c bus to give up to 64 buttons and or leds. (Example would be appreciated)
There is no out-of-the-box support for MCP23017 expanders. Feel free to add it though, implementing the ExtIO interface should be simple enough. See also here: tttapa/MIDI_controller#90

Then No oleds (I wanted to add 4 using your oled example 2) unless you could modify the code to use i2c oleds.

You can use the OLED examples with I²C without any problems, they use the Adafruit_SSD1306 library. Have a look at their examples on how to use I²C.

And would it be possible to use 2 buttons to control master volume as there would be no analog Pin available?

Sure, you can use the IncrementDecrementButtons class.

@rogerarends
Copy link
Author

rogerarends commented Dec 18, 2019 via email

@rogerarends
Copy link
Author

rogerarends commented Dec 18, 2019 via email

@rogerarends
Copy link
Author

rogerarends commented Dec 18, 2019 via email

@tttapa
Copy link
Owner

tttapa commented Dec 19, 2019

To switch between PB encoder and CC encoder, you could probably use something like this:

#include <Encoder.h>

#include <Control_Surface.h>

USBMIDI_Interface midi;

Button button = 4;

Encoder enc = {2, 3};
BorrowedMIDIRotaryEncoder<ContinuousCCSender> ccenc = {
  enc, 
  MCU::V_POT_1,
  1,   // multiplier
  4,   // pulses per step
  {},  // MIDI sender
};
BorrowedMIDIAbsoluteEncoder<PitchBendSender<14>> pbenc = {
  enc, 
  CHANNEL_1,
  127, // multiplier
  4,   // pulses per step
  {},  // MIDI sender
};

void setup() {
  button.begin();
  Control_Surface.begin();
  pbenc.disable();
}

void loop() {
  Control_Surface.loop();

  auto buttonState = button.update();
  if (buttonState == Button::Falling) {
    ccenc.disable();
    pbenc.resetPositionOffset();
    pbenc.enable();
  } else if (buttonState == Button::Rising) {
    pbenc.disable();
    ccenc.resetPositionOffset();
    ccenc.enable();
  } 
}

You have to use the share-encoder branch of the Control Surface library, and my fork of the Encoder library.

I'm pretty sure I made a mistake somewhere in the position logic and the resetPositionOffset functions, but I don't have an Arduino at hand to test it.

@rogerarends
Copy link
Author

After messing around with it for a few days . I've given up on the switch and decided to make it a 4 channel mixer. edited the mackie control script and files in the Daw from 8 to 4 channels and it seems to be working ok. So I have 4 channels with encoders for pan and volume. an encoder for scrub and a pot for master volume. 4 screens, one per channel using an adapted version of your 2 oled example. The mux for buttons i'm still trying to figure out using the control surface library, but it works fine with the teensy library. but that i'll leave for another day when i have the other 4 mux chips.

The main issue now is getting the channel info from Studio one 4 . tried using your 2 screen oled example as is but everything except "MCU::LCD" works, what daw are you using or tested it on?

@tttapa
Copy link
Owner

tttapa commented Dec 24, 2019

You can check if the LCD receives anything using the LCD::getText method.
I tested it using the Traction 6 DAW.

I should be able to get the the 8 track encoders working, but it won't be before early February.

@rogerarends
Copy link
Author

These are the messages that Studio one sends when I change the name of the tracks:
On channel 1:
changed track name to TRACK1
then to drums
then back to TRACK1

SysEx: f0 00 00 66 14 12 00 54 72 61 63 6b 31 20 f7 on cable 0
SysEx: f0 00 00 66 14 12 00 64 72 75 6d 73 20 20 f7 on cable 0
SysEx: f0 00 00 66 14 12 00 54 72 61 63 6b 31 20 f7 on cable 0

On channel 2:
changed track name to TRACK2
then to hats
then back to TRACK2

SysEx: f0 00 00 66 14 12 07 54 72 61 63 6b 32 20 f7 on cable 0
SysEx: f0 00 00 66 14 12 07 68 61 74 20 20 20 20 f7 on cable 0
SysEx: f0 00 00 66 14 12 07 54 72 61 63 6b 32 20 f7 on cable 0

included the config files in Studio One for Mackie control, hope
this will help you point me in the right direction on how to get
the track names displayed.

MackieShared.surface.xml.txt

MackieShared.js.txt

@rogerarends
Copy link
Author

Picture of the screens in action.

screens

and just finished soldering the buttons and encoders. bout 80% completed. will have a face plate laser cut once all the coding and wiring is complete.
controls

@tttapa
Copy link
Owner

tttapa commented Dec 25, 2019

At first glance, the sysex data looks alright. What does LCD::getText return? You can print it to the serial monitor.

@tttapa tttapa reopened this Dec 25, 2019
@rogerarends
Copy link
Author

rogerarends commented Dec 25, 2019 via email

@tttapa
Copy link
Owner

tttapa commented Dec 25, 2019

I'll post some code when I get home.

@tttapa
Copy link
Owner

tttapa commented Dec 25, 2019

The following should print the display data to the Serial Monitor (you can open it from the Arduino IDE after uploading):

#include <Control_Surface.h> // Include the Control Surface library

USBMIDI_Interface midi;

MCU::LCD<> lcd = {};

void setup() {
  Control_Surface.begin(); // Initialize Control Surface
  Serial.begin(115200);
}

void loop() {
  Control_Surface.loop(); // Refresh all elements
  Serial.println(lcd.getText());
}

@rogerarends
Copy link
Author

Opened the first song and it displayed this:
Ld_Vcl Bckng_VBckng_VAd_Libs -0.8 -2.1 -2.1 -2.5

Then opened a second one with this result:
Bass Rhodes Guitar Kck_Snr -7.7 0dB -0.4 -1.0

Then closed everything and opened the DAW with a different song:
Ld_Vcl Bckng_VBckng_VAd_Libs -0.8 -2.1 -2.1 -2.5

It matches the names and volume of the 3 songs like they are in the DAW.

FYI: I edited the mackie files to only show the first 4 tracks to match my controller

@tttapa
Copy link
Owner

tttapa commented Dec 25, 2019

Ah, the reason is that your DAW doesn't separate the track names with spaces.

/**
* @brief Check if the display contains a message for each track
* separately.
*
* On the original Mackie Control surfaces, the LCD display consists of two
* 56-character lines, where each of the 8 channels has 7 characters.
* If the LCD is used to display a message for each channel separately, the
* seventh character of each channel is always a space, as separation
* between the channels.
*
* @retval true
* The display contains a message for each track separately, and
* the messages are separated by spaces.
* @retval false
* The display contains a message that spans across multiple
* tracks, without separating spaces between the tracks.
*/
bool separateTracks() const {
for (uint8_t i = 0; i < 7; ++i) {
const char *text = lcd.getText() + 7 * i + 56 * line;
if (text[6] != ' ')
return false;
}
return true;
}

If you just bypass the check and change the length from 6 to 7, it should work, but it's not too hard to just extract the interesting text fields from the getText method.

@rogerarends
Copy link
Author

Out of curiosity I opened Traction then I loaded a song and it showed the first 8 track names:
bass Adlibs LD vcl snare BGV 1 synth tlkbx kick

Closed Traction, put back the original files for Studio one and loaded a song and it showed all 8 tracks and volume.
Kick HiHat 1Hihat 2Snare Prcssn Crash Drums Bass 0dB 0dB 0dB 0dB 0dB 0dB -1.3 0dB

Loaded my sketch, opened traction and the track names show on screen. Then closed it and opened Studio one... no names show.

@tttapa
Copy link
Owner

tttapa commented Dec 25, 2019

You can leave out this check (just delete those lines):

if (!separateTracks())
return;

And then change 7 to 8 and 6 to 7 in these lines:

char buffer[7];
strncpy(buffer, text, 6);
buffer[6] = '\0';

You might run into problems with the 8th (or 4th in your case) track though, as it might not have 7 characters to read, and maybe you need a special case to handle that.

Edit: that shouldn't be a problem, from the Mackie Logic Control manual:

There are 7 displayed characters per channel, with the exception of channel 8, which displays only the first 6 characters. Internally however, the LCD stores 2 x 56 characters.

@rogerarends
Copy link
Author

and getting the volume to display?

Promise I won't bother you until Feb. LOL

@tttapa
Copy link
Owner

tttapa commented Dec 25, 2019

For the normal 8-track version, you would set line to 1 in the constructor (i.e. add an extra parameter after the track number):

LCDDisplay(DisplayInterface &display, const MCU::LCD<> &lcd,
const OutputBank &bank, uint8_t track, uint8_t line,
PixelLocation loc, uint8_t textSize, uint16_t color)

In your case, however, I think it'll be on tracks 5 - 8 (on line 0).

Excuse the inconsistencies in the numbering of the tracks and lines (tracks start at 1, lines start at 0), I didn't find the time yet to cleanup this part of the code, I'll probably change it in a later release.

@rogerarends
Copy link
Author

Thanks for all your time and help. I really appreciate it.

@tttapa
Copy link
Owner

tttapa commented Dec 25, 2019

Glad I could help :)

@rogerarends
Copy link
Author

STUCK!
In line 36 I changed it to: line(2)
changing line 66 to:
0 will give me track names
1 will give me track volume
Doesn't matter if I'm using 4 or 8 tracks.
Can't figure out how to show both on the display at the same time. I tried adding a second instance of LCD.hpp and LCDDisplay.hpp pointing it to the second instance of LCD.hpp and adding these two to the Control_surface.h file but get errors regarding the two instances.
adding this "MCU::LCDDisplay lcddisps2[] = {" to my sketch will get it to display the tracks twice per display.

@tttapa
Copy link
Owner

tttapa commented Dec 26, 2019

I should have been more clear: you don't have to edit anything related to lines in the LCDDisplay.hpp file. You just have to add the extra argument to the constructors in your sketch. Like this:

// Track names and volumes
MCU::LCDDisplay lcddisps[] = {
  // track (1), line(0), position (0, 40), font size (1)
  {display_L, lcd, bank, 1, 0, {0, 40}, 1, WHITE},
  {display_L, lcd, bank, 2, 0, {64, 40}, 1, WHITE},
  {display_R, lcd, bank, 3, 0, {0, 40}, 1, WHITE},
  {display_R, lcd, bank, 4, 0, {64, 40}, 1, WHITE},
  // track (1), line(1), position (0, 50), font size (1)
  {display_L, lcd, bank, 1, 1, {0, 50}, 1, WHITE},
  {display_L, lcd, bank, 2, 1, {64, 50}, 1, WHITE},
  {display_R, lcd, bank, 3, 1, {0, 50}, 1, WHITE},
  {display_R, lcd, bank, 4, 1, {64, 50}, 1, WHITE},
};

Top 4 use line 0 (i.e. names), bottom 4 use line 1 (i.e. volumes).

@rogerarends
Copy link
Author

Thank you. works perfectly

@rogerarends
Copy link
Author

how do I do this if there's nothing in the folder.
4. (Optional) Run Doxygen again (in doc/Doxygen) to include the new icon in the documentation.

I'm getting an error when trying to compile.
error: unterminated #ifndef

#ifndef DOXYGEN

@tttapa
Copy link
Owner

tttapa commented Dec 26, 2019

I reworked the structure of the documentation recently, I haven't updated the documentation for it yet.
The folder is now just doxygen, instead of doc/doxygen.

However, this has nothing to do with the compilation error you're getting. Did you change any of the code?

Please post the full and exact error message.

@rogerarends
Copy link
Author

rogerarends commented Dec 27, 2019

Followed instructions in README.md on how to add custom xbm files. used the script file and it created the axbm files and placed it with the others in the BITMAPS folder and created png files in the script folder. copied the png files into the DOXYGEN/images folder.

Then opened my sketch, tried to compile it, haven't added any inputs or changed images.

The errors listed below:
refers to all the images I added.

In file included from C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Display/Bitmaps/XBitmaps.hpp:54:0,

                 from C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Control_Surface.h:20,

                 from C:\Users\Roger\Desktop\testoledinput\testoledinput.ino:2:

C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Display/Bitmaps/ASSIGN_SEND.axbm:1:0: error: unterminated #ifndef

 #ifndef DOXYGEN

 ^

In file included from C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Display/Bitmaps/XBitmaps.hpp:89:0,

                 from C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Control_Surface.h:20,

                 from C:\Users\Roger\Desktop\testoledinput\testoledinput.ino:2:

C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Display/Bitmaps/CYCLE.axbm:1:0: error: unterminated #ifndef

 #ifndef DOXYGEN

 ^

In file included from C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Display/Bitmaps/XBitmaps.hpp:96:0,

                 from C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Control_Surface.h:20,

                 from C:\Users\Roger\Desktop\testoledinput\testoledinput.ino:2:

C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Display/Bitmaps/FAST_FWD.axbm:1:0: error: unterminated #ifndef

 #ifndef DOXYGEN

 ^

In file included from C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Display/Bitmaps/XBitmaps.hpp:103:0,

                 from C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Control_Surface.h:20,

                 from C:\Users\Roger\Desktop\testoledinput\testoledinput.ino:2:

C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Display/Bitmaps/MUTE.axbm:1:0: error: unterminated #ifndef

 #ifndef DOXYGEN

 ^

In file included from C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Display/Bitmaps/XBitmaps.hpp:110:0,

                 from C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Control_Surface.h:20,

                 from C:\Users\Roger\Desktop\testoledinput\testoledinput.ino:2:

C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Display/Bitmaps/PLAY.axbm:1:0: error: unterminated #ifndef

 #ifndef DOXYGEN

 ^

In file included from C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Display/Bitmaps/XBitmaps.hpp:117:0,

                 from C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Control_Surface.h:20,

                 from C:\Users\Roger\Desktop\testoledinput\testoledinput.ino:2:

C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Display/Bitmaps/RECORD.axbm:1:0: error: unterminated #ifndef

 #ifndef DOXYGEN

 ^

In file included from C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Display/Bitmaps/XBitmaps.hpp:124:0,

                 from C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Control_Surface.h:20,

                 from C:\Users\Roger\Desktop\testoledinput\testoledinput.ino:2:

C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Display/Bitmaps/REWIND.axbm:1:0: error: unterminated #ifndef

 #ifndef DOXYGEN

 ^

In file included from C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Display/Bitmaps/XBitmaps.hpp:138:0,

                 from C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Control_Surface.h:20,

                 from C:\Users\Roger\Desktop\testoledinput\testoledinput.ino:2:

C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Display/Bitmaps/SOLO.axbm:1:0: error: unterminated #ifndef

 #ifndef DOXYGEN

 ^

In file included from C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Display/Bitmaps/XBitmaps.hpp:145:0,

                 from C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Control_Surface.h:20,

                 from C:\Users\Roger\Desktop\testoledinput\testoledinput.ino:2:

C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Display/Bitmaps/STOP.axbm:1:0: error: unterminated #ifndef

 #ifndef DOXYGEN

 ^

In file included from C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Display/Bitmaps/XBitmaps.hpp:152:0,

                 from C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Control_Surface.h:20,

                 from C:\Users\Roger\Desktop\testoledinput\testoledinput.ino:2:

C:\Program Files (x86)\Arduino\libraries\Control-Surface-master\src/Display/Bitmaps/ZOOM.axbm:1:0: error: unterminated #ifndef

 #ifndef DOXYGEN

 ^
Multiple libraries were found for "Encoder.h"
 Used: C:\Program
 Not used: C:\Program
Multiple libraries were found for "Control_Surface.h"
 Used: C:\Program
Multiple libraries were found for "SPI.h"
 Used: C:\Program
Multiple libraries were found for "SoftwareSerial.h"
 Used: C:\Program
Multiple libraries were found for "Adafruit_SSD1306.h"
 Used: F:\Users\Roger\Documents\Arduino\libraries\Adafruit_SSD1306
 Not used: C:\Program
Multiple libraries were found for "Wire.h"
 Used: C:\Program
 Not used: F:\Users\Roger\Documents\Arduino\libraries\Wire-master
Multiple libraries were found for "Adafruit_GFX.h"
 Used: C:\Program
 Not used: C:\Program
 Not used: F:\Users\Roger\Documents\Arduino\libraries\Adafruit_GFX_Library
Using library Encoder at version 1.4.1 in folder: C:\Program Files
Using library Control-Surface-master at version 1.1.0 in folder: C:\Program Files
Using library SPI at version 1.0 in folder: C:\Program Files
Using library SoftwareSerial at version 1.0 in folder: C:\Program Files
Using library Adafruit_SSD1306 at version 2.0.4 in folder: F:\Users\Roger\Documents\Arduino\libraries\Adafruit_SSD1306 
Using library Wire at version 1.0 in folder: C:\Program Files
Using library Adafruit_GFX at version 1.5.6 in folder: C:\Program Files
Error compiling for board Teensy 4.0.

@tttapa
Copy link
Owner

tttapa commented Dec 27, 2019

Most likely a Windows line ending issue (I use Linux for development).

Try adding +'\n' here:

axbm.write('#ifndef DOXYGEN\n'+contents+'#endif\n')

axbm.write('#ifndef DOXYGEN\n'+contents+'\n'+'#endif\n')

@rogerarends
Copy link
Author

Here's the whole error message after editing the py file
error.txt

@tttapa
Copy link
Owner

tttapa commented Dec 27, 2019

Could you zip and post the entire Bitmaps folder?

@rogerarends
Copy link
Author

Bitmaps.zip

@tttapa
Copy link
Owner

tttapa commented Dec 27, 2019

The issue is that your image editor saves the bitmaps as char instead of unsigned char, and the Python script couldn't parse that.

This should fix it:

        # Replace the existing identifier for the data array,
        # change the type from (unsigned) char to uint8_t, 
        # and store it in PROGMEM
        contents = re.sub(r'static (?:unsigned )?char [a-zA-Z_][a-zA-Z0-9_]*(_bits\[\] *= *{ *(?:0x[0-9a-fA-F]{2}, *)*}?;?) *',
                          r'static const PROGMEM uint8_t {}\1'.format(identifier), contents)

@rogerarends
Copy link
Author

Thanks, will try it when I get home.

@rogerarends
Copy link
Author

Hi ... HAPPY NEW YEAR! (Depending on when you read this message)
I have a question related to using rotary encoders as pitch bend volume controls instead of pots.
My DAW sends out "position" messages on volume changes and when changing banks and channels for each of the 8 channels (4 in my case). I assume it is used to "tell" the motorized faders what position to be at per channel.
Currently, the encoders act like pots and "remember" the position it was last turned to, causing it to "jump" to the previous position it was on, when in a different bank or channel. The reason I went with using rotary encoders, was to prevent the jump and the only way I can think of fixing it would be to change the PBencoders to CCencoders but then they won't work in MCU mode in my DAW.
So, when you're done studying or writing exams, is there a way to make the teensy to take the incoming volume message and set the PBencoders position to that position so there wont be a "jump". Or maybe a change in your code to make the DAW accept CCencoders as PBencoders in MCU mode.

Also, how do I add a Bitmap as a boot image (like the splash in the adafruit1306 example) with your implementation of the Adafruit library.

@rogerarends
Copy link
Author

This is what the DAW sens out on a channel change

90 00 00 (REC_RDY_1)
90 08 00 (SOLO_1)
90 10 00 (MUTE_1)
90 18 00 (SELECT_1)
b0 30 46
e0 7f 7f
90 01 00 (REC_RDY_2)
90 09 00 (SOLO_2)
90 11 00 (MUTE_2)
90 19 00 (SELECT_2)
b0 31 46
e1 54 26
90 02 00 (REC_RDY_3)
90 0a 00 (SOLO_3)
90 12 00 (MUTE_3)
90 1a 00 (SELECT_3)
b0 32 46
e2 0a 55
90 03 00 (REC_RDY_4)
90 0b 00 (SOLO_4)
90 13 00 (MUTE_4)
90 1b 7f (SELECT_4)
b0 33 46
e3 0f 05
SysEx: f0 00 00 66 14 12 00 4b 69 63 6b 20 20 20 53 6e 61 72 65 20 20 48 61 74 73 20 20 20 43 79 6d 62 61 6c 73 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2b 31 30 2e 30 20 20 2d 32 38 2e 32 20 20 2d 34 2e 30 20 20 20 2d 36 30 2e 30 20 20 f7 on cable 0
e0 64 26
SysEx: f0 00 00 66 14 12 38 2d 32 38 2e 31 20 20 f7 on cable 0
e0 54 26
SysEx: f0 00 00 66 14 12 38 2d 32 38 2e 32 20 20 f7 on cable 0

@tttapa
Copy link
Owner

tttapa commented Dec 31, 2019

is there a way to make the teensy to take the incoming volume message and set the PBencoders position to that position so there wont be a "jump".

That's certainly possible, and not too hard to implement, but I simply don't have the time right now to set up a test rig or debug a lot of code.

Basically, you have to add a new class for receiving Pitch Bend messages. This will be almost the same as the Channel Pressure class.
Then you have to override the updateWith method for your specific use case. It is called whenever a Pitch Bend message on the given channel is received, and in this case it would set the position of the encoder to the value it received.
The final step is to add the Pitch Bend MIDI input class to the Control_Surface_Class to initialize and update it.

This is what the DAW sens out on a channel change

Thanks, that'll come in handy for testing later.

A Happy New Year!

@rogerarends
Copy link
Author

Hi
So, I was reading up on the Faderport 8, Mackie control specs and Studio 1's implementation of it and realized there is a "flip" function to switch the faders to pan. After tweaking the script and config files in Studio 1 and changing my sketch to only 8 V_Pots (CCencoders) gives me the desired effect of "no jump" when changing channels and using 1 button I'm able to switch between Vol and Pan.
So I've sorted most of my issues.
I do, however, still need help with getting my own bitmap to display when switching on. like the adafruit splash. Tried using their example but cant' get it to work in your library. (also tried to copy and paste LOL)
Also, I would like to add 4 more oleds as there's not enough space to show 2 channels info per screen, and a schlep having to switch banks. but I don't have enough pins available, So, would it be possible to use 8 pins of a 4067 as the Cable select pins for the oleds and if yes how? I'm swapping out the four 4051 for 4067 to give me 64 buttons, and will sacrifice 8 of those for the screens.

@tttapa
Copy link
Owner

tttapa commented Jan 5, 2020

To get the display splash screen working, add a displaySplash method to the MySSD1306DisplayInterface class that draws the bitmap and calls display. Then in the setup, after initialization of the displays, call this method for each of the displays, and then add a delay to wait before starting the main loop.

Using multiplexers for the CS lines is not possible, because these lines are managed by the Adafruit_SSD1306 library, not Control Surface. You could of course edit the library's source. Analog multiplexers are not the right way to drive outputs though, it would be better to use shift registers. They can share an SPI bus with the displays.

@simoniddqd
Copy link

To switch between PB encoder and CC encoder, you could probably use something like this:

#include <Encoder.h>

#include <Control_Surface.h>

USBMIDI_Interface midi;

Button button = 4;

Encoder enc = {2, 3};
BorrowedMIDIRotaryEncoder<ContinuousCCSender> ccenc = {
  enc, 
  MCU::V_POT_1,
  1,   // multiplier
  4,   // pulses per step
  {},  // MIDI sender
};
BorrowedMIDIAbsoluteEncoder<PitchBendSender<14>> pbenc = {
  enc, 
  CHANNEL_1,
  127, // multiplier
  4,   // pulses per step
  {},  // MIDI sender
};

void setup() {
  button.begin();
  Control_Surface.begin();
  pbenc.disable();
}

void loop() {
  Control_Surface.loop();

  auto buttonState = button.update();
  if (buttonState == Button::Falling) {
    ccenc.disable();
    pbenc.resetPositionOffset();
    pbenc.enable();
  } else if (buttonState == Button::Rising) {
    pbenc.disable();
    ccenc.resetPositionOffset();
    ccenc.enable();
  } 
}

You have to use the share-encoder branch of the Control Surface library, and my fork of the Encoder library.

I'm pretty sure I made a mistake somewhere in the position logic and the resetPositionOffset functions, but I don't have an Arduino at hand to test it.

To switch between PB encoder and CC encoder, you could probably use something like this:

#include <Encoder.h>

#include <Control_Surface.h>

USBMIDI_Interface midi;

Button button = 4;

Encoder enc = {2, 3};
BorrowedMIDIRotaryEncoder<ContinuousCCSender> ccenc = {
  enc, 
  MCU::V_POT_1,
  1,   // multiplier
  4,   // pulses per step
  {},  // MIDI sender
};
BorrowedMIDIAbsoluteEncoder<PitchBendSender<14>> pbenc = {
  enc, 
  CHANNEL_1,
  127, // multiplier
  4,   // pulses per step
  {},  // MIDI sender
};

void setup() {
  button.begin();
  Control_Surface.begin();
  pbenc.disable();
}

void loop() {
  Control_Surface.loop();

  auto buttonState = button.update();
  if (buttonState == Button::Falling) {
    ccenc.disable();
    pbenc.resetPositionOffset();
    pbenc.enable();
  } else if (buttonState == Button::Rising) {
    pbenc.disable();
    ccenc.resetPositionOffset();
    ccenc.enable();
  } 
}

You have to use the share-encoder branch of the Control Surface library, and my fork of the Encoder library.

I'm pretty sure I made a mistake somewhere in the position logic and the resetPositionOffset functions, but I don't have an Arduino at hand to test it.

This will not compile here, is something outdated?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants