Jump to content

Serial Port /COM Port UDF


martin
 Share

Recommended Posts

Whoops, yes, I thought I commented that out. Give me a few minutes and I'll fix it.

New version to download. dll is now v2.75.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

the link to win7/64 bit information in the first post is dead, please update...

Can anyone tell me if this works on 64bit win7? My first test failed...did not find the com ports...

Some time ago the first post got scrambled and Valik sorted out what he could. I don't know what the original link was and I hadn't noticed it no longer worked so I have siomply removed it.

At the start of the first post it says

"Note the dll is 32 bit so it will not work with a 64 bit app"

I have no plans to produce a 64 bit version.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

Hi reaper7,

I need to know more about how the Arduino board expects to receive data before I can answer your question. Maybe you can can provide a short explanation or a link which will give me a quick overview.

Can you send the values with a terminal emulator? If so then you only need _CommSendString which would make it much simpler.

If you do need to send bytes for each value then I assume that you need to send 4 bytes for each value. There must be some way to indicate the start and end as well.

You can send a single float value like this if the Arduino has the same way of storing a float

Hi Martin, thanks for assist but I've being trying to understand all this but getting nowhere fast :)

This is what I have that works so far:

Auto it code:

#include 'CommMG.au3'
    
;Internal for the Serial UDF
Global $sportSetError = ''
 
;COM Vars
Global $CMPort = 1 ; Port
Global $CmBoBaud = 9600 ; Baud
Global $CmboDataBits = 8 ; Data Bits
Global $CmBoParity = "none" ; Parity
Global $CmBoStop = 1 ; Stop
Global $setflow = 2 ; Flow

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

_CommSetRTS(0)
_CommSetDTR(0)
    
If @error Then
 ConsoleWrite("Error in Com Port!" & @CR)
 Exit
EndIf

while 1
        // Only showing one of the Functions - There are over 50 of them
    $TargetRange = Read_Target_Range () // Calls the Function Read_Target_Range

    ;_CommSendstring($TargetRange) // Send the value for Range
    Sleep(100) // Delay to stop overuse of comms
WEnd 

//Only showing 1 of the 50 plus memory

;##################################
;Function Read Target Range from Memory
;##################################
Func Read_Target_Range ()
        //Function not shown - but works ok
    //function returns a one decimal placed Float 
        //value is in range from 0 to 160 (Will display the needle position on a dial).
 
    Return $TargetRangeValue
EndFunc

And my arduino code

#include <Servo.h> 
 
Servo ServoAngleServo;  // create servo object to control a servo 
int ServoAngleValue;    // variable to store the servo position 
 
void setup() 
{ 
  Serial.begin(9600);  
  ServoAngleServo.attach(9);  // attaches the servo on pin 9 to the servo object 
} 
 
 
void loop() 
{ 
  if (Serial.available())               // wait for serial input
  {
    ServoAngleValue = Serial.read();  // read the incoming byte:
    Serial.write(ServoAngleValue); 
    if(ServoAngleValue >=0 and ServoAngleValue <= 180)
    { 
      ServoAngleValue = map(ServoAngleValue, 0, 20, 10, 180); // Reads the sent value (Range 0-20) and converts to servo momement (0-180 degrees) 
      ServoAngleServo.write(ServoAngleValue);  
      delay(15);      // waits 15ms for the servo to reach the position
    }     
   } 
 }

The above works but values are not received as float but int values

eg In Autoit I send a value for $TargetRange of 10.6 it only send the value 10. This is received by the arduino as 10 and the servo responds correctly ( But this resolution is not accurate enough due to stepper only moving in 1 degree steps (Due to decimal place being lost).

I have tried using:

$sf = Dllstructcreate("float")
$psf = dllstructgetptr($sf)

$sb = DllStructCreate("byte;byte;byte;byte", $psf);array of bytes but in same memory location as the float

$srf = Dllstructcreate("byte;byte;byte;byte");to hold the reversed bytes<br>$psrf = DllStructGetPtr($srf)

for $h = 1 to 4
    DllStructSetData($srf,$h,dllstructgetdata($sb,5 - $h))
Next


_CommSendByteArray($psrf,4,1)

But this does not seem to send my value correctly example sending value of 0.6 shows 33?A (33:33:D7:41) in 'Free Serial Port Monitor'.

What I hope to do with Autoit Serial comms:

I wish to send to the Arduino using serial handshake the following

a; start bit, 1byte (0x7E)

b: ID, 1byte (eg 0x01)

c: float value, 4bytes (eg Float 285.4)

e: end bit. 1byte (oxFF)

I can use the above to send each value one by one, and with code on the Arduino detect the startbit, read in the ID and assign it to relevant variable, then read in the 4bytes for for the value and convert back to float. When end byte is received wait for new data.

Again my knowledge on serial comms is very weak, but I know it should be straight forward enough - but alas it eludes me at this moment in time ;)

