Initializing potentiometers as inputs?

I've seen this code:

  for (int i = 0; i < nPots; i++) {
    pinMode(potPins[i], INPUT);
  }

However, I've never before needed to initialize pots as inputs on analog pins before. Is there a reason or benefit to use the code above?
Thanks,
TonyA

  • At power up time, GPIOs default as inputs.
  • A potentiometer use analogRead();
    If you are reading a potentiometer, you do not need to make an analog pin an INPUT.
  • We need to see your preliminary schematic.

That's what I thought. The code does use analogRead() in the loop(). The initialization of the pins as inputs is in the setup(); The pots just connect as usual to A0, A1, A2. Wiper to pin, outside tabs (tabs 1 & 3) of pot to gnd and +5V.

It is from someone's code on github that I'm using for a project. I just did't understand why the need to "initialize" the pots as INPUTs if using analogRead().

Code is here: Code on GitHub

Thanks again,
TonyA

  • Their code leaves a lot to be desired! :grimacing:

  • Their schematic:

  • I believe the Pro Micro A/D is 10 bit (0-1023)
    R1 = 10k should not be used. See post #10

  • You probably should come up with your own code and schematic. :scream:

I am modifying the code slightly, using my own schematic with an Arduino Nano.

Do you see any big problems with the code that you can point out so I can maybe improve the code for anyone wanting to use it?

(I am using the text only OLED library for the 1306 chip based OLED called; GitHub - greiman/SSD1306Ascii: Text only Arduino Library for SSD1306 OLED displays) Saves a lot of memory on the Nano.

thanks again,
TonyA

  • We can review your changes and add comments in this thread.

  • Do not use the analog wiring in the above schematic.

Why not?
I see nothing wrong with it except see post #8

I see nothing wrong with the code or schematic, except there should be a 220 ohm resistor between TX0 and the midi connector.

Why don't you use it as is?

Not clear why you state this.
R1 is the rightmost potentiometer, same value as the other two potentiometers.
The positioning of the labels for R1, R2, and R3 is a bit confusing. Glancing at the schematic quickly, at small size, tends to imply that R1 is a resistor along the horizontal line, not a label for the vertical symbol for the potentiometer.

  • My mistake, I was working on 3 different projects and was mixing things up between them. :face_with_spiral_eyes:

I can do that with but one project!

a7

I have used it as is, I just changed the OLED library to a light-weight, less memory usage library for the Oled. I also used the map() function to set the potentiometer parameters instead of what the author of the code did; setting a range for each pot value.

The original code worked fine as it was, but I couldn't understand the use of initializing the analog pot inputs, I've always just used analogRead() without setting the pins to inputs, so I thought I was not understanding somethings there.

The author used 7 push button switches to send MIDI note messages, one button for each note in a musical scale. I'm using the Adafruit MPR121 Capacitive touch board with 12 cap touch sensors.

Here's what I did:

/*   Jupertronic Root Commander - Smart MIDI Controller
      by Janis Wilson Hughes aka Jupertronic aka J Dub aka Evolution Stoneware on youtube
      Root Commander is a smart Arduino MIDI controller that sends single note commands when a button is pressed. 
      The scale or 'mode', key, and octave are selected with 3 potentiometers. 
      Then the note or 'step' in that scale is sent out via MIDI when you press any of 7 normally open, momentary buttons. 
      Every note you play will always be in tune with the scale you selected because Root Commander sets the proper notes for you on the buttons. 
      OLED display is used to show the scale, key, octave, and step (shown in Roman Numerals) you've selected.
      Programmed for Arduino Pro Micro. Change line 29 and 30 to A4 and A5 for Nano SDA and SCL pins.

      *7-19-25 Modified to use the "Light weight" text only OLED library (called: SSD1306Ascii) for OLED's with the 1306 chip driver. 
      **Using the Adafruit Capacitive Touch Sensor library v.1.1.3, newer version 1.2.0 doesn't work.
*/

#include <MIDI.h>
#include "Adafruit_MPR121.h"  //the MPR131 cap touch sensor board. Using older library v 1.1.3
#include <SPI.h>
#include <Wire.h>
#include "SSD1306Ascii.h" //Light weight, text only oled library to reduce memory use
#include "SSD1306AsciiAvrI2c.h"

//OLED Address
#define I2C_ADDRESS 0x3C

// Define proper RST_PIN if required.
#define RST_PIN -1

