【问题标题】:Reading FTDI TTL-232R to USB将 FTDI TTL-232R 读取到 USB
【发布时间】:2016-04-19 08:11:59
【问题描述】:

我正在尝试使用 FTDI RS232 到 USB 5V 可编程电缆通过 USB 读取 RS232 输入。使用 FTD2XX_NET 库。连接到每 10 秒发送一次电报的智能电表。

似乎一切正常。我可以并且已经设置了波特率、数据位、停止位等。但是在读取数据时它会停止。下面的代码 sn-p 只是在没有数据的情况下传递。我在电子方面没有经验,所以这有点超出我的舒适区。

我的问题。

  • FlowControl 如何影响设备的读取能力。
  • numBytesAvailable 如何影响设备的读取能力。
  • numBytesRead 如何影响设备的读取能力。

我不知道上述属性的变量的设置。我根本不知道我会收到多少数据。任何帮助将不胜感激。

在此处找到的电缆数据表: http://www.ftdichip.com/Support/Documents/DataSheets/Cables/DS_TTL-232R_CABLES.pdf

智能电表数据表可在此处找到: http://files.domoticaforum.eu/uploads/Smartmetering/DSMR%20v4.0%20final%20P1.pdf

enter code here

namespace P1_reader
{
class Program
{

    static void Main(string[] args)
    {
       if (args.Count() > 0) 
         { 
             ExecuteOption(args[0]); 
         } 
         else 
         { 
             string option; 
             do 
             { 
                 var menu = new StringBuilder(); 
                 menu.AppendLine("(1) ListenForData");
                 menu.AppendLine("(x) Exit"); 

                 System.Console.WriteLine(menu); 
                 option = System.Console.ReadKey().KeyChar.ToString();                     
                 System.Console.WriteLine(); 
                 ExecuteOption(option); 
                 System.Console.WriteLine(); 
             } while (option.ToLower() != "x"); 
         }
    }

     private static void ExecuteOption(string option)
     { 
         switch (option.ToLower()) 
         { 
             case "1": 
                 ListenForData(); 
                 break;
             case "x": 
                 break; 
             default: 
                 System.Console.WriteLine("That's not an option!"); 
                 break; 
         } 
     }