Edited by reaper7
Link to comment
Share on other sites

Hi Martin, thanks for assist but I've being trying to understand all this but getting nowhere fast Posted Image

The AutoIt code you showed doesn't help because you haven't included anything that would tell me what you've tried.

The C code helps a bit but because I don't know anything about Arduinos I have to guess abit.

In the C code I assume that

SerialAvailable is true when there is something received which could be read.

SerialRead reads the next byte.

You don't need anything clever to read and write float values. I would just ignore the decimal point and let that be calculated.

Suppose you only want to deal with positive numbers accurate to one decimal place, and assume that you won't send anything larger than 9999. Then you could send from the AutoIt script something like this

$val = 25.4
_CommSendString(stringformat("F%05d",int($val*10)))

This will result in sending "F00254". Whatever the value, provided it is less than 10000, the value will be sent in a string of length 6 characters.

Now you have to interpret that in the C code.

The small requirement here is that you have some understanding of ASCII codes. If you haven't then you must learn about them to do the sort of thing you want.

Below is pseudo code

if (SerialAvailable )
 {switch (SerialRead)
    {case 'F'://read a 5 digit float
     Val = 0;//must be a float or double
    //read the integral val 
    for (n=0;n<5;n++)
        {Val = Val * 10 + SerialRead - '0';//Note 1
            delay(50);//should be something better here to ensure you only read when there is something available
        }   
    //now read the deciaml val
    Val += ((float)(SerialRead - '0'))/10;
     break;
     case 'I'://Integer??


    }


}

Note 1. In case this line made no sense-

The character received after 'F' will be the ascii code for the number. Ascii codes for 0 to 9 are (hex) 30 to 39. So if you take away the character code for zero, ie '0', from the characters received then you have the number that they represent.

Of course you could make it more complicated but that might be all you need.

Edited by martin
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

You don't need anything clever to read and write float values. I would just ignore the decimal point and let that be calculated.

Suppose you only want to deal with positive numbers accurate to one decimal place, and assume that you won't send anything larger than 9999. Then you could send from the AutoIt script something like this

$val = 25.4

This will result in sending "F00254". Whatever the value, provided it is less than 10000, the value will be sent in a string of length 6 characters.

Now you have to interpret that in the C code.

The small requirement here is that you have some understanding of ASCII codes. If you haven't then you must learn about them to do the sort of thing you want.

Thanks Martin, that gives me a good footing to work with. Using your String example above - can this also be used for negative float values eg -100.5 :mellow:

Regards

John G

Edited by reaper7
Link to comment
Share on other sites

Thanks Martin, that gives me a good footing to work with. Using your String example above - can this also be used for negative float values eg -100.5 :mellow:

Regards

John G

To have negative numbers you can just do what I generally do, which is to make it up as you go along. One way would be to send the string of the float values and parse it checking for the -ve sign and checking for the decimal point so that you could deal with anything. But it is usually simpler to say something like "I only need this so that's all I'll worry about".

So for simplicity you could do this as a small mod to the example I gave.

$val = 25.4

if $val < 0 then
$Signcode = 'M';means Minus
else
 $Signcode = 'P';means plus
EndIf

 _CommSendString(stringFormat("F%c%05d",$Signcode,int(Abs($val*10))))

if (SerialAvailable )
 {switch (SerialRead)
    {case 'F'://read a sign code then 5 digit float
        signcode = SerialRead;
        sign = signcode=='P'?1:-1;<----- corrected colon used where I meant ?
     Val = 0;
    //read the integral val 
    for (n=0;n<5;n++)
        {Val = Val * 10 + SerialRead - '0';
            delay(50);
        }   
    //now read the deciaml val
    Val += ((float)(SerialRead - '0'))/10;
    Val *= sign;
     break;
     case 'I'://Integer??

    }

}

EDIT: correct where shown

Edited by martin
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

Thanks Martin :) Finally got it working once I got my head around it all.

Here's my working code so far

