Adjusting the Pots

Is is assumed you have an Arduino connected to two different potentiometers.
Then you can test the circuit and that the pots produce values in the range you’d
expect using a sketch like the one below.

// This sketch shows the output from 2 pots.
// The objective is to use this sketch to find out what range of values
// is being produced by these pots.  The results will be used in the
// pingpong program.

int POT0 = 0;  // The pot attached to A0 will be called "POT0"
int POT1 = 1;  // The pot attached to A1

void setup() {
  Serial.begin(57600);
  while (!Serial) {}
  pinMode(POT0, INPUT);
  pinMode(POT1, INPUT);
}

void loop() {
  // The Serial Plotter sceen fills up after 500 values.  this loop
  // causes the plot to pause after the screen is filled up so that you
  // can review the values before they run off the screen.

  for (int count = 0; count < 500; count++) {
    int vin0 = analogRead(POT0);
    int vin1 = analogRead(POT1);

    Serial.print(vin0);
    Serial.print(",");    // data values must be separated by a comma or something else
    Serial.println(vin1); // Use println to signify the end of data for this time period
    delay(100);
  }
  delay(5000);
}

If you want to ensure that the vertical scale doesn’t change, then plot a high constant
and a lot constant as well as your analog readings:

  for (int count = 0; count < 500; count++) {
    int vin0 = analogRead(POT0);
    int vin1 = analogRead(POT1);

Serial.print(1000);    // Plot a horizontal line equal to 1000
Serial.print(",");    
    Serial.print(vin0);    // Plot vin from A0
    Serial.print(",");
    Serial.print(vin1);    // Plot vin from A1
    Serial.print(",");
Serial.println(0);     // Plot a horizontal line equal to 0
    delay(100);
  }

By inspecting the plots generated by the above sketch, you should learn the typical
voltage range that you can make with each pot.

Using the MD_MAX72xx library

The sketches below uses the MD_MAX72xx library, which makes it especially easy
to use the full capabilities of the MAX7219 on the PC board. This library can
handle hardware configurations which consist of up to 12 LED matrices, and those
LED matrices can be used to control any one of several different types of PC boards
that carry MAX7219 display driver chips.

If it is not installed on your system, then install it using the following click path:

Sketch -> Include Library -> Manage Libraries

Hint: Rather than scrolling through all the many libraries, just enter MD_MAX in the
Search box at the top right. (You will not find MD_MAX72xx in the resulting
list, only MD_MAXXX; but when you try to use this library in a sketch, be
sure to use its real name, which actually is MD_MAX72xx.)

The MD_MAX72xx library comes with many examples. If you try any of them,
be sure to customize the values of these constants, which are defined near
the top of the sketches:

Simple example: use the pots with the LED matrix

This example just shows how the illuminated pixel on an LED matrix will change
when the inputs from the two pots in the circuit are adjusted.
It is a modification of another program
originally written just to illustrate how the MAX_MD72xx library simplifies the
coding of LED matrices.

// This code moves a dot over the 8x8 LED Display with 2 pot-meters
// for x- and y-position.

#include <MD_MAX72xx.h>

#define CLK_PIN         13  // pin position of CLK, aka SCK
#define DATA_PIN        11  // pin position of MOSI
#define CS_PIN          10  // pin position of SS, aka CS
#define MAX_DEVICES     1   // our circuit has only 1 LED matrix

#define POT0            0   // The pot attached to A0 will be called "POT0"
#define POT1            1   // The pot attached to A1

// Set up an object called "matrix".  It can execute any of the functions defined in MD_MAX72xx.h
MD_MAX72XX matrix = MD_MAX72XX(MD_MAX72XX::FC16_HW, CS_PIN, MAX_DEVICES);

int pixels[8][8];           // 2-dimensional array of pixels:
int x=5;                    // cursor position:
int y=5;

void resetMatrix() {
    matrix.control(MD_MAX72XX::INTENSITY, MAX_INTENSITY/2);
    matrix.control(MD_MAX72XX::UPDATE, MD_MAX72XX::ON);
    matrix.clear();
}

