Control motors with arduino using serial connection with computer

I am working on an automated dispensing project where I intend to control ten different 12V 600mA DC pumps with an arduino. A computer transmits messages over usb connection to the arduino in the following form:

lh = pumps off
0h = pump 0 on
1h = pump 1 on
etc.

The arduino gives power to the pumps by activating a TIP120 npn resistor connected to a 12V 2A DC power supply. Only one pump will be running at any given time.

When I test this by powering LEDs, the serial connection works flawlessly. However when I try it with a pump, the arduino begins to respond sluggishly to commands, and eventually I lose serial connection with the arduino. I can only imagine that there is some sort of power issue causing the arduino to lose connection. Any ideas where I am going wrong?
Arduino Code:

 #define PUMP5 5    //pin for turning transistor on/off
    const byte numChars = 32;
    char msg[numChars];
    
    void setup()
    {
      Serial.begin(9600,SERIAL_8N1);  
      Serial.println(msg[0]);
      pinMode(PUMP5, OUTPUT);
    }        
    void loop()
    {       
      read_msg();
      command_pumps();         
    }
    
    void read_msg()
    {
      char rc;
     if (Serial.available() > 0) {   
        rc = Serial.read();
        msg[0] = rc;
     }
     if(Serial.available() > 0) {
        rc = Serial.read();
        msg[1] = rc;
     }
        Serial.print("msg[0]: ");
        Serial.println(msg[0]);
        Serial.print("msg[1]: ");
        Serial.println(msg[1]);        
    }
    
    //PUMP5 is used for each of the scenarios since I am only testing with one pump 
    void command_pumps(){
       if (msg[0] == 'l'||msg[1]=='l')
      {  
        digitalWrite(PUMP5, LOW);       
      } 
      else if (msg[1] == 'h')
      {
        if(msg[0]=='0')  
          digitalWrite(PUMP5, HIGH);           
        else if (msg[0]=='1')
          digitalWrite(PUMP5, LOW);
        else if (msg[0]=='2')
          digitalWrite(PUMP5, HIGH); 
        else if (msg[0]=='3')
          digitalWrite(PUMP5, HIGH); 
        else if (msg[0]=='4')
          digitalWrite(PUMP5, HIGH); 
        else if (msg[0]=='5')
          digitalWrite(PUMP5, HIGH); 
        else if (msg[0]=='6')
          digitalWrite(PUMP5, HIGH); 
        else if (msg[0]=='7')
          digitalWrite(PUMP5, HIGH); 
        else if (msg[0]=='8')
          digitalWrite(PUMP5, HIGH); 
        else if (msg[0]=='9')
          digitalWrite(PUMP5, HIGH); 
      }
      return;
    }

     if (Serial.available() > 0) {   
        rc = Serial.read();
        msg[0] = rc;
     }
     if(Serial.available() > 0) {
        rc = Serial.read();
        msg[1] = rc;
     }

This is NOT the way to read two characters. If the command will ALWAYS be two characters, wait until there are two characters, and then read both of them.

What is sending the data to the Arduino? Try using the Serial Monitor app, with the line ending set to none, to send the same data.

Hey thanks for the response Paul. would you recommend something like this to read the characters?

char msg[2];

void read_msg(char *msg, byte length)
{
 while (length > 0) {
   if (Serial.available()) {
     *char++ = Serial.read();
     length -= 1;
   }
 }
}
void loop()
{       
    read_msg(msg, 2);
    command_pumps();         
}

The data is being sent to the arduino from a c++ program using Linux's termios functions to set the port attributes, and then the write function to write the characters to the serial port. That's a great idea to try another app, I will try that tonight and provide updates.

Besides the read_msg() portion of my code, can you think of anything else that could be causing the strange behavior with the serial port? Everything, including the serial portions, works well when I am powering an led.
Thanks for your time.

would you recommend something like this to read the characters?

Not really. What I'd do is something more like:

void loop()
{
   if(Serial.available() >= 2)
   {
      read_msg();
      command_pumps();
   }
}

In other words, a given pass through loop() will cause something to happen only when there are 2 or more bytes to be read. Then, read_msg() knows that it is OK to do two reads without checking that there is anything to read.

Everything, including the serial portions, works well when I am powering an led.

What I would try, then, is having the transistor control the LED rather than a motor. Is it the motor causing problems, or the transistor?

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data.

I don't see any advantage in sending 2-character commands. Using different letters of the alphabet you can have 52 different single-character commands.

...R

Awesome thanks for the advice PaulS and Robin2! You have been extremely helpful. I will make modifications and hopefully try these suggestions tonight. I'll update with the results.

Thanks again for all of your help guys. Everything works great now. I have modified my program to use PaulS's example.