Giter VIP home page Giter VIP logo

tttapa / control-surface Goto Github PK

View Code? Open in Web Editor NEW
1.2K 58.0 131.0 94.5 MB

Arduino library for creating MIDI controllers and other MIDI devices.

License: GNU General Public License v3.0

Shell 0.37% C++ 94.44% C 3.04% Python 1.43% CMake 0.22% CSS 0.40% HTML 0.10% Makefile 0.01%
arduino arduino-library midi-controller control-surface midi midi-over-usb midi-over-ble teensy esp32 raspberry-pi-pico

control-surface's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

control-surface's Issues

How to connect multiple multiplexers and buttons?

Hello Pieter!
I use Multiplexers 4067
I saw your example with multiplexer and button but what if I wanna use multiple multiplexers and many buttons that send midi notes

How should I connect pins of all multiplexers? I mean pins SIG, S0, S1, S2, S3

What code for multiplexers should look like? Can you give me an example?

Arduino Esplora Example

I tried to use your library with the Arduino Esplora board and got it finally working.

Are you interested to add my code to your examples? Just asking because Arduino does not support the Esplora board any more.
All sensors are handled as potentiometer. Except for the temperature sensor, which crashed my board, and the piezo buzzer.

For the piezo buzzer, it would be nice to have an easy input access based on this library if this inside to goals of your work.

/**
 * Example for accessing sensors and actuators of the Arduino Esplora board with the 
 * Control Surface library
 * 
 * Currently excluded are the temperature sensor (crashed the Board for me) and the 
 * piezo buzzer.
 * See https://www.arduino.cc/en/Reference/EsploraLibrary for accessing them separately
 * 
 * @boards  Arduino Esplora
 *
 *  Written by tarTG, 2019-12-11  
 *  https://github.com/tttapa/Control-Surface
 */

// Include the library
#include <Esplora.h>
#include <Control_Surface.h>

// Instantiate a MIDI Interface to use
USBMIDI_Interface midi;

//Multiplexer interface
CD74HC4067 mux = {
  A4,       // Analog input pin
  {A0, A1, A2, A3} // Address pins S0, S1, S2
};

//Accelerlometer pins
const byte ACCEL_X_PIN = A5;
const byte ACCEL_Y_PIN = A11;
const byte ACCEL_Z_PIN = A6;

//LED pins
const byte RED_PIN    = 5;
const byte BLUE_PIN   = 9;
const byte GREEN_PIN = 10;


using namespace MIDI_Notes;


// Instantiate a NoteButton object
NoteButton EsploraSwitches[] = {
    //Switches 
    { mux.pin(CH_SWITCH_1), {note(C, 4), CHANNEL_1} },   // Down
    { mux.pin(CH_SWITCH_2), {note(D, 4), CHANNEL_1} },   // Left
    { mux.pin(CH_SWITCH_3), {note(E, 4), CHANNEL_1} },   // Up
    { mux.pin(CH_SWITCH_4), {note(F, 4), CHANNEL_1} },   // Right
    { mux.pin(CH_JOYSTICK_SW), {note(G, 4), CHANNEL_1} } // Joystick switch
};

//Sensors are handled as potentiometer
CCPotentiometer potentiometer[] = {
  { mux.pin(CH_SLIDER),{MIDI_CC::Channel_Volume, CHANNEL_1}},     // Slider
  { mux.pin(CH_JOYSTICK_X),{MIDI_CC::Channel_Volume, CHANNEL_2}}, // Joystick X-Axis
  { mux.pin(CH_JOYSTICK_Y),{MIDI_CC::Channel_Volume, CHANNEL_3}}, // Joystick Y-Axis
  { mux.pin(CH_LIGHT),{MIDI_CC::Channel_Volume, CHANNEL_5}},      // light sensor
  { mux.pin(CH_MIC),{MIDI_CC::Channel_Volume, CHANNEL_6}},        // microphone
  { ACCEL_X_PIN,{MIDI_CC::Channel_Volume, CHANNEL_7}},            // accelerometer X-axis
  { ACCEL_Y_PIN,{MIDI_CC::Channel_Volume, CHANNEL_8}},            // accelerometer Y-axis
  { ACCEL_Z_PIN,{MIDI_CC::Channel_Volume, CHANNEL_9}}             // accelerometer Z-axis
};

//example for accessing the LEDs
NoteValueLED leds[] = 
{
  {RED_PIN, note(C, 4)},
  {BLUE_PIN, note(D, 4)},
  {GREEN_PIN, note(E, 4)} 
};

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

void loop() {
  Control_Surface.loop(); // Update the Control Surface 
} 

Transpose function

Hi Pete

Does the transpose function work on rotary encoder addresses?

To change the panning from the address i set to another address

This way i can activate/deactivate the encoder button top and adjust the lh or rh panning function in a dual pan setup?

Cheers

Program Changer with Banks

Hi,
is it possible to make a Program Changer with 4 Buttons in each Bank for sending an individual Program Change command with this library? Because I tried to make the PcBtn bankable but that didn't work. I can't figure out how to accomplish that.
Regards
Paul

MUX Ext Io

Hi Peter

This is an extension on the mux button issue that was in the closed issues section

Can I use a button matrix with a multiplexer by passing the mux pin numbers to the button matrix constructor?

And can rotary encoders be used with a multiplexer?

Send MIDI Note value through a potentiometer.

Hi!

Hope you're doing well.
I am currently in the beginning process of building a MIDI controller which works in a slightly unusual way and I am not too sure where to head in terms of writing the code for one specific action.

To be precise, I would like to use the variable resistance of a potentiometer to assign specific note values to each knob and have it in a way such as:

the potentiometer is all the way to the left at 0 = note off
as it turns clockwise = note on (a specific note for example middle c) and for each incremental change in the position of the knob have it reflect into an increase of midi velocity with the max being at 127.

How is it possible to do this?

Thank you so much for your time in advance,

Kindly

Gio

(SOLVED) MIDI IN / LED with multiplexer ?

