#include "Wire.h"
int leftMeter = 20; // left meter (hours) is attached to pin 5 (PWM)
int leftChannel = 0; // left channel of audio (analog 1)
int sensitivity = 0; // 10k pot sensitivity control (analog 0)
int rightLevel = 0; // position of the right meter
int leftLevel = 0; // position of the left meter
// rtc - SDA to A4 - SCL to A5
void setup() {
Wire.begin();
// Serial.begin(9600); Un-comment to view time in serial monitor
pinMode(leftMeter, OUTPUT); // Initialize Outputs
digitalWrite(leftMeter, HIGH); // Test meters on startup
digitalWrite(13, HIGH);
delay (1000);
digitalWrite(leftMeter, LOW);
digitalWrite(13, LOW);
delay(1000);
// loop to configure input pins and internal pullup resisters for digital section
for (int i=0;i<D_PINS;i++){
pinMode(DIGITAL_PINS[i], INPUT_PULLUP);
}
}
void loop() {
sensitivity = (analogRead(A8) / 3 + 1); // potentiometer sensitivity control
{
analogWrite(leftMeter, leftLevel); // adjust left meter level
}
leftChannel = analogRead(A4); // read left channel of audio
// Below is the code to set meter levels based on sound levels:
// If you change the values, remember to make sure that the Left and Right channels are matching.
// leftLevel and rightLevel can be set from 0 to 255 (PWM)
if (leftChannel >= sensitivity && leftLevel < 20){
leftLevel = 20;
}
if (leftChannel >= sensitivity + 5 && leftLevel < 41){
leftLevel = 41;
}
if (leftChannel >= sensitivity + 10 && leftLevel < 62){
leftLevel = 62;
}
if (leftChannel >= sensitivity + 15 && leftLevel < 83){
leftLevel = 83;
}
if (leftChannel >= sensitivity + 20 && leftLevel < 104){
leftLevel = 104;
}
if (leftChannel >= sensitivity + 25 && leftLevel < 125){
leftLevel = 125;
}
if (leftChannel >= sensitivity + 30 && leftLevel < 146){
leftLevel = 146;
}
if (leftChannel >= sensitivity + 35 && leftLevel < 167){
leftLevel = 167;
}
if (leftChannel >= sensitivity + 37 && leftLevel < 188){
leftLevel = 188;
}
if (leftChannel >= sensitivity + 40 && leftLevel < 209){
leftLevel = 209;
}
if (leftChannel >= sensitivity + 42 && leftLevel < 230){
leftLevel = 230;
}
if (leftChannel >= sensitivity + 45 && leftLevel < 255){
leftLevel = 255;
}
// Fade the meters out to 0
if (leftChannel < sensitivity && leftLevel > 0){
leftLevel = --leftLevel; // left meter
delayMicroseconds(1000); // can be increased and decreased to adjust smoothness
} // (how long it takes to get back to 0)
getAnalogData();
getDigitalData();
while (usbMIDI.read()) {
// controllers must call .read() to keep the queue clear even if they are not responding to MIDI
}
}
//************LIBRARIES USED**************
// include the ResponsiveAnalogRead library for analog smoothing
#include <ResponsiveAnalogRead.h>
// include the Bounce library for 'de-bouncing' switches -- removing electrical chatter as contacts settle
#include <Bounce.h>
//usbMIDI.h library is added automatically when code is compiled as a MIDI device
// ******CONSTANT VALUES********
// customize code behaviour here!
const int channel = 1; // MIDI channel
const int A_PINS = 4; // number of Analog PINS
const int D_PINS = 9; // number of Digital PINS
const int ON_VELOCITY = 99; // note-one velocity sent from buttons (should be 65 to 127)
// define the pins you want to use and the CC ID numbers on which to send them..
const int ANALOG_PINS[A_PINS] = {A0,A1,A2,A3};
const int CCID[A_PINS] = {21,22,23,24};
// define the pins and notes for digital events
const int DIGITAL_PINS[D_PINS] = {0,1,2,3,4,5,6,7,8};
const int note[D_PINS] = {60,61,62,63,64,65,66,67,68};
const int BOUNCE_TIME = 15; // 5 ms is usually sufficient
const boolean toggled = true;
//******VARIABLES***********
// a data array and a lagged copy to tell when MIDI changes are required
byte data[A_PINS];
byte dataLag[A_PINS]; // when lag and new are not the same then update MIDI CC value
//************INITIALIZE LIBRARY OBJECTS**************
// not sure if there is a better way... some way run a setup loop on global array??
// use comment tags to comment out unused portions of array definitions
// initialize the ReponsiveAnalogRead objects
ResponsiveAnalogRead analog[]{
{ANALOG_PINS[0],true},
{ANALOG_PINS[1],true},
{ANALOG_PINS[2],true},
{ANALOG_PINS[3],true}/*,
{ANALOG_PINS[4],true},
{ANALOG_PINS[5],true},
{ANALOG_PINS[6],true},
{ANALOG_PINS[7],true},
{ANALOG_PINS[8],true}/*,
{ANALOG_PINS[6],true},
{ANALOG_PINS[7],true},*/
};
// initialize the bounce objects
Bounce digital[] = {
Bounce(DIGITAL_PINS[0], BOUNCE_TIME),
Bounce(DIGITAL_PINS[1], BOUNCE_TIME),
Bounce(DIGITAL_PINS[2], BOUNCE_TIME),
Bounce(DIGITAL_PINS[3], BOUNCE_TIME),
Bounce(DIGITAL_PINS[4], BOUNCE_TIME),
Bounce(DIGITAL_PINS[5], BOUNCE_TIME),
Bounce(DIGITAL_PINS[6], BOUNCE_TIME),
Bounce(DIGITAL_PINS[7], BOUNCE_TIME),
Bounce(DIGITAL_PINS[8], BOUNCE_TIME)/*,,*/
};
//************ANALOG SECTION**************
void getAnalogData(){
for (int i=0;i<A_PINS;i++){
// update the ResponsiveAnalogRead object every loop
analog[i].update();
// if the repsonsive value has change, print out 'changed'
if(analog[i].hasChanged()) {
data[i] = analog[i].getValue()>>3;
if (data[i] != dataLag[i]){
dataLag[i] = data[i];
usbMIDI.sendControlChange(CCID[i], data[i], channel);
}
}
}
}
//************DIGITAL SECTION**************
void getDigitalData(){
for (int i=0;i<D_PINS;i++){
digital[i].update();
if (digital[i].fallingEdge()) {
usbMIDI.sendNoteOn(note[i], ON_VELOCITY, channel);
}
// Note Off messages when each button is released
if (digital[i].risingEdge()) {
usbMIDI.sendNoteOff(note[i], 0, channel);
}
}
}