Communicating with arduino over serial port using windows batch files - question

Hi,

I have an arduino pro mini connected to several servo motors and photomos relays.

I have a program running on Windows 7 that will run several .bat files when specific events are triggered.

I have attached a sample of a .bat file and the arduino program - basic stuff.

The arduino will move a servo when it receives a letter or number sent across the serial port - e.g. "f" or "g".

I put delays in the .bat files instead of in the arduino program so that I can modify timing events without having to modify the arduino program.

Everything works fine except when...

One problem that I run into is that if two .bat files are run at nearly the same time I get an "ACCESS DENIED" message displayed
in one of the command windows and the arduino fails to execute the .bat file commands completely.

I have to say I'm not sure where the error is occuring - I don't know if all the data is getting transmitted across the serial connection or if the info is being transmitted but not getting received by the arduino.

I was just wondering if anybody knew of a way to buffer the transmission across the serial connection - or spool the .bat files - or increase the communication - or add some code to the .bat files.

Any advice would be greatly appreciated.

@ECHO OFF

MODE COM5:9600,N,8,1 >NUL

ECHO b >COM5

PING 1.1.1.1 -n 1 -w 5000 >NUL

ECHO a >COM5
@ECHO OFF

MODE COM5:9600,N,8,1 >NUL

ECHO g >COM5

PING 1.1.1.1 -n 1 -w 5000 >NUL

ECHO f >COM5
#include <Servo.h> 

Servo servo_01;
Servo servo_02;
Servo servo_03;
Servo servo_04;
Servo servo_05;
Servo servo_06;

int usb_switch_01 = 8;
int usb_switch_02 = 7;
int usb_switch_03 = 13;

void setup() {
  servo_01.attach(10);
  servo_02.attach(11);
  servo_03.attach(9);
  servo_04.attach(6);
  servo_05.attach(5);
  servo_06.attach(3);
  
  servo_01.write(68);  
  servo_02.write(70);
  servo_03.write(65);
  servo_04.write(75);
  servo_05.write(57);
  servo_06.write(83);
  
  pinMode(usb_switch_01, OUTPUT);
  pinMode(usb_switch_02, OUTPUT);
  pinMode(usb_switch_03, OUTPUT);
  
  digitalWrite(usb_switch_01, LOW);
  digitalWrite(usb_switch_02, LOW);
  digitalWrite(usb_switch_03, LOW);
  
  Serial.begin(9600); 
} 

void loop() {
  if (Serial.available() > 0) {
    int keyboard_button = Serial.read();
    
    switch (keyboard_button) {
      case 'a':
        servo_01.write(68);
        break;

      case 'b':
        servo_01.write(57);
        break;
        
      case 'c':
        servo_01.write(56);
        break;
        
      case 'd':
        servo_01.write(118);
        break;
      
      case 'e':
        servo_01.write(119);
        break;
        
        
        
       
      case 'f':
        servo_03.write(65);
        break;
        
      case 'g':
        servo_03.write(55);
        break;
        
      case 'h':
        servo_03.write(54);
        break;
        
      case 'i':
        servo_03.write(106);
        break;
        
      case 'j':
        servo_03.write(107);
        break;
      
      
      
      
      case 'k':
        servo_05.write(57);
        break;
        
      case 'l':
        servo_05.write(47);
        break;
        
      case 'm':
        servo_05.write(46);
        break;
        
      case 'n':
        servo_05.write(106);
        break;
        
      case 'o':
        servo_05.write(107);
        break;
        
      
      
      
      case 'p':
        servo_02.write(70);
        break;
        
      case 'q':
        servo_02.write(46);
        break;
        
      
      
      
      case 'r':
        servo_04.write(75);
        break;
        
      case 's':
        servo_04.write(51);
        break;
        
        
        
        
      case 't':
        servo_06.write(83);
        break;
        
      case 'u':
        servo_06.write(107);
        break;
        
        
        
        
      case '1':
        digitalWrite(usb_switch_01, LOW);
        break;
        
      case '4':
        digitalWrite(usb_switch_01, HIGH);
        break;
        
        
        
        
      case '2':
        digitalWrite(usb_switch_02, LOW);
        break;
        
      case '5':
        digitalWrite(usb_switch_02, HIGH);
        break;
        
        
        
        
      case '3':
        digitalWrite(usb_switch_03, LOW);
        break;
        
      case '6':
        digitalWrite(usb_switch_03, HIGH);
        break;
    }  
  }
}

The serial port can't be shared across processes, so if one of your batch files has 'ownership' of it, another batch file running at the same time will be refused access.

One problem that I run into is that if two .bat files are run at nearly the same time I get an "ACCESS DENIED" message displayed
in one of the command windows and the arduino fails to execute the .bat file commands completely.

It is reasonable that the Arduino doesn't execute commands it doesn't get. That's hardly a failure on the Arduino's part.

I have experimented with manually running the .bat files.

As shown in the .bat files there is a letter sent and then a pause and then another letter sent - in this case.

If I run the .bat files one after another in close succession (manually by double-clicking them fast) most often the first letters of the .bat files are received by the arduino but the second letter sent in the second .bat file does not appear to be received and the servo never returns to its position.

Unfortunately, I can't modify the Windows software so it may run multiple .bat files quickly.

I tried to add a condition to the arduino program that would remedy the case of not receiving the second letter but it doesn't seem to work.

Here it is if anybody wants to see it and let me know any "stupid" mistake I made.

Basically, I'm trying to put in a condition that when the first letter is received the servo is moved and if the second letter is not received with a certain amount of time the servo will automatically move back to its original position - so far the program doesn't do what it was supposed to.

#include <Servo.h> 

Servo servo_01;
Servo servo_02;
Servo servo_03;
Servo servo_04;
Servo servo_05;
Servo servo_06;