SSD1306AsciiAvrI2c oled;

// Bit stuff for the MPR121 cap touch
#ifndef _BV
#define _BV(bit) (1 << (bit))
#endif

//*Cap Touch Boards
Adafruit_MPR121 capBoard = Adafruit_MPR121();  // Up to 4 I2c devices can be used using the same sda & scl, use different
// // address for each device.
uint16_t lasttouched = 0;
uint16_t currtouched = 0;


MIDI_CREATE_DEFAULT_INSTANCE();

//Pots
uint8_t scalePot = A0;
uint8_t octavePot = A1;
uint8_t keyPot = A2;

long scaleVal;
long octVal;
long keyVal;

int scaleSelect;
int keySelect;
int octaveSelect;

//Scale and Note Controls
const int nRoots = 7;   // Number of root notes and number of notes in scale
const int key[12] = {57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68}; //Array of MIDI notes from A2 to Ab3 including flats

//scales[scaleSelect][i] 
const int nScales = 5; // Number of modes/scales
const int scales[nScales][nRoots] = { //Array of scale arrays containing the steps between each note
  {0, 2, 4, 5, 7, 9, 11}, // Ionian, Major
  {0, 2, 3, 5, 7, 8, 10}, // Natural Minor
  {0, 2, 4, 5, 7, 9, 11}, // Dorian
  {0, 2, 4, 5, 7, 9, 10}, // Mixolydian
  {0, 1, 2, 3, 4, 5, 6},  // Chromatic
};


void setup() {

#if RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN);
#else   // RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS);
#endif  // RST_PIN >= 0
  // Call oled.setI2cClock(frequency) to change from the default frequency.

  oled.clear();
  oled.setFont(System5x7);

  //X=COL, Y=ROW
  oled.setCursor(0, 0);  //x=0, y=8 pixels
  oled.println("Scale:");

  oled.setCursor(0, 2);  //x=0, y=16 pixels
  oled.println("Octave:");

  oled.setCursor(0, 4);  //x=0, y=24 pixels
  oled.println("Key:");


  // *MPR121 Capacitive touch sensor board setup.
  // SCL on the mpr121 connects to pin A5 on Arduino Uno and Metro Mini, (also serves as the I2C clock pin)
  // SDA on mpr121 to -->pin A4 of Arduino, I2C data pin.
  // The MPR121 ADDR pin is pulled to ground and has a default I2C address of 0x5A
  // You can change the I2C address of the mpr121 by connecting ADDR to other pins on the arduino:
  /*
    ADDR pin tied to 3V: 0x5B
    ADDR pin tied to SDA: 0x5C
    ADDR pin tied to SCL: 0x5D */
  capBoard.begin(0x5A);

  //Initialize MIDI
  MIDI.begin(MIDI_CHANNEL_OMNI);
}

