EricInCanada Posted November 1, 2020 Posted November 1, 2020 (edited) 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 November 3, 2020 by EricInCanada
EricInCanada Posted November 1, 2020 Author Posted November 1, 2020 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; } }
GokAy Posted November 2, 2020 Posted November 2, 2020 Hey Eric, Not in any way experienced in this, and quite new to AutoIt. Something I wondered, what if you add some sleep to this part? While 1 Hotkeyset("{F9}", LED_ON) sleep(50) WEnd
funkey Posted November 2, 2020 Posted November 2, 2020 You have to set HotKey before loop! Programming today is a race between software engineers striving tobuild bigger and better idiot-proof programs, and the Universetrying to produce bigger and better idiots.So far, the Universe is winning.
EricInCanada Posted November 2, 2020 Author Posted November 2, 2020 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.
EricInCanada Posted November 3, 2020 Author Posted November 3, 2020 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.
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now