4
\$\begingroup\$

I've made an Arduino program to run on my Teensy 3.1 board. It accepts characters and strings sent to a Bluetooth module (BC417) from any Bluetooth-enabled device and uses these to power certain pins on my 8x8 LED matrix.

I believe the code works, but I haven't been able to test it fully yet. I'm hoping (if it's the right subject for this site) that there are ways the code can be improved. I'm still somewhat a beginner with Arduino programming, and I know there are many functions I don't know about that will probably be useful for me now and in the future

#define MyBtooth Serial2
#define dw digitalWrite
char incomingChar;
String inString;
bool stream;

//********************************************************
//    Setup
//********************************************************
void setup() {
  for (int x = 0; x <= 23; x++) {
    if ((x >= 0) && (x <= 11) || (x >= 14) && (x <= 23)) {
      pinMode(x, OUTPUT);
    }
    else {}
  }
  //  for (int x = 14; x <= 23; x++) {
  //    dw(x, HIGH);        //TAKE THIS OUT TEMP
  //  }
  Serial.begin(9600);
  pinMode(13, OUTPUT);
  MyBtooth.begin(9600);
}

//********************************************************
//    Main Loop
//********************************************************
void loop() {
  Serial.println("How do you want to control the RGB matrix?");
  Serial2.println("How do you want to control the RGB matrix?");
  Serial.println("Send 'Bluetooth' for Bluetooth control and 'Serial' for USB control.");
  Serial2.println("Send 'Bluetooth' for Bluetooth control and 'Serial' for USB control.");
  Serial.println("Sending 'Cancel' at any time after making a choice will return you to this menu.");
  Serial2.println("Sending 'Cancel' at any time after making a choice will return you to this menu.");

  String choice = Serial.readString();
  String choicebt = Serial2.readString();

  if ((choice.toUpperCase() == "BLUETOOTH") || (choicebt.toUpperCase() == "BLUETOOTH")) {
    BTControl();
  }
  else if ((choice.toUpperCase() == "SERIAL") || (choicebt.toUpperCase() == "SERIAL")) {
    serialControl();
  }
  else{}
}

void serialControl() {
  while (true) {
    if (Serial.available() > 0) {
      incomingChar = Serial.read();
      Serial.print("USB received: ");
      Serial.println(incomingChar);
      MyBtooth.print("USB received:");
      MyBtooth.println(incomingChar);

      switches();
    }

    String cancel = Serial.readString();
    if (cancel.toUpperCase() == "CANCEL") {
      break;
    }
  }
}

void BTControl() {
  while (true) {
    if (MyBtooth.available() > 0) {
      incomingChar = MyBtooth.read();
      Serial.print("UART received: ");
      Serial.println(incomingChar);
      MyBtooth.print("UART received:");
      MyBtooth.println(incomingChar);

      switches();
    }

    String cancel = Serial2.readString();
    if (cancel.toUpperCase() == "CANCEL") {
      break;
    }
  }
}
void letterA() {
  for (int x = 0; x <= 100000; x++) {
    dw(0, HIGH);
    dw(1, HIGH);
    dw(6, HIGH);
    dw(7, HIGH);
    dw(21, HIGH);
    dw(3, LOW);
    dw(4, LOW);
    delay(0.5);
    dw(21, LOW);
    dw(3, HIGH);
    dw(4, HIGH);
    dw(2, LOW);
    dw(5, LOW);
    dw(20, HIGH);
    delay(0.5);
    dw(20, LOW);
    dw(2, HIGH);
    dw(5, HIGH);
    dw(1, LOW);
    dw(6, LOW);
    dw(19, HIGH);
    dw(18, HIGH);
    dw(17, HIGH);
    dw(16, HIGH);
    dw(15, HIGH);
    dw(14, HIGH);
    delay(0.5);
    dw(14, LOW);
    dw(15, LOW);
    dw(16, LOW);
    dw(17, LOW);
    dw(19, LOW);
    dw(1, HIGH);
    dw(6, HIGH);
    delay(0.5);
  }
  delay(200);
}

void letterB() {
  for(int x = 0; x <= 500; x++) {
    dw(0, HIGH);
    dw(1, LOW);
    dw(2, HIGH);
    dw(3, HIGH);
    dw(4, HIGH);
    dw(5, HIGH);
    dw(6, HIGH);
    dw(7, HIGH);
    dw(21, HIGH);
    dw(20, HIGH);
    dw(19, HIGH);
    dw(18, HIGH);
    dw(17, HIGH);
    dw(16, HIGH);
    dw(15, HIGH);
    dw(14, HIGH);
    delay(1);
    dw(21, LOW);
    dw(14, LOW);
    dw(18, LOW);
    dw(5, LOW);
    dw(1, HIGH);
    delay(1);    
    dw(1, HIGH);
    dw(5, HIGH);
    dw(2, LOW);
    dw(3, LOW);
    dw(4, LOW);
    dw(21, HIGH);
    dw(14, HIGH);
    dw(18, HIGH);
    dw(20, LOW);
    dw(19, LOW);
    dw(17, LOW);
    dw(16, LOW);
    dw(15, LOW);
    delay(1);
    dw(2, HIGH);
    dw(3, HIGH);
    dw(4, HIGH);
    dw(14, LOW);
    dw(18, LOW);
    delay(1);
  }
  delay(200);
}

void letterC() {
  for(int x = 0; x <= 1500; x++) {
    dw(0, HIGH);
    dw(1, LOW);
    dw(2, HIGH);
    dw(3, HIGH);
    dw(4, HIGH);
    dw(5, HIGH);
    dw(6, HIGH);
    dw(7, HIGH);
    dw(20, HIGH);
    dw(19, HIGH);
    dw(18, HIGH);
    dw(17, HIGH);
    dw(16, HIGH);
    dw(15, HIGH);
    delay(1);
    dw(6, LOW);
    dw(19, LOW);
    dw(18, LOW);
    dw(17, LOW);
    dw(16, LOW);
    delay(1);
    dw(1, HIGH);
    dw(6, HIGH);
    dw(2, LOW);
    dw(3, LOW);
    dw(4, LOW);
    dw(5, LOW);
    dw(20, LOW);
    dw(15, LOW);
    dw(21, HIGH);
    dw(14, HIGH);
    delay(1);
    dw(21, LOW);
    dw(14, LOW);
    delay(1);
  }
  delay(200);
}

void letterW() {
  for (int x = 0; x <= 80000; x++) {
    dw(21, HIGH);
    dw(0, LOW);
    dw(7, LOW);
    dw(1, HIGH);
    dw(2, HIGH);
    dw(3, HIGH);
    dw(4, HIGH);
    dw(5, HIGH);
    dw(6, HIGH);
    delay(0.5);
    dw(21, LOW);
    dw(20, HIGH);
    delay(0.5);
    dw(20, LOW);
    dw(19, HIGH);
    delay(0.5);
    dw(19, LOW);
    dw(18, HIGH);
    delay(0.5);
    dw(18, LOW);
    dw(0, HIGH);
    dw(7, HIGH);
    dw(1, LOW);
    dw(6, LOW);
    dw(17, HIGH);
    delay(0.5);
    dw(17, LOW);
    dw(16, HIGH);
    delay(0.5);
    dw(16, LOW);
    dw(15, HIGH);
    delay(0.5);
    dw(15, LOW);
    dw(1, HIGH);
    dw(6, HIGH);
    dw(2, LOW);
    dw(5, LOW);
    dw(14, HIGH);
    delay(0.5);
    dw(14, LOW);
    dw(2, HIGH);
    dw(5, HIGH);
    dw(3, LOW);
    dw(4, LOW);
    dw(15, HIGH);
    delay(0.5);
    dw(15, LOW);
    dw(3, HIGH);
    dw(4, HIGH);
    delay(0.5);
  }
  delay(200);
}

void letterZ() {
  for (int x = 0; x <= 100000; x++) {
    dw(21, HIGH);
    dw(14, HIGH);
    dw(0, LOW);
    dw(1, LOW);
    dw(2, LOW);
    dw(3, LOW);
    dw(4, LOW);
    dw(5, LOW);
    dw(6, LOW);
    dw(7, LOW);
    delay(0.5);
    dw(0, HIGH);
    dw(1, HIGH);
    dw(2, HIGH);
    dw(3, HIGH);
    dw(4, HIGH);
    dw(5, HIGH);
    dw(7, HIGH);
    dw(21, LOW);
    dw(14, LOW);
    dw(20, HIGH);
    delay(0.5);
    dw(20, LOW);
    dw(6, HIGH);
    dw(19, HIGH);
    dw(5, LOW);
    delay(0.5);
    dw(19, LOW);
    dw(5, HIGH);
    dw(18, HIGH);
    dw(4, LOW);
    delay(0.5);
    dw(18, LOW);
    dw(4, HIGH);
    dw(17, HIGH);
    dw(3, LOW);
    delay(0.5);
    dw(17, LOW);
    dw(3, HIGH);
    dw(16, HIGH);
    dw(2, LOW);
    delay(0.5);
    dw(16, LOW);
    dw(2, HIGH);
    dw(15, HIGH);
    dw(1, LOW);
    delay(0.5);
    dw(15, LOW);
    delay(0.5);
  }
  delay(200);
}
void switches() {
  /*
       REFERENCE TABLE FOR ON/OFF CHARS
       PIN NO.             CHAR

       0 ON                 a
       1 ON                 b
       2 ON                 c
       3 ON                 d
       4 ON                 e
       5 ON                 f
       6 ON                 g
       7 ON                 h
       14 ON                1
       15 ON                2
       16 ON                3
       17 ON                4
       18 ON                5
       19 ON                6
       20 ON                7
       21 ON                8

       0 OFF                i
       1 OFF                j
       2 OFF                k
       3 OFF                l
       4 OFF                m
       5 OFF                n
       6 OFF                o
       7 OFF                p
       14 OFF               9
       15 OFF               0
       16 OFF               q
       17 OFF               r
       18 OFF               s
       19 OFF               t
       20 OFF               u
       21 OFF               v

       ALL LETTER FUNCTIONS USE THEIR CORRESPSONDNG CAPITAL LETTER
          'A' == letterA();, 'B' == letterB();, etc.
  */

  switch (incomingChar) {
    //LETTERS
    case 'A':
      letterA();
      break;
    case 'B':
      letterB();
      break;
    case 'C':
      letterC();
      break;
    case 'W':
      letterW();
      break;
    case 'Z':
      letterZ();
      break;

    //GROUND "ON"
    case 'a':
      dw(0, LOW);
      break;
    case 'b':
      dw(1, LOW);
      break;
    case 'c':
      dw(2, LOW);
      break;
    case 'd':
      dw(3, LOW);
      break;
    case 'e':
      dw(4, LOW);
      break;
    case 'f':
      dw(5, LOW);
      break;
    case 'g':
      dw(6, LOW);
      break;
    case 'h':
      dw(7, LOW);
      break;

    //GROUND "OFF"
    case 'i':
      dw(0, HIGH);
      break;
    case 'j':
      dw(1, HIGH);
      break;
    case 'k':
      dw(2, HIGH);
      break;
    case 'l':
      dw(3, HIGH);
      break;
    case 'm':
      dw(4, HIGH);
      break;
    case 'n':
      dw(5, HIGH);
      break;
    case 'o':
      dw(6, HIGH);
      break;
    case 'p':
      dw(7, HIGH);
      break;

    //POSITIVE ON
    case '1':
      dw(14, HIGH);
      break;
    case '2':
      dw(15, HIGH);
      break;
    case '3':
      dw(16, HIGH);
      break;
    case '4':
      dw(17, HIGH);
      break;
    case '5':
      dw(18, HIGH);
      break;
    case '6':
      dw(19, HIGH);
      break;
    case '7':
      dw(20, HIGH);
      break;
    case '8':
      dw(21, HIGH);
      break;

    //POSITIVE OFF
    case '9':
      dw(14, HIGH);
      break;
    case '0':
      dw(15, HIGH);
      break;
    case 'q':
      dw(16, HIGH);
      break;
    case 'r':
      dw(17, HIGH);
      break;
    case 's':
      dw(18, HIGH);
      break;
    case 't':
      dw(19, HIGH);
      break;
    case 'u':
      dw(20, HIGH);
      break;
    case 'v':
      dw(21, HIGH);
      break;

    //ALL OFF
    case 'y':
      dw(0, HIGH);
      dw(1, HIGH);
      dw(2, HIGH);
      dw(3, HIGH);
      dw(4, HIGH);
      dw(5, HIGH);
      dw(6, HIGH);
      dw(7, HIGH);
      dw(14, LOW);
      dw(15, LOW);
      dw(16, LOW);
      dw(17, LOW);
      dw(18, LOW);
      dw(19, LOW);
      dw(20, LOW);
      dw(21, LOW);
      break;

    //ALL ON
    case 'z':
      dw(0, LOW);
      dw(1, LOW);
      dw(2, LOW);
      dw(3, LOW);
      dw(4, LOW);
      dw(5, LOW);
      dw(6, LOW);
      dw(7, LOW);
      dw(14, HIGH);
      dw(15, HIGH);
      dw(16, HIGH);
      dw(17, HIGH);
      dw(18, HIGH);
      dw(19, HIGH);
      dw(20, HIGH);
      dw(21, HIGH);
      break;
  }
}

Is there anything that wouldn't work, anything that could be improved or anything that could be done in a better way? I usually learn by testing, but I made most of this without access to my Teensy. The Verify function comes back clean, but anything I can fix and thus learn from would be very helpful.

\$\endgroup\$
3
  • \$\begingroup\$ Is there nothing that can be done? \$\endgroup\$ Commented May 6, 2016 at 1:43
  • \$\begingroup\$ Are you sure that this code works? BTControl() reads inString but never uses it. \$\endgroup\$ Commented May 6, 2016 at 5:01
  • \$\begingroup\$ @200_success Oops. That's a mistake. It should be incomingChar. Thanks for pointing that out. \$\endgroup\$ Commented May 6, 2016 at 10:01

2 Answers 2

3
\$\begingroup\$

Remove duplication

There's clearly some duplication in your code, such as:

Serial.println("How do you want to control the RGB matrix?");
Serial2.println("How do you want to control the RGB matrix?");

As you seem to commonly write the same string to both Serial and MyBtooth, it's probably worth defining a function that simply does that and using it instead:

void println(const char *text) {
    Serial.println(text);
    MyBtooth.println(text);
}

I'd also consider refactoring this:

String choice = Serial.readString();
String choicebt = Serial2.readString();

if ((choice.toUpperCase() == "BLUETOOTH") || (choicebt.toUpperCase() == "BLUETOOTH")) {
    BTControl();
}
else if ((choice.toUpperCase() == "SERIAL") || (choicebt.toUpperCase() == "SERIAL")) {
    serialControl();
}
else{}

To something like this:

setupCommControl(Serial.readString());
setupCommControl(MyBtooth.readString());

Where:

void setupCommControl(const char *choice) {
    if (choice.toUpperCase() == "BLUETOOTH") {
        BTControl();
    }
    else if (choice.toUpperCase() == "SERIAL") {
        serialControl();
    }
}    

You also seem to write to ordered ranges of pins like this:

dw(0, LOW);
dw(1, LOW);
dw(2, LOW);
dw(3, LOW);
dw(4, LOW);
dw(5, LOW);
dw(6, LOW);
dw(7, LOW);

Again it might be worth writing a utility method something like this (I'm not sure of the type for pinState), where direction is either 1 (incrementing range) or -1 (decrementing range):

void dwRange(int startPin, int endPin, int direction, int pinState) {
    for(int pin = startPin; pin <= endPin; pin += direction)  {
        dw(pin, pinState);
    }
}

Called as:

dwRange(0, 7, 1, LOW);

There may also be scope for doing a similar reduction in your large case statement. Something like:

if(incomingChar >= 'a' && incomingChar <= 'h') {
    dw(incomingChar - 'a', LOW);
}

Would remove:

case 'a':
  dw(0, LOW);
  break;
case 'b':
  dw(1, LOW);
  break;
case 'c':
  dw(2, LOW);
  break;
case 'd':
  dw(3, LOW);
  break;
case 'e':
  dw(4, LOW);
  break;
case 'f':
  dw(5, LOW);
  break;
case 'g':
  dw(6, LOW);
  break;
case 'h':
  dw(7, LOW);
  break;

Serial2 Vs MyBtooth

It looks like you started off using Serial2, then defined MyBtooth to make it more explicit when you were talking to blue tooth vs serial. There are some lingering references to Serial2 in the code that should be updated so that it is consistent throughout.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks for this. I've since moved on from this revision of the code, but some of this will certainly be helpful in what I have now. \$\endgroup\$ Commented Jun 14, 2016 at 23:32
1
\$\begingroup\$

There might be a cleaner way to represent the output going to the LEDs. Can you encode the letters into a 2d 8x8 grid like:

int [][] a = {
{0, 0, 0, 1, 1, 0, 0, 0},
{0, 0, 1, 0, 0, 1, 0, 0},
{0, 0, 1, 0, 0, 1, 0, 0},
{0, 1, 0, 0, 0, 0, 1, 0},
{0, 1, 1, 1, 1, 1, 1, 0},
{0, 1, 0, 0, 0, 0, 1, 0},
{0, 1, 0, 0, 0, 0, 1, 0},
{0, 1, 0, 0, 0, 0, 1, 0}
};

or

String a = 
  "...00..."
+ "..0..0.."
+ "..0..0.."
+ ".0....0."
+ ".000000."
+ ".0....0."
+ ".0....0."
+ ".0....0.";

Then you would have a function that converts this version into the format that the pins expect. That way you have an easy way to edit and construct the LED patterns.

I'm not sure if this will work because I don't know the interface between the output pins and the 8x8 LED array. Do the letters come pre-programmed into the 8x8 array or do you have one pin for each LED?

\$\endgroup\$
1
  • \$\begingroup\$ had to make them manually \$\endgroup\$ Commented Jul 24, 2016 at 1:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.