Привет! Есть устройство на микроконтроллере которое посылает в порт строку данных раз в секунду, состоящую из четырех чисел через запятую или точку Выглядит примерно так "-15, 25, 0, 200" или "1300. -145. -344. 0"
Вобщем любые четыре челых числа от -1600 до 1600. Необходимо сделать окно с четырымя тексовыми окнами, где будут отображаться эти числа с порта. Тоесть в первом окне будет первое чило, во втором окне второе число после запятой и т. д. Помогите разобраться как разделить строку и поместить каждое число в нужное окно. Понимаю что это возможно очень просто, однако изучаю PB всего неделю и пока мне трудно разобраться. Заранее спасибо за помощь!
работа с com портом
Сообщений 1 страница 27 из 27
Поделиться115.08.2011 21:14:46
Поделиться215.08.2011 21:26:45
Если в строке разделитель повторяется, то есть одна функция, которая поможет
For k=1 To 4 Debug StringField("-10, 233, 155, 12", k, ", ") Next
Т.о. если вы назначите своим TextGadget номера от 1 до 4 то можно написать такой код:
For k=1 To 4 SetGadgetText(k,StringField("-10, 233, 155, 12", k, ", ")) Next
Поделиться315.08.2011 22:04:28
спасибо, буду разбираться
Поделиться405.12.2012 21:58:49
здрасте я тут не давно вопрос о том как вообще организовать прием данных с ком порта
If OpenSerialPort(0,"COM4",9600,#PB_SerialPort_NoParity,8,1,#PB_SerialPort_NoHandshake,255,255)=0
MessageRequester("", "Ошибка открытия порта")
EndIf
это я освоил ,но есть вопрос ,ответ с компа должен являться откликом т.е я открываю порт .к нему устройство подключено ,
даю определенную команду, их четыре и должен получить ответ на эту команду
как это организовать не пойму пока подскажите
спасибо
Поделиться505.12.2012 22:16:12
Нужно по таймеру проверять наличие новых данных, полученных через COM порт и если они есть, то считывать с буфера порта и выполнять требуемые действия.
Поделиться615.12.2012 14:10:40
привет вопрос такой созрел
есть три источника данных как их можно распределить и отправить на устройство которое поймет какие данные откуда
Поделиться715.12.2012 14:11:44
работа с джойстиком и планируется что то вроде ну мех руки с тремя координатами вот
Поделиться821.12.2012 15:33:17
есть три источника данных как их можно распределить и отправить на устройство которое поймет какие данные откуда
Сделай так, чтобы каждое устройство начинало передавать свои данные с какого-нибудь фиксированного символа(символов), и откликалось каждый на свой символ(символы).Желательно, чтобы эти символы не встречались в теле сообщений. Сумбурно как-то написал, но думаю, суть ясна.
Поделиться925.12.2012 21:41:25
да мнеб хотькусок кода как это сделать ,вопрос мк -ответ пк ,как это делается вообще спасибо
Поделиться1026.12.2012 13:32:31
да мнеб хотькусок кода
If OpenSerialPort(0,"COM1",9600,#PB_SerialPort_NoParity,8,1,#PB_SerialPort_NoHandshake,255,255) ; если порт открыт Repeat *Buffer=AllocateMemory(1) ;выделяем память под принимаемые данные, принимать будем по-одному байту If ReadSerialPortData(0, *Buffer,1) ; если данные приняты RX.c=PeekC(*Buffer) ; помещаем принятый байт в переменную для дальнейшего использования Delay(1) ;пауза перед ответом WriteSerialPortData(0, *Buffer, 1); ответ "той же монетой" -эхо EndIf FreeMemory(*Buffer) ; освобождаем память ForEver ; Until твое условие CloseSerialPort(0) EndIf
Достаточно для начала?
Поделиться1126.12.2012 21:53:47
окей спасибо добрый людь ,ща попробую ,но есть вопрос, нужно не просто эхо, а адыкватный отвед мк ,т.е.сначала отправляем быйт "символ" в мк ,потом ловим ответ и только потом передаем поток данных в мк вот проблема для меня
Отредактировано trim (26.12.2012 21:58:29)
Поделиться1226.12.2012 22:23:06
А так не пойдет ?
чото не то выходит но выходит
otvet.s=Space(2)
otvet1.w
otvet2.s=Space(30)
otvet3.l
restart:
WriteSerialPortString(0,Chr(10)+"redy"+Chr(13),6)
Delay(30)
ReadSerialPortData(0,@otvet1,1)
otvet=Chr(otvet1)
If otvet=otvet
WriteSerialPortString(0,Chr(10)+"xp"+Chr(13), 7)
WriteSerialPortString(0,Chr(10)+"yp"+Chr(13), 7)
WriteSerialPortString(0,Chr(10)+"rp"+Chr(13), 7)
WriteSerialPortString(0,Chr(10)+"stop"+Chr(13),4)
Delay (20)
ReadSerialPortData(0,@otvet3,27)
otvet2=Hex(otvet3)
Debug otvet2
Else
Goto restart
EndIf
EndIf
Else
Поделиться1327.12.2012 09:42:30
Опиши вкратце твой протокол обмена между МК и ПК, т.е каким ты его себе представляешь.
Поделиться1427.12.2012 12:29:22
чото не то выходит
Третий аргумент функции WriteSerialPortString() это формат строки. http://purebasic.com/documentation/seri … tring.html
Но в коде заданы значения взятые "с потолка", поэтому "не то выходит".
И разве в МК проще будет работать со строками, чем с двоичными данными?
Поделиться1527.12.2012 13:27:25
с потолка имеется ввиду ,хр,yp,rp? это переменные в них данные с программы обработки координат джойстика
непойму никак как с двоичными работать со строковыми результат есть и мк видит тока координаты осей всеже наверное придется в бинарном формате отсылать но как ...........там значит так, переменная х ,у,р имеет по три символа каждая их нужно отправить в мк ,как в бинарном варианте отправить так чтоб мк понял какая ось какая ?вот
Поделиться1627.12.2012 14:00:08
trim, я не понял, программа в МК твоя или это готовый девайс?
Поделиться1727.12.2012 14:46:48
Всем привет! Вот мои наработки http://avrproject.ru/publ/poleznaja_inf … /4-1-0-128 возможно пригодится кому-нибудь.
Поделиться1827.12.2012 15:25:41
с потолка имеется ввиду ,хр,yp,rp?
Нет, они во втором аргументе функции,а я пишу про третий. Выделил цветом.
WriteSerialPortString(0,Chr(10)+"xp"+Chr(13), 7)
WriteSerialPortString(0,Chr(10)+"yp"+Chr(13), 7)
WriteSerialPortString(0,Chr(10)+"rp"+Chr(13), 7)
как в бинарном варианте отправить так чтоб мк понял какая ось какая
Ну например так.
; Структуру размещаем в начале кода. Structure SendDevice Size.a ; Длина пакета (1 байт). Num.a ; Номер джойстика (1 байт). x.u ; Координата X (2 байта). y.u ; Координата Y (2 байта). EndStructure ; Допустим, порт уже открыт и необходимо отправить данные. Send.SendDevice Send\Size = SizeOf(SendDevice) ; Длина пакета (размер в байтах). Send\Num=1 ; Первый джойстик. Send\x = 20 ; Позиция джойстика. Send\y = 100 WriteSerialPortData(0, @Send, Send\Size)
Поделиться1927.12.2012 16:34:11
КЭС
моя ,прога моя
Поделиться2027.12.2012 16:36:06
Пётр
не не это я так пытаюсь прощитывать символы которые посылаю просто незнаю как правильно
Поделиться2127.12.2012 16:37:20
exersizze
приветствую великого и могучего гуру аврпроэкта на этом великолепном сайте
Поделиться2227.12.2012 22:09:25
приветствую великого и могучего гуру аврпроэкта на этом великолепном сайте
спасибо =) этот форум и правда кладезь информации
Теперь по теме: в терминале брэя (aka by Bra@y) выбор компорта сделан очень удобно. Он как-то определяет возможные порты которые установлены в компьютере и предлагает выбрать только из них. Может знает как такое можно организовать?
Отредактировано exersizze (27.12.2012 22:19:13)
Поделиться2328.12.2012 10:58:22
Можно просто попытаться их открыть. Если порт не открывается, то он или отсутствует, или занят другой программой.
If OpenWindow(0, 0, 0, 100, 80, "ComboBoxGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) ComboBoxGadget(0, 10, 20, 80, 22) For i=1 To 255 If OpenSerialPort(0, "COM"+Str(i), 9600, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 255, 255) AddGadgetItem(0, -1, "COM"+Str(i)) CloseSerialPort(0) EndIf Next i SetGadgetState(0,0) Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow EndIf
Поделиться2417.11.2020 20:50:34
Можно просто попытаться их открыть.
Это под Виндой.
А как быть с Линуксом?
Поделиться2517.11.2020 21:11:00
Общий код:
Global NewList AvailableComs.s() Procedure GetAvailableComPorts() ;this procedure scans the registry (on win) or dmesg (on linux) to find the connected com ports Protected hKey, lpcbName, lpName.s, a$, lType, i, j, Dmesg, Fgrep, Port.s CompilerSelect #PB_Compiler_OS CompilerCase #PB_OS_Windows If RegOpenKeyEx_(#HKEY_LOCAL_MACHINE, "HARDWARE\DEVICEMAP\SERIALCOMM", 0, #KEY_QUERY_VALUE, @hKey) = #ERROR_SUCCESS lpName = Space(1024) Repeat lpcbName = 1024 If RegEnumValue_(hKey, i, @lpName, @lpcbName, 0, 0, 0, 0) = #ERROR_SUCCESS a$ = Left(lpName, lpcbName) If a$ = "" Break EndIf lpcbName = 1024 lType = 0 If RegQueryValueEx_(hKey, a$, 0, @lType, @lpName, @lpcbName) = #ERROR_SUCCESS AddElement(AvailableComs()) AvailableComs() = lpName EndIf i + 1 Else Break EndIf ForEver RegCloseKey_(hKey) EndIf CompilerCase #PB_OS_Linux Dmesg = RunProgram("/bin/dmesg", "", "", #PB_Program_Open | #PB_Program_Read) If Dmesg Fgrep = RunProgram("/bin/fgrep", "tty", "", #PB_Program_Open | #PB_Program_Connect | #PB_Program_Read, Dmesg) If Fgrep While ProgramRunning(Fgrep) a$ = ReadProgramString(Fgrep) i = FindString(a$, "ttyS", 1) If i > 0 j = FindString(a$, " ", i) Port = "/dev/" + Mid(a$, i, j - i) hKey = 1 ForEach AvailableComs() If AvailableComs() = Port hKey = 0 Break EndIf Next If hKey AddElement(AvailableComs()) AvailableComs() = Port EndIf EndIf Wend CloseProgram(Fgrep) EndIf CloseProgram(Dmesg) EndIf CompilerCase #PB_OS_MacOS CompilerEndSelect EndProcedure GetAvailableComPorts() ForEach AvailableComs() Debug AvailableComs() Next
Поделиться2618.11.2020 20:36:44
Общий код:
Тенкс!
Поделиться2720.11.2020 21:28:44
Что-то я рано обрадовался.
Как-то данная процедура, под Линухом, работает "раз из десяти".
Кроме того, для преобразователей USB-Com явно необходима доработка.
Я делал по-тупому:
For Temp=0 To 32-1 If Temp < 16 TempS$ = "/dev/ttyS" Temp2.a = Temp ElseIf Temp >= 16 And Temp <32 TempS$ = "/dev/ttyUSB" Temp2.a = Temp - 16 Else MessageRequester(FatalError00$, FatalErrorMes01_00$ + SetStringOutSys$ + "Code: 01??" + SetStringOutSys$ + FatalErrorMes01_01$) End EndIf If OpenSerialPort(#OpenComPort, TempS$+Str(Temp2), 38400, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 128, 128) AddElement(ComPortList()) ComPortList() = TempS$+Str(Temp2) CloseSerialPort(#OpenComPort) Else EndIf Next
Соответственно все 16 (или сколько надо) КОМ-портов появляются в списке в независимости от реального наличия, а вот ЮСБ-Ком, как и надо, только при наличии.