• 0

Outputting +5v to serial port c++


Question

hi there

was just wondering, i want to output a +5v signal to a specific pin of a serial port for the period that a certain set of conditions is met. anything ive found on serial communication goes in far too deep and starts about sending and recieving. is there a simple way of outputting this +5v signal.

many thanks

wes

Link to comment
https://www.neowin.net/forum/topic/159492-outputting-5v-to-serial-port-c/
Share on other sites

12 answers to this question

Recommended Posts

  • 0

I don't think you can output to a specific pin.

As far as I know, all you can do is write to it using the normal methods (fopen etc) which will output a signal on the tx pin. Any proper OS will prevent you from being able to directly talk to the hardware anyway, unless you write a driver for it.

Edit : I'm not 100% on this, so don't take it as gospel. :ninja:

Edited by hornett
  • 0

I don't have DevStudio installed on this machine to check this, but I think you'll need CreateFile, WriteFile and CloseHandle.

You can then do something like

unsigned char data=0xFF;
int ns;

WriteFile(hCom,&data,1,&ns,NULL);

hCom being the handle to the com port you want, &data being an unsigned char containing 0xFF, and ns returns the actual number of chars sent (this should be 1 in this case). The 1 in that statement represents the number of bytes to send.

Off the top of my head I can't remember how it all works, I always have to look this stuff up in MSDN because my memory is rubbish.

Edited by hornett
  • 0

Here's some code from MSDN. Hopefully you're writing on Windows. :) We should make that a requirement for posts, too. Language and platform.

/***********************************************************************
Module Name:
  port.c

***********************************************************************/

#include <windows.h>
#include "tty.h"

/***********************************************************************

  PortInitialize (LPTSTR lpszPortName)

***********************************************************************/
BOOL PortInitialize (LPTSTR lpszPortName)
{
  DWORD dwError,
        dwThreadID;
  DCB PortDCB;
  COMMTIMEOUTS CommTimeouts;

  // Open the serial port.
  hPort = CreateFile (lpszPortName, // Pointer to the name of the port
                      GENERIC_READ | GENERIC_WRITE,
                                    // Access (read/write) mode
                      0,            // Share mode
                      NULL,         // Pointer to the security attribute
                      OPEN_EXISTING,// How to open the serial port
                      0,            // Port attributes
                      NULL);        // Handle to port with attribute
                                    // to copy

  // If it fails to open the port, return FALSE.
  if ( hPort == INVALID_HANDLE_VALUE ) 
  {
    // Could not open the port.
    MessageBox (hMainWnd, TEXT("Unable to open the port"), 
                TEXT("Error"), MB_OK);
    dwError = GetLastError ();
    return FALSE;
  }

  PortDCB.DCBlength = sizeof (DCB);     

  // Get the default port setting information.
  GetCommState (hPort, &PortDCB);

  // Change the DCB structure settings.
  PortDCB.BaudRate = 9600;              // Current baud 
  PortDCB.fBinary = TRUE;               // Binary mode; no EOF check 
  PortDCB.fParity = TRUE;               // Enable parity checking. 
  PortDCB.fOutxCtsFlow = FALSE;         // No CTS output flow control 
  PortDCB.fOutxDsrFlow = FALSE;         // No DSR output flow control 
  PortDCB.fDtrControl = DTR_CONTROL_ENABLE; 
                                        // DTR flow control type 
  PortDCB.fDsrSensitivity = FALSE;      // DSR sensitivity 
  PortDCB.fTXContinueOnXoff = TRUE;     // XOFF continues Tx 
  PortDCB.fOutX = FALSE;                // No XON/XOFF out flow control 
  PortDCB.fInX = FALSE;                 // No XON/XOFF in flow control 
  PortDCB.fErrorChar = FALSE;           // Disable error replacement. 
  PortDCB.fNull = FALSE;                // Disable null stripping. 
  PortDCB.fRtsControl = RTS_CONTROL_ENABLE; 
                                        // RTS flow control 
  PortDCB.fAbortOnError = FALSE;        // Do not abort reads/writes on 
                                        // error.
  PortDCB.ByteSize = 8;                 // Number of bits/bytes, 4-8 
  PortDCB.Parity = NOPARITY;            // 0-4=no,odd,even,mark,space 
  PortDCB.StopBits = ONESTOPBIT;        // 0,1,2 = 1, 1.5, 2 

  // Configure the port according to the specifications of the DCB 
  // structure.
  if (!SetCommState (hPort, &PortDCB))
  {
    // Could not create the read thread.
    MessageBox (hMainWnd, TEXT("Unable to configure the serial port"), 
                TEXT("Error"), MB_OK);
    dwError = GetLastError ();
    return FALSE;
  }

  // Retrieve the time-out parameters for all read and write operations
  // on the port. 
  GetCommTimeouts (hPort, &CommTimeouts);

  // Change the COMMTIMEOUTS structure settings.
  CommTimeouts.ReadIntervalTimeout = MAXDWORD;  
  CommTimeouts.ReadTotalTimeoutMultiplier = 0;  
  CommTimeouts.ReadTotalTimeoutConstant = 0;    
  CommTimeouts.WriteTotalTimeoutMultiplier = 10;  
  CommTimeouts.WriteTotalTimeoutConstant = 1000;    

  // Set the time-out parameters for all read and write operations
  // on the port. 
  if (!SetCommTimeouts (hPort, &CommTimeouts))
  {
    // Could not create the read thread.
    MessageBox (hMainWnd, TEXT("Unable to set the time-out parameters"), 
                TEXT("Error"), MB_OK);
    dwError = GetLastError ();
    return FALSE;
  }

  // Direct the port to perform extended functions SETDTR and SETRTS.
  // SETDTR: Sends the DTR (data-terminal-ready) signal.
  // SETRTS: Sends the RTS (request-to-send) signal. 
  EscapeCommFunction (hPort, SETDTR);
  EscapeCommFunction (hPort, SETRTS);

  // Create a read thread for reading data from the communication port.
  if (hReadThread = CreateThread (NULL, 0, PortReadThread, 0, 0, 
                                  &dwThreadID))
  {
    CloseHandle (hReadThread);
  }
  else
  {
    // Could not create the read thread.
    MessageBox (hMainWnd, TEXT("Unable to create the read thread"), 
                TEXT("Error"), MB_OK);
    dwError = GetLastError ();
    return FALSE;
  }

  return TRUE;
}