void OledDisplay() {

  //Scales
  scaleVal = analogRead(scalePot);
  scaleSelect = map(scaleVal, 0, 1023, 0, 5);

  switch (scaleSelect) {
    case 0:
      scaleSelect = 0;
      oled.setCursor(40, 0);  // X,Y Start at top-left corner
      //***Use spaces after the text to clear characters from the previous written text, 
      //if newly written word has fewer characters than previous word.
      //Spaces need to be equivalent or greater than the # of characters of the largest word written to OLED, "Mixolydian".
      oled.println("Major      ");//equivalent to 10 character spaces; Major PLUS 5 spaces.
      break;

    case 1:
      scaleSelect = 1;
      oled.setCursor(40, 0);  // Start at top-left corner
      oled.println("Minor      ");
      break;

    case 2:
      scaleSelect = 2;
      oled.setCursor(40, 0);  // Start at top-left corner
      oled.println("Dorian     ");
      break;

    case 3:
      scaleSelect = 3;
      oled.setCursor(40, 0);  // Start at top-left corner
      oled.println("Mixolydian ");
      break;

    case 4:
      scaleSelect = 4;
      oled.setCursor(40, 0);  // Start at top-left corner
      oled.println("Chromatic  ");
      break;
  }

  //Octave
  octVal = analogRead(octavePot);
  octaveSelect = map(octVal, 0, 1023, 0, 4);

  switch (octaveSelect) {
    case 0:
      octaveSelect = -24;
      oled.setCursor(40, 2);  // Print next to "Oct:" on OLED
      oled.println(" -2");
      break;
    case 1:
      octaveSelect = -12;
      oled.setCursor(40, 2);  // Print next to "Oct:" on OLED
      oled.println(" -1");
      break;
    case 2:
      octaveSelect = 0;
      oled.setCursor(40, 2);  // Print next to "Oct:" on OLED
      oled.println(" 0 ");
      break;
    case 3:
      octaveSelect = 12;
      oled.setCursor(40, 2);  // Print next to "Oct:" on OLED
      oled.println(" +1");
      break;
  }

  //Keys
  keyVal = analogRead(keyPot);
  keySelect = map(keyVal, 0, 1023, 0, 12);

  switch (keySelect) {
    case 0:
      keySelect = key[0];
      oled.setCursor(40, 4);  // Print next to "Oct:" on OLED
      oled.println("A ");
      break;
    case 1:
      keySelect = key[1];
      oled.setCursor(40, 4);  // Print next to "Oct:" on OLED
      oled.println("A#");
      break;
    case 2:
      keySelect = key[2];
      oled.setCursor(40, 4);  // Print next to "Oct:" on OLED
      oled.println("B ");
      break;
    case 3:
      keySelect = key[3];
      oled.setCursor(40, 4);  // Print next to "Oct:" on OLED
      oled.println("C ");
      break;
    case 4:
      keySelect = key[4];
      oled.setCursor(40, 4);  // Print next to "Oct:" on OLED
      oled.println("C#");
      break;
    case 5:
      keySelect = key[5];
      oled.setCursor(40, 4);  // Print next to "Oct:" on OLED
      oled.println("D ");
      break;
    case 6:
      keySelect = key[6];
      oled.setCursor(40, 4);  // Print next to "Oct:" on OLED
      oled.println("D#");
      break;
    case 7:
      keySelect = key[7];
      oled.setCursor(40, 4);  // Print next to "Oct:" on OLED
      oled.println("E ");
      break;
    case 8:
      keySelect = key[8];
      oled.setCursor(40, 4);  // Print next to "Oct:" on OLED
      oled.println("F ");
      break;
    case 9:
      keySelect = key[9];
      oled.setCursor(40, 4);  // Print next to "Oct:" on OLED
      oled.println("F#");
      break;
    case 10:
      keySelect = key[10];
      oled.setCursor(40, 4);  // Print next to "Oct:" on OLED
      oled.println("G ");
      break;
    case 11:
      keySelect = key[11];
      oled.setCursor(40, 4);  // Print next to "Oct:" on OLED
      oled.println("G#");
      break;
  }
}  //end OledDisplay()

void loop() {

  OledDisplay();

  // Touch Sensor Edge Detection:
  // Trigger the note based on the MPR121 Cap Touch result
  // Get the currently touched pads
  currtouched = capBoard.touched();  // MPR121 board #1
  // Poll the 12 touch sensors on the adafruit mpr121 cap touch board
  // Assign each touch sensor pin (0-11) on the MPR121 a midi note number via the array nRoots
  for (uint8_t i = 0; i < 12; i++) {

    // if it *is* touched now and *wasnt* touched before = just been touched play note.
    if ((currtouched & _BV(i)) && !(lasttouched & _BV(i))) {
      //velocity[i] = 127;  // if button is pressed velocity is 127
      //int note = (scales[scaleSelect][i] + keySelect + octaveSelect);
      MIDI.sendNoteOn((scales[scaleSelect][i] + keySelect + octaveSelect), 127, 1);
                       
 
      // Debug midi note:
      // //          Serial.print("BUTTON ");
      // //          Serial.print(i);
      // //          Serial.print("MIDI note ");
      // //          Serial.println((scales[scaleSelect][i] + keySelect + octaveSelect));
      // //          break;
     }

    // if the MPR121 pin *was* touched previously and now *is not*, it has been released, send note off(MIDI note velocity = 0).
    if (!(currtouched & _BV(i)) && (lasttouched & _BV(i))) {
      MIDI.sendNoteOn((scales[scaleSelect][i] + keySelect + octaveSelect), 0, 1);
      //*Debug- when the pin has been released and the note has been stopped.
      // Serial.print("Voice 0 Note Stopped is:  ");
      // Serial.println(AminorPent[i] + keySelect() + octSelect());
    }
  }
  // reset the touch state for captouchnotes
  lasttouched = currtouched;
  return;
}