void setup() {
  matrix.begin();
  resetMatrix();
  // Adjust to your own needs
  // matrix.setPosition(0, 0, 0);            // The first display is at <0, 0>
  // matrix.setPosition(1, 1, 0);            // The second display is at <1, 0>
  // matrix.setPosition(2, 2, 0);            // The third display is at <2, 0>
  // matrix.setPosition(3, 3, 0);            // And the last display is at <3, 0>
  // ...
  // matrix.setRotation(0, 2);               // The first display is position upside down
  // matrix.setRotation(3, 2);               // The same hold for the last display
  // clean display
  // matrix.fillScreen(LOW);

  for (int x = 0; x <8; x++) {               // initialize the pixel matrix:
    for (int y = 0; y <8; y++) {
      pixels[x][y] = HIGH;
    }
  }

  // If you want to see the result on the Serial Monitor or Plotter, initialize them here
  /*
  Serial.begin(57600);
  while (!Serial) {}

  // Initialize the pins used to read the pot values
  pinMode(PIN0, INPUT);
  pinMode(PIN1, INPUT);
}

void loop() {
  readSensors();                             // read input
  refreshScreen();                           // draw the screen
}

void readSensors() {
  pixels[x][y] = HIGH;                       // turn off the last position:
  x = 7 - map(analogRead(POT0), 0,1015, 0, 7); // read the sensors for X and Y values:
  y = map(analogRead(POT1), 0, 1015, 0, 7);    // set the new pixel position low so that the LED will 
                                             // turn on in the next screen refresh:
  pixels[x][y] = LOW;

  // test to see if pot-meters are working well?
  /*
  Serial.print("x = ");
  Serial.print(x);
  Serial.print(" y = ");
  Serial.println(y);
  */
}

void refreshScreen() {
  matrix.clear();                            // clear the screen
  matrix.setPoint(x, y, HIGH);               // set needed dot
}

Ping Pong with the LED Matrix

The ping pong sketch shown below uses the MD_MAX72xx library. It is a modified version of
another sketch originally written
for a “direct connect” LED matrix, i.e., one without a display driver like the
MAX7219 chip. It does not exploit the full potential of the MD_MAX72xx library, and could
probably be streamlined much further.

#include <MD_MAX72xx.h>

#define PIN_LEFT  0    // Use A0 for the pot pin from one player
#define PIN_RIGHT 1    // Use A1 for the pot pin from the other player
#define CLK_PIN   13   // or SCK
#define DATA_PIN  11   // or MOSI
#define CS_PIN    10   // or SS

#define MAX_DEVICES 1

MD_MAX72XX matrix = MD_MAX72XX(MD_MAX72XX::FC16_HW, CS_PIN, MAX_DEVICES);

unsigned int left = 0;
unsigned int right = 0;
int angle = 0;
int radians;

byte screen[8] = {0, 0, 0, 0, 0, 0, 0, 0};    // Change this?
volatile byte screenRow = 0;                  // Change this?
volatile byte screenCol = 0;                  // Change this?

int pixels[8][8];                             // Added this; it is the internal array where pixel data are stored

int _angle;
int _px;
int _py;
int _w = 7;
int _h = 7;
int _wall[] = {3, 3};
int _count = 0;
int _speed = 3;
int _countPoints = 0;

const uint8_t face[8] = { 0x03, 0x43, 0x80, 0x98, 0x98, 0x80, 0x43, 0x03 };

void resetMatrix() {
  matrix.control(MD_MAX72XX::INTENSITY, MAX_INTENSITY/2);
  matrix.control(MD_MAX72XX::UPDATE, MD_MAX72XX::ON);
  matrix.clear();
}

void setup() {
  matrix.begin();
  resetMatrix();

  for (int x = 0; x < 8; x++) {
    for (int y = 0; y < 8; y++) {
      pixels[x][y] = HIGH;
    }
  }

  matrix.clear();
  showface();
  matrix.clear();
}

void showface() {
  for (uint8_t i=0; i<8; i++) {
    matrix.setColumn(i, face[i]);
  }
  delay(5000);
}

void loop() {
  calcWall();
  enterFrameHandler();
  delay(100);
}

