Pages: [1]   Go Down
Author Topic: Communicating with arduino over serial port using windows batch files - question  (Read 3668 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Code:

@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


Code:

@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


Code:

#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;
    } 
  }
}
Logged

Gosport, UK
Offline Offline
Faraday Member
**
Karma: 21
Posts: 3113
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 613
Posts: 49339
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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.

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Code:

#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;
  }
}
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Gosport, UK
Offline Offline
Faraday Member
**
Karma: 21
Posts: 3113
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 613
Posts: 49339
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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?

Quote
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.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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.

Quote
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.

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

0
Offline Offline
Tesla Member
***
Karma: 143
Posts: 9596
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

Pages: [1]   Go Up
Jump to: