shaduzlabs / synapse

Arduino CV/Gate I/O shield and its software library
Other
78 stars 11 forks source link

View this project on CADLAB.io.

Build Status

Synapse

A rendering of the Arduino shield Synapse is an Arduino shield (and the corresponding library) which provides CV and Gate I/O for Arduino boards.

Features

Compatible Boards

The shield should work fine with any Arduino with onboard 5V regulator which can tolerate up to 12V on the VIN pin (e.g. it will NOT work with an Arduino Yùn or Tian and will most likely damage the board).

Verified Boards

Hardware

Order from OSH Park

Passive components

Diodes, transistors ICs

Mechanical

Software library usage

The library can be installed using Arduino Library Manager (Sketch -> Include Library -> Library Manager), just search for "synapse".

Once the library is installed (please remember to install the dependencies, as well - see the last paragraph below), you can call SynapseShield.begin() in the setup() function to initialize the library and the shield

#include <Synapse.h>
using namespace sl;

void setup()
{
  SynapseShield.begin();
  // ...
}

when calling the begin() function you can optionally specify the SPI divider (by default it's set to 8)

Optionally, you can configure a callback function for each gate input channel which will be called when a specific condition is met.

#include <Synapse.h>
using namespace sl;

void onGateAChanged();
void onGateBRisingEdge();

void setup()
{
  SynapseShield.begin();

  SynapseShield.gateInputInterrupt(
    Synapse::GateChannel::A,
    onGateAChanged,
    Synapse::GateInterrupt::ValueChange
  );

  SynapseShield.gateInputInterrupt(
    Synapse::GateChannel::B,
    onGateBRisingEdge,
    Synapse::GateInterrupt::RisingEdge
  );
  // ...
}
void loop()
{
  // ...
}

void onGateAChanged()
{
  // Do something when the logic value of gate input A changes
  // WARNING: keep this function as unexpensive as possible
}

void onGateBRisingEdge()
{
  // Do something when the logic value of gate input B goes from LOW to HIGH
  // WARNING: keep this function as unexpensive as possible
}

The range of each CV output channel can be individually configured (even dinamically)

#include <Synapse.h>
using namespace sl;

void setup()
{
  SynapseShield.begin();

  SynapseShield.setCVRange(
    Synapse::CVChannel::A,
    Synapse::Range::ZeroToTenVolts
  );

  SynapseShield.setCVRange(
    Synapse::CVChannel::B,
    Synapse::Range::MinusFiveToFiveVolts
  );
  // ...
}

void loop()
{
  Synapse::Range rangeA = SynapseShield.getCVRange( Synapse::CVChannel::A );

  if(rangeA == Synapse::Range::MinusFiveToFiveVolts)
  {
    SynapseShield.setCVRange(
      Synapse::CVChannel::A,
      Synapse::Range::ZeroToTenVolts
    );
  }
  else
  {
    SynapseShield.setCVRange(
      Synapse::CVChannel::A,
      Synapse::Range::MinusFiveToFiveVolts
    );
  }
  delay(1000);
}

CV and Gate I/O operations are also very easy:

#include <Synapse.h>
using namespace sl;

bool gateInA{false};
unsigned cvInA{0};

void setup()
{
  SynapseShield.begin();
  // ...
}

void loop()
{
  gateInA = SynapseShield.readGate(Synapse::GateChannel::A);
  cvInA = SynapseShield.readCV(Synapse::CVChannel::A);

  if(gateInA)
  {
    SynapseShield.writeCV(Synapse::CVChannel::A, 4095);
    SynapseShield.writeCV(Synapse::CVChannel::B, 0);
  }
  else
  {
    SynapseShield.writeCV(Synapse::CVChannel::A, 0);
    SynapseShield.writeCV(Synapse::CVChannel::B, 4095);
  }

  if(cvInA > 2047)
  {
    SynapseShield.writeGate(Synapse::GateChannel::A, false);
    SynapseShield.writeGate(Synapse::GateChannel::B, true);
  }
  else
  {
    SynapseShield.writeGate(Synapse::GateChannel::A, true);
    SynapseShield.writeGate(Synapse::GateChannel::B, false);
  }
}

Dependencies