int usb_switch_01 = 8;
int usb_switch_02 = 7;
int usb_switch_03 = 13;

long millis_b = 0;
long millis_c = 0;

long millis_g = 0;
long millis_h = 0;

long millis_l = 0;
long millis_m = 0;

void setup() {
  servo_01.attach(10);
  servo_02.attach(11);
  servo_03.attach(9);
  servo_04.attach(6);
  servo_05.attach(5);
  servo_06.attach(3);
  
  servo_01.write(68);  
  servo_02.write(70);
  servo_03.write(65);
  servo_04.write(75);
  servo_05.write(57);
  servo_06.write(83);
  
  pinMode(usb_switch_01, OUTPUT);
  pinMode(usb_switch_02, OUTPUT);
  pinMode(usb_switch_03, OUTPUT);
  
  digitalWrite(usb_switch_01, LOW);
  digitalWrite(usb_switch_02, LOW);
  digitalWrite(usb_switch_03, LOW);
  
  Serial.begin(9600); 
} 

void loop() {
  
  unsigned long current_millis = millis();
  
  if (Serial.available() > 0) {
    int keyboard_button = Serial.read();
    
    switch (keyboard_button) {
      case 'a':
        servo_01.write(68);
        millis_b = 0;
        millis_c = 0;
        break;

      case 'b':
        servo_01.write(57);
        millis_b = current_millis;
        break;
        
      case 'c':
        servo_01.write(56);
        millis_c = current_millis;
        break;
        
      case 'd':
        servo_01.write(118);
        break;
      
      case 'e':
        servo_01.write(119);
        break;
        
        
        
       
      case 'f':
        servo_03.write(65);
        millis_g = 0;
        millis_h = 0;
        break;
        
      case 'g':
        servo_03.write(55);
        millis_g = current_millis;
        break;
        
      case 'h':
        servo_03.write(54);
        millis_h = current_millis;
        break;
        
      case 'i':
        servo_03.write(106);
        break;
        
      case 'j':
        servo_03.write(107);
        break;
      
      
      
      
      case 'k':
        servo_05.write(57);
        millis_l = 0;
        millis_m = 0;
        break;
        
      case 'l':
        servo_05.write(47);
        millis_l = current_millis;
        break;
        
      case 'm':
        servo_05.write(46);
        millis_m = current_millis;
        break;
        
      case 'n':
        servo_05.write(106);
        break;
        
      case 'o':
        servo_05.write(107);
        break;
        
      
      
      
      case 'p':
        servo_02.write(70);
        break;
        
      case 'q':
        servo_02.write(46);
        break;
        
      
      
      
      case 'r':
        servo_04.write(75);
        break;
        
      case 's':
        servo_04.write(51);
        break;
        
        
        
        
      case 't':
        servo_06.write(83);
        break;
        
      case 'u':
        servo_06.write(107);
        break;
        
        
        
        
      case '1':
        digitalWrite(usb_switch_01, LOW);
        break;
        
      case '4':
        digitalWrite(usb_switch_01, HIGH);
        break;
        
        
        
        
      case '2':
        digitalWrite(usb_switch_02, LOW);
        break;
        
      case '5':
        digitalWrite(usb_switch_02, HIGH);
        break;
        
        
        
        
      case '3':
        digitalWrite(usb_switch_03, LOW);
        break;
        
      case '6':
        digitalWrite(usb_switch_03, HIGH);
        break;
    }  
  }
  
  if (millis_b > current_millis + 10000) {
    servo_01.write(68);
    millis_b = 0;
  }
  
  if (millis_c > current_millis + 10000) {
    servo_01.write(68);
    millis_c = 0;
  }
  
  if (millis_g > current_millis + 10000) {
    servo_03.write(65);
    millis_g = 0;
  }
  
  if (millis_h > current_millis + 10000) {
    servo_03.write(65);
    millis_b = 0;
  }
  
  if (millis_l > current_millis + 10000) {
    servo_05.write(57);
    millis_l = 0;
  }
  
  if (millis_m > current_millis + 10000) {
    servo_05.write(57);
    millis_m = 0;
  }
}

I agree, the problem is communicating with the arduino using .bat files and the serial port - it's a bottleneck problem I'm trying to understand and maybe minimize.

I would think the best solution would be to have a proxy application/service that took your requests and passed them to the serial port.

I tried to add a condition to the arduino program that would remedy the case of not receiving the second letter but it doesn't seem to work.

How would you know that you didn't get a second letter? Is that anything like the dog that didn't bark in the middle of the night?

it's a bottleneck problem I'm trying to understand and maybe minimize.

Create one program that reads from a file, and sends to the serial port. Make all the batch jobs append to that file. The executable opens the file, reads the next "command", closes the file, and takes some action.

Create one program that reads from a file, and sends to the serial port. Make all the batch jobs append to that file. The executable opens the file, reads the next "command", closes the file, and takes some action.

Thanks. I'll give this some thought.

How would you know that you didn't get a second letter? Is that anything like the dog that didn't bark in the middle of the night?

If the second letter was sent and received then the servo would have moved.

The servo doesn't move when the second letter is "supposedly" sent so I can't tell if it's a transmission or reception problem.

Anyway, it most definitly not the arduino's fault.

I would think the best solution would be to have a proxy application/service that took your requests and passed them to the serial port.

Any idea if this kind of program exists?

One way to spool batch files would be to use
for %a in (*.bat) do $a
Make a separate directory for the batch files. DOS will execute each batch file in the directory in turn

auto_pear:
I agree, the problem is communicating with the arduino using .bat files and the serial port - it's a bottleneck problem I'm trying to understand and maybe minimize.

Have you disabled the auto reset "feature" on the arduino to prevent the arduino reboot every time the serial port is opened/closed?