/***********************************************************************

  PortWrite (BYTE Byte)

***********************************************************************/
void PortWrite (BYTE Byte)
{
  DWORD dwError,
        dwNumBytesWritten;

  if (!WriteFile (hPort,              // Port handle
                  &Byte,              // Pointer to the data to write 
                  1,                  // Number of bytes to write
                  &dwNumBytesWritten, // Pointer to the number of bytes 
                                      // written
                  NULL))              // Must be NULL for Windows CE
  {
    // WriteFile failed. Report error.
    dwError = GetLastError ();
  }
}



/***********************************************************************

  PortReadThread (LPVOID lpvoid)

***********************************************************************/
DWORD PortReadThread (LPVOID lpvoid)
{
  BYTE Byte;
  DWORD dwCommModemStatus,
        dwBytesTransferred;
  
  // Specify a set of events to be monitored for the port.
  SetCommMask (hPort, EV_RXCHAR | EV_CTS | EV_DSR | EV_RLSD | EV_RING);

  while (hPort != INVALID_HANDLE_VALUE) 
  {
    // Wait for an event to occur for the port.
    WaitCommEvent (hPort, &dwCommModemStatus, 0);

    // Re-specify the set of events to be monitored for the port.
    SetCommMask (hPort, EV_RXCHAR | EV_CTS | EV_DSR | EV_RING);

    if (dwCommModemStatus & EV_RXCHAR) 
    {
      // Loop for waiting for the data.
      do 
      {
        // Read the data from the serial port.
        ReadFile (hPort, &Byte, 1, &dwBytesTransferred, 0);

        // Display the data read.
        if (dwBytesTransferred == 1)
          ProcessChar (Byte);

      } while (dwBytesTransferred == 1);
    }

    // Retrieve modem control-register values.
    GetCommModemStatus (hPort, &dwCommModemStatus);

    // Set the indicator lights.
    SetLightIndicators (dwCommModemStatus);
  }

  return 0;
}