AUTOIT:

#include <NomadMemory2.au3>
#include <GUIConstants.au3>
#include <String.au3>
#include <Date.au3>
#include <array.au3>
#Include <Misc.au3>
#include 'CommMG.au3'


$path = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\xxxxxxxxx\xxxxxxxxxxxx", "InstalledPath")
If StringRight($path, 1) <> "\" Then $path &= "\"
If NOT ProcessExists("xxxxxxxx.exe") Then
Run($path & "sxxxxxxxxxx.exe")
EndIf

sleep(10000)
Global $ProcessID = WinGetProcess("xxxxxxxxxxx","")
sleep(2000)
    
;Internal for the Serial UDF
Global $sportSetError = ''
 
;COM Vars
Global $CMPort = 1 ; Port
Global $CmBoBaud = 9600 ; Baud
Global $CmboDataBits = 8 ; Data Bits
Global $CmBoParity = "none" ; Parity
Global $CmBoStop = 1 ; Stop
Global $setflow = 2 ; Flow

Global $TorpSpeedValue

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

_CommSetRTS(0)
_CommSetDTR(0)
    
If @error Then
 ConsoleWrite("Error in Com Port!" & @CR)
 Exit
EndIf


while 1
    $TorpedoDepth = Read_Torpedo_Depth ()
    $SalvoAngle = Read_Salvo_Angle ()
    
    _CommSendString(stringformat("A%03d",int($SalvoAngle*10)))
    Sleep(10)
    _CommSendString(stringformat("B%03d",int($TorpedoDepth*10)))
    Sleep(10)   
    
WEnd 

;##################################
;Function Read Torpedo Depth
;##################################
Func Read_Torpedo_Depth ()
    Local $TorpedoDepthValue, $TorpedoDepthPointer_1
    Local $TorpedoDepthOffset1 = 0x50
    Local $DllInformation = _MemoryOpen($ProcessID)

    $TorpedoDepthValue = _MemoryRead(0x5543DC, $DllInformation)
    $TorpedoDepthPointer_1 = '0x' & hex($TorpedoDepthValue + $TorpedoDepthOffset1)  
    $TorpedoDepthValue = _MemoryRead($TorpedoDepthPointer_1, $DllInformation, 'float')

    _MemoryClose($DllInformation)
    Return $TorpedoDepthValue
EndFunc

;##################################
;Function Read Salvo Angle
;##################################
Func Read_Salvo_Angle ()
    Local $SalvoAngleValue, $SalvoAnglePointer_1, $SalvoAngleSend
    Local $SalvoAngleOffset1 = 0x94
    Local $DllInformation = _MemoryOpen($ProcessID)

    $SalvoAngleValue = _MemoryRead(0x5543DC, $DllInformation)
    $SalvoAnglePointer_1 = '0x' & hex($SalvoAngleValue + $SalvoAngleOffset1)    
    $SalvoAngleValue = _MemoryRead($SalvoAnglePointer_1, $DllInformation, 'float')
    $SalvoAngleSend = Round($SalvoAngleValue, 1)

    _MemoryClose($DllInformation)
    Return $SalvoAngleSend
EndFunc

And my Arduino:

//****************************** ALPHA SIMULATOR PANEL ******************************
//****************************** JOHN GREANEY V0.01 ******************************

#include <Servo.h>

Servo SalvoAngle;  // create servo called SalvoAngle
Servo TorpedoDepth;  // create servo called TorpedoDepth
char Address;  //Variable to store Incoming Packets ID
int val = 0;
int data = 0;

//****************************** Main Setup ******************************
void setup() 
{
  Serial.begin(9600);
  TorpedoDepth.attach(8);  // attaches the servo on pin 8 to the servo object 
  SalvoAngle.attach(9);  // attaches the servo on pin 9 to the servo object 
}

//****************************** READ ADDRESS IDENTIFIERS ******************************
void loop()
{
  while (Serial.available() > 0)
  {
    Address = Serial.read();
    if (Address == 'A') Read_SalvoAngle();  // If ID = A goto SalvoAngle 
    if (Address == 'B') Read_TorpedoDepth();  // If ID = B goto TorpedoDepth
  }
}
  
//****************************** READ DATA IN FROM SERIAL ******************************