I know this library is under construction, but my questions is there is a way or did it support using Multiplexer for MIDI Input / LEDs for the Final/Alpha Release? Maybe an example?

Thank You

How to use rgb leds with common anode?

Hello Pieter!
I have one shift register and 3 RGB Leds.
I have 3 buttons in multiplexer
When I press first button red color of led should light up. WHen I press it again a led light should go out.
Second button - green color of second led
Third button - blue color of third led
Usually RGB leds have common cathode, but my rgb leds have common anode.
How should I wire rgb led to shift register in this case?

Can you give me a simple example of buttons and rgb leds for my case?

Overlapping banks for MIDI inputs

Right now, as soon as a MIDI input element matches an incoming message, it doesn't search any further for other elements that match.

This means that overlapping banks are impossible.

A simple solution would be to allow a setting that tries to match all elements. This isn't super efficient, but I don't think I can do any better without completely refactoring the MIDI input elements.

Inspiration: https://forum.arduino.cc/index.php?topic=627369.0

Missing define on ESP32

I wanted to try your library on an ESP32, but there is a define missing, so i can't compile.

/Control-Surface-master/src/Helpers/Exit.cpp: In function 'void CS::fatalErrorExit()': Control-Surface-master/src/Helpers/Exit.cpp:10:13: error: 'LED_BUILTIN' was not declared in this scope pinMode(LED_BUILTIN, OUTPUT);

Even if i define LED_BUILTIN in my code, it does not compile.

If i select another board, everything works fine.

Led with shift register 74hc595 doesn't work by SPI

Hello Pieter!

My board is Arduino Leonardo

I connected a led to shift register SN74HC595N by SPI. It doesn't work. Led blinks fast even if I change a code. It seems it work incorrectly. But if I connect a led in a regular way(digital pins instead of iscp header pins) with a sketch for regular connection it works fine

Did I make wrong wiring?

Here is i connected all the stuff:

arduino leonardo shift register

Here is my sketch:

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

using namespace ExtIO; // Bring the ExtIO pin functions into your sketch

// Instantiate a shift register with the SPI slave select pin as latch pin, most
// significant bit first, and a total of 8 outputs.
SPIShiftRegisterOut<8> sreg = {10, MSBFIRST};

const pin_t ledPin = sreg.pin(1); // first pin of the shift register

void setup() {
sreg.begin(); // Initialize the shift registers
pinMode(ledPin, OUTPUT); // You don't even need this line, since
// shift registers are always outputs
}

void loop() {
// Toggle the state of the LED every 1/2 second
digitalWrite(ledPin, HIGH);
delay(700);
digitalWrite(ledPin, LOW);
delay(700);
}`

Invert Potentiometer

I looked, but I don't see a way to invert a potentiometer signal. Is this possible to do? I would rather not need to reverse polarity in hardware. Specifically, I have an array of potentiometers.

Espressif chips

I was looking for a way to revive old controllers and this looks ideal. Are there any plans to get this working for ESP8266 or the bigger ESP32? They have wireless and BLE onboard along with loads of GPIO and may be cheaper than their Arduino equipvalents.

MMC

Hi,
I am trying to make a simple remote control with MIDI, just play, stop, rec button with feedback from the controlled machine, lighting led for each function. I have tried your library but no way. I am trying to control protools with hui protocol. It seems that MCU does not match HUI.
Do you have a clue?
Thanks?
Pierre

How to send Program Change for Bank/Presets

How to send MIDI message with particular preset (bank) number? Let's assume we have buttons: Bank Down, Bank Up.
Bank Down sends decremented by -1 bank value and Bank Up sends incremented by +1 value. I would like to achieve solution for e.g. LED display which would display bank number and preset number.
Is possible and is there any sense?

bank_and_presets

Shift Registers with leds

Hi Pieter!
I want to use shift register 74HC595 to connect 8 leds to Arduino Leonardo. I saw your example TOGGLE LEDs, but I didn't find line with code where you define Arduino pins for connecting shift registers. Shift register require 3 pins for communication with Arduino(latch pin, data pin and clock pin) I just can't find where you define it.

May be there is some file in your library where you did it?

Can you explain this to me?

botton bank

hi, i am having trouble on a code for a 6 banks of buttonmatrix with 6 leds and two butons for changing banks
buttom matrix is 6 buttons (two rows 3 colums)
i want to be able to choose the note for each button in every bank. i try some of the examples but i get errors with them.
thanks in advance

Possibility of communication between modules

Hi Pete

Is there a possibility of getting the Arduino boards to communicate with each other so that each module is on the buss with one master module passing the Midi information to/from the PC via usb.
Either over I2C or similar using the spare TX RX ports

If the message is a channel 2 message it only gets recognized by the #2 module

The modules can be programmed exactly the same except for the midi channel number
All of the slaves would only need to be powered by a 9v supply.and connected on the bus.

With this approach there is the possibility of having a modular up to 48 ch mixing console with with (EQ and Dynamics modules) setup using only 3 usb ports (and only 3 generic midi controllers).

i.e.

Fader module 1 : (mega 1 sends and receives midi data to/from Master)
CCPotentiometer potentiometer(A0, {MIDI_CC::Channel_Volume, CHANNEL_1});

Fader Module 2 : (mega 2 sends and receives midi data to/from Master)
CCPotentiometer potentiometer(A0, {MIDI_CC::Channel_Volume, CHANNEL_2});

Master Module: (Mega 16) Passes all information to PC
CCPotentiometer potentiometer(A0, {MIDI_CC::Channel_Volume, CHANNEL_16});

I am about to start the design of the EQ Module and Master Modules
All will have their own controller(Mega) and custom pcb
All Face panels will be laser cut
8 fader assembly img2

button matrix.ino

With the new "fix" it seems to compile the basic examples but the button-matrix sketch is still giving me error in compile:

Ex.11.Button-Matrix:34:81:` error: no matching function for call to 'ButtonMatrix<4, 3>::ButtonMatrix(<brace-enclosed initializer list>, <brace-enclosed initializer list>, const uint8_t [4][3], int, const uint8_t&)'
 ButtonMatrix<4, 3> buttonmatrix( {2, 3, 4, 5}, {6, 7, 8}, addresses, 1, velocity);
                                                                                 ^