/***********************************************************************

  PortClose (HANDLE hCommPort)

***********************************************************************/
BOOL PortClose (HANDLE hCommPort)
{
  DWORD dwError;

  if (hCommPort != INVALID_HANDLE_VALUE)
  {
    // Close the communication port.
    if (!CloseHandle (hCommPort))
    {
      dwError = GetLastError ();
      return FALSE;
    }
    else
    {
      hCommPort = INVALID_HANDLE_VALUE;
      return TRUE;
    }
  }

  return FALSE;
}

  • 0

ok ive had a go but im a bit confused at the errors here is my code and the errors i get

#include <windows.h>

DCB PortDCB;

HANDLE hPort;

LPTSTR lpszPortName = TEXT("COM1");

hport = CreateFile(lpszPortName, // Pointer to the name of the port //error C2501: 'hport' : missing decl-specifiers

GENERIC_WRITE, // Access (read/write) mode

0, // Share mode

NULL, // Pointer to the security attribute

OPEN_EXISTING, // How to open the serial port

0, // Port attributes

NULL); // Handle to port with attribute to copy //error C2440: 'initializing' : cannot convert from 'void *' to 'int' This conversion requires a reinterpret_cast, a C-style cast or function-style cast

unsigned char data=0xFF;

int ns;

WriteFile("COM1", //error C2065: 'COM1' : undeclared identifier

&data,

1,

&ns,

NULL); //error C2501: 'WriteFile' : missing decl-specifiers

// error C2040: 'WriteFile' : 'int' differs in levels of indirection from 'int (void *,const void *,unsigned long,unsigned long *,struct _OVERLAPPED *)'

error executing cl.exe.

Any suggestions would be appreciated

wes

BTW im using win XP MSVC++ 5.0

  • 0

Use the parallel port instead since it's ttl based you can output +5v to any of the data register pins just use inpout32.dll found anywhere on the net for free and output the hex value to the adrees of you base parallel port (usually 888 in decimal or 378 in hex).

first declare the dll:

Public Declare Function Inp Lib "inpout32.dll" _
Alias "Inp32" (ByVal PortAddress As Integer) As Integer
Public Declare Sub Out Lib "inpout32.dll" _
Alias "Out32" (ByVal PortAddress As Integer, ByVal Value As Integer)

then you can output or even read those pins wich are I/O like this:

out <port adress in decimal> <value in decimal (255 all 8 lines high, 0 all 8 lines low)>

since each of the three registers of the parallel port are comprised of 8 bits outputing a 255 would set all 8 data lines to high (+5v)

let's say you'd whant to output a high (+5) to pin 2 (data 0) of the parallel port wich has a base adress of 888 (378 hex), it's as simple as:

You have 8 data lines and whant to set the first bit (bit 0) to one then you'll output 1 in decimal wich is 00000001 in binary then data line 0 of the data register wich is pin 2 of the port will be high.

out 888 1

one parallel port is comprised as i said of three registers wich are the data register, the control register and the status register and addressing them you need to know the base adress of the port (wich you can see in the bios or in device manager and is usually 378 in hexadecimal) and the other two adresses are base+1 and base+2. Some lines are bidirectional and can be used for data I/O others are inverted.

Be carefull and use optocoupling or risk frying your port, also you could use one of those port expander cards and not your motherboard's port. And remenber the the port only output's like 12mA or something so don't use it for anything that will drain to much current.

There are plenty of resources about this around so google it ;) hope to have helped you out :woot:

  • 0

Yes, you're far better off using the parallel port, as suggested by underscorebios.

I would just like to stress the fact that the parallel port has NO protection whatsoever (meaning it is very easy to do permanent damage to your motherboard), nor is it capable of delivering any useful amount of current (about 5mA at most -- sufficient for TTL data transfers, but not much else).

The serial port can deliver slightly more, but it does not use +5V. The serial port is rated as +/-12V (Varies a lot). To get +5V you would need to hook up a voltage regulator (such as the 78L05 (And a MAX2xx if you wanted to do bidirectional TTL). The parallel port is definitely the easiest to control, as long as you are aware of its limitations. If all you want to do is power some LEDs or something, it'll be fine. Otherwise, go for an external power supply, or use the one in your PC (+/-12, +/-5V readily available!), and just use the port to turn it on/off.

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.