    private static void ListenForData()
    {
        try
        {
            UInt32 ftdiDeviceCount = 0;
            FTDI.FT_STATUS ftStatus = FTDI.FT_STATUS.FT_OK;

            FTDI myFtdiDevice = new FTDI();

            ftStatus = myFtdiDevice.GetNumberOfDevices(ref ftdiDeviceCount);

            if (ftStatus == FTDI.FT_STATUS.FT_OK)
            {
                Console.WriteLine("Number of FTDI devices: " + ftdiDeviceCount.ToString());
                Console.WriteLine("");
            }
            else
            {
                Console.WriteLine("Failed to get number of devices (error " + ftStatus.ToString() + ")");
                Console.ReadKey();
                return;
            }

            if (ftdiDeviceCount == 0)
            {
                Console.WriteLine("Failed to get number of devices (error " + ftStatus.ToString() + ")");
                Console.ReadKey();
                return;
            }

            FTDI.FT_DEVICE_INFO_NODE[] ftdiDeviceList = new FTDI.FT_DEVICE_INFO_NODE[ftdiDeviceCount];

            ftStatus = myFtdiDevice.GetDeviceList(ftdiDeviceList);

            if (ftStatus == FTDI.FT_STATUS.FT_OK)
            {
                for (UInt32 i = 0; i < ftdiDeviceCount; i++)
                {
                    Console.WriteLine("Device Index: " + i.ToString());
                    Console.WriteLine("Flags: " + String.Format("{0:x}", ftdiDeviceList[i].Flags));
                    Console.WriteLine("Type: " + ftdiDeviceList[i].Type.ToString());
                    Console.WriteLine("ID: " + String.Format("{0:x}", ftdiDeviceList[i].ID));
                    Console.WriteLine("Location ID: " + String.Format("{0:x}", ftdiDeviceList[i].LocId));
                    Console.WriteLine("Serial Number: " + ftdiDeviceList[i].SerialNumber.ToString());
                    Console.WriteLine("Description: " + ftdiDeviceList[i].Description.ToString());
                    Console.WriteLine("");
                }
            }

            ftStatus = myFtdiDevice.OpenBySerialNumber(ftdiDeviceList[0].SerialNumber);
            if (ftStatus != FTDI.FT_STATUS.FT_OK)
            {
                Console.WriteLine("Failed to open device (error " + ftStatus.ToString() + ")");
                Console.ReadKey();
                return;
            }

            ftStatus = myFtdiDevice.SetBaudRate(115200);
            if (ftStatus != FTDI.FT_STATUS.FT_OK)
            {
                Console.WriteLine("Failed to set Baud rate (error " + ftStatus.ToString() + ")");
                Console.ReadKey();
                return;
            }

            ftStatus = myFtdiDevice.SetDataCharacteristics(FTDI.FT_DATA_BITS.FT_BITS_8, FTDI.FT_STOP_BITS.FT_STOP_BITS_1, FTDI.FT_PARITY.FT_PARITY_NONE);

            if (ftStatus != FTDI.FT_STATUS.FT_OK)
            {
                Console.WriteLine("Failed to set data characteristics (error " + ftStatus.ToString() + ")");
                Console.ReadKey();
                return;
            }

            ftStatus = myFtdiDevice.SetFlowControl(FTDI.FT_FLOW_CONTROL.FT_FLOW_RTS_CTS, 0x11, 0x13);
            if (ftStatus != FTDI.FT_STATUS.FT_OK)
            {
                Console.WriteLine("Failed to set flow control (error " + ftStatus.ToString() + ")");
                Console.ReadKey();
                return;
            }

            // Set read timeout to 12 seconds, write timeout to infinite
            ftStatus = myFtdiDevice.SetTimeouts(12000, 0);
            if (ftStatus != FTDI.FT_STATUS.FT_OK)
            {
                Console.WriteLine("Failed to set timeouts (error " + ftStatus.ToString() + ")");
                Console.ReadKey();
                return;
            }

            UInt32 numBytesAvailable = 0;

            ftStatus = myFtdiDevice.GetRxBytesAvailable(ref numBytesAvailable);
            if (ftStatus != FTDI.FT_STATUS.FT_OK)
            {
                Console.WriteLine("Failed to get number of bytes available to read (error " + ftStatus.ToString() + ")");
                Console.ReadKey();
                return;
            }
            Thread.Sleep(10);

            string readData = "";
            UInt32 numBytesRead = 0;
            byte[] dataBuffer = new byte[1024];

            ftStatus = myFtdiDevice.Read(out readData, numBytesAvailable, ref numBytesRead);
            while (readData == "")
            {
                ftStatus = myFtdiDevice.Read(out readData, numBytesAvailable, ref numBytesRead);
            }

            if (ftStatus != FTDI.FT_STATUS.FT_OK)
            {
                Console.WriteLine("Failed to read data (error " + ftStatus.ToString() + ")");
                Console.ReadKey();
                return;
            }
            Console.WriteLine(readData);

            ftStatus = myFtdiDevice.Close();

            Console.WriteLine("Press any key to continue.");
            Console.ReadKey();
            return;
        }
        catch
        {
            Console.WriteLine("Something realy bad happened..");
        }
    }

}
}

【问题讨论】:

    标签: c# .net serial-port ftdi


    【解决方案1】:

    FTDI 驱动程序有一个内部缓冲区,并自动将从 RX 数据线读取的任何数据复制到此缓冲区中。对GetRxBytesAvailable() 的调用将告诉您内部缓冲区中有多少数据,即芯片已读取多少数据。

    Read() 的调用是阻塞的,它会等到它达到您请求的字节数后再返回。如果我没记错的话,您可以使用 API 设置读取超时。

    您希望在 while 循环中调用 GetRxBytesAvailable(),例如

    UInt32 numBytesAvailable = 0;
    
    while (true)
    {
        ftStatus = myFtdiDevice.GetRxBytesAvailable(ref numBytesAvailable);
        if (ftStatus != FTDI.FT_STATUS.FT_OK)
        {
            Console.WriteLine("Failed to get number of bytes available to read (error " + ftStatus.ToString() + ")");
            Console.ReadKey();
            break;
        }
    
        string readData = "";
        UInt32 numBytesRead = 0;
        byte[] dataBuffer = new byte[1024];    
    
        // TODO: check so you don't over your buffer.
        ftStatus = myFtdiDevice.Read(out readData, numBytesAvailable, ref numBytesRead);
    
        ProcessData(readData);
    
        Thread.Sleep(10000); // Sleep 10 seconds.
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多