Технический форум по робототехнике.
Madf » 09 июн 2013, 12:29
Алоха!
Пытаюсь тут одну "игрушку" сделать, но всё никак не приду к конечному результату, никак не определюсь с выводом данных (на чем и как лучше реализовывать). Решил делать через USB (т.к. устройство должно ещё будет в будущем заряжаться, портативное). Нужно быстро в компьютер передавать до 8МБ данных. Рассчитывал, что передаваться они должны секунд за 8-10 (в среднем 1МБ/сек). Решил поиграться параллельным вводом/выводом FT245, по датащиту может передавать как раз на нужной скорости.
Собрал пока простенькое устройство МК+FT245<>USB и теперь пытаюсь замерить скорость передачи данных. Пишу на VB6, пока максимум, что получилось достичь используя MSCOMM (в вин 7) при передачи 1МБ - это 278 КБ/сек (около 2781 Kbps), а нужно в 4-5 раз шустрее. Судя по осциллографу, запас пропускной способности у МК предостаточно. Т.е. уперся в потолок пропускной способности стандартного драйвера. Теперь пытаюсь попробовать сделать на D2xx драйвере (должно работать шустрее) и в очередной раз сталкиваясь с продукцией FTDI низкого уровня - возникает куча вопросов и всё работает как-то через...в общем перерыл весь инет, их сайт и пока стабильного работающего результата не нашел. Везде либо одни и те же куски кода на Си (не работающие) или примеры демонстрирующие совершено другое (не то, что нужно).
В общем у меня получилось на D2xx: про инициализировать устройство (сразу к нему привязаться), подключиться, отправить данные на устройство; а вот принять - нет. С приёмом данных выходит какая-то чехарда, даже если всё проходит без ошибок, то данные всё равно не читаются из порта.
Никто не пробовал разбираться с D2xx драйверами под винду, как правильно читать данные из порта, есть у кого-нить работающий код?
AndreiSk » 09 июн 2013, 14:45
FT245 эт которая по 8 каналам сразу или обычный UART?
ЗЫ. VB6 безумное старье, переходи на C#.
Visual studio 98 (где vb6) уже никак не ставится на W7 x64...
Madf » 09 июн 2013, 14:56
Да, с 8 каналами (параллельная).
зы: Не возникло никаких проблем с установкой VB6, работает как часы, а вот пробовал на семерку (винду х64) ставить все последующие студии (более новые) - не поставились (забил). С горя попробовал пуребэйсик, так там с стандартным (последовательным) обменом вообще тормоза. Да не суть, мне бы код работающий или чтобы кто-нить объяснил, последовательность действий чтения...
AndreiSk » 09 июн 2013, 15:39
Я делал три года назад,
но ничерта уже не помню.
Вот этот кусочек вижу на стороне МК
#define FTDI_RXF 2 // IN
#define FTDI_WR 4 // OUT
#define FTDI_RD 5 // OUT
#define FTDI_SND 7 // OUT
ты их используешь как то? Это оно?
Это пины которые придется дергать чтобы передать на комп
Добавлено спустя 6 минут 21 секунду:
Вспомнил чуток. Значит если делать все по даташиту, с проверками там всякими,
скорость будет невелика, наверное ты ее и достиг.
Там когда посылаешь,
у меня делается вот так:
1) что то все что связано с TXE закомментарено.. не знаю зачем (код мой)
2) вижу, что выставляю все 8 линий и дергаю WR туда-сюда без всяких проверок,
потом SND дергаю в самом конце.
Тогда можно достичь наверное пары мегабайт в сек, не больше.
Но на комп может приходить побитое...
Пиши в скайп, сброшу код, он огромен, но вырезать не хочу...
Добавлено спустя 1 минуту 49 секунд:
с d2xx работал под xp, потом VCP меня вполне устраивал (под W7)
Madf » 09 июн 2013, 16:12
использую, похоже, только:
rxf - in (по умолчанию надо в чипе отключить бит автоматической спячки, чтобы было меньше геморроя с просыпанием)
txe - in
rd - out
wr - out
с этим проблем нет, это всё работает
проблема приема данных с стороны компа - "FT_read"
Добавлено спустя 31 минуту 45 секунд:
вот на VCP уперся в потолок, народ в инете пишет, что на d2xx можно получить больше
хочу попробовать поработать с этим драйвером, посмотреть на производительность
на счет скорости, судя по временным диаграммам и хар-ам USB заявленным на это чип, она должна тянуть 10-12Мбит/сек, пока (судя по тому, что я вижу) скорость используется на порядок меньше от возможностей (должно в раза 3-9 быстрее быть)
AndreiSk » 09 июн 2013, 16:13
а у тебя обычный UART FTDI есть? Проверь сначала на нем все процедуры чтения-записи, а потом переключишься на 8 канальный.
Ну не знаю чем еще помочь, там вроде никаких граблей не было.
У меня c#, использовал вот этот класс. Сейчас использую обычный COM порт,
т.к. суперскоростей мне не надо уже...
ЗЫ. Видео гонять хочешь?
- Вложения
-
- FTDIUsage.zip
- (1.84 КиБ) Скачиваний: 0
Madf » 09 июн 2013, 17:43
нет, не видео
просто думал сделать GPS-логер на флешь память, а потом данные сгружать по USB на комп (понятно, что хотелось чтобы процесс скидывания накопленных данных происходил быстро, а не копировался 2 минуты (как-то дико по сейчашним меркам 8 МБ так долго перемещать))
а если бы получилось быстро передавать поток, то можно было уже развивать тему и для других идей
elmot » 09 июн 2013, 23:52
ГПС логгеры с карточкой в китае стоят $30. Смысла делать самому - никакого.
Madf » 10 июн 2013, 12:22
Они все убогие и не предоставляют полностью интересующий функционал.
Так вот возвращаюсь к проблеме (более детально), использую простой код вытягивания данных (алгоритм на просторах инета):
- Код: Выделить всё • Развернуть
Dim lpszBuffer As String
Dim lngBytesReturned As Long
Dim lngBufferSize As Long
Dim lngBytesToRead As Long
...
If FT_GetQueueStatus(lngHandle, lngBytesToRead) = FT_OK Then LoggerList.AddItem "GetQueueStatus OK"
If lngBytesToRead > 0 Then
lngBufferSize = lngBytesToRead
If FT_Read(lngHandle, lpszBuffer, lngBufferSize, lngBytesReturned) = FT_OK Then LoggerList.AddItem "Read OK"
End If
...
Идет постоянный опрос "GetQueueStatus" переменой "lngBytesToRead", когда эта переменная отличная от нуля - значит в буфере есть данные. Как только данные появляются в буфере, то сразу переходим на чтения их "FT_Read". Всё очень просто. Но в реальности: все операции проходят с статусом "ОК", в буфере есть данные, а когда читаю их, то строковая переменная "lpszBuffer" остается всегда пустой.
Пробовал менять её с строковой, на массив байтовый - тишина.
Пробовал "FT_Read" несколько раз опрашивать (ну малоли там данные не сразу притекают из буфера) - тишина.
Не работает "FT_Read" - вообще.
Dmitry__ » 10 июн 2013, 13:04
Я вообще эту хрень FT245 не понял. Крутил, вертел, потом забил на нее, перешел на визнетовские модули и получил около 20 мбит поток.
http://www.efo.ru/doc/Wiznet/Wiznet.pl?2759С ftdi232 вопросов нет, и самоделки работали и покупные, в vb6 использовал только vcp.
Правда, очень долго допиливал исходники на дельфи - работу с коммпортом, чтоб заработало в vb6. Получившееся простыня инициализации компорта просто убивает
Гугление по ft245 показывает, что не зря я плюнул на них.
Со скоростью, попробуй отключить фифо буфер в ком., как тут советуют:
http://caxapa.ru/83576.htmlА лучше - выброси
Madf » 10 июн 2013, 13:27
Спасибо, попробую.
В VB6 + VCP - проблем нет (простыни с инициализацией порта не заметил, всё просто), только быстрее 278 КБ/сек не получается. (
Визнет - это же сетка, как-то вообще не в тему..
У меня с FTDI дружба как-то с самого начала не заладилась, Ванкулум второй у них с виду вкусный, но документация и поддержка у них - отвратная! Примеры все с ошибками, работают с глюками. Т.е. все средства разработки ужас - забил. Нормально работает только готовые, закрытые изделия типа готовых чипов 232..может есть какие-нить конкуретны типа цирус лоджика?
Dmitry__ » 10 июн 2013, 13:35
Madf писал(а):В VB6 + VCP - проблем нет (простыни с инициализацией порта не заметил, всё просто)
Я через api делал, а там - простыня:
- Код: Выделить всё • Развернуть
Attribute VB_Name = "SerialPort"
Option Explicit
Global XpsHandle As Long 'манипулятор
Global XpsPort As String 'порт к которому подкл. Xps
Global bRead(255) As Byte 'приемный/передающий буфер
Global Count_bRead As Long 'колич. принятых байт
Type COMSTAT
fCtsHold As Long
fDsrHold As Long
fRlsdHold As Long
fXoffHold As Long
fXoffSent As Long
fEof As Long
fTxim As Long
fReserved As Long
cbInQue As Long
cbOutQue As Long
End Type
Type COMMTIMEOUTS
ReadIntervalTimeout As Long
ReadTotalTimeoutMultiplier As Long
ReadTotalTimeoutConstant As Long
WriteTotalTimeoutMultiplier As Long
WriteTotalTimeoutConstant As Long
End Type
Type DCB
DCBlength As Long
BaudRate As Long
fBinary As Long
fParity As Long
fOutxCtsFlow As Long
fOutxDsrFlow As Long
fDtrControl As Long
fDsrSensitivity As Long
fTXContinueOnXoff As Long
fOutX As Long
fInX As Long
fErrorChar As Long
fNull As Long
fRtsControl As Long
fAbortOnError As Long
fDummy2 As Long
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
End Type
Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Declare Function GetLastError Lib "kernel32" () As Long
Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, ByRef lpBuffer As Byte, ByVal nNumberOfBytesToRead As Long, ByRef lpNumberOfBytesRead As Long, ByVal lpOverlapped As Long) As Long
Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, ByRef lpBuffer As Byte, ByVal nNumberOfBytesToWrite As Long, ByRef lpNumberOfBytesWritten As Long, ByVal lpOverlapped As Long) As Long
Declare Function SetCommTimeouts Lib "kernel32" (ByVal hFile As Long, ByRef lpCommTimeouts As COMMTIMEOUTS) As Long
Declare Function GetCommTimeouts Lib "kernel32" (ByVal hFile As Long, ByRef lpCommTimeouts As COMMTIMEOUTS) As Long
Declare Function BuildCommDCB Lib "kernel32" Alias "BuildCommDCBA" (ByVal lpDef As String, lpDCB As DCB) As Long
Declare Function SetCommState Lib "kernel32" (ByVal hCommDev As Long, ByRef lpDCB As DCB) As Long
Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Declare Function FlushFileBuffers Lib "kernel32" (ByVal hFile As Long) As Long
Function FlushComm(PortHandle As Long)
FlushFileBuffers (PortHandle)
End Function
Function Init_Com(ComPort As String, Comsettings As String) As Boolean
Dim ComSetup As DCB, Answer, Stat As COMSTAT, RetBytes As Long
Dim retval As Long, CtimeOut As COMMTIMEOUTS, BarDCB As DCB
Init_Com = False 'ошибка открытия порта
On Error GoTo handelinitcom
' Open the communications port for read/write (&HC0000000).
' Must specify existing file (3).
XpsHandle = CreateFile(ComPort, &HC0000000, 0, 0&, &H3, 0, 0)
If XpsHandle = -1 Then Exit Function
'Setup Time Outs for com port
CtimeOut.ReadIntervalTimeout = 20
CtimeOut.ReadTotalTimeoutConstant = 1
CtimeOut.ReadTotalTimeoutMultiplier = 1
CtimeOut.WriteTotalTimeoutConstant = 10
CtimeOut.WriteTotalTimeoutMultiplier = 1
retval = SetCommTimeouts(XpsHandle, CtimeOut)
If retval = -1 Then
retval = GetLastError()
MsgBox "Unable to set timeouts for port " & ComPort & " Error: " & retval
Exit Function
End If
retval = BuildCommDCB(Comsettings, BarDCB)
If retval = -1 Then
retval = GetLastError()
MsgBox "Unable to build Comm DCB " & Comsettings & " Error: " & retval
Exit Function
End If
retval = SetCommState(XpsHandle, BarDCB)
If retval = -1 Then
retval = GetLastError()
MsgBox "Unable to set Comm DCB " & Comsettings & " Error: " & retval
Exit Function
End If
Init_Com = True
Exit Function
handelinitcom:
Exit Function
End Function
Function Init_Com2(ComNumber As String, Comsettings As String) As Boolean
On Error GoTo handelinitcom
Dim ComSetup As DCB, Answer, Stat As COMSTAT, RetBytes As Long
Dim retval As Long
Dim CtimeOut As COMMTIMEOUTS, BarDCB As DCB
' Open the communications port for read/write (&HC0000000).
' Must specify existing file (3).
XpsHandle = CreateFile(ComNumber, &HC0000000, 0, 0&, &H3, 0, 0)
If XpsHandle = -1 Then
MsgBox "Нет платы телеметрии:" & ComNumber, 48
Init_Com2 = False
Exit Function
End If
'Setup Time Outs for com port
CtimeOut.ReadIntervalTimeout = 20
CtimeOut.ReadTotalTimeoutConstant = 1
CtimeOut.ReadTotalTimeoutMultiplier = 1
CtimeOut.WriteTotalTimeoutConstant = 10
CtimeOut.WriteTotalTimeoutMultiplier = 1
retval = SetCommTimeouts(XpsHandle, CtimeOut)
If retval = -1 Then
retval = GetLastError()
MsgBox "Unable to set timeouts for port " & ComNumber & " Error: " & retval
retval = CloseHandle(XpsHandle)
Init_Com2 = False
Exit Function
End If
retval = BuildCommDCB(Comsettings, BarDCB)
If retval = -1 Then
retval = GetLastError()
MsgBox "Unable to build Comm DCB " & Comsettings & " Error: " & retval
retval = CloseHandle(XpsHandle)
Init_Com2 = False
Exit Function
End If
retval = SetCommState(XpsHandle, BarDCB)
If retval = -1 Then
retval = GetLastError()
MsgBox "Unable to set Comm DCB " & Comsettings & " Error: " & retval
retval = CloseHandle(XpsHandle)
Init_Com2 = False
Exit Function
End If
Init_Com2 = True
handelinitcom:
Exit Function
End Function
Function WriteCOM32(CounByte As Long)
On Error GoTo handelwritelpt
Dim RetBytes As Long, retval As Long
retval = WriteFile(XpsHandle, bRead(0), CounByte, RetBytes, 0)
Exit Function
handelwritelpt:
Exit Function
End Function
Function SendGoneom(COMString As String)
On Error GoTo handelwritelpt
Dim RetBytes As Long, LenVal As Long
Dim retval As Long
If Len(COMString) > 255 Then
SendGoneom Left$(COMString, 255)
SendGoneom Right$(COMString, Len(COMString) - 255)
Exit Function
End If
For LenVal = 0 To Len(COMString) - 1
bRead(LenVal) = Asc(Mid$(COMString, LenVal + 1, 1))
Next LenVal
' bRead(LenVal) = 0
retval = WriteFile(XpsHandle, bRead(0), Len(COMString), RetBytes, 0)
' FlushComm
SendGoneom = RetBytes
handelwritelpt:
Exit Function
End Function
Function ReadSerial(PortHandle As Long, InpByte As Long)
Dim retval As Long
retval = ReadFile(PortHandle, bRead(0), InpByte, Count_bRead, 0)
End Function
Function WaitSerialData(PortHandle As Long, TimeVal As Single) As Boolean
Dim retval As Long, TimerTmp As Single
'если есть данные, то быстро получить и выход
WaitSerialData = True
retval = ReadFile(PortHandle, bRead(0), 1, Count_bRead, 0)
If Count_bRead > 0 Then Exit Function
'иначе ждать данные опред. время
TimerTmp = Timer
Do While Timer < TimerTmp + TimeVal
retval = ReadFile(PortHandle, bRead(0), 1, Count_bRead, 0)
If Count_bRead > 0 Then Exit Function
' FlushComm (PortHandle)
DoEvents
Loop
'не получены данные за опред. время
WaitSerialData = False
End Function
'Поиск портов в системе ***********************************************
Sub SearchCom()
Dim ComNum As Integer, PortHandle As Long
CloseHandle (XpsHandle) 'закрыть порт, чтоб был доступен в установках
'FormRobotSetngs.MousePointer = vbHourglass
FormRobotSetngs.ComboComPort.Clear 'очистить список
For ComNum = 1 To 20
PortHandle = CreateFile("COM" & ComNum, &HC0000000, 0, 0&, &H3, 0, 0)
If PortHandle > -1 Then
FormRobotSetngs.ComboComPort.AddItem "COM" & ComNum
End If
CloseHandle (PortHandle)
Next
'**********************************************************************
'FormRobotSetngs.MousePointer = vbDefault
End Sub
Madf » 10 июн 2013, 13:40
Познавательно, спасибо.
А в чем плюс использования API, если через MSCOMM проще работать? Или через API быстрее выходит передача?
Dmitry__ » 10 июн 2013, 14:02
Не помню, думаю из-за скорости и делал. Все должно быть на буферах...
Madf писал(а):может есть какие-нить конкуретны типа цирус лоджика?
Я думаю тут надо плакать, колоться, но продолжать грызть кактус как те мыши
Ибо ftdi слишком распространен, конкуренты за бортом.
Вот кста, ткнул ftdi232, выставил скорость 921600, а это почти мегабит/с.
Грызите кактус
Madf » 10 июн 2013, 14:11
Последовательные интерфейсы не подходят как раз в силу ограниченности в скорости МК, я не зря остановился на 245 чипе (из-за параллельности). Да ест больше ног, но при этом в 8-10 раз шустрее на тех же характеристиках. Буду грызть кактус..