PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » Вопросы по PureBasic » работа с com портом


работа с com портом

Сообщений 1 страница 27 из 27

1

Привет! Есть устройство на микроконтроллере которое посылает в порт строку данных раз в секунду, состоящую из четырех чисел через запятую или точку Выглядит примерно так "-15, 25, 0, 200" или "1300. -145. -344. 0"
Вобщем любые четыре челых числа от -1600 до 1600. Необходимо сделать окно с четырымя тексовыми окнами, где будут  отображаться эти числа с порта. Тоесть в первом окне будет первое чило, во втором окне второе число после запятой и т. д. Помогите разобраться как разделить строку и поместить каждое число в нужное окно. Понимаю что это возможно очень просто, однако изучаю PB всего неделю и пока  мне трудно разобраться. Заранее спасибо за помощь!

0

2

Если в строке разделитель повторяется, то есть одна функция, которая поможет

Код:
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

0

3

спасибо, буду разбираться

0

4

здрасте я тут не давно вопрос о том как вообще организовать прием данных с ком порта

If OpenSerialPort(0,"COM4",9600,#PB_SerialPort_NoParity,8,1,#PB_SerialPort_NoHandshake,255,255)=0
  MessageRequester("", "Ошибка открытия порта")
EndIf

это я освоил ,но есть вопрос ,ответ с компа должен являться откликом  т.е я открываю порт  .к нему устройство подключено ,
даю определенную команду, их четыре  и должен получить ответ на эту команду
как это организовать не пойму пока подскажите
спасибо

0

5

Нужно по таймеру проверять наличие новых данных, полученных через COM порт и если они есть, то считывать с буфера порта и выполнять требуемые действия.

0

6

привет вопрос такой созрел

есть три источника данных как их можно распределить и отправить на устройство которое поймет какие данные откуда

0

7

работа с джойстиком и планируется что то вроде ну мех руки с тремя координатами вот

0

8

trim написал(а):

есть три источника данных как их можно распределить и отправить на устройство которое поймет какие данные откуда

Сделай так, чтобы каждое устройство начинало передавать свои данные с какого-нибудь фиксированного символа(символов), и откликалось каждый на свой символ(символы).Желательно, чтобы эти символы не встречались в теле сообщений. Сумбурно как-то написал, но думаю, суть ясна.

0

9

да мнеб хотькусок кода как это сделать ,вопрос мк -ответ пк ,как это делается вообще спасибо

0

10

trim написал(а):

да мнеб хотькусок кода

Код:
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

Достаточно для начала?

0

11

окей спасибо добрый людь ,ща попробую ,но есть вопрос, нужно не просто эхо, а адыкватный отвед мк ,т.е.сначала отправляем быйт "символ" в мк ,потом ловим ответ и только потом передаем поток данных в мк вот проблема для меня

Отредактировано trim (26.12.2012 21:58:29)

0

12

А так не пойдет ?
чото не то выходит но выходит


  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

0

13

Опиши вкратце твой протокол обмена между МК и ПК, т.е каким ты его себе представляешь.

0

14

trim написал(а):

чото не то выходит

Третий аргумент функции WriteSerialPortString() это формат строки. http://purebasic.com/documentation/seri … tring.html
Но в коде заданы значения взятые "с потолка", поэтому "не то выходит".

И разве в МК проще будет работать со строками, чем с двоичными данными?

0

15

с потолка имеется ввиду ,хр,yp,rp? это переменные в них данные с программы обработки координат джойстика

непойму никак как с двоичными работать со строковыми результат есть и мк видит  тока координаты осей всеже наверное придется в бинарном формате отсылать но как ...........там значит так, переменная х ,у,р имеет по три символа  каждая их нужно отправить в мк ,как в бинарном варианте отправить так чтоб мк понял какая ось какая ?вот

0

16

trim, я не понял, программа в МК твоя или это готовый девайс?

0

17

Всем привет! Вот мои наработки http://avrproject.ru/publ/poleznaja_inf … /4-1-0-128 возможно пригодится кому-нибудь.

0

18

trim написал(а):

с потолка имеется ввиду ,хр,yp,rp?

Нет, они во втором аргументе функции,а я пишу про третий. Выделил цветом.

trim написал(а):

WriteSerialPortString(0,Chr(10)+"xp"+Chr(13), 7)
WriteSerialPortString(0,Chr(10)+"yp"+Chr(13), 7)
WriteSerialPortString(0,Chr(10)+"rp"+Chr(13), 7)

trim написал(а):

как в бинарном варианте отправить так чтоб мк понял какая ось какая

Ну например так.

Код:
; Структуру размещаем в начале кода.
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)

0

19

КЭС
моя ,прога моя

0

20

Пётр
не не это я так пытаюсь прощитывать символы которые посылаю просто незнаю как правильно

0

21

exersizze
приветствую великого и могучего гуру аврпроэкта на этом великолепном сайте

0

22

trim написал(а):

приветствую великого и могучего гуру аврпроэкта на этом великолепном сайте

спасибо =) этот форум и правда кладезь информации
Теперь по теме: в терминале брэя (aka by Bra@y) выбор компорта сделан очень удобно. Он как-то определяет возможные порты которые установлены в компьютере и предлагает выбрать только из них. Может знает как такое можно организовать?

Отредактировано exersizze (27.12.2012 22:19:13)

0

23

Можно просто попытаться их открыть. Если порт не открывается, то он или отсутствует, или занят другой программой.

Код:
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

0

24

Пётр написал(а):

Можно просто попытаться их открыть.

Это под Виндой.
А как быть с Линуксом?

0

25

Общий код:

Код:
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

0

26

ВиниПур написал(а):

Общий код:

Тенкс!

0

27

Что-то я рано обрадовался.
Как-то данная процедура, под Линухом, работает "раз из десяти".
Кроме того, для преобразователей 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 (или сколько надо) КОМ-портов появляются в списке в независимости от реального наличия, а вот ЮСБ-Ком, как и надо, только при наличии.

0


Вы здесь » PureBasic - форум » Вопросы по PureBasic » работа с com портом