In file included from /Users/brorgustav/Documents/Arduino/Sketches/libraries/Control-Surface/src/Hardware/ButtonMatrix.hpp:78:0,
                 from /Users/brorgustav/Documents/Arduino/Sketches/libraries/Control-Surface/src/MIDI_Outputs/Abstract/MIDIButtonMatrix.hpp:4,
                 from /Users/brorgustav/Documents/Arduino/Sketches/libraries/Control-Surface/src/MIDI_Outputs/CCButtonMatrix.hpp:3,
                 from /Users/brorgustav/Documents/Arduino/Sketches/libraries/Control-Surface/src/Control_Surface.h:31,
                 from /Users/brorgustav/Documents/Arduino/Sketches/libraries/Control-Surface/examples.old/very-old/Ex.11.Button-Matrix/Ex.11.Button-Matrix.ino:22:
/Users/brorgustav/Documents/Arduino/Sketches/libraries/Control-Surface/src/Hardware/ButtonMatrix.ipp:8:1: note: candidate: ButtonMatrix<nb_rows, nb_cols>::ButtonMatrix(PinList<nb_rows>&, PinList<nb_cols>&) [with unsigned char nb_rows = 4; unsigned char nb_cols = 3; PinList<nb_rows> = Array<short unsigned int, 4>; PinList<nb_cols> = Array<short unsigned int, 3>]
 ButtonMatrix<nb_rows, nb_cols>::ButtonMatrix(const PinList<nb_rows> &rowPins,
 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/brorgustav/Documents/Arduino/Sketches/libraries/Control-Surface/src/Hardware/ButtonMatrix.ipp:8:1: note:   candidate expects 2 arguments, 5 provided
In file included from /Users/brorgustav/Documents/Arduino/Sketches/libraries/Control-Surface/src/MIDI_Outputs/Abstract/MIDIButtonMatrix.hpp:4:0,
                 from /Users/brorgustav/Documents/Arduino/Sketches/libraries/Control-Surface/src/MIDI_Outputs/CCButtonMatrix.hpp:3,
                 from /Users/brorgustav/Documents/Arduino/Sketches/libraries/Control-Surface/src/Control_Surface.h:31,
                 from /Users/brorgustav/Documents/Arduino/Sketches/libraries/Control-Surface/examples.old/very-old/Ex.11.Button-Matrix/Ex.11.Button-Matrix.ino:22:
/Users/brorgustav/Documents/Arduino/Sketches/libraries/Control-Surface/src/Hardware/ButtonMatrix.hpp:18:7: note: candidate: constexpr ButtonMatrix<4, 3>::ButtonMatrix(const ButtonMatrix<4, 3>&)
 class ButtonMatrix {
       ^~~~~~~~~~~~
/Users/brorgustav/Documents/Arduino/Sketches/libraries/Control-Surface/src/Hardware/ButtonMatrix.hpp:18:7: note:   candidate expects 1 argument, 5 provided
Ex.11.Button-Matrix:34:20: error: cannot declare variable 'buttonmatrix' to be of abstract type 'ButtonMatrix<4, 3>'
 ButtonMatrix<4, 3> buttonmatrix( {2, 3, 4, 5}, {6, 7, 8}, addresses, 1, velocity);
                    ^~~~~~~~~~~~
In file included from /Users/brorgustav/Documents/Arduino/Sketches/libraries/Control-Surface/src/MIDI_Outputs/Abstract/MIDIButtonMatrix.hpp:4:0,
                 from /Users/brorgustav/Documents/Arduino/Sketches/libraries/Control-Surface/src/MIDI_Outputs/CCButtonMatrix.hpp:3,
                 from /Users/brorgustav/Documents/Arduino/Sketches/libraries/Control-Surface/src/Control_Surface.h:31,
                 from /Users/brorgustav/Documents/Arduino/Sketches/libraries/Control-Surface/examples.old/very-old/Ex.11.Button-Matrix/Ex.11.Button-Matrix.ino:22:
/Users/brorgustav/Documents/Arduino/Sketches/libraries/Control-Surface/src/Hardware/ButtonMatrix.hpp:18:7: note:   because the following virtual functions are pure within 'ButtonMatrix<4, 3>':
 class ButtonMatrix {
       ^~~~~~~~~~~~
/Users/brorgustav/Documents/Arduino/Sketches/libraries/Control-Surface/src/Hardware/ButtonMatrix.hpp:63:18: note: 	void ButtonMatrix<nb_rows, nb_cols>::onButtonChanged(uint8_t, uint8_t, bool) [with unsigned char nb_rows = 4; unsigned char nb_cols = 3; uint8_t = unsigned char]
     virtual void onButtonChanged(uint8_t row, uint8_t col, bool state) = 0;
                  ^~~~~~~~~~~~~~~
/Users/brorgustav/Documents/Arduino/Sketches/libraries/Control-Surface/examples.old/very-old/Ex.11.Button-Matrix/Ex.11.Button-Matrix.ino: In function 'void loop()':
Ex.11.Button-Matrix:40:19: error: 'class Control_Surface_' has no member named 'refresh'
   Control_Surface.refresh();
                   ^~~~~~~
Multiple libraries were found for "SPI.h"
 Used: /Users/brorgustav/Documents/Arduino/Sketches/libraries/SPI
 Not used: /Users/brorgustav/Library/Arduino15/packages/arduino/hardware/samd/1.8.3/libraries/SPI
Using library Control-Surface at version 1.0.0 in folder: /Users/brorgustav/Documents/Arduino/Sketches/libraries/Control-Surface 
Using library SPI at version 1.0 in folder: /Users/brorgustav/Documents/Arduino/Sketches/libraries/SPI 
Using library MIDIUSB at version 1.0.4 in folder: /Users/brorgustav/Documents/Arduino/Sketches/libraries/MIDIUSB 
exit status 1
no matching function for call to 'ButtonMatrix<4, 3>::ButtonMatrix(<brace-enclosed initializer list>, <brace-enclosed initializer list>, const uint8_t [4][3], int, const uint8_t&)'

Pro Micro Supported ?

Hi Pieter
Thank you for your work on this great library !

I need to ask - Is Pro Micro ATMega32U4 currently supported?

I tried the Potentiometer example and code compiles and uploads fine, but USB device is not recognized in Windows. This is the same for Control-Surface as well as MIDIController. The unit should be ok, USBMidiKlik seems to be recognized.

This could very well be problems with my toolchain, I just wanted to check if it's supposed to work : )

Thank you a million in advance for clarifying this, and have a nice day.
BR Jesper

Debugging

Hey there Pete

I have uncommented the lines 17 and 19
can you please give detailed description of how to use debugging

i cannot work out where to see the messages (i.e the arduino serial monitor)
and what must be connected

then i can see what messages are being sent to the arduino for fader movements and vu signals
to help with the programing of motor faders and vu meters

For some reason i cannot get any of the software midi monitors to work with cubase
it must take full control of the ports

Cheers for all the help
Sam

How to use buttons and send Midi CC and Midi Note through multiplexer?

I have multiplexer CD74HC4067, I connected 3 buttons to it.
I didn't find an example how to send midi notes or midi CC through multiplexer
Can you show me a sketch with one or more buttons?

I found wiring in your test sketch
CD74HC4067 mux = {
2, // input pin
{3, 4, 5, 6}, // Address pins S0, S1, S2, S3
// 7, // Optionally, specify the enable pin
};

should I connect 2 pin on Arduino to pin SIG on multiplexer?

Incomplete?

Are you still considering finishing this library? I could really use something like this

Great work

How can I read Note ID(Address) and velocity from DAW?

Hi, there!
I want to receive a MIDI signal from the DAW and read it from the Arduino to adjust my LED strip based on Note ID and Velocity.
I'm using Neopixel's strip and hopefully I can read the Note ID and Velocity even if there's no function for that.
The example on the part that receives the MIDI signal seems to be missing these questions.
Can you show me a simple example of reading MIDI Note Signals?

Thanks!

How to change leds' channel used in shift register?

Hello Pieter!
I have 3 momentary buttons that connected to multiplexer and send midi notes.
I have 3 leds connected to 3 shift registers

My sketch works fine and leds react to push buttons. The problem is that leds react only on CHANNEL_1, if I change buttons' channel to CHANNEL_2 leds doesn't work.

How can I change leds' channel that react on midi notes?

Here is a piece of code from my sketch:

NoteButton button[] = {
  {mux.pin(0),{note(C, 4), CHANNEL_1}},
  {mux.pin(7),{note(D, 4), CHANNEL_1}},
  {mux.pin(15),{note(E, 4), CHANNEL_1}}
};
  
// Create an array of LEDs that listen to MIDI Note messages, turning on and off
// the LEDs connected to the eight input pins of the shift register
MIDINoteLED leds[] = {
  {sreg.pin(1), note(C, 4)}, // LED pin, address (note number, channel, cable)
  {sreg.pin(9), note(D, 4)},
  {sreg.pin(17), note(E, 4)}
};

How to use Midi CC instead of Note with button?

Hi Pieter!
I want to use button and send midi cc, but in your example : Midi Output/Buttons and Switched/Momentary push buttons/NoteButton you made sending only NoteNumber

How can I change the code to send Midi CC to my DAW instead of NoteNumber with a button?

Can you give me a nexample of using a button that sends midi cc?

MIDI input elements mutex lock ESP32 bug

static void updateAllWith(const MIDI_message_matcher &midimsg) {

The updateAllWith functions can be called asynchronously on ESP32. In the function, iterators over the entire linked list of the type of MIDI input elements are used. However, the iterators can be invalidated if the enable/disable (or constructors or destructors) are called from the main thread.

Proposed solution: add a lock to the updateAllWith function, remove the lock in the moveDown function, and make sure that it isn't used anywhere else.

It's possible? One LED for VU

wonder if there is any implementation to use one LED to inform the intensity of the sound in a particular DAW channel. Something like the led that is used in the MUTE, (MCU :: MUTE_1, 1) only by alternating the led intensity according to volume.

thanks for attention

Compiling ex11 button matrix example for MKRZERO

When compiling buttonmatrix.ino:

In file included from /Users/brorgustav/Library/Arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/arm-none-eabi/include/c++/7.2.1/bits/char_traits.h:39:0,
                 from /Users/brorgustav/Library/Arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/arm-none-eabi/include/c++/7.2.1/ios:40,
                 from /Users/brorgustav/Library/Arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/arm-none-eabi/include/c++/7.2.1/ostream:38,
                 from /Users/brorgustav/Library/Arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/arm-none-eabi/include/c++/7.2.1/iterator:64,
                 from /Users/brorgustav/Documents/Arduino/Sketches/libraries/Control-Surface/src/Helpers/LinkedList.hpp:9,
                 from /Users/brorgustav/Documents/Arduino/Sketches/libraries/Control-Surface/src/Display/DisplayInterface.hpp:4,
                 from /Users/brorgustav/Documents/Arduino/Sketches/libraries/Control-Surface/src/Display/DisplayElement.hpp:3,
                 from /Users/brorgustav/Documents/Arduino/Sketches/libraries/Control-Surface/src/Control_Surface/Control_Surface_Class.hpp:7,
                 from /Users/brorgustav/Documents/Arduino/Sketches/libraries/Control-Surface/src/Control_Surface.h:16,
                 from /Users/brorgustav/Documents/Arduino/Sketches/axiom32_ttappa-lib_mkrzero_keyboard/axiom32_ttappa-lib_mkrzero_keyboard.ino:22:
/Users/brorgustav/Library/Arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/arm-none-eabi/include/c++/7.2.1/bits/stl_algobase.h:243:56: error: macro "min" passed 3 arguments, but takes just 2
     min(const _Tp& __a, const _Tp& __b, _Compare __comp)
                                                        ^
/Users/brorgustav/Library/Arduino15/packages/arduino/tools/arm-none-eabi-gcc/7-2017q4/arm-none-eabi/include/c++/7.2.1/bits/stl_algobase.h:265:56: error: macro "max" passed 3 arguments, but takes just 2
     max(const _Tp& __a, const _Tp& __b, _Compare __comp)
                                                        ^
Multiple libraries were found for "SPI.h"
 Used: /Users/brorgustav/Documents/Arduino/Sketches/libraries/SPI
 Not used: /Users/brorgustav/Library/Arduino15/packages/arduino/hardware/samd/1.8.3/libraries/SPI
Using library Control-Surface at version 1.0.0 in folder: /Users/brorgustav/Documents/Arduino/Sketches/libraries/Control-Surface 
Using library SPI at version 1.0 in folder: /Users/brorgustav/Documents/Arduino/Sketches/libraries/SPI 
Using library MIDIUSB at version 1.0.4 in folder: /Users/brorgustav/Documents/Arduino/Sketches/libraries/MIDIUSB 
exit status 1
Error compiling for board Arduino MKRZERO.

rotary encoders

Hi Peter

How you going

So i have updated my library to your latest version of control surface
and just going through and changing all the namespaces
but i cant find any examples of the rotary encoder code lines

can you help me out or point me in the right direction where i can find it

i was using the old RotaryEncoder for my pan control and now it throws an error on compiling
says it does not name a type

sorry to bother you with something so trivial (i really am terrible at any form of coding)

and thanks again you have put a lot of time and effort into this code and i really appreciate it

HOW TO Modif LIBRARY

HI PIETER..
I want ask about library control surface
how i can make CCButtonlatched.hpp send MIDI CC from modif NoteButtonLatched.hpp.
i want make like example like pushbutton no midi feedback .. but with MIDI CC send..
thanks
Best Regards.

Potentiometer Calibrated? Need Help

There is a example for Potentiometer map Calibrated like the old version? im trying :

CCPotentiometer potentiometer(A15, {MIDI_CC::Channel_Volume, CHANNEL_2});

const int minimumValue = 10;    // the analog value read when the potentiometer is in the minimum position.
const int maximumValue = 1000; // the analog value read when the potentiometer is in the maximum position.

int mapCalibrated(int value) {
  value = constrain(value, minimumValue, maximumValue); // make sure that the analog value is between the minimum and maximum value
  return map(value, minimumValue, maximumValue, 0, 1023); // map the value from [minimumValue, maximumValue] to [0, 1023]
}

but doesnt work
Thank you

Toggle buttons and leds and send midi cc

Hello Pieter!
I have buttons in multiplexer 4067 and leds in shift registers.

When I press a button midi cc with value should be sent and led will light up, when I press the same button again midi cc with another value should be sent and led will go out.
Buttons should be like toggles.
It's like when you press a a button on a footswitch to change preset on midi controller in some guitar VST like Guitar Rig or Bias FX.

Screenshot_1

I saw CCButtonLatched class, is it what I should use for my task?
I didn't find an example with toggle buttons and leds
Can you write me an example how to use buttons as toggles with leds?

Dual midi interface

hello Pieter
i got error using dual midi interface... im using lilypad atmega32u4
the problem is when i upload dual midi interface always got error Couldn't find a Board on the selected port. but if i just using USBMIDI_Interface midi always succesfull.

and this my code..

#include <Control_Surface.h>

// Instantiate a MIDI over USB interface.
//USBMIDI_Interface midi;

USBMIDI_Interface usbmidi;
HardwareSerialMIDI_Interface serialmidi = {Serial1, MIDI_BAUD};
MultiMIDI_Interface<2> midi = {{&usbmidi, &serialmidi}};

// Instantiate the momentary pbuush buttons that send out MIDI Note events.
CCButtonLatched  buttons[] = {
    {21, MIDI_CC::Effects_1}, // 
    {19, MIDI_CC::Effects_2},
};

constexpr size_t numberOfButtons = sizeof(buttons) / sizeof(*buttons);

// The pins of the LEDs that will display the state of the buttons
pin_t ledPins[] = {
    18,
    15,
};

constexpr size_t numberOfLEDs = sizeof(ledPins) / sizeof(*ledPins);
static_assert(numberOfButtons == numberOfLEDs,
              "Error: number of buttons is not "
              "the same as the number of LEDs!");
void setup() {
    // Initialize everything
    Control_Surface.begin();

    for (pin_t &pin : ledPins)
        pinMode(pin, OUTPUT);
}

void loop() {
    // Update the control surface: read new MIDI events, and read all inputs
    Control_Surface.loop();

    for (uint8_t i = 0; i < numberOfLEDs; ++i)
        digitalWrite(ledPins[i], buttons[i].getState());
}

Reading a CC value to ShiftReg Vu-Meter

Hello, I want to read a CC value send from Traktor( for example the CC 004 of the channel 3) with a range from 0 to 127 and according to the value, light 8 leds increasingly like a VU-Meter.

I have searched and I only have found in the examples some banks and in the example of the ShiftReg LEDs that it light up all the LEDs, but it doesn0t read the CC value and according to that, make the VUMeter effect.
So, how can I do that?
Thank you so much
Best regards

How can I change button's note with master button?

I tried to semitone the notes assigned to all buttons while pressing the 'master button'.

...
#define MASTERBTN      42
boolean isMaster = false;
...
char noteNames[] = {C, D, E, F, G, A, B};
int noteNum = 3;
...
NoteButton buttons[] = {
  {43, {note(noteNames[0], noteNum), CHANNEL_1}},
  ...
  {33, {note(noteNames[0], noteNum + 2), CHANNEL_1}}
};
...
void loop() {
  if(digitalRead(MASTERBTN) == LOW) {
    if(!isMaster) {
      isMaster = true;
      noteNames[0] = C;
      noteNames[1] = Db;
      noteNames[2] = Eb;
      noteNames[3] = F;
      noteNames[4] = Gb;
      noteNames[5] = Ab;
      noteNames[6] = Bb;
      Serial.println("here we are");
    }
  } else {
    if(isMaster) {
      isMaster = false;
      noteNames[0] = C;
      noteNames[1] = D;
      noteNames[2] = E;
      noteNames[3] = F;
      noteNames[4] = G;
      noteNames[5] = A;
      noteNames[6] = B;
      Serial.println("now here");
    }
  }
  Control_Surface.loop();
  FastLED.show();
}

I could check the serial messages, but the log and MIDI signals did not output the modified note.
How can I change button's note with master button?

Use input value in project

Hi,

I Want to use the value of an input in code

example
i get an input for MIDI_CC::Channel_Volume
i want to do some calculations and write it to the serial port

how can i get this to work

add led on/off while midi send note

Description of the problem or question

i make usb midi foot controller from your library and your library very good and easy to use .. but i use 8 button and 8 led... i want when button press
led is on and when button press again led is off.. can you teach me how can make easy away for the code or method modif your library?
this is my code

Full code

#include <MIDI_Controller.h>

int led1 = 10;
int led2 = 16;
int led3 = 14;
int led4 = 15;
int led5 = 18;
int led6 = 19;
int led7 = 20;
int led8 = 21;


const uint8_t velocity = 0b1111111; // Maximum velocity (0b1111111 = 0x7F = 127)
const uint8_t C4 = 60;
const uint8_t D4 = 63;
const uint8_t E4 = 64;
const uint8_t F4 = 65;
const uint8_t G4 = 67;
const uint8_t C3 = 48;
const uint8_t B4 = 71;
const uint8_t D3 = 50;

Digital button1(2, C4, 1, velocity);
Digital button2(3, D4, 1, velocity);
Digital button3(4, E4, 1, velocity);
Digital button4(5, F4, 1, velocity);
Digital button5(6, G4, 1, velocity);
Digital button6(7, A3, 1, velocity);
Digital button7(8, B4, 1, velocity);
Digital button8(9, 72, 1, velocity);


void setup () {}

void loop() {
  MIDI_Controller.refresh();
}

How to make leds react on MidiCC instead of notes?

I have 3 shift registers and 3 leds.
You have an example to use leds that reacts on MidiNote

Is it possible to make leds react on MidiCC instead? How can I do that?

MIDINoteLED leds[] = {
{sreg.pin(1), note(C, 4)}, // LED pin, address (note number, channel, cable)
{sreg.pin(9), note(D, 4)},
{sreg.pin(17), note(E, 4)}
};

OLED display + midi clock

I see that you already have implemented OLED display possibilities but it is for spi displays. Will it be possible to have the same for I2C ?

Also, I don't find a way to use midi clock to display the bpm from my DAW with,for example, a led. Is it in your plans ?

Getting MIDI Clock from DAW

Hi
First of all thank you for this great library.
I have a sketch that works fine with getting the realtime messages via midi.read() / serial.read() and sync is working fine but once I call Control_Surface.begin() the midi clock timing is messed up.
I saw that there is a "onRealtimeMessage" callback in the documentation but I can't manage to get it to work, can you please share an example on how to define callback for real time midi messages in a sketch?
Thank you.

Track Names for OLED

Hi Pete

More of a question than an issue

I have been looking through the getting stated doc for the oled displays and i am wondering if there is a "Track name" display for the oled display
so i can see what track the controller is on

i set cubase as a mackie controller and changed the track name- in the debugging serial monitor it says Data bye ignored when it send the message through to the controller

So i think it is sending out the messages

What are your thoughts

Cheers Sam

Motorised Faders

Looking through the files i can see that there are several ways to receive the incoming midi messages from Cubase 8.5 but i am using it a a generic remote. that way io can programm my own functions.
and it works great.
I have managed to get everything working except the shift registers :( any help there with your schematics would be great. i think its my wiring that's wrong

But....

How can i modify this to give me the data from the MIDIcc message to control the motor fader controlled on a Hbridge for instance. https://github.com/codyhazelwood/motorized-fader-arduino such as this.

Other than that this code is awesom and works great on my 2560 with HIDUINO. NICE WORK

sorry im not very good a coding. i have been looking through all the LIB source code and i think i can do it in a similar way to your VU input for instance.

In cubase i have turned the transmit and receive button on and can see on the RX LED on the Board that every time i switch banks in cubase it is sending the data for the Fader position.

I just cannot work out how to use it :(
cubase

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

const uint8_t velocity = 0b1111111; // Maximum velocity (0b1111111 = 0x7F = 127)
const uint8_t addresses[4][4] = {   // the note numbers corresponding to the buttons in the matrix
  {  1,  2,  3, 13 },
  {  4,  5,  6, 14 },
  {  7,  8,  9, 15 },
  { 10, 11, 12, 16 },
};

// Create a new instance of the class 'ButtonMatrix', called 'buttonmatrix', with dimensions 4 rows and 3 columns, with the rows connected to pins 2, 3, 4 and 5
// and the columns connected to pins 6, 7 and 8, that sends MIDI messages with the notes specified in 'addresses' on MIDI channel 1, with velocity 127
ButtonMatrix<4, 4> buttonmatrix( {14, 15, 16, 17}, {18, 19, 20, 21}, addresses, 1, velocity);

const uint8_t BANK_LEFT = 0x2E;
const uint8_t BANK_RIGHT = 0x2F;
const uint8_t LED1 = 61;// Note number 60 is defined as middle C in the MIDI specification
const uint8_t LED2 = 62;
const uint8_t LED3 = 63;
const uint8_t LED4 = 64;
const uint8_t LED5 = 65;
const uint8_t LED6 = 66;
const uint8_t LED7 = 67;
const uint8_t LED8 = 68;
const uint8_t LED9 = 69;
const uint8_t LED10 = 70;
const uint8_t LED11 = 71;
const uint8_t LED12 = 72;
const uint8_t LED13 = 73;
const uint8_t LED14 = 74;
const uint8_t LED15 = 75;
const uint8_t LED16 = 76;
const uint8_t test = 60;

//_____________________________________________________________________________________________________________________________________________________________________________________________

MIDI_LED leds[] = {
    {22, LED1, 1},
    {23, LED2, 1},
    {24, LED3, 1},
    {25, LED4, 1},
    {26, LED5, 1},
    {27, LED6, 1},
    {28, LED7, 1},
    {29, LED8, 1},
    {30, LED9, 1},
    {31, LED10, 1},
    {32, LED11, 1},
    {33, LED12, 1},
    {34, LED13, 1},
    {35, LED14, 1},
    {36, LED15, 1},
    {37, LED16, 1},
};

Digital switches[] = {
    {2, 0x10, 1, velocity}, 
    {3, 0x11, 1, velocity},
    {4, 0x12, 1, velocity},
    {5, 0x13, 1, velocity},
    {6, 0x14, 1, velocity},
    {7, 0x15, 1, velocity},
    {8, 0x16, 1, velocity},
};

Analog faders[] = {
    {A0, MIDI_CC::Channel_Volume, 1},
    {A1, MIDI_CC::Channel_Volume, 2},
    {A2, MIDI_CC::Channel_Volume, 3},
    {A3, MIDI_CC::Channel_Volume, 4},
};

Digital bankswitch[] = {
     {9, BANK_LEFT, 1},
     {10, BANK_RIGHT, 1},
};

//_____________________________________________________________________________________________________________________________________________________________________________________________

void setup() {}


void loop() {
  // Refresh the MIDI controller (check whether the potentiometer's input has changed since last time, if so, send the new value over MIDI)
  Control_Surface.refresh();
}

Selectors and banks

Pieter, thank you for an awesome library and just what I need at the moment for my little project of building a midi controller. Please excuse the questions as I am not a developer. I can understand some programming languages when I read through them slowly but get quite lost in the more technical source code.

I have defined 2 banks, 1 to control the octave being played by a group of NoteButtons, and 1 to control the active midi channel. Octave bank is linked to an Increment/Decrement selector and works perfectly. Channel bank also linked to an Increment/Decrement selector that I'm connecting to pin13 to use as an object holder for the banks. I am successfully using the results from turning a potentiometer to set the active midi channel. So both banks work 100%. My problem is that I would like to use a pot as well to change the octave bank. Doing what I did with the other bank does not work however. In fact nothing works if I set the value of the bank using a variable. I can statically change the bank to a value using an actual int. The code uploads but nothing works, as in there are no midi signals going out and my 7 segment led display does not come on.

I'm pretty sure I'm not using the selectors as they are meant to be, but as mentioned I'm not a developer so I cut and paste a lot, and I work from examples to see how to use certain functions etc, and sometimes I can get what the source is trying to tell me.

I cannot for the life of me figure out what is different between the 2 banks where one would allow me to programatically set the bank and the other causes the entire system not to function ?

Apologies for the very lengthy post...

/* Alpaha Station Zero
 * -------------------
 * Midi controler unit using an Arduino to control buttons, slide potentiometers, rotary potentiometers, and a 4 digit 7 segment LED display 
 * 16 buttons will be direct midi inputs for instrument activation
 * 4 slide potentiometers to control effects
 * 4 rotary potentiometers to control changing of setting options which can be used to assign different settings to the effects sliders for eg...
 * 4 digit 7 segment LED display unit which is controlled by the rotary potentiometers giving each bank 10 settings
 * 
 * https://github.com/tttapa/Control-Surface
 */

#include <Control_Surface.h> // Include the Control Surface library
#include "LedControl.h" // Include library to control 4 Digit 7 Segment display

const int speedMultiplier = 1;

const uint8_t velocity = 0b1111111; // Maximum velocity (0b1111111 = 0x7F = 127)

USBMIDI_Interface midi; // Instantiate a MIDI Interface to use

using namespace MIDI_Notes; // Enable midi notes

CD74HC4067 buttonMux = { // Instantiate a multiplexer to connect all 16 buttons
  12,                    // input pin
  {11, 10, 9, 8},        // Address pins S0, S1, S2, S3
};

CD74HC4067 potMux = { // Instantiate a multiplexer to connect all 8 potentiometers (4 rotary, 4 slide)
  A0,                 // input pin
  {A4, A3, A2, A1},   // Address pins S0, S1, S2, S3
};

LedControl fourdig=LedControl(7, 6, 5, 1); // Instantiate a LED Display object, pin 7 = DataIn, pin 6 = CLK, pin 5 = LOAD, 1 max7219

Bank<16> channelBank(1); // Create 16 banks for the 16 midi channels available
IncrementDecrementSelector<16> switchChannel(channelBank, {13, 13}, Wrap::NoWrap);  // Instantiate an increment/decrement button selector to manipulate with a potentiometer as a channel Bank

Bankable::CCPotentiometer controlPots[] = { // Create an array of potentiometers that send out MIDI Control Change messages when you turn the potentiometers (testing Midi-cc and using pots to control banks)
  {{channelBank, BankType::CHANGE_CHANNEL}, potMux.pin(0), {MIDI_CC::Channel_Volume, CHANNEL_1}},
  {{channelBank, BankType::CHANGE_CHANNEL}, potMux.pin(1), {MIDI_CC::Pan, CHANNEL_1}},
  {{channelBank, BankType::CHANGE_CHANNEL}, potMux.pin(2), {MIDI_CC::Modulation_Wheel, CHANNEL_1}},
  {{channelBank, BankType::CHANGE_CHANNEL}, potMux.pin(3), {MIDI_CC::Effects_5, CHANNEL_1}},
//  {potMux.pin(4), {MIDI_CC::Effects_1, CHANNEL_1}},
//  {A3, {MIDI_CC::Effects_1, CHANNEL_1}},
//  {A5, {MIDI_CC::Modulation_Wheel, CHANNEL_1}},
};


Bankable::PBPotentiometer pbFader = { // Instantiate a PBPotentiometer object, Analog pin connected to potentiometer, MIDI Channel 1 
  {channelBank, BankType::CHANGE_CHANNEL}, potMux.pin(4), CHANNEL_1,                
};

Bank<9> octaveBank(12);  // Create 9 banks for the playable octaves with 12 tracks for the notes

IncrementDecrementSelector<9> switchOctave(octaveBank, {4, 3}, Wrap::NoWrap);  // Instantiate an increment/decrement button selector, increment on pin4 and decrement on pin 3, linked to octaveBank

Bankable::NoteButton buttons[] = {  // Instantiate the momentary push buttons that send out MIDI note events.
    {{octaveBank, BankType::CHANGE_ADDRESS}, buttonMux.pin(0), note(C, 0), 1}, // bankselector, bank type, digital input pin, note number, channel
    {{octaveBank, BankType::CHANGE_ADDRESS}, buttonMux.pin(1), note(Db, 0), 1},
    {{octaveBank, BankType::CHANGE_ADDRESS}, buttonMux.pin(2), note(D, 0), 1},
    {{octaveBank, BankType::CHANGE_ADDRESS}, buttonMux.pin(3), note(Eb, 0), 1},
    {{octaveBank, BankType::CHANGE_ADDRESS}, buttonMux.pin(4), note(E, 0), 1},
    {{octaveBank, BankType::CHANGE_ADDRESS}, buttonMux.pin(5), note(F, 0), 1},
    {{octaveBank, BankType::CHANGE_ADDRESS}, buttonMux.pin(6), note(Gb, 0), 1},
    {{octaveBank, BankType::CHANGE_ADDRESS}, buttonMux.pin(7), note(G, 0), 1},
    {{octaveBank, BankType::CHANGE_ADDRESS}, buttonMux.pin(8), note(Ab, 0), 1},
    {{octaveBank, BankType::CHANGE_ADDRESS}, buttonMux.pin(9), note(A, 0), 1},
    {{octaveBank, BankType::CHANGE_ADDRESS}, buttonMux.pin(10), note(Bb, 0), 1},
    {{octaveBank, BankType::CHANGE_ADDRESS}, buttonMux.pin(11), note(B, 0), 1},
    {{octaveBank, BankType::CHANGE_ADDRESS}, buttonMux.pin(12), note(C, 1), 1},
    {{octaveBank, BankType::CHANGE_ADDRESS}, buttonMux.pin(13), note(Db, 1), 1},
    {{octaveBank, BankType::CHANGE_ADDRESS}, buttonMux.pin(14), note(D, 1), 1},
    {{octaveBank, BankType::CHANGE_ADDRESS}, buttonMux.pin(15), note(Eb, 1), 1},
};

unsigned long delaytime=10; // set a time to use for global delay

void setup() {
  Control_Surface.begin(); // Setup the Control Surface
  Serial.begin(115200); // Setup Serial output
  buttonMux.begin();                  // Initialize multiplexer for buttons
  buttonMux.pinMode(0, INPUT_PULLUP); // Set the pin mode (setting it for one pin of the multiplexers sets it for all of them)
  potMux.begin();                     // Initialize multiplexer for potentiometers
  potMux.pinMode(0, INPUT_PULLUP);    // Set the pin mode (setting it for one pin of the multiplexers sets it for all of them)

  fourdig.shutdown(0,false);          //The MAX72XX is in power-saving mode on startup, we have to do a wakeup call
  fourdig.setIntensity(0,10);         // Set the brightness of the display -15 to 15
  fourdig.clearDisplay(0);            // Clear the display                       

  switchOctave.set(4);                // Set the starting octave at middle C (C4)

  switchChannel.set(map(controlPots[2].getValue(), 0, 124, 15, 0)); // Set starting channel to pot2 value
}

void loop() {
  switchChannel.set(map(controlPots[3].getValue(), 0, 124, 15, 0));

  //switchOctave.set(map(controlPots[2].getValue(), 0, 124, 15, 0));
  Serial.println(map(controlPots[2].getValue(), 0, 124, 15, 0));
   
  // Show LED display linked to the 4 rotary potentiometers, 1 digit for each individual potentiometer
  fourdig.setDigit(0,4, switchOctave.get(),false);  // set digit 4 to show current octave activated for the Note Buttons
//  fourdig.setChar(0,4, map(controlPots[2].getValue(), 0, 124, 15, 0),false);  // set digit 3 to pot(3) value
  fourdig.setChar(0,3, map(controlPots[3].getValue(), 0, 124, 15, 0),false);  // set digit 3 to pot(3) value
  fourdig.setDigit(0,2, map(controlPots[2].getValue(), 0, 124, 9, 0),false);  // set digit 2 to pot(2) value
  fourdig.setDigit(0,1, map(controlPots[1].getValue(), 0, 124, 9, 0),false);  // set digit 1 to pot(1) value
  fourdig.setDigit(0,0, map(controlPots[0].getValue(), 0, 124, 9, 0),false);  // set digit 0 to pot(0) value
  delay(delaytime);  // a delay is required before clearing the display otherwise the display will simply light up
  fourdig.clearDisplay(0);  // clear the LED display

  Control_Surface.loop();
}

Teensy 3.6 Problem with Mux (CD74HC4067) and Reading Buttons

I have a problem that drives me crazy, same wiring and code working 100% on Arduino Mega but on Teensy 3.6 one button affects the other once.

I tried reducing the Teensy CPU Speed to 24MHZ and it looks like it is working correctly,
I searched in the documentation and didn't see a special settings to define once using Teensy...
Am I missing something?

another less urgent question - how can I change the midi device name ? tried renaming the string in Teensy-USB-MIDI-name.c and it didn't work...

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.