Inviare codice "0A" (hex) a shell

di il
66 risposte

66 Risposte - Pagina 5

  • Re: Inviare codice "0A" (hex) a shell

    Magari posta la soluzione così da aiutare altri...!
  • Re: Inviare codice "0A" (hex) a shell

    Scusa ma non riesco a caricare il file di excel, nemmeno zippato, "Estensione del file non valido"
    come faccio?
  • Re: Inviare codice "0A" (hex) a shell

    Copia il codice lo incolli e metti qualche indicazione.
  • Re: Inviare codice "0A" (hex) a shell

    I moduli sono 3:
    - modCOMM, contiene le funzioni per la gestione della porta, gestione errori ecc
    - readStatus, contiene la routine per leggere la porta COMM, SerialPort_status
    - setRelay, contiene la routine per comandare la porta COMM, SerialPort_set

    modCOMM
    Option Explicit
    
    '-------------------------------------------------------------------------------
    ' modCOMM - Written by: David M. Hitchner
    '
    ' This VB module is a collection of routines to perform serial port I/O without
    ' using the Microsoft Comm Control component.  This module uses the Windows API
    ' to perform the overlapped I/O operations necessary for serial communications.
    '
    ' The routine can handle up to 4 serial ports which are identified with a
    ' Port ID.
    '
    ' All routines (with the exception of CommRead and CommWrite) return an error
    ' code or 0 if no error occurs.  The routine CommGetError can be used to get
    ' the complete error message.
    '-------------------------------------------------------------------------------
    
    '-------------------------------------------------------------------------------
    ' Public Constants
    '-------------------------------------------------------------------------------
    
    ' Output Control Lines (CommSetLine)
    Public Const LINE_BREAK = 1
    Public Const LINE_DTR = 2
    Public Const LINE_RTS = 3
    
    ' Input Control Lines  (CommGetLine)
    Public Const LINE_CTS = &H10&
    Public Const LINE_DSR = &H20&
    Public Const LINE_RING = &H40&
    Public Const LINE_RLSD = &H80&
    Public Const LINE_CD = &H80&
    
    '-------------------------------------------------------------------------------
    ' System Constants
    '-------------------------------------------------------------------------------
    Private Const ERROR_IO_INCOMPLETE = 996&
    Private Const ERROR_IO_PENDING = 997
    Private Const GENERIC_READ = &H80000000
    Private Const GENERIC_WRITE = &H40000000
    Private Const FILE_ATTRIBUTE_NORMAL = &H80
    Private Const FILE_FLAG_OVERLAPPED = &H40000000
    Private Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000
    Private Const OPEN_EXISTING = 3
    
    ' COMM Functions
    Private Const MS_CTS_ON = &H10&
    Private Const MS_DSR_ON = &H20&
    Private Const MS_RING_ON = &H40&
    Private Const MS_RLSD_ON = &H80&
    Private Const PURGE_RXABORT = &H2
    Private Const PURGE_RXCLEAR = &H8
    Private Const PURGE_TXABORT = &H1
    Private Const PURGE_TXCLEAR = &H4
    
    ' COMM Escape Functions
    Private Const CLRBREAK = 9
    Private Const CLRDTR = 6
    Private Const CLRRTS = 4
    Private Const SETBREAK = 8
    Private Const SETDTR = 5
    Private Const SETRTS = 3
    
    '-------------------------------------------------------------------------------
    ' System Structures
    '-------------------------------------------------------------------------------
    Private Type COMSTAT
            fBitFields As Long ' See Comment in Win32API.Txt
            cbInQue As Long
            cbOutQue As Long
    End Type
    
    Private Type COMMTIMEOUTS
            ReadIntervalTimeout As Long
            ReadTotalTimeoutMultiplier As Long
            ReadTotalTimeoutConstant As Long
            WriteTotalTimeoutMultiplier As Long
            WriteTotalTimeoutConstant As Long
    End Type
    
    '
    ' The DCB structure defines the control setting for a serial
    ' communications device.
    '
    Private Type DCB
            DCBlength As Long
            BaudRate As Long
            fBitFields As Long ' See Comments in Win32API.Txt
            wReserved As Integer
            XonLim As Integer
            XoffLim As Integer
            ByteSize As Byte
            Parity As Byte
            StopBits As Byte
            XonChar As Byte
            XoffChar As Byte
            ErrorChar As Byte
            EofChar As Byte
            EvtChar As Byte
            wReserved1 As Integer 'Reserved; Do Not Use
    End Type
    
    Private Type OVERLAPPED
            Internal As Long
            InternalHigh As Long
            offset As Long
            OffsetHigh As Long
            hEvent As Long
    End Type
    
    Private Type SECURITY_ATTRIBUTES
            nLength As Long
            lpSecurityDescriptor As Long
            bInheritHandle As Long
    End Type
    
    '-------------------------------------------------------------------------------
    ' System Functions
    '-------------------------------------------------------------------------------
    '
    ' Fills a specified DCB structure with values specified in
    ' a device-control string.
    '
    Declare Function BuildCommDCB Lib "kernel32" Alias "BuildCommDCBA" _
        (ByVal lpDef As String, lpDCB As DCB) As Long
    '
    ' Retrieves information about a communications error and reports
    ' the current status of a communications device. The function is
    ' called when a communications error occurs, and it clears the
    ' device's error flag to enable additional input and output
    ' (I/O) operations.
    '
    Declare Function ClearCommError Lib "kernel32" _
        (ByVal hFile As Long, lpErrors As Long, lpStat As COMSTAT) As Long
    '
    ' Closes an open communications device or file handle.
    '
    Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    '
    ' Creates or opens a communications resource and returns a handle
    ' that can be used to access the resource.
    '
    Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" _
        (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, _
        ByVal dwShareMode As Long, lpSecurityAttributes As Any, _
        ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, _
        ByVal hTemplateFile As Long) As Long
    '
    ' Directs a specified communications device to perform a function.
    '
    Declare Function EscapeCommFunction Lib "kernel32" _
        (ByVal nCid As Long, ByVal nFunc As Long) As Long
    '
    ' Formats a message string such as an error string returned
    ' by anoher function.
    '
    Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" _
        (ByVal dwFlags As Long, lpSource As Any, ByVal dwMessageId As Long, _
        ByVal dwLanguageId As Long, ByVal lpBuffer As String, ByVal nSize As Long, _
        Arguments As Long) As Long
    '
    ' Retrieves modem control-register values.
    '
    Declare Function GetCommModemStatus Lib "kernel32" _
        (ByVal hFile As Long, lpModemStat As Long) As Long
    '
    ' Retrieves the current control settings for a specified
    ' communications device.
    '
    Declare Function GetCommState Lib "kernel32" _
        (ByVal nCid As Long, lpDCB As DCB) As Long
    '
    ' Retrieves the calling thread's last-error code value.
    '
    Declare Function GetLastError Lib "kernel32" () As Long
    '
    ' Retrieves the results of an overlapped operation on the
    ' specified file, named pipe, or communications device.
    '
    Declare Function GetOverlappedResult Lib "kernel32" _
        (ByVal hFile As Long, lpOverlapped As OVERLAPPED, _
        lpNumberOfBytesTransferred As Long, ByVal bWait As Long) As Long
    '
    ' Discards all characters from the output or input buffer of a
    ' specified communications resource. It can also terminate
    ' pending read or write operations on the resource.
    '
    Declare Function PurgeComm Lib "kernel32" _
        (ByVal hFile As Long, ByVal dwFlags As Long) As Long
    '
    ' Reads data from a file, starting at the position indicated by the
    ' file pointer. After the read operation has been completed, the
    ' file pointer is adjusted by the number of bytes actually read,
    ' unless the file handle is created with the overlapped attribute.
    ' If the file handle is created for overlapped input and output
    ' (I/O), the application must adjust the position of the file pointer
    ' after the read operation.
    '
    Declare Function ReadFile Lib "kernel32" _
        (ByVal hFile As Long, ByVal lpBuffer As String, _
        ByVal nNumberOfBytesToRead As Long, ByRef lpNumberOfBytesRead As Long, _
        lpOverlapped As OVERLAPPED) As Long
    '
    ' Configures a communications device according to the specifications
    ' in a device-control block (a DCB structure). The function
    ' reinitializes all hardware and control settings, but it does not
    ' empty output or input queues.
    '
    Declare Function SetCommState Lib "kernel32" _
        (ByVal hCommDev As Long, lpDCB As DCB) As Long
    '
    ' Sets the time-out parameters for all read and write operations on a
    ' specified communications device.
    '
    Declare Function SetCommTimeouts Lib "kernel32" _
        (ByVal hFile As Long, lpCommTimeouts As COMMTIMEOUTS) As Long
    '
    ' Initializes the communications parameters for a specified
    ' communications device.
    '
    Declare Function SetupComm Lib "kernel32" _
        (ByVal hFile As Long, ByVal dwInQueue As Long, ByVal dwOutQueue As Long) As Long
    '
    ' Writes data to a file and is designed for both synchronous and a
    ' synchronous operation. The function starts writing data to the file
    ' at the position indicated by the file pointer. After the write
    ' operation has been completed, the file pointer is adjusted by the
    ' number of bytes actually written, except when the file is opened with
    ' FILE_FLAG_OVERLAPPED. If the file handle was created for overlapped
    ' input and output (I/O), the application must adjust the position of
    ' the file pointer after the write operation is finished.
    '
    Declare Function WriteFile Lib "kernel32" _
        (ByVal hFile As Long, ByVal lpBuffer As String, _
        ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, _
        lpOverlapped As OVERLAPPED) As Long
    
    '-------------------------------------------------------------------------------
    ' Program Constants
    '-------------------------------------------------------------------------------
    
    Private Const MAX_PORTS = 4
    
    '-------------------------------------------------------------------------------
    ' Program Structures
    '-------------------------------------------------------------------------------
    
    Private Type COMM_ERROR
        lngErrorCode As Long
        strFunction As String
        strErrorMessage As String
    End Type
    
    Private Type COMM_PORT
        lngHandle As Long
        blnPortOpen As Boolean
        udtDCB As DCB
    End Type
    
    '-------------------------------------------------------------------------------
    ' Program Storage
    '-------------------------------------------------------------------------------
    
    Private udtCommOverlap As OVERLAPPED
    Private udtCommError As COMM_ERROR
    Private udtPorts(1 To MAX_PORTS) As COMM_PORT
    '-------------------------------------------------------------------------------
    ' GetSystemMessage - Gets system error text for the specified error code.
    '-------------------------------------------------------------------------------
    Public Function GetSystemMessage(lngErrorCode As Long) As String
    Dim intPos As Integer
    Dim strMessage As String, strMsgBuff As String * 256
    
        Call FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, lngErrorCode, 0, strMsgBuff, 255, 0)
    
        intPos = InStr(1, strMsgBuff, vbNullChar)
        If intPos > 0 Then
            strMessage = Trim$(Left$(strMsgBuff, intPos - 1))
        Else
            strMessage = Trim$(strMsgBuff)
        End If
        
        GetSystemMessage = strMessage
        
    End Function
    
    
    '-------------------------------------------------------------------------------
    ' CommOpen - Opens/Initializes serial port.
    '
    '
    ' Parameters:
    '   intPortID   - Port ID used when port was opened.
    '   strPort     - COM port name. (COM1, COM2, COM3, COM4)
    '   strSettings - Communication settings.
    '                 Example: "baud=9600 parity=N data=8 stop=1"
    '
    ' Returns:
    '   Error Code  - 0 = No Error.
    '
    '-------------------------------------------------------------------------------
    Public Function CommOpen(intPortID As Integer, strPort As String, _
        strSettings As String) As Long
        
    Dim lngStatus       As Long
    Dim udtCommTimeOuts As COMMTIMEOUTS
    
        On Error GoTo Routine_Error
        
        ' See if port already in use.
        If udtPorts(intPortID).blnPortOpen Then
            lngStatus = -1
            With udtCommError
                .lngErrorCode = lngStatus
                .strFunction = "CommOpen"
                .strErrorMessage = "Port in use."
            End With
            
            GoTo Routine_Exit
        End If
    
        ' Open serial port.
        udtPorts(intPortID).lngHandle = CreateFile(strPort, GENERIC_READ Or _
            GENERIC_WRITE, 0, ByVal 0&, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
    
        If udtPorts(intPortID).lngHandle = -1 Then
            lngStatus = SetCommError("CommOpen (CreateFile)")
            GoTo Routine_Exit
        End If
    
        udtPorts(intPortID).blnPortOpen = True
    
        ' Setup device buffers (1K each).
        lngStatus = SetupComm(udtPorts(intPortID).lngHandle, 1024, 1024)
        
        If lngStatus = 0 Then
            lngStatus = SetCommError("CommOpen (SetupComm)")
            GoTo Routine_Exit
        End If
    
        ' Purge buffers.
        lngStatus = PurgeComm(udtPorts(intPortID).lngHandle, PURGE_TXABORT Or _
            PURGE_RXABORT Or PURGE_TXCLEAR Or PURGE_RXCLEAR)
    
        If lngStatus = 0 Then
            lngStatus = SetCommError("CommOpen (PurgeComm)")
            GoTo Routine_Exit
        End If
    
        ' Set serial port timeouts.
        With udtCommTimeOuts
            .ReadIntervalTimeout = -1
            .ReadTotalTimeoutMultiplier = 0
            .ReadTotalTimeoutConstant = 1000
            .WriteTotalTimeoutMultiplier = 0
            .WriteTotalTimeoutMultiplier = 1000
        End With
    
        lngStatus = SetCommTimeouts(udtPorts(intPortID).lngHandle, udtCommTimeOuts)
    
        If lngStatus = 0 Then
            lngStatus = SetCommError("CommOpen (SetCommTimeouts)")
            GoTo Routine_Exit
        End If
    
        ' Get the current state (DCB).
        lngStatus = GetCommState(udtPorts(intPortID).lngHandle, _
            udtPorts(intPortID).udtDCB)
    
        If lngStatus = 0 Then
            lngStatus = SetCommError("CommOpen (GetCommState)")
            GoTo Routine_Exit
        End If
    
        ' Modify the DCB to reflect the desired settings.
        lngStatus = BuildCommDCB(strSettings, udtPorts(intPortID).udtDCB)
    
        If lngStatus = 0 Then
            lngStatus = SetCommError("CommOpen (BuildCommDCB)")
            GoTo Routine_Exit
        End If
    
        ' Set the new state.
        lngStatus = SetCommState(udtPorts(intPortID).lngHandle, _
            udtPorts(intPortID).udtDCB)
    
        If lngStatus = 0 Then
            lngStatus = SetCommError("CommOpen (SetCommState)")
            GoTo Routine_Exit
        End If
    
        lngStatus = 0
    
    Routine_Exit:
        CommOpen = lngStatus
        Exit Function
    
    Routine_Error:
        lngStatus = Err.Number
        With udtCommError
            .lngErrorCode = lngStatus
            .strFunction = "CommOpen"
            .strErrorMessage = Err.Description
        End With
        Resume Routine_Exit
    End Function
    
    
    Private Function SetCommError(strFunction As String) As Long
        
        With udtCommError
            .lngErrorCode = Err.LastDllError
            .strFunction = strFunction
            .strErrorMessage = GetSystemMessage(.lngErrorCode)
            SetCommError = .lngErrorCode
        End With
        
    End Function
    
    Private Function SetCommErrorEx(strFunction As String, lngHnd As Long) As Long
    Dim lngErrorFlags As Long
    Dim udtCommStat As COMSTAT
        
        With udtCommError
            .lngErrorCode = GetLastError
            .strFunction = strFunction
            .strErrorMessage = GetSystemMessage(.lngErrorCode)
        
            Call ClearCommError(lngHnd, lngErrorFlags, udtCommStat)
        
            .strErrorMessage = .strErrorMessage & "  COMM Error Flags = " & _
                    Hex$(lngErrorFlags)
            
            SetCommErrorEx = .lngErrorCode
        End With
        
    End Function
    
    '-------------------------------------------------------------------------------
    ' CommSet - Modifies the serial port settings.
    '
    ' Parameters:
    '   intPortID   - Port ID used when port was opened.
    '   strSettings - Communication settings.
    '                 Example: "baud=9600 parity=N data=8 stop=1"
    '
    ' Returns:
    '   Error Code  - 0 = No Error.
    '-------------------------------------------------------------------------------
    Public Function CommSet(intPortID As Integer, strSettings As String) As Long
        
    Dim lngStatus As Long
        
        On Error GoTo Routine_Error
    
        lngStatus = GetCommState(udtPorts(intPortID).lngHandle, _
            udtPorts(intPortID).udtDCB)
    
        If lngStatus = 0 Then
            lngStatus = SetCommError("CommSet (GetCommState)")
            GoTo Routine_Exit
        End If
    
        lngStatus = BuildCommDCB(strSettings, udtPorts(intPortID).udtDCB)
    
        If lngStatus = 0 Then
            lngStatus = SetCommError("CommSet (BuildCommDCB)")
            GoTo Routine_Exit
        End If
    
        lngStatus = SetCommState(udtPorts(intPortID).lngHandle, _
            udtPorts(intPortID).udtDCB)
    
        If lngStatus = 0 Then
            lngStatus = SetCommError("CommSet (SetCommState)")
            GoTo Routine_Exit
        End If
    
        lngStatus = 0
    
    Routine_Exit:
        CommSet = lngStatus
        Exit Function
    
    Routine_Error:
        lngStatus = Err.Number
        With udtCommError
            .lngErrorCode = lngStatus
            .strFunction = "CommSet"
            .strErrorMessage = Err.Description
        End With
        Resume Routine_Exit
    End Function
    
    '-------------------------------------------------------------------------------
    ' CommClose - Close the serial port.
    '
    ' Parameters:
    '   intPortID   - Port ID used when port was opened.
    '
    ' Returns:
    '   Error Code  - 0 = No Error.
    '-------------------------------------------------------------------------------
    Public Function CommClose(intPortID As Integer) As Long
        
    Dim lngStatus As Long
        
        On Error GoTo Routine_Error
    
        If udtPorts(intPortID).blnPortOpen Then
            lngStatus = CloseHandle(udtPorts(intPortID).lngHandle)
        
            If lngStatus = 0 Then
                lngStatus = SetCommError("CommClose (CloseHandle)")
                GoTo Routine_Exit
            End If
        
            udtPorts(intPortID).blnPortOpen = False
        End If
    
        lngStatus = 0
    
    Routine_Exit:
        CommClose = lngStatus
        Exit Function
    
    Routine_Error:
        lngStatus = Err.Number
        With udtCommError
            .lngErrorCode = lngStatus
            .strFunction = "CommClose"
            .strErrorMessage = Err.Description
        End With
        Resume Routine_Exit
    End Function
    
    '-------------------------------------------------------------------------------
    ' CommFlush - Flush the send and receive serial port buffers.
    '
    ' Parameters:
    '   intPortID   - Port ID used when port was opened.
    '
    ' Returns:
    '   Error Code  - 0 = No Error.
    '-------------------------------------------------------------------------------
    Public Function CommFlush(intPortID As Integer) As Long
        
    Dim lngStatus As Long
        
        On Error GoTo Routine_Error
    
        lngStatus = PurgeComm(udtPorts(intPortID).lngHandle, PURGE_TXABORT Or _
            PURGE_RXABORT Or PURGE_TXCLEAR Or PURGE_RXCLEAR)
    
        If lngStatus = 0 Then
            lngStatus = SetCommError("CommFlush (PurgeComm)")
            GoTo Routine_Exit
        End If
    
        lngStatus = 0
    
    Routine_Exit:
        CommFlush = lngStatus
        Exit Function
    
    Routine_Error:
        lngStatus = Err.Number
        With udtCommError
            .lngErrorCode = lngStatus
            .strFunction = "CommFlush"
            .strErrorMessage = Err.Description
        End With
        Resume Routine_Exit
    End Function
    
    '-------------------------------------------------------------------------------
    ' CommRead - Read serial port input buffer.
    '
    ' Parameters:
    '   intPortID   - Port ID used when port was opened.
    '   strData     - Data buffer.
    '   lngSize     - Maximum number of bytes to be read.
    '
    ' Returns:
    '   Error Code  - 0 = No Error.
    '-------------------------------------------------------------------------------
    Public Function CommRead(intPortID As Integer, strData As String, _
        lngSize As Long) As Long
    
    Dim lngStatus As Long
    Dim lngRdSize As Long, lngBytesRead As Long
    Dim lngRdStatus As Long, strRdBuffer As String * 1024
    Dim lngErrorFlags As Long, udtCommStat As COMSTAT
        
        On Error GoTo Routine_Error
    
        strData = ""
        lngBytesRead = 0
        DoEvents
        
        ' Clear any previous errors and get current status.
        lngStatus = ClearCommError(udtPorts(intPortID).lngHandle, lngErrorFlags, _
            udtCommStat)
    
        If lngStatus = 0 Then
            lngBytesRead = -1
            lngStatus = SetCommError("CommRead (ClearCommError)")
            GoTo Routine_Exit
        End If
            
        If udtCommStat.cbInQue > 0 Then
            If udtCommStat.cbInQue > lngSize Then
                lngRdSize = udtCommStat.cbInQue
            Else
                lngRdSize = lngSize
            End If
        Else
            lngRdSize = 0
        End If
    
        If lngRdSize Then
            lngRdStatus = ReadFile(udtPorts(intPortID).lngHandle, strRdBuffer, _
                lngRdSize, lngBytesRead, udtCommOverlap)
    
            If lngRdStatus = 0 Then
                lngStatus = GetLastError
                If lngStatus = ERROR_IO_PENDING Then
                    ' Wait for read to complete.
                    ' This function will timeout according to the
                    ' COMMTIMEOUTS.ReadTotalTimeoutConstant variable.
                    ' Every time it times out, check for port errors.
    
                    ' Loop until operation is complete.
                    While GetOverlappedResult(udtPorts(intPortID).lngHandle, _
                        udtCommOverlap, lngBytesRead, True) = 0
                                        
                        lngStatus = GetLastError
                                            
                        If lngStatus <> ERROR_IO_INCOMPLETE Then
                            lngBytesRead = -1
                            lngStatus = SetCommErrorEx( _
                                "CommRead (GetOverlappedResult)", _
                                udtPorts(intPortID).lngHandle)
                            GoTo Routine_Exit
                        End If
                    Wend
                Else
                    ' Some other error occurred.
                    lngBytesRead = -1
                    lngStatus = SetCommErrorEx("CommRead (ReadFile)", _
                        udtPorts(intPortID).lngHandle)
                    GoTo Routine_Exit
                
                End If
            End If
        
            strData = Left$(strRdBuffer, lngBytesRead)
        End If
    
    Routine_Exit:
        CommRead = lngBytesRead
        Exit Function
    
    Routine_Error:
        lngBytesRead = -1
        lngStatus = Err.Number
        With udtCommError
            .lngErrorCode = lngStatus
            .strFunction = "CommRead"
            .strErrorMessage = Err.Description
        End With
        Resume Routine_Exit
    End Function
    
    '-------------------------------------------------------------------------------
    ' CommWrite - Output data to the serial port.
    '
    ' Parameters:
    '   intPortID   - Port ID used when port was opened.
    '   strData     - Data to be transmitted.
    '
    ' Returns:
    '   Error Code  - 0 = No Error.
    '-------------------------------------------------------------------------------
    Public Function CommWrite(intPortID As Integer, strData As String) As Long
        
    Dim i As Integer
    Dim lngStatus As Long, lngSize As Long
    Dim lngWrSize As Long, lngWrStatus As Long
        
        On Error GoTo Routine_Error
        
        ' Get the length of the data.
        lngSize = Len(strData)
    
        ' Output the data.
        lngWrStatus = WriteFile(udtPorts(intPortID).lngHandle, strData, lngSize, _
            lngWrSize, udtCommOverlap)
    
        ' Note that normally the following code will not execute because the driver
        ' caches write operations. Small I/O requests (up to several thousand bytes)
        ' will normally be accepted immediately and WriteFile will return true even
        ' though an overlapped operation was specified.
            
        DoEvents
        
        If lngWrStatus = 0 Then
            lngStatus = GetLastError
            If lngStatus = 0 Then
                GoTo Routine_Exit
            ElseIf lngStatus = ERROR_IO_PENDING Then
                ' We should wait for the completion of the write operation so we know
                ' if it worked or not.
                '
                ' This is only one way to do this. It might be beneficial to place the
                ' writing operation in a separate thread so that blocking on completion
                ' will not negatively affect the responsiveness of the UI.
                '
                ' If the write takes long enough to complete, this function will timeout
                ' according to the CommTimeOuts.WriteTotalTimeoutConstant variable.
                ' At that time we can check for errors and then wait some more.
    
                ' Loop until operation is complete.
                While GetOverlappedResult(udtPorts(intPortID).lngHandle, _
                    udtCommOverlap, lngWrSize, True) = 0
                                    
                    lngStatus = GetLastError
                                        
                    If lngStatus <> ERROR_IO_INCOMPLETE Then
                        lngStatus = SetCommErrorEx( _
                            "CommWrite (GetOverlappedResult)", _
                            udtPorts(intPortID).lngHandle)
                        GoTo Routine_Exit
                    End If
                Wend
            Else
                ' Some other error occurred.
                lngWrSize = -1
                        
                lngStatus = SetCommErrorEx("CommWrite (WriteFile)", _
                    udtPorts(intPortID).lngHandle)
                GoTo Routine_Exit
            
            End If
        End If
        
        For i = 1 To 10
            DoEvents
        Next
        
    Routine_Exit:
        CommWrite = lngWrSize
        Exit Function
    
    Routine_Error:
        lngStatus = Err.Number
        With udtCommError
            .lngErrorCode = lngStatus
            .strFunction = "CommWrite"
            .strErrorMessage = Err.Description
        End With
        Resume Routine_Exit
    End Function
    
    '-------------------------------------------------------------------------------
    ' CommGetLine - Get the state of selected serial port control lines.
    '
    ' Parameters:
    '   intPortID   - Port ID used when port was opened.
    '   intLine     - Serial port line. CTS, DSR, RING, RLSD (CD)
    '   blnState    - Returns state of line (Cleared or Set).
    '
    ' Returns:
    '   Error Code  - 0 = No Error.
    '-------------------------------------------------------------------------------
    Public Function CommGetLine(intPortID As Integer, intLine As Integer, _
       blnState As Boolean) As Long
        
    Dim lngStatus As Long
    Dim lngComStatus As Long, lngModemStatus As Long
        
        On Error GoTo Routine_Error
    
        lngStatus = GetCommModemStatus(udtPorts(intPortID).lngHandle, lngModemStatus)
    
        If lngStatus = 0 Then
            lngStatus = SetCommError("CommReadCD (GetCommModemStatus)")
            GoTo Routine_Exit
        End If
    
        If (lngModemStatus And intLine) Then
            blnState = True
        Else
            blnState = False
        End If
            
        lngStatus = 0
            
    Routine_Exit:
        CommGetLine = lngStatus
        Exit Function
    
    Routine_Error:
        lngStatus = Err.Number
        With udtCommError
            .lngErrorCode = lngStatus
            .strFunction = "CommReadCD"
            .strErrorMessage = Err.Description
        End With
        Resume Routine_Exit
    End Function
    
    '-------------------------------------------------------------------------------
    ' CommSetLine - Set the state of selected serial port control lines.
    '
    ' Parameters:
    '   intPortID   - Port ID used when port was opened.
    '   intLine     - Serial port line. BREAK, DTR, RTS
    '                 Note: BREAK actually sets or clears a "break" condition on
    '                 the transmit data line.
    '   blnState    - Sets the state of line (Cleared or Set).
    '
    ' Returns:
    '   Error Code  - 0 = No Error.
    '-------------------------------------------------------------------------------
    Public Function CommSetLine(intPortID As Integer, intLine As Integer, _
       blnState As Boolean) As Long
       
    Dim lngStatus As Long
    Dim lngNewState As Long
        
        On Error GoTo Routine_Error
        
        If intLine = LINE_BREAK Then
            If blnState Then
                lngNewState = SETBREAK
            Else
                lngNewState = CLRBREAK
            End If
        
        ElseIf intLine = LINE_DTR Then
            If blnState Then
                lngNewState = SETDTR
            Else
                lngNewState = CLRDTR
            End If
        
        ElseIf intLine = LINE_RTS Then
            If blnState Then
                lngNewState = SETRTS
            Else
                lngNewState = CLRRTS
            End If
        End If
    
        lngStatus = EscapeCommFunction(udtPorts(intPortID).lngHandle, lngNewState)
    
        If lngStatus = 0 Then
            lngStatus = SetCommError("CommSetLine (EscapeCommFunction)")
            GoTo Routine_Exit
        End If
    
        lngStatus = 0
            
    Routine_Exit:
        CommSetLine = lngStatus
        Exit Function
    
    Routine_Error:
        lngStatus = Err.Number
        With udtCommError
            .lngErrorCode = lngStatus
            .strFunction = "CommSetLine"
            .strErrorMessage = Err.Description
        End With
        Resume Routine_Exit
    End Function
    
    
    
    '-------------------------------------------------------------------------------
    ' CommGetError - Get the last serial port error message.
    '
    ' Parameters:
    '   strMessage  - Error message from last serial port error.
    '
    ' Returns:
    '   Error Code  - Last serial port error code.
    '-------------------------------------------------------------------------------
    Public Function CommGetError(strMessage As String) As Long
        
        With udtCommError
            CommGetError = .lngErrorCode
            strMessage = "Error (" & CStr(.lngErrorCode) & "): " & .strFunction & _
                " - " & .strErrorMessage
        End With
        
    End Function
    
  • Re: Inviare codice "0A" (hex) a shell

    Mod readStatus
     #If VBA7 Then ' Excel 2010 or later
        Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal Milliseconds As LongPtr)
    #Else ' Excel 2007 or earlier
        Public Declare Sub Sleep Lib "kernel32" (ByVal Milliseconds As Long)
    #End If
     
     Public Sub SerialPort_status()
        Dim intPortID As Integer
        Dim lngStatus As Long
        Dim strError  As String
        Dim strData   As String
        Dim hex_word As Variant
    
    
        'imposta la porta COMM
        intPortID = 4
        
        ' Initializza la Communicazione
        lngStatus = CommOpen(intPortID, "COM" & CStr(intPortID), _
            "baud=9600 parity=N data=8 stop=1")
            Debug.Print "Port Opened"
        
        If lngStatus <> 0 Then
        ' Gestione errori.
            lngStatus = CommGetError(strError)
        MsgBox "COM Error: " & strError
        End If
        
        '-------------- Stringa da inviare alla scheda.
        'il codice per interrogare la scheda e ottenere lo stato dei relè è il seguente:
        'FF Ax 00
        
        'il primo numero corrisponde FF
        'il secondo numero corrisponde all'indirizzzo della scheda
        'il terzo numero corrisponde a 00
        '
        'quindi A1 = 161, A2 = 162, A3 =164
        
        strData = Chr$(255) + Chr$(161) + Chr$(0) 'FF A1 00
        
        ' Invia la stringa alla porta seriale.
        lngSize = Len(strData)
        lngStatus = CommWrite(intPortID, strData)
        If lngStatus <> lngSize Then
        ' Gestione errori.
        Debug.Print "ERROR"
        End If
    
        Sleep 20
        ' Riceve massimo 64 bytes in risposta dalla porta seriale.
        lngStatus = CommRead(intPortID, strData, 64)
        If lngStatus > 0 Then
            ' Processa la risposta.
            ' hex_word contiene la risposta sullo stato dei relè
            ' es FFA100000000 dove gli ultimi 8 numeri corrisposndono allo stato di ciascun relè
            
            
            '-------------- Stringa ricevuta dalla scheda.
            hex_word = str_to_hex(strData)
           
            Debug.Print hex_word
            
        ElseIf lngStatus < 0 Then
            ' Gestione errori.
            Debug.Print "ERROR"
        End If
    
        ' Resetta la stringa di controllo.
        lngStatus = CommSetLine(intPortID, LINE_RTS, False)
        lngStatus = CommSetLine(intPortID, LINE_DTR, False)
    
    
    
        ' Close communications.
        Call CommClose(intPortID)
        Debug.Print "Port Closed"
        
    
    End Sub
    
    Function str_to_hex(p_str As Variant) As Variant
        Dim x As Long
        Dim resp As Variant
        Dim tmp As String
        For x = 1 To Len(p_str)
          tmp = Mid$(p_str, x, 1)
          resp = resp & Hex(Asc(tmp))
        Next
        str_to_hex = resp
    End Function
    
    
    
  • Re: Inviare codice "0A" (hex) a shell

    Mod setRelay
     #If VBA7 Then ' Excel 2010 or later
        Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal Milliseconds As LongPtr)
    #Else ' Excel 2007 or earlier
        Public Declare Sub Sleep Lib "kernel32" (ByVal Milliseconds As Long)
    #End If
     
     Public Sub SerialPort_set(relayNumber, relayState)
        Dim intPortID As Integer
        Dim lngStatus As Long
        Dim strError  As String
        Dim strData   As String
        Dim hex_word As Variant
    
        intPortID = 4 'numero della porta COMM che si sta utilizzando
        ' Initialize Communications
        lngStatus = CommOpen(intPortID, "COM" & CStr(intPortID), _
            "baud=9600 parity=N data=8 stop=1")
            Debug.Print "Port Opened"
        
        If lngStatus <> 0 Then
        ' Handle error.
            lngStatus = CommGetError(strError)
        MsgBox "COM Error: " & strError
        End If
        
    
        ' Set modem control lines.
        'lngStatus = CommSetLine(intPortID, LINE_RTS, False)
        'lngStatus = CommSetLine(intPortID, LINE_DTR, False)
        strData = Chr$(255) + Chr$(relayNumber) + Chr$(relayState)
        ' Write data to serial port.
        lngSize = Len(strData)
        lngStatus = CommWrite(intPortID, strData)
        If lngStatus <> lngSize Then
        ' Handle error.
        Debug.Print "ERROR"
        End If
    
        ' Read maximum of 64 bytes from serial port.
    
        ' Reset modem control lines.
        lngStatus = CommSetLine(intPortID, LINE_RTS, False)
        lngStatus = CommSetLine(intPortID, LINE_DTR, False)
    
    
    
        ' Close communications.
        Call CommClose(intPortID)
        Debug.Print "Port Closed"
        
    
    End Sub
    
    Function str_to_hex(p_str As Variant) As Variant
        Dim x As Long
        Dim resp As Variant
        Dim tmp As String
        For x = 1 To Len(p_str)
          tmp = Mid$(p_str, x, 1)
          resp = resp & Hex(Asc(tmp))
        Next
        str_to_hex = resp
    End Function
    
    
  • Re: Inviare codice "0A" (hex) a shell

    Poi ho adattato il tutto alle mie esisgenze.
Devi accedere o registrarti per scrivere nel forum
66 risposte