Still working on it. Praticularly this part:

  // Touch Sensor Edge Detection:
  // Trigger the note based on the MPR121 Cap Touch result
  // Get the currently touched pads
  currtouched = capBoard.touched();  // MPR121 board #1
  // Poll the 12 touch sensors on the adafruit mpr121 cap touch board
  // Assign each touch sensor pin (0-11) on the MPR121 a midi note number via the array nRoots
  for (uint8_t i = 0; i < 12; i++) {

    // if it *is* touched now and *wasnt* touched before = just been touched play note.
    if ((currtouched & _BV(i)) && !(lasttouched & _BV(i))) {
      //velocity[i] = 127;  // if button is pressed velocity is 127
      //int note = (scales[scaleSelect][i] + keySelect + octaveSelect);
      MIDI.sendNoteOn((scales[scaleSelect][i] + keySelect + octaveSelect), 127, 1);

Originally the [i] variable above was = to nRoots, which equaled "7", for each of the push buttons in the original schematic. I changed it to 12 for each capacitive touch sensor.

It works, but I'm still making sure I understand the author's use of the 2D array here:

//Scale and Note Controls
const int nRoots = 7;   // Number of root notes and number of notes in scale
const int key[12] = {57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68}; //Array of MIDI notes from A2 to Ab3 including flats

//scales[scaleSelect][i] 
const int nScales = 5; // Number of modes/scales
const int scales[nScales][nRoots] = { //Array of scale arrays containing the steps between each note
  {0, 2, 4, 5, 7, 9, 11}, // Ionian, Major
  {0, 2, 3, 5, 7, 8, 10}, // Natural Minor
  {0, 2, 4, 5, 7, 9, 11}, // Dorian
  {0, 2, 4, 5, 7, 9, 10}, // Mixolydian
  {0, 1, 2, 3, 4, 5, 6},  // Chromatic
};

*I added the extra Chromatic scale, originally there were 4 scales
Some comments I made might not make sense, since I haven't yet cleaned them up.

Here is schematic. I am only using 3 pots of the schematic; A0, A1, A2.
(This schematic doubles as a MIDI out device & a MIDI input synth (but not simultaneously), depending on how the jumpers are configured and of course the code.)

Thanks for any suggestions, comments and advice, appreciated.

TonyA

Same here, and often...

You do not have a case for scaleSelect == 5.
There is no need to set the value of scaleSelect in each case, since you are setting it to the value that it already contains.

  scaleSelect = map(scaleVal, 0, 1023, 0, 5);

  switch (scaleSelect) {
    case 0:
      scaleSelect = 0;
      oled.setCursor(40, 0);  // X,Y Start at top-left corner
      //***Use spaces after the text to clear characters from the previous written text,
      //if newly written word has fewer characters than previous word.
      //Spaces need to be equivalent or greater than the # of characters of the largest word written to OLED, "Mixolydian".
      oled.println("Major      ");//equivalent to 10 character spaces; Major PLUS 5 spaces.
      break;

    case 1:
      scaleSelect = 1;
      oled.setCursor(40, 0);  // Start at top-left corner
      oled.println("Minor      ");
      break;

    case 2:
      scaleSelect = 2;
      oled.setCursor(40, 0);  // Start at top-left corner
      oled.println("Dorian     ");
      break;

    case 3:
      scaleSelect = 3;
      oled.setCursor(40, 0);  // Start at top-left corner
      oled.println("Mixolydian ");
      break;

    case 4:
      scaleSelect = 4;
      oled.setCursor(40, 0);  // Start at top-left corner
      oled.println("Chromatic  ");
      break;
  }

Shorter code that should accomplish the same as the above switch/case:

  static const char textScale[][12] = {
    "Major      ",
    "Minor      ",
    "Dorian     ",
    "Mixolydian ",
    "Chromatic  ",
  };
  if (scaleSelect < 5) { //not needed if you map the input to 0-4)
    oled.setCursor(40, 0);
    oled.println(textScale[scaleSelect]);
  }

You could save a considerable amount of ram by using the F() macro with the print statements.

< edit >
You can map the value of scaleSelect to 0-4 using the following code. The map() function does the math using integers, a value of 1023 will give an output of 4, only 1024 would produce 5, which will never occur from an analog input.

  scaleSelect = map(scaleVal, 0, 1024, 0, 5);

Thank you, I see what you're saying. Will review and edit.
TonyA