//****************************** SALVO ANGLE SERVO ROUTINE ****************************** 
void Read_SalvoAngle()
{
  delay(2); int data100 = Serial.read()- '0';  // Read in first bit od data
  delay(2); int data10 = Serial.read()- '0';  // Read in second bit od data
  delay(2); int data1 = Serial.read()- '0';  // Read in third bit od data
  data = 100*data100 + 10*data10 + data1; // Left shift each byte, add add together to get our value 000
  val = map(data, 0, 200, 10, 180);  // Asign our range of 0 - 200 to the servos range of  0 - 180
  SalvoAngle.write(val);  //Write the value to Serial
  delay(10);      // waits 10ms for the servo to reach the position
}

//****************************** TORPDEDO DEPTH SERVO ROUTINE ****************************** 
void Read_TorpedoDepth()
{
  delay(2); int data100 = Serial.read()- '0';
  delay(2); int data10 = Serial.read()- '0';
  delay(2); int data1 = Serial.read()- '0';
  data = 100*data100 + 10*data10 + data1;  
  val = map(data, 0, 250, 10, 180);
  TorpedoDepth.write(val); 
  delay(10);      // waits 10ms for the servo to reach the position
}

It works perfectly, reads the two values from Sim Memory (Floats) and sends them via serial to the Arduino.

The Arduino takes the values and send them to there relevant servo routine. (I've decided not to convert to decimal place and leave my value*10 - ie instead of 20.2 its 202)

This value is then mapped to the servos range of 0 to 180.

When running - The Servos now rotate in conjunction with the Dials Needles in the Sim :mellow: So that's a great start - now I need to do all the dials and other values.

One question though for now - Im using the startbit from "_CommSendString(stringformat("A%03d",int($SalvoAngle*10))" So 'A' is the ascii value that the serial looks for and jumps to the relevant routine.

How could I remake my code to read in two ascii characters to give me more ID addresses as I dont have enough using just one ascii character (I reckon I need at least 100 IDs and not 50)

For example in AutoIt sending the following: "_CommSendString(stringformat("ZA%03d",int($SalvoAngle*10))

Had tried the following with no success

void loop()
{
  while (Serial.available() > 0)
  {
    Address1 = Serial.read();
    while (Address1 == 'Z')
    {
      Address2 = Serial.read();
      if (Address2 == 'A') Read_SalvoAngle();    // If ID = ZA goto SalvoAngle
      if (Address2 == 'B') Read_TorpedoDepth();  // If ID = ZB goto TorpedoDepth
    }
  }
}

And this

void loop()
{
  while (Serial.available() > 0)
  {
    Address1 = Serial.read();
    Address2 = Serial.read();
    if (Address2 == 'Z' && Address2 == 'A') Read_SalvoAngle();    // If ID = ZA goto SalvoAngle
    if (Address2 == 'Z' && Address2 == 'B') Read_TorpedoDepth();  // If ID = ZB goto TorpedoDepth
  }
}
:

Any suggestions :)

Edited by reaper7
Link to comment
Share on other sites

Thanks Martin :) Finally got it working once I got my head around it all.

Here's my working code so far

AUTOIT:

#include <NomadMemory2.au3>
#include <GUIConstants.au3>
#include <String.au3>
#include <Date.au3>
#include <array.au3>
#Include <Misc.au3>
#include 'CommMG.au3'


$path = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\xxxxxxxxx\xxxxxxxxxxxx", "InstalledPath")
If StringRight($path, 1) <> "\" Then $path &= "\"
If NOT ProcessExists("xxxxxxxx.exe") Then
Run($path & "sxxxxxxxxxx.exe")
EndIf

sleep(10000)
Global $ProcessID = WinGetProcess("xxxxxxxxxxx","")
sleep(2000)
    
;Internal for the Serial UDF
Global $sportSetError = ''
 
;COM Vars
Global $CMPort = 1 ; Port
Global $CmBoBaud = 9600 ; Baud
Global $CmboDataBits = 8 ; Data Bits
Global $CmBoParity = "none" ; Parity
Global $CmBoStop = 1 ; Stop
Global $setflow = 2 ; Flow

Global $TorpSpeedValue

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

_CommSetRTS(0)
_CommSetDTR(0)
    
If @error Then
 ConsoleWrite("Error in Com Port!" & @CR)
 Exit
EndIf


while 1
    $TorpedoDepth = Read_Torpedo_Depth ()
    $SalvoAngle = Read_Salvo_Angle ()
    
    _CommSendString(stringformat("A%03d",int($SalvoAngle*10)))
    Sleep(10)
    _CommSendString(stringformat("B%03d",int($TorpedoDepth*10)))
    Sleep(10)   
    
