Jump to content

SOLVED: Serial to Arduino: fast in console, slow using AutoIT


Recommended Posts

I appreciate the expertise of the folks in this forum, I'm hoping you can help me solve a stubborn issue that I've hit a wall with, implementing serial coms in AutoIT.

I'm building a simulator cockpit panel that needs to turn LEDs on and off in response to events on a PC. I've got an Arduino running a simple script that lists for a three-digit number over serial: when it sees the number "808" it turns on LED number "808" on the panel. It works fine using the serial console in the Arduino IDE: it's basically instantaneous: I hit "enter" to send the three-bit command, and the corresponding LED lights up instantaneously. 

But when sending the same command in response to an AutoIT hotkey, there's a delay of almost two seconds between hotkey and the LED changing, which is too slow for this situation. I guess either something must be taking ages to spin up on the PC every time it tries to use the serial port, or my script must be bombarding the port in some way that the IDE console does not, therefore slowing things down on the Arduino end. 

Here's the script in AutoIT, using the ComMG serial coms library: 

#include <CommMG.au3>
#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Global $CMPort = 4
Global $CmBoBaud = 9600
Global $sportSetError = ''
Global $CmboDataBits = 8
Global $CmBoParity = "none"
Global $CmBoStop = 1
Global $setflow = 2

_CommSetPort($CMPort, $sportSetError, $CmBoBaud, $CmboDataBits, $CmBoParity, $CmBoStop, $setflow)

If @error Then
    MsgBox(16, "Error!", "Can't connect to Arduino on port - " & $CMPort)
    Exit
EndIf

_CommSetRTS(0)
_CommSetDTR(0)

While 1
Hotkeyset("{F9}", LED_ON)
WEnd

Func LED_ON() ;Sends Arduino "808" to turn on the corresponding combination of LEDs
    _CommSendByte(56, 0)
    _CommSendByte(48, 0)
    _CommSendByte(56, 0)
EndFunc

Any help you can suggest to understand the problem or help me troubleshoot further would be really appreciated, thanks for having a look. 

 

Edited by EricInCanada
Link to comment
Share on other sites

And, in case it's relevant here's the Arduino sketch. Very simple because all the heavy lifting is done by adafruit's NeoPixel library for controlling WS2812 individually-addressable RGB LED arrays. This code sets LED number "1" in the strip to RGB level 10,0,0 (a dim red), as soon as it sees "808" from the serial port. 

Responds instantly from the Arduino LED, but very slowly when sending those same three bits with an AutoIT script. 

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

#define PIN        9 // On Trinket or Gemma, suggest changing this to 1
#define NUMPIXELS 64 // Popular NeoPixel ring size

Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

int Mesg;
String ledLevel;
boolean newData = false;

void setup() {
  pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
  pixels.clear();
  pixels.show();            
  Serial.begin(9600);
}

void loop() {
    if (Serial.available() > 0) {
        Mesg = Serial.parseInt();
        newData = true;
    }

  if (newData == true) {

      if (Mesg == 808){
            pixels.setPixelColor(1, pixels.Color(10, 0, 0)); 
            pixels.show(); 
         }  
      newData = false;    
  } 
}



 

Link to comment
Share on other sites

You have to set HotKey before loop!

Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the Universe
trying to produce bigger and better idiots.
So far, the Universe is winning.

Link to comment
Share on other sites

16 hours ago, funkey said:

You have to set HotKey before loop!

Ah okay thanks, didn't realize AutoIT expected hotkeys to be defined this way. I've done this, but, no change to the result. Hitting "F9" turns on the LED on the arduino but with a big delay. 

I've also now tested this both with _CommSendByte(56, 0) and _CommSendString("8") and there is no discernable difference. Which makes sense, because they're both doing the same thing. 

I have noticed that the Arduino board's "Rx" light flashes differently:

  • Sending command using Arduno IDE's provided console: RX light flashes instantly, LED turns on instantly. 
  • Sending command using AutoIT: RX light flashes as soon as I hit the hotkey. Then a delay, then LED turns on. 

This makes me think that something about how AutoIT and the CommMg library are communicating with the Arduino is more taxing for the Arduino: like it's working hard to parse a complex signal. But this makes no sense... all that's being sent is three bytes!  Unless there's something I really don't understand about how serial coms work. 

Link to comment
Share on other sites

Solved it! Ridiculously simple fix: the Arduino IDE console was sending a "Newline" after every command, but my autoitscript was not. So the whole thing did still sort of work, because the Arduino would eventually timeout and just pass whatever was in its buffer on for processing, but the default timeout is 1000ms so there was a noticeable delay. 

Two possible solutions:
1. Add serial.setTimeout(50); to the Arduino sketch to decrease the time it waits. Works... but is kinda sketchy and could cause buffer overruns. 
2. Add  _CommSendByte(10, 0) to the AutoIT script to send an ASCII "newline" character after each three-digit command. 

So, in the end not really an AutoIT issue at all, but just me not understanding how serial coms are usually parsed. 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...