tttapa / Control-Surface

Arduino library for creating MIDI controllers and other MIDI devices.
GNU General Public License v3.0
1.27k stars 140 forks source link

PB and CC encoder #76

Closed rogerarends closed 4 years ago

rogerarends commented 4 years ago

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 commented 4 years ago

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

rogerarends commented 4 years ago

I mean rotary encoders. There is an example for pots in your library already.

Would be ok having a pushbutton to switch for each encoder as long as it works. Or is there a mix chip and library example for rotary encoders

On Dec 17, 2019 22:35, tttapa notifications@github.com wrote:

Do you mean encoders or potentiometers? If the latter, would something like thishttps://tttapa.github.io/Control-Surface-doc/Doxygen/d4/d79/One-Pot-Both-PB-and-CC_8ino-example.html work?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://github.com/tttapa/Control-Surface/issues/76?email_source=notifications&email_token=AJSCCYDBF5WBKJSHTPF7ULLQZEZYPA5CNFSM4J4AAKA2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEHD3ZFY#issuecomment-566738071, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AJSCCYFX3KY2EYKP3W3UKNTQZEZYPANCNFSM4J4AAKAQ.

tttapa commented 4 years ago

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 commented 4 years ago

It would be similar to your pb and cc potentiometer example.

In the first bank I want 8 rotary encoders that send pitch bend.

In the second bank I want 8 rotary encoders that send control change.

1 or 2 buttons to select between the two banks.

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 (VPOT 1 to 8) for the first 8 channels.

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

Other option is connect 16 encoders to 32 pins on the teensy 4. 8 for volume 8 for v_pot

leaving 2 accessable pins for connecting 4 mcp23017 on the i2c bus to give up to 64 buttons and or leds. (Example would be appreciated)

Then No oleds (I wanted to add 4 using your oled example 2) unless you could modify the code to use i2c oleds. I know it's about ten times slower than spi but I'd only require the displays to show static information like; track name, mute, solo, touch, write, read, zoom, cycle, play, record, pan and select. The axbm files I would create and implement myself.

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

I know it's asking alot but I'm patient and wait till end of Feb ...like you said.

On Wed, Dec 18, 2019, 15:44 tttapa notifications@github.com wrote:

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.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/tttapa/Control-Surface/issues/76?email_source=notifications&email_token=AJSCCYFQGMAFGK4LXF4XMHTQZISJ3A5CNFSM4J4AAKA2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEHGEW6Y#issuecomment-567036795, or unsubscribe https://github.com/notifications/unsubscribe-auth/AJSCCYB4EGV2Y5EGZVBDOXDQZISJ3ANCNFSM4J4AAKAQ .

tttapa commented 4 years ago

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 (VPOT 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: https://github.com/tttapa/MIDI_controller/issues/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 commented 4 years ago

Awesome.... But the reason I wanted to use rotary encoders for cc and pitch bend in the first place with studio one was that when changing banks or channels they didn't "remember" the previous position. Will give it a try in about 12 hours time when I finish work.

Also with regard to the first question of having 2 banks... one with 8 cc encoders and one with 8 pb encoders. How do I go about setting it up.

rogerarends commented 4 years ago

Just a thought. If I edit the mackie control xml file to indicate 4 instead of 8 channels as default.

Then could I use the first pb example you gave me for volume of the first 4 channels and the normal cc encoder for the v_pot of the first 4 channels. Including mute solo select buttons for the 4 channels. Then 2 oleds on spi using your example. Showing track names VU and pan for the 4 channels. 3rd oled I can setup to show time ,play record and other easy to implement note in stuff.

Then use midix16 to create virtual mackie extenders(with 4 channels per extender) so that I would be able to see the track names. When changing banks.

Reason being I sometimes mixdown songs with up to 30 tracks. And would be advantages to see what track I'm on as apposed to the channel number or bank number.

I'll attemp to setup or implement 2 expander on i2c.

Also try messing around with the extender example in the library for a few days. Then get back to you when I'm really stuck.

rogerarends commented 4 years ago

Hi found a work around Going to use the : CCIncrementDecrementButtons example and map the vpots to buttons.

Will try combining the oled 2 example and the io extender examples and bother you if I get stuck.

Thanks for all you help this far

tttapa commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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

rogerarends commented 4 years ago

Sorry for my ignorance but I don't know how to do it. I installed traction and it works. Included the OLD part of my sketch so you can tell me where to insert "LCD::getText" please.


From: tttapa notifications@github.com Sent: Tuesday, 24 December 2019 21:34 To: tttapa/Control-Surface Control-Surface@noreply.github.com Cc: rogerarends rogerarends@hotmail.com; State change state_change@noreply.github.com Subject: Re: [tttapa/Control-Surface] PB and CC encoder (#76)

You can check if the LCD receives anything using the LCD::getTexthttps://github.com/tttapa/Control-Surface/blob/afec0f0a95f3239400c12b9722dca1106ff7c951/src/MIDI_Inputs/MCU/LCD.hpp#L40 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.

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHubhttps://github.com/tttapa/Control-Surface/issues/76?email_source=notifications&email_token=AJSCCYCVFOZUCRYZQY2NZCDQ2JP2RA5CNFSM4J4AAKA2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEHTR52A#issuecomment-568794856, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AJSCCYE37O7SZVJNTSR5BVLQ2JP2RANCNFSM4J4AAKAQ.

tttapa commented 4 years ago

I'll post some code when I get home.

tttapa commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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

https://github.com/tttapa/Control-Surface/blob/6fae919d837a3e65f118d8a6dea8cb7a22bdf9e1/src/Display/MCU/LCDDisplay.hpp#L78-L102

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 commented 4 years ago

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 commented 4 years ago

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

https://github.com/tttapa/Control-Surface/blob/6fae919d837a3e65f118d8a6dea8cb7a22bdf9e1/src/Display/MCU/LCDDisplay.hpp#L59-L60

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

https://github.com/tttapa/Control-Surface/blob/6fae919d837a3e65f118d8a6dea8cb7a22bdf9e1/src/Display/MCU/LCDDisplay.hpp#L68-L70

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 commented 4 years ago

and getting the volume to display?

Promise I won't bother you until Feb. LOL

tttapa commented 4 years ago

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):

https://github.com/tttapa/Control-Surface/blob/6fae919d837a3e65f118d8a6dea8cb7a22bdf9e1/src/Display/MCU/LCDDisplay.hpp#L51-L53

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 commented 4 years ago

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

tttapa commented 4 years ago

Glad I could help :)

rogerarends commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

Thank you. works perfectly

rogerarends commented 4 years ago

how do I do this if there's nothing in the folder.

  1. (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 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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

Try adding +'\n' here: https://github.com/tttapa/Control-Surface/blob/25fb79f78487ea587e44a7ed0b8d578819b94c63/src/Display/Bitmaps/Scripts/XBM-export.py#L113

axbm.write('#ifndef DOXYGEN\n'+contents+'\n'+'#endif\n')
rogerarends commented 4 years ago

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

tttapa commented 4 years ago

Could you zip and post the entire Bitmaps folder?

rogerarends commented 4 years ago

Bitmaps.zip

tttapa commented 4 years ago

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 commented 4 years ago

Thanks, will try it when I get home.

rogerarends commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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 commented 1 year ago

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?