WEnd 

;##################################
;Function Read Torpedo Depth
;##################################
Func Read_Torpedo_Depth ()
    Local $TorpedoDepthValue, $TorpedoDepthPointer_1
    Local $TorpedoDepthOffset1 = 0x50
    Local $DllInformation = _MemoryOpen($ProcessID)

    $TorpedoDepthValue = _MemoryRead(0x5543DC, $DllInformation)
    $TorpedoDepthPointer_1 = '0x' & hex($TorpedoDepthValue + $TorpedoDepthOffset1)  
    $TorpedoDepthValue = _MemoryRead($TorpedoDepthPointer_1, $DllInformation, 'float')

    _MemoryClose($DllInformation)
    Return $TorpedoDepthValue
EndFunc

;##################################
;Function Read Salvo Angle
;##################################
Func Read_Salvo_Angle ()
    Local $SalvoAngleValue, $SalvoAnglePointer_1, $SalvoAngleSend
    Local $SalvoAngleOffset1 = 0x94
    Local $DllInformation = _MemoryOpen($ProcessID)

    $SalvoAngleValue = _MemoryRead(0x5543DC, $DllInformation)
    $SalvoAnglePointer_1 = '0x' & hex($SalvoAngleValue + $SalvoAngleOffset1)    
    $SalvoAngleValue = _MemoryRead($SalvoAnglePointer_1, $DllInformation, 'float')
    $SalvoAngleSend = Round($SalvoAngleValue, 1)

    _MemoryClose($DllInformation)
    Return $SalvoAngleSend
EndFunc

And my Arduino:

//****************************** ALPHA SIMULATOR PANEL ******************************
//****************************** JOHN GREANEY V0.01 ******************************

#include <Servo.h>

Servo SalvoAngle;  // create servo called SalvoAngle
Servo TorpedoDepth;  // create servo called TorpedoDepth
char Address;  //Variable to store Incoming Packets ID
int val = 0;
int data = 0;

//****************************** Main Setup ******************************
void setup() 
{
  Serial.begin(9600);
  TorpedoDepth.attach(8);  // attaches the servo on pin 8 to the servo object 
  SalvoAngle.attach(9);  // attaches the servo on pin 9 to the servo object 
}

//****************************** READ ADDRESS IDENTIFIERS ******************************
void loop()
{
  while (Serial.available() > 0)
  {
    Address = Serial.read();
    if (Address == 'A') Read_SalvoAngle();  // If ID = A goto SalvoAngle 
    if (Address == 'B') Read_TorpedoDepth();  // If ID = B goto TorpedoDepth
  }
}
  
//****************************** READ DATA IN FROM SERIAL ******************************

//****************************** SALVO ANGLE SERVO ROUTINE ****************************** 
void Read_SalvoAngle()
{
  delay(2); int data100 = Serial.read()- '0';  // Read in first bit od data
  delay(2); int data10 = Serial.read()- '0';  // Read in second bit od data
  delay(2); int data1 = Serial.read()- '0';  // Read in third bit od data
  data = 100*data100 + 10*data10 + data1; // Left shift each byte, add add together to get our value 000
  val = map(data, 0, 200, 10, 180);  // Asign our range of 0 - 200 to the servos range of  0 - 180
  SalvoAngle.write(val);  //Write the value to Serial
  delay(10);      // waits 10ms for the servo to reach the position
}

//****************************** TORPDEDO DEPTH SERVO ROUTINE ****************************** 
void Read_TorpedoDepth()
{
  delay(2); int data100 = Serial.read()- '0';
  delay(2); int data10 = Serial.read()- '0';
  delay(2); int data1 = Serial.read()- '0';
  data = 100*data100 + 10*data10 + data1;  
  val = map(data, 0, 250, 10, 180);
  TorpedoDepth.write(val); 
  delay(10);      // waits 10ms for the servo to reach the position
}

It works perfectly, reads the two values from Sim Memory (Floats) and sends them via serial to the Arduino.