void calcWall() {
  left  = analogRead(PIN_LEFT);
  right = analogRead(PIN_RIGHT);
  left  = constrain(map(left, 223, 800, 0, 6), 0, 6);
  right = constrain(map(right, 223, 800, 6, 0), 0, 6);
  clearWall();
  matrix.setPoint(0, left  + 1, true);
  matrix.setPoint(0, left  + 2, true);
  matrix.setPoint(7, right + 1, true);
  matrix.setPoint(7, right + 2, true);
  _wall[0] = left;
  _wall[1] = right;
  show();
}

void clearWall() {
  for (int i = 0; i < 8; i++) {
    matrix.setPoint(i, 0, false);
    matrix.setPoint(i, 7, false);
  }
}

void clearGame() {
  for (int i = 0; i < 8; i++) {
    for (int j = 1; j < 7; j++) {
      matrix.setPoint(i, j, false);
    }
  }
}

void enterFrameHandler() {
  if (_count++ < _speed)  return;
  _count = 0;
  checkCollision();
  calcAngleIncrement();
  show();
}

void retorted(int angle) {
  // Serial.println(angle);
  _angle = angle;
  if (++_countPoints % 5 == 0 && _speed > 1)  _speed-- ;
}

void resetAnim() {
  for (uint8_t i = 0; i < 8; i++)  {
    for (uint8_t j = 0; j < 8; j++) {
      matrix.setPoint(i, j, true);
    // screen[i] = B11111111;
    }
    delay(25);
  }

  for (uint8_t i = 0; i < 8; i++)  {
    for (uint8_t j = 0; j < 8; j++) {
      matrix.setPoint(i, j, false);
      // screen[i] = B00000000;
    }
    delay(25);
  }
}

void reset() {
  resetAnim();
  _px = random(3, 5);
  _py = random(3, 5);
  _angle = random(0, 2) == 0  ? 0  : 180;
  _speed = 5;
  _countPoints = 0;
  show();
  delay(500);
}

void show() {
  clearGame();
  matrix.setPoint(_px + 1, _py + 1, true);
}


void checkCollision() {
  if (_px == _w - 1) {
    if (_angle == 315 || _angle == 0 || _angle == 45)  {
      if (_py == _wall[1] || _py == _wall[1] + 1)  {
        if (_angle == 0 && _py == _wall[1])  retorted(225);
        else if (_angle == 0 && _py == _wall[1] + 1)  retorted(135);
        else if (_angle == 45 && _py == _wall[1])  retorted(135);
        else if (_angle == 45 && _py == _wall[1] + 1)  retorted(180);
        else if (_angle == 315 && _py == _wall[1])  retorted(180);
        else if (_angle == 315 && _py == _wall[1] + 1)  retorted(225);
      }
    }
  }
  else if (_px == 1)  {
    if (_angle == 225 || _angle == 180 || _angle == 135)  {
      if (_py == _wall[0] || _py == _wall[0] + 1)  {
        if (_angle == 180 && _py == _wall[0])  retorted(315);
        else if (_angle == 180 && _py == _wall[0] + 1)  retorted(45);
        else if (_angle == 135 && _py == _wall[0])  retorted(45);
        else if (_angle == 135 && _py == _wall[0] + 1)  retorted(0);
        else if (_angle == 225 && _py == _wall[0])  retorted(0);
        else if (_angle == 225 && _py == _wall[0] + 1)  retorted(315);
      }
    }
  }
  if (_px == _w)  {
    reset();
  }
  else if (_px == 0)  {
    reset();
  }
  else if (_py == _h)  {
    if (_angle == 45)  _angle = 315;
    else if (_angle == 135)  _angle = 225;
  }
  else if (_py == 0)  {
    if (_angle == 225)  _angle = 135;
    else if (_angle == 315)  _angle = 45;
  }
}


void calcAngleIncrement() {
  if (_angle == 0 || _angle == 360)  {
    _px += 1;
  }
  else if (_angle == 45)  {
    _px += 1;
    _py += 1;
  }
  else if (_angle == 135)  {
    _px -= 1;
    _py += 1;
  }
  else if (_angle == 180)  {
    _px -= 1;
  }
  else if (_angle == 225)  {
    _px -= 1;
    _py -= 1;
  }
  else if (_angle == 315)  {
    _px += 1;
    _py -= 1;
  }
}