The Arduino takes the values and send them to there relevant servo routine. (I've decided not to convert to decimal place and leave my value*10 - ie instead of 20.2 its 202)

This value is then mapped to the servos range of 0 to 180.

When running - The Servos now rotate in conjunction with the Dials Needles in the Sim :mellow: So that's a great start - now I need to do all the dials and other values.

One question though for now - Im using the startbit from "_CommSendString(stringformat("A%03d",int($SalvoAngle*10))" So 'A' is the ascii value that the serial looks for and jumps to the relevant routine.

How could I remake my code to read in two ascii characters to give me more ID addresses as I dont have enough using just one ascii character (I reckon I need at least 100 IDs and not 50)

For example in AutoIt sending the following: "_CommSendString(stringformat("ZA%03d",int($SalvoAngle*10))

Had tried the following with no success

void loop()
{
  while (Serial.available() > 0)
  {
    Address1 = Serial.read();
    while (Address1 == 'Z')
    {
      Address2 = Serial.read();
      if (Address2 == 'A') Read_SalvoAngle();    // If ID = ZA goto SalvoAngle
      if (Address2 == 'B') Read_TorpedoDepth();  // If ID = ZB goto TorpedoDepth
    }
  }
}

And this

void loop()
{
  while (Serial.available() > 0)
  {
    Address1 = Serial.read();
    Address2 = Serial.read();
    if (Address2 == 'Z' && Address2 == 'A') Read_SalvoAngle();    // If ID = ZA goto SalvoAngle
    if (Address2 == 'Z' && Address2 == 'B') Read_TorpedoDepth();  // If ID = ZB goto TorpedoDepth
  }
}
:

Any suggestions :)

This is into general programming now and not really connected with this thread. This should probably be on the Arduino forum assuming there is one. I would also expect there are examples of reading serial data using the Arduino libraries you could find.

I assume that loop is called every time period.

If the characters are read faster than they arrive then you might read Z then there is no character then you return,. Next time you call loop the Z is forgotten and you read A and that isn't any good so you return from loop etc.

Maybe something like this

void loop()
{ if Serial.available() > 0)
  if ((err = getcommand()) != 0)
    givesomewarning(err);
}

int getcommand()
{int n, angle;etc 
 char nchar;
 
 switch (Serial.read())//we only come here if there is something to read
  {case 'Z';
    for (n=1;n < zcommandlength;n++)
    if ((nchar = waitforchar(60)) == 0) then return -1;//return failed
    switch (nchar)
    {case 'A';
    angle = readintval(zcommandlength-1); //read an int of zcommandlength - 1 digits
    //do something with angle
    return 0;//success
    } 
    default:
    return -2;//unknown start code
  }
}

////return the next char read which is not NULL within itime, or return 0 if itime elapsed.
int waitforchar(itime)
{int n, dt = 5;
 int icounts = itime div dt;
 int res;

 for (n=0; n< icounts;n++)
 {if (Serial.available())
   if ((res = Serial.Read()) != 0)//ignore nulls. OK as long as we're not reading binary data
    return res;
   delay(5);
 }

return 0; 

}
Edited by martin
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

Maybe something like this

void loop()
{ if Serial.available() > 0)
  if ((err = getcommand()) != 0)
    givesomewarning(err);
}

int getcommand()
{int n, angle;etc 
 char nchar;
 
 switch (Serial.read())//we only come here if there is something to read
  {case 'Z';
    for (n=1;n < zcommandlength;n++)
    if ((nchar = waitforchar(60)) == 0) then return -1;//return failed
    switch (nchar)
    {case 'A';
    angle = readintval(zcommandlength-1); //read an int of zcommandlength - 1 digits
    //do something with angle
    return 0;//success
    } 
    default:
    return -2;//unknown start code
  }
}

////return the next char read which is not NULL within itime, or return 0 if itime elapsed.
int waitforchar(itime)
{int n, dt = 5;
 int icounts = itime div dt;
 int res;

 for (n=0; n< icounts;n++)
 {if (Serial.available())
   if ((res = Serial.Read()) != 0)//ignore nulls. OK as long as we're not reading binary data
    return res;
   delay(5);
 }

return 0; 

}

Cheers Martin, Appreciate you taking time out to answer my questions. Got some Arduino Books ordered so hopefully they answer my remaining questions.

Thanks for your Serial scripts :mellow: they have brought my project to life.

Link to comment
Share on other sites

Hi Martin,

I've been using your UDF for a few days now, talking to an Arduino (like others above) under XP. However, when I moved it to Windows7, _CommListPorts() fails. Any ideas? Any known issues with Windows7?

Just hoping for a simple "duh"...

-R-

Link to comment
Share on other sites

Hi Martin,

I've been using your UDF for a few days now, talking to an Arduino (like others above) under XP. However, when I moved it to Windows7, _CommListPorts() fails. Any ideas? Any known issues with Windows7?

Just hoping for a simple "duh"...

-R-

Don't know, but if you have compiled your script as 64 bit then it won't work with the dll which is 32 bit.

Otherwise I need to know more about what works and what doesn't and what the errors are.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

  • 2 weeks later...

Hi Martin

1.

New version commg.dll and my script ?do=embed' frameborder='0' data-embedContent> can crash when I want connect again.

How to crash

1. Run my script ?do=embed' frameborder='0' data-embedContent>

2. Connect to port

3. Disconnect

4. Connect to port

With old commg.dll 2009-12-03 it is OK

Where is a problem ?

2.

It is possible change baud when we are connected without port closing?

Edited by kmeleon

Feed Polish children: pajacyk - just go to this page and close it. Thanks. World website: free rice.

Link to comment
Share on other sites

Hi Martin

1.

New version commg.dll and my script ?do=embed' frameborder='0' data-embedContent> can crash when I want connect again.

How to crash

1. Run my script ?do=embed' frameborder='0' data-embedContent>

2. Connect to port

3. Disconnect

4. Connect to port

With old commg.dll 2009-12-03 it is OK

Where is a problem ?

Thanks for telling me kmeleon. The error is in _CommClosePort but it also needs a change to the dll. I will update the download but I don't have much time to test so I would be grateful if you could try it out for me.

2.

It is possible change baud when we are connected without port closing?

Yes, just call _CommSetPort with whatever parameter changes you want.

EDIT: Changed the function again.

Edited by martin
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

Question 1

Thanks for telling me kmeleon. The error is in _CommClosePort but it also needs a change to the dll. I will update the download but I don't have much time to test so I would be grateful if you could try it out for me.

Thanks Martin. Now is OK.

Question 2

Yes, just call _CommSetPort with whatever parameter changes you want.

EDIT: Changed the function again.

When I want change baud by using _CommSetPort port is close and open with new parameters.

I checked this on Serial Port Monitor 4.0 by Eltima Software (14 days trial version).

Feed Polish children: pajacyk - just go to this page and close it. Thanks. World website: free rice.

Link to comment
Share on other sites

..

When I want change baud by using _CommSetPort port is close and open with new parameters.

I checked this on Serial Port Monitor 4.0 by Eltima Software (14 days trial version).

When the port has already been opened and you set it again then the new parameters are applied. Before the new settings are made the port is deactivated which effectively closes it, and after the settings are made the port is reactivated. It doesn't make sense to have characters being transmitted or received while the baud rate changed, so the buffers should be empty before a change is made.

But what I meant was that you do not need to call _CommClosePort before calling _CommSetPort with new parameters.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

Hi martin,

I just noticed the version I downloaded responds with version

V2.75 for the dll and V2.85 for the au3 file.

My other problem is with closing the post via _CommClosePort().

I also work with http://www.serial-port-monitor.com/ on an XP machine

with a native serial port as well as with an virtual com port.

This is how the problem occurs:

1. Call _CommSetPort(..) -> this is shown in serial port monitor and data transfer is possible

2. Call _CommClosePort() -> this shown in serial port monitor, the port is poroperly closed as

another terminal application (TeraTerm) can open and use it

3. Call _CommSetPort(..) -> this shown in serial port monitor and data transfer is possible

4. Call _CommClosePort() -> is NOT shown in serial port monitor, TeraTerm can not open the port

-> I assume the 2nd port close does not work properly

If I now try to open the port again from within the autoit application I can notice from

serial port monitor that the port gets first closed and then opened. As if the closing command

is buffered and not executed until the next open command is send.

Switching debugging on in your au3 script did not help .

Do you have any idea what might go wrong?

aboy

Link to comment
Share on other sites

Hi aboy,

I don 't know what's going wrong. Could you try this as I don't have time to try now.

After you close the port the first time, insert a line

_ComSwitch(1); or whatever channel you are using. If you don't use _ComSwitch in your script then use 1 as shown.

Then see if the second _CommClose works. If it does then the fix is quite simple and quick, otherwise I don't have time to look at it now and I won't be able to investigate it for about a week.

The version numbers for the UDF and dll are independantly assigned. The lastest version of the dll is 2.75. The latest UDF is version 2.85. It should say that in the first post and on the download page so I'll check it.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
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

×
×
  • Create New...