PureBasic. Работа с COM портом
|
|
exersizze | Дата: Понедельник, 17.12.2012, 02:15 | Сообщение # 1 |
Группа: Администраторы
Сообщений: 723
Статус: Offline
| Cейчас вплотную подошел к общению микроконтроллера с ПК, колдую над своей программой. Задача стоит в том чтобы по нажатию кнопки в программе (на ПК) отослать контроллеру некую команду по rs232, и в обратку получить данные которые контроллер нам отошлет и показать их. Пока остановился на том что попробую сделать это на PureBasic. Поэтому сразу вопросы новичка: как прикрутить в свою программу функцию работы с СОМ-портом, и далее по ТЗ - отправлять и принимать данные?
|
|
| |
Aleks8383 | Дата: Понедельник, 17.12.2012, 08:18 | Сообщение # 2 |
Группа: Проверенные
Сообщений: 104
Статус: Offline
| Ну как пример,делаем обработку кнопки ,к примеру"отправить" при её нажатии переходим в процедуру.В прцедуре открываем порт командой OpenSerialPort(смотрим хелп там всё расписано).Перед тем как открывать порт можно сделать проверке открыт ли порт IsSerialPort то закрыть его CloseSerialPort чтобы небыло конфликтов с другими программами.Ну а далее соответственно отправляем данные в контроллер WriteSerialPortString (для буковок ) или WriteSerialPortData (для цифирок). Также можно проверять что там у нас в буфере творится AvailableSerialPortInput для приёма и AvailableSerialPortOutput для передачи.Проверяем вышеприведённой командой данные в буфере на приём и если там чтото есть принимаем их ReadSerialPortData, ну а дальше думаю всё понятно.Обрабатываем там как нам нужно и выводим на экран.Ну вот как тот так если в кратце.
|
|
| |
exersizze | Дата: Понедельник, 17.12.2012, 21:03 | Сообщение # 3 |
Группа: Администраторы
Сообщений: 723
Статус: Offline
| Туговато идет освоение нового языка справку как будто писали партизаны-все написано по минимуму. Удалось написать только установку гаджетов (знаю что это можно сделать проще с помощью визуального редактора, но это не тру)
Code If OpenWindow(0, 300, 100, 650, 410, "Тестовая программа") ButtonGadget(1, 90, 360, 100, 35, "Принять данные", #PB_Button_Default) TextGadget(2,10,360,25,15,"Порт") ; Выводим в окно надпись "Порт". ComboBoxGadget(3, 10, 375, 70, 21, #PB_ComboBox_Editable) AddGadgetItem(3, -1, "COM1") AddGadgetItem(3, -1, "COM2") AddGadgetItem(3, -1, "COM3") AddGadgetItem(3, -1, "COM4") AddGadgetItem(3, -1, "COM5") AddGadgetItem(3, -1, "COM6") AddGadgetItem(3, -1, "COM7") AddGadgetItem(3, -1, "COM8") AddGadgetItem(3, -1, "COM9") AddGadgetItem(3, -1, "COM10") AddGadgetItem(3, -1, "COM11") AddGadgetItem(3, -1, "COM12") AddGadgetItem(3, -1, "COM13")
SetGadgetState(3,0); Делаем активным нулевой пункт выпадающего списка. StringGadget(4, 8, 10, 630, 300, "", #PB_String_ReadOnly) ;строковый гаджет, сюда пишем принятые данные
Repeat A= WaitWindowEvent() If A=#PB_Event_Gadget B= EventGadget ( ) ;узнаем какой гаджет был активирован If b=1 ;если нажата кнопка MessageRequester("Сообщение", "Нажата кнопка", 0) ;выполняемая функция по нажатию кнопки EndIf EndIf If A=#PB_Event_CloseWindow Q=1 EndIf Until Q=1 EndIf End
как из выпадающего списка взять номер порта который мы выбираем и открыть его?
|
|
| |
exersizze | Дата: Вторник, 18.12.2012, 03:30 | Сообщение # 4 |
Группа: Администраторы
Сообщений: 723
Статус: Offline
| C выбором нужного порта разобрался, осталось не много, до утра наверно управлюсь Вот что на данный момент есть Code If OpenWindow(0, 300, 100, 650, 415, "Тестовая программа") ButtonGadget(1, 90, 360, 100, 35, "Принять данные", #PB_Button_Default) TextGadget(2,10,360,25,15,"Порт") ; Выводим в окно надпись "Порт". ComboBoxGadget(3, 10, 375, 70, 21, #PB_ComboBox_Editable) AddGadgetItem(3, -1, "COM1") AddGadgetItem(3, -1, "COM2") AddGadgetItem(3, -1, "COM3") AddGadgetItem(3, -1, "COM4") AddGadgetItem(3, -1, "COM5") AddGadgetItem(3, -1, "COM6") AddGadgetItem(3, -1, "COM7") AddGadgetItem(3, -1, "COM8") AddGadgetItem(3, -1, "COM9") AddGadgetItem(3, -1, "COM10") AddGadgetItem(3, -1, "COM11") AddGadgetItem(3, -1, "COM12") AddGadgetItem(3, -1, "COM13") AddGadgetItem(3, -1, "COM14") AddGadgetItem(3, -1, "COM15") AddGadgetItem(3, -1, "COM16") AddGadgetItem(3, -1, "COM17") AddGadgetItem(3, -1, "COM18") AddGadgetItem(3, -1, "COM19") AddGadgetItem(3, -1, "COM20") AddGadgetItem(3, -1, "COM21") AddGadgetItem(3, -1, "COM22")
SetGadgetState(3,0); Делаем активным нулевой пункт выпадающего списка. StringGadget(4, 8, 10, 630, 300, "", #PB_String_ReadOnly) ;строковый гаджет, сюда пишем принятые данные TextGadget(5,10,400,100,15,"") ;Здесь будет отображаться результат открытия порта.
ComboBox.s=GetGadgetText(3) : CB_Temp.s=ComboBox Gosub SelectPort ;идем в подпрограмму и открываем выбранный по умолчанию порт Repeat A= WaitWindowEvent() If A=#PB_Event_Gadget B= EventGadget ( ) ;узнаем какой гаджет был активирован If b=1 ;если нажата кнопка MessageRequester("Сообщение", "Нажата кнопка", 0) ;выполняемая функция по нажатию кнопки ElseIf b=3 ;если был активирован выпадающий список ComboBox.s=GetGadgetText(3) ; Считываем текст из текущего пункта выпадающего списка. ; Код между операторами If и EndIf будет выполнен только если ; текст текущего пункта отличается от ранее выбранного. If ComboBox<>CB_Temp CB_Temp=ComboBox ; Переходим на подпрограмму, закрывающую текущий порт и открывающую выбранный. Gosub SelectPort EndIf EndIf EndIf If A=#PB_Event_CloseWindow Q=1 EndIf Until Q=1 EndIf End
; Подпрограмма выбора порта SelectPort:
Port.s=ComboBox+":"+"38400,N,8,1" ;Настройки порта If ComId>0 ;Если порт открыт в другом приложении, принудительо закрываем его ComClose(ComId) ComId=0 EndIf ComId=ComOpen(Port,#HandShakeModeNone,1024,1024) ;И заново открываем порт
If ComId>0 SetGadgetText(5,"Порт открыт") SetGadgetColor(5,#PB_Gadget_FrontColor,RGB(12, 2, 202)) Else SetGadgetText(5,"Порт не доступен!") SetGadgetColor(5,#PB_Gadget_FrontColor,RGB(220, 20, 60)) EndIf
Return
Вопрос, как сделать в выпадающем списке ползунок? Чтобы весь список портов не вываливался целиком.
С отрисовкой графиков из полученных данных не сталкивался?
|
|
| |
Aleks8383 | Дата: Вторник, 18.12.2012, 11:44 | Сообщение # 5 |
Группа: Проверенные
Сообщений: 104
Статус: Offline
| Вчера вечером неуспел код выложить,выкладываю сейчас. хотя смотрю у тебя и самого получается неплохо. Code Declare UART()
Global text_com.s Global text_bit.s Global com Global bit
If OpenWindow(0, 300, 100, 650, 410, "Тестовая программа") ButtonGadget(1, 200, 360, 100, 35, "Принять данные", #PB_Button_Default) TextGadget(2,10,360,25,15,"Порт") ; Выводим в окно надпись "Порт". ComboBoxGadget(3, 10, 375, 70, 21, #PB_ComboBox_Editable) ComboBoxGadget(4, 100, 375, 70, 21, #PB_ComboBox_Editable) TextGadget(5,100,360,60,15,"Скорость") ;TextGadget(6,350,370,80,21,"", #PB_Text_Center|#PB_Text_Border) ;TextGadget(7,450,370,80,21,"", #PB_Text_Center|#PB_Text_Border) For i=1 To 15 AddGadgetItem(3,-1,"COM"+Str(i)) Next i SetGadgetState(3,com) AddGadgetItem(4,-1,"75") AddGadgetItem(4,-1,"110") AddGadgetItem(4,-1,"134") AddGadgetItem(4,-1,"150") AddGadgetItem(4,-1,"300") AddGadgetItem(4,-1,"600") AddGadgetItem(4,-1,"1200") AddGadgetItem(4,-1,"1800") AddGadgetItem(4,-1,"2400") AddGadgetItem(4,-1,"4800") AddGadgetItem(4,-1,"7200") AddGadgetItem(4,-1,"9600") AddGadgetItem(4,-1,"14400") AddGadgetItem(4,-1,"19200") AddGadgetItem(4,-1,"38400") AddGadgetItem(4,-1,"57600") AddGadgetItem(4,-1,"115200") AddGadgetItem(4,-1,"128000") SetGadgetState(4,bit) StringGadget(8, 8, 10, 630, 300, "", #PB_String_ReadOnly) ;строковый гаджет, сюда пишем принятые данные
EndIf Procedure UART() If OpenSerialPort(1, text_com.s, Val(text_bit.s), #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 1024, 1024) EndIf EndProcedure Repeat A= WaitWindowEvent() Event=WaitWindowEvent() Gadget=EventGadget() Event=#PB_Event_Gadget com=GetGadgetState(3) : text_com.s=GetGadgetText(3) ;SetGadgetText(6,text_com.s) Event=#PB_Event_Gadget bit=GetGadgetState(4) : text_bit.s=GetGadgetText(4) ; SetGadgetText(7,text_bit.s) If A=#PB_Event_Gadget B= EventGadget ( ) ;узнаем какой гаджет был активирован If b=1 ;если нажата кнопка MessageRequester("Сообщение", "Нажата кнопка", 0) ;выполняемая функция по нажатию кнопки EndIf EndIf
If A=#PB_Event_CloseWindow Q=1 EndIf
Until Q=1 Добавил выбор скорости обмены и немного упростил выбор Ком порта.И ввёл процедуру отправки данных,где уже будут выставлены выбранные скорость и порт. Чтобы был ползынок нужно другой гаджет применять listicongadget или можно spingadget/
Сообщение отредактировал Aleks8383 - Вторник, 18.12.2012, 11:51 |
|
| |
exersizze | Дата: Вторник, 18.12.2012, 16:58 | Сообщение # 6 |
Группа: Администраторы
Сообщений: 723
Статус: Offline
| выбор компорта вида Code For i=1 To 15 AddGadgetItem(3,-1,"COM"+Str(i)) Next i понравился, применил у себя) существенно экономит кол-во строк
|
|
| |
Петр | Дата: Вторник, 18.12.2012, 19:16 | Сообщение # 7 |
Группа: Проверенные
Сообщений: 47
Статус: Offline
| Code #COM_Port = 2 ; Идентификатор COM порта.
Procedure Select_ComPort() Protected Port.s, Text.s, Color If IsSerialPort(#COM_Port) ; С таким ИД уже открыт порт. CloseSerialPort(#COM_Port) ; Закрываем его. EndIf Port = GetGadgetText(3) If OpenSerialPort(#COM_Port, Port, 9600, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 255, 255) Text="Порт "+Port+" открыт" : Color=RGB(46, 137, 36) Else Text="Не удалоссь открыть порт "+Port : Color=RGB(255,0,0) EndIf SetGadgetText(5, Text) SetGadgetColor(5, #PB_Gadget_FrontColor, Color) EndProcedure
Procedure InData() ; Прием данных. Protected InBytes If IsSerialPort(#COM_Port) ; С таким ИД порт открыт. InBytes = AvailableSerialPortInput(#COM_Port) If InBytes>0 ; Получены данные. Protected Dim InBuffer.a(InBytes), RealInBytes RealInBytes = ReadSerialPortData(#COM_Port, @InBuffer(), InBytes) If RealInBytes>0 AddGadgetItem(4, -1, PeekS(@InBuffer(), RealInBytes, #PB_Ascii)) EndIf EndIf EndIf EndProcedure
If OpenWindow(0, 300, 100, 650, 415, "Тестовая программа") ButtonGadget(1, 90, 360, 100, 35, "Принять данные", #PB_Button_Default) TextGadget(2,10,360,25,15,"Порт") ; Выводим в окно надпись "Порт". ComboBoxGadget(3, 10, 375, 70, 21) For i=1 To 10 AddGadgetItem(3,-1,"COM"+Str(i)) Next i SetGadgetState(3,0); Делаем активным нулевой пункт выпадающего списка. ;StringGadget(4, 8, 10, 630, 300, "", #PB_String_ReadOnly) ;строковый гаджет, сюда пишем принятые данные EditorGadget(4, 8, 10, 630, 300) TextGadget(5,10,400,200,15,"") ;Здесь будет отображаться результат открытия порта. Select_ComPort() Repeat Event = WaitWindowEvent() If Event=#PB_Event_Gadget Gadget = EventGadget ( ) ;узнаем какой гаджет был активирован If Gadget=1 ;если нажата кнопка ;MessageRequester("Сообщение", "Нажата кнопка", 0) ;выполняемая функция по нажатию кнопки InData() ElseIf Gadget=3 ;если был активирован выпадающий список ComboBox.s=GetGadgetText(3) ; Считываем текст из текущего пункта выпадающего списка. ; Код между операторами If и EndIf будет выполнен только если ; текст текущего пункта отличается от ранее выбранного. If EventType() = #PB_EventType_Change ; Переходим на процедуру, закрывающую текущий порт и открывающую выбранный. Select_ComPort() EndIf EndIf EndIf Until Event=#PB_Event_CloseWindow EndIf End
Сообщение отредактировал Петр - Вторник, 18.12.2012, 19:17 |
|
| |
exersizze | Дата: Вторник, 18.12.2012, 22:31 | Сообщение # 8 |
Группа: Администраторы
Сообщений: 723
Статус: Offline
| Петр, спасибо! Похоже то что нужно, попробую переварить.
|
|
| |
exersizze | Дата: Четверг, 20.12.2012, 17:06 | Сообщение # 9 |
Группа: Администраторы
Сообщений: 723
Статус: Offline
| С процедурой приема и выбора порта разобрался, была проблема с If EventType() = #PB_EventType_Change, закомментировал это условие и стало нормально. Сейчас не получается отправить данные в порт, подскажите в чем проблема? И не особо понял для чего вот это #COM_Port = 2 в первой строчке. Поясните пжлст почему именно 2?
Code #COM_Port = 2 ; Идентификатор COM порта.
Global Send_data.s ;объявляем переменную глобальной, чтобы получить доступ к ней в процедурах
Procedure Select_ComPort() Protected Port.s, Text.s, Color If IsSerialPort(#COM_Port) ; С таким ИД уже открыт порт. CloseSerialPort(#COM_Port) ; Закрываем его. EndIf Port = GetGadgetText(3) If OpenSerialPort(#COM_Port, Port, 38400, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 255, 255) Text="Порт "+Port+" открыт" : Color=RGB(46, 137, 36) Else Text="Не удалось открыть порт "+Port : Color=RGB(255,0,0) EndIf SetGadgetText(5, Text) SetGadgetColor(5, #PB_Gadget_FrontColor, Color) EndProcedure
Procedure InData() ; Прием данных. Protected InBytes If IsSerialPort(#COM_Port) ; С таким ИД порт открыт. InBytes = AvailableSerialPortInput(#COM_Port) If InBytes>0 ; Получены данные. Protected Dim InBuffer.a(InBytes), RealInBytes RealInBytes = ReadSerialPortData(#COM_Port, @InBuffer(), InBytes) If RealInBytes>0 AddGadgetItem(4, -1, PeekS(@InBuffer(), RealInBytes, #PB_Ascii)) EndIf EndIf EndIf EndProcedure Procedure ComOut() ; Передача данных в порт. Protected Out If IsSerialPort(#COM_Port) ;если порт открыт Out=Val(Send_data) ComWrite(#COM_Port,@Out,1) ;Посылаем в порт данные из переменной Out Else ; Выводим сообщение об ошибке. MessageRequester("Ошибка","Текущий порт не доступен!",16) EndIf
EndProcedure
If OpenWindow(0, 300, 100, 650, 415, "Тестовая программа") ButtonGadget(1, 90, 360, 100, 35, "Принять данные", #PB_Button_Default) TextGadget(2,10,360,25,15,"Порт") ; Выводим в окно надпись "Порт". ComboBoxGadget(3, 10, 375, 70, 21, #PB_ComboBox_Editable) For i=1 To 99 AddGadgetItem(3,-1,"COM"+Str(i)) Next i SetGadgetState(3,0); Делаем активным нулевой пункт выпадающего списка. ;StringGadget(4, 8, 10, 630, 300, "", #PB_String_ReadOnly) ;строковый гаджет, сюда пишем принятые данные EditorGadget(4, 8, 10, 630, 300,#PB_String_ReadOnly) TextGadget(5,10,400,200,15,"") ;Здесь будет отображаться результат открытия порта. ButtonGadget(6, 200, 360, 100, 35, "Очистить окно", #PB_Button_Default) Select_ComPort() Repeat Event = WaitWindowEvent() InData() ;принимаем данные из UART If Event=#PB_Event_Gadget Gadget = EventGadget ( ) ;узнаем какой гаджет был активирован If Gadget=1 ;если нажата кнопка ;MessageRequester("Сообщение", "Нажата кнопка", 0) ;выполняемая функция по нажатию кнопки Send_data="1" ComOut() ;Переходим на процедуру передачи байта. InData() ElseIf Gadget=3 ;если был активирован выпадающий список ComboBox.s=GetGadgetText(3) ; Считываем текст из текущего пункта выпадающего списка. ;If EventType() = #PB_EventType_Change ; Переходим на процедуру, закрывающую текущий порт и открывающую выбранный. Select_ComPort() ;EndIf ElseIf Gadget=6 ;нажата кнопка очистки ClearGadgetItems(4) ;удаляем содержимое окна с данными EndIf EndIf Until Event=#PB_Event_CloseWindow EndIf End
|
|
| |
trim | Дата: Четверг, 20.12.2012, 22:34 | Сообщение # 10 |
Группа: Проверенные
Сообщений: 105
Статус: Offline
| привет ребят кто потскажет как передать координаты осей джойстика в мк через компорт
|
|
| |
exersizze | Дата: Пятница, 21.12.2012, 02:54 | Сообщение # 11 |
Группа: Администраторы
Сообщений: 723
Статус: Offline
| ты хотябы написал какой джойстик и прочие вводные данные
|
|
| |
Aleks8383 | Дата: Пятница, 21.12.2012, 11:59 | Сообщение # 12 |
Группа: Проверенные
Сообщений: 104
Статус: Offline
| Quote (exersizze) Сейчас не получается отправить данные в порт, подскажите в чем проблема? Да скорее всего по тому что есть команды WriteSerialPortData и WriteSerialPortString для предачи, а вот команды ComWrite я невстречал.
|
|
| |
exersizze | Дата: Пятница, 21.12.2012, 13:06 | Сообщение # 13 |
Группа: Администраторы
Сообщений: 723
Статус: Offline
| а, ну тогда это все объясняет) вечером попробую.
|
|
| |
trim | Дата: Пятница, 21.12.2012, 20:37 | Сообщение # 14 |
Группа: Проверенные
Сообщений: 105
Статус: Offline
| есть три строчки данных (координаты осей )типа х=32767,y=32767,r=65535 как их отправить так, чтоб мк понял откуда какая строчка ,приэтом мне нужно только первые две цифры
|
|
| |
Aleks8383 | Дата: Пятница, 21.12.2012, 22:11 | Сообщение # 15 |
Группа: Проверенные
Сообщений: 104
Статус: Offline
| Снимается информация с оси(к примеру)Х присваеваем ей индекс 1 и передаём индекс и само показание оси.Соответственно У присваиваем 2 и тд и тп.
|
|
| |
trim | Дата: Пятница, 21.12.2012, 22:23 | Сообщение # 16 |
Группа: Проверенные
Сообщений: 105
Статус: Offline
| это как это в пурике выглядеть будет подскажи пжалусто
|
|
| |
trim | Дата: Пятница, 21.12.2012, 22:25 | Сообщение # 17 |
Группа: Проверенные
Сообщений: 105
Статус: Offline
| вот прога тестовая глянь Саш и если джойс есть то попробуеш на практике
Сообщение отредактировал trim - Пятница, 21.12.2012, 22:27 |
|
| |
Aleks8383 | Дата: Суббота, 22.12.2012, 12:52 | Сообщение # 18 |
Группа: Проверенные
Сообщений: 104
Статус: Offline
| Цитата (trim) это как это в пурике выглядеть будет Это я предположил так,как то оси должны маркироваться(отличаться).Надо точно протокол смотреть что они передают,тогда и скажу как будет выглядеть.
|
|
| |
Петр | Дата: Суббота, 22.12.2012, 15:20 | Сообщение # 19 |
Группа: Проверенные
Сообщений: 47
Статус: Offline
| Цитата (exersizze) была проблема с If EventType() = #PB_EventType_Change Этот тип события появится в версии 4.60. Текущая версия 5.00. Анонсировали версию 5.10 http://www.purebasic.fr/english/viewtopic.php?f=14&t=52423 Не помешало бы обновится.
Цитата (exersizze) Сейчас не получается отправить данные в порт, подскажите в чем проблема? Уже написали выше что проблема в том, что использована "не та" функция. Функция ComWrite() из сторонней библиотеки, а остальные функции, работающие с портом - библиотечные. В принципе в этом коде. ее тоже можно использовать, но ей следует передавать не идентификатор порта, а его хендл. Код ComWrite(SerialPortID(#COM_Port),@Out,1) Весь код будет таким. Код #COM_Port = 2 ; Идентификатор COM порта.
;Global Send_data.s ;объявляем переменную глобальной, чтобы получить доступ к ней в процедурах
Procedure Select_ComPort() Protected Port.s, Text.s, Color If IsSerialPort(#COM_Port) ; С таким ИД уже открыт порт. CloseSerialPort(#COM_Port) ; Закрываем его. EndIf Port = GetGadgetText(3) If OpenSerialPort(#COM_Port, Port, 38400, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 255, 255) Text="Порт "+Port+" открыт" : Color=RGB(46, 137, 36) Else Text="Не удалось открыть порт "+Port : Color=RGB(255,0,0) EndIf SetGadgetText(5, Text) SetGadgetColor(5, #PB_Gadget_FrontColor, Color) EndProcedure
Procedure InData() ; Прием данных. Protected InBytes If IsSerialPort(#COM_Port) ; С таким ИД порт открыт. InBytes = AvailableSerialPortInput(#COM_Port) If InBytes>0 ; Получены данные. Protected Dim InBuffer.a(InBytes), RealInBytes RealInBytes = ReadSerialPortData(#COM_Port, @InBuffer(), InBytes) If RealInBytes>0 AddGadgetItem(4, -1, PeekS(@InBuffer(), RealInBytes, #PB_Ascii)) EndIf EndIf EndIf EndProcedure
Procedure ComOut(Send_data.s) ; Передача данных в порт. Protected Out If IsSerialPort(#COM_Port) ;если порт открыт Out=Val(Send_data) ComWrite(SerialPortID(#COM_Port),@Out,1) ;Посылаем в порт данные из переменной Out Else ; Выводим сообщение об ошибке. MessageRequester("Ошибка","Текущий порт не доступен!",16) EndIf EndProcedure
If OpenWindow(0, 300, 100, 650, 415, "Тестовая программа") ButtonGadget(1, 90, 360, 100, 35, "Принять данные", #PB_Button_Default) TextGadget(2,10,360,25,15,"Порт") ; Выводим в окно надпись "Порт". ComboBoxGadget(3, 10, 375, 70, 21, #PB_ComboBox_Editable) For i=1 To 99 AddGadgetItem(3,-1,"COM"+Str(i)) Next i SetGadgetState(3,0); Делаем активным нулевой пункт выпадающего списка. ;StringGadget(4, 8, 10, 630, 300, "", #PB_String_ReadOnly) ;строковый гаджет, сюда пишем принятые данные EditorGadget(4, 8, 10, 630, 300,#PB_String_ReadOnly) TextGadget(5,10,400,200,15,"") ;Здесь будет отображаться результат открытия порта. ButtonGadget(6, 200, 360, 100, 35, "Очистить окно", #PB_Button_Default) Select_ComPort() Repeat Event = WaitWindowEvent() InData() ;принимаем данные из UART If Event=#PB_Event_Gadget Gadget = EventGadget ( ) ;узнаем какой гаджет был активирован If Gadget=1 ;если нажата кнопка ;MessageRequester("Сообщение", "Нажата кнопка", 0) ;выполняемая функция по нажатию кнопки ComOut("1") ;Переходим на процедуру передачи байта. InData() ElseIf Gadget=3 ;если был активирован выпадающий список ComboBox.s=GetGadgetText(3) ; Считываем текст из текущего пункта выпадающего списка. ;If EventType() = #PB_EventType_Change ; Переходим на процедуру, закрывающую текущий порт и открывающую выбранный. Select_ComPort() ;EndIf ElseIf Gadget=6 ;нажата кнопка очистки ClearGadgetItems(4) ;удаляем содержимое окна с данными EndIf EndIf Until Event=#PB_Event_CloseWindow EndIf End Но все же лучше использовать функцию WriteSerialPortData(). Код #COM_Port = 2 ; Идентификатор COM порта.
;Global Send_data.s ;объявляем переменную глобальной, чтобы получить доступ к ней в процедурах
Procedure Select_ComPort() Protected Port.s, Text.s, Color If IsSerialPort(#COM_Port) ; С таким ИД уже открыт порт. CloseSerialPort(#COM_Port) ; Закрываем его. EndIf Port = GetGadgetText(3) If OpenSerialPort(#COM_Port, Port, 38400, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 255, 255) Text="Порт "+Port+" открыт" : Color=RGB(46, 137, 36) Else Text="Не удалось открыть порт "+Port : Color=RGB(255,0,0) EndIf SetGadgetText(5, Text) SetGadgetColor(5, #PB_Gadget_FrontColor, Color) EndProcedure
Procedure InData() ; Прием данных. Protected InBytes If IsSerialPort(#COM_Port) ; С таким ИД порт открыт. InBytes = AvailableSerialPortInput(#COM_Port) If InBytes>0 ; Получены данные. Protected Dim InBuffer.a(InBytes), RealInBytes RealInBytes = ReadSerialPortData(#COM_Port, @InBuffer(), InBytes) If RealInBytes>0 AddGadgetItem(4, -1, PeekS(@InBuffer(), RealInBytes, #PB_Ascii)) EndIf EndIf EndIf EndProcedure
Procedure ComOut(Send_data.s) ; Передача данных в порт. Protected Out If IsSerialPort(#COM_Port) ;если порт открыт Out=Val(Send_data) WriteSerialPortData(#COM_Port, @Out, 1) Else ; Выводим сообщение об ошибке. MessageRequester("Ошибка","Текущий порт не доступен!",16) EndIf EndProcedure
If OpenWindow(0, 300, 100, 650, 415, "Тестовая программа") ButtonGadget(1, 90, 360, 100, 35, "Принять данные", #PB_Button_Default) TextGadget(2,10,360,25,15,"Порт") ; Выводим в окно надпись "Порт". ComboBoxGadget(3, 10, 375, 70, 21, #PB_ComboBox_Editable) For i=1 To 99 AddGadgetItem(3,-1,"COM"+Str(i)) Next i SetGadgetState(3,0); Делаем активным нулевой пункт выпадающего списка. ;StringGadget(4, 8, 10, 630, 300, "", #PB_String_ReadOnly) ;строковый гаджет, сюда пишем принятые данные EditorGadget(4, 8, 10, 630, 300,#PB_String_ReadOnly) TextGadget(5,10,400,200,15,"") ;Здесь будет отображаться результат открытия порта. ButtonGadget(6, 200, 360, 100, 35, "Очистить окно", #PB_Button_Default) Select_ComPort() Repeat Event = WaitWindowEvent() InData() ;принимаем данные из UART If Event=#PB_Event_Gadget Gadget = EventGadget ( ) ;узнаем какой гаджет был активирован If Gadget=1 ;если нажата кнопка ;MessageRequester("Сообщение", "Нажата кнопка", 0) ;выполняемая функция по нажатию кнопки ComOut("1") ;Переходим на процедуру передачи байта. InData() ElseIf Gadget=3 ;если был активирован выпадающий список ComboBox.s=GetGadgetText(3) ; Считываем текст из текущего пункта выпадающего списка. ;If EventType() = #PB_EventType_Change ; Переходим на процедуру, закрывающую текущий порт и открывающую выбранный. Select_ComPort() ;EndIf ElseIf Gadget=6 ;нажата кнопка очистки ClearGadgetItems(4) ;удаляем содержимое окна с данными EndIf EndIf Until Event=#PB_Event_CloseWindow EndIf End Вот весь список библиотечных функции, работающих с COM портом. http://purebasic.ru/manual.php?id=1148&lng=rus Такой же список можно найти в справке. Для этого достаточно разместить текстовый курсор, скажем на функции OpenSerialPort() и нажать на F1.
Что касается #COM_Port = 2, то это константа, хранящая идентификатор объекта, в нашем случае, COM порта. Дело в том, что одновременно можно открыть несколько портов и нужно как-то их идентифицировать при обращении к ним.
Цитата (trim) привет ребят кто потскажет как передать координаты осей джойстика в мк через компорт Нужно придумать протокол обмена и реализовать его со стороны ПК и МК.
Сообщение отредактировал Петр - Суббота, 22.12.2012, 15:30 |
|
| |
trim | Дата: Суббота, 22.12.2012, 18:00 | Сообщение # 20 |
Группа: Проверенные
Сообщений: 105
Статус: Offline
| чо нить типа этого
Dim Vhod As String * 28 'хранит команду пришедшую по UART Dim Xpos As String * 5
Dim Ypos As String * 5 'хранит числовое значение необходимых шагов Dim Rpos As String * 5 Dim Stp As Byte Dim A As Byte Dim B As Byte Dim C As Byte Dim D As Byte
Stp = 0
Config Portd.2 = Input Config Portd.3 = Output Config Porta.5 = Output Config Porta.4 = Output
Enable Interrupts Enable Urxc On Urxc Command
Do
Command: Input Vhod Xpos = Left(vhod , 5) Ypos = Mid(vhod , 6 , 5) Rpos = Right(vhod , 5)
A = Len(vhod) B = Len(xpos) C = Len(ypos) D = Len(rpos)
A = A - B
C = C - D
Stp = A - C
If Stp > 0 Then Print Stp Else Waitms 50 End If If A = 5 Then Porta.4 = 1 Else Porta.4 = 0 End If
Gosub Command Loop Return
|
|
| |
exersizze | Дата: Воскресенье, 23.12.2012, 16:04 | Сообщение # 21 |
Группа: Администраторы
Сообщений: 723
Статус: Offline
| Петр, спасибо! только что проверил, все работает!!
|
|
| |
trim | Дата: Пятница, 28.12.2012, 23:46 | Сообщение # 22 |
Группа: Проверенные
Сообщений: 105
Статус: Offline
| exersizze, уважаемый гуру ,вопрос теперь к вам ,как организовать прием байт в мк ,вот ,даже не знаю как спросить то правильно, вопщем данные поступают постоянно первая цыфра 8 размер пакета ,три оси по 5 цифр и конец передачи цыфра 13 как их принять последовательно и обработать вот наверное как то так
Сообщение отредактировал trim - Суббота, 29.12.2012, 00:45 |
|
| |
exersizze | Дата: Суббота, 29.12.2012, 08:40 | Сообщение # 23 |
Группа: Администраторы
Сообщений: 723
Статус: Offline
| Есть несколько способов. Первый и самый простой - командой Input
Код Dim A as string*20 Do Input A 'в переменную А будут записываться данные из буфера UART ..... 'дальше обрабатываем данные как необходимо Loop End
Прием данных можно вынести из главного цикла и сделать обработку по прерыванию
Код Dim A as string*20
On Urxc Priem 'даем ссылку обработчику прерывания UART
'разрешаем прерывания Enable Interrupts Enable Urxc 'разрешаем прерывание UART Do 'основная программа Loop End
Priem: 'сработало прерывание при появлении данных в буфере UART Input A 'принимаем их Return
Для извлечения данных есть еще команды Inkey http://avrhelp.mcselec.com/index.html?inkey.htm и Waitkey http://avrhelp.mcselec.com/index.html?waitkey.htm Прием данных с применением функции Inkey я недавно описывал здесь http://avrproject.ru/publ....1-0-128 Waitkey используется аналогично, отличия от инкея лишь в том что эта функция не возвращает ничего если буфер пуст (инкей возвратит 0), поэтому если в буфере ничего нет вайткей будет ждать пока что-нибудь появится, т.е. выполнение программы остановится
|
|
| |
trim | Дата: Суббота, 29.12.2012, 21:20 | Сообщение # 24 |
Группа: Проверенные
Сообщений: 105
Статус: Offline
| спасибо огромное все понятно
|
|
| |
max | Дата: Вторник, 01.01.2013, 21:56 | Сообщение # 25 |
Группа: Друзья
Сообщений: 170
Статус: Offline
| Цитата (Петр) Функция ComWrite() из сторонней библиотеки А где скачать эту библиотеку?
|
|
| |
Петр | Дата: Среда, 02.01.2013, 15:06 | Сообщение # 26 |
Группа: Проверенные
Сообщений: 47
Статус: Offline
| Цитата (max) А где скачать эту библиотеку? Например в этой статье есть на нее ссылка.
|
|
| |
max | Дата: Четверг, 03.01.2013, 00:53 | Сообщение # 27 |
Группа: Друзья
Сообщений: 170
Статус: Offline
| Спасибо.
|
|
| |
AlekS | Дата: Понедельник, 04.02.2013, 22:29 | Сообщение # 28 |
Группа: Проверенные
Сообщений: 247
Статус: Offline
| Петр, Есть ли команда для сохранения лога принятаго в файл, при посылки команды? В СОМ передаем типа 0133, а принятое идет в файл лога.
|
|
| |
Петр | Дата: Среда, 06.02.2013, 23:00 | Сообщение # 29 |
Группа: Проверенные
Сообщений: 47
Статус: Offline
| Есть функции работы с файлами и этого достаточно. http://purebasic.ru/manual.php?id=374&lng=rus
Нужно в начале программы открыть файл и перейти в его конец. Код If OpenFile(0, "Log.txt") FileSeek(0, Lof(0)) EndIf Допустим что данные, которые нужно записать в файл, находятся в строковой переменной с именем LogString. Тогда запись в файл будет иметь вид: Код WriteString(0, LogString) FlushFileBuffers(0) Для чего нужна функция WriteString() думаю и так понятно и не требует пояснений. А назначение функции FlushFileBuffers() может быть не очевидно. Она нужна для скидывания данных в файл. Дело в том, что ОС буферизирует данные и не факт что при записи в файл, произойдет фактическая запись в него. ОС может поместить данные в буфер и записать его содержимое в файл только при закрытии файла. В принципе функция FlushFileBuffers() не обязательна, но ее вызов позволит сразу же записать данные из буфера в файл. Тем самым они не будут потеряны если программу некорректно завершить.
В конце программы, нужно вызвать функцию CloseFile(), которая закроет файл.
Сообщение отредактировал Петр - Среда, 06.02.2013, 23:01 |
|
| |
AlekS | Дата: Среда, 06.02.2013, 23:13 | Сообщение # 30 |
Группа: Проверенные
Сообщений: 247
Статус: Offline
| Спасибо, роде все внятно. Буду пытать.
|
|
| |
nooby | Дата: Понедельник, 04.03.2013, 15:38 | Сообщение # 31 |
Группа: Пользователи
Сообщений: 2
Статус: Offline
| Привет всем!
Разбираюсь с кодом для проекта "Управляем микроконтроллером с ПК по UART". Подключаюсь к своему устройству (Bluetooth, профиль SPP) порт нормально открывается (использую COM4). Однако, если затем кликнуть на конпки или в текстовое окно, то выскакивает ошибка "Текущий порт не доступен" и зеленая надпись "порт СОМ4 открыт" сменяется красной надписью "Не удалось открыть порт". Если же в коде сделать активным четвертый пункт выпадающего списка (тоесть SetGadgetState(3,3)), то порт сразу открывается (после компиляции) и все отлично работает. В чем ошибка? Спасибо!
|
|
| |
exersizze | Дата: Понедельник, 04.03.2013, 18:19 | Сообщение # 32 |
Группа: Администраторы
Сообщений: 723
Статус: Offline
| Странное поведение, а если открыть другим терминалом (например "by Bray") порт нормально открывается?
|
|
| |
nooby | Дата: Понедельник, 04.03.2013, 18:34 | Сообщение # 33 |
Группа: Пользователи
Сообщений: 2
Статус: Offline
| С другими терминалами (встроенный в баском, putty и т.д) проблем нет.
|
|
| |
AlekS | Дата: Суббота, 09.03.2013, 14:20 | Сообщение # 34 |
Группа: Проверенные
Сообщений: 247
Статус: Offline
| Петр, Что у меня не так?
|
|
| |
max | Дата: Суббота, 09.03.2013, 15:09 | Сообщение # 35 |
Группа: Друзья
Сообщений: 170
Статус: Offline
| У Петра есть свой форум.
|
|
| |
Петр | Дата: Воскресенье, 10.03.2013, 14:10 | Сообщение # 36 |
Группа: Проверенные
Сообщений: 47
Статус: Offline
| Цитата (AlekS) Что у меня не так? Ну как минимум, отсутствует подробное описание проблемы.
|
|
| |
AlekS | Дата: Воскресенье, 10.03.2013, 19:59 | Сообщение # 37 |
Группа: Проверенные
Сообщений: 247
Статус: Offline
| Файл создается, запись нет, длина ноль.
|
|
| |
Петр | Дата: Воскресенье, 10.03.2013, 22:56 | Сообщение # 38 |
Группа: Проверенные
Сообщений: 47
Статус: Offline
| В программе нет записи в файл. В 92 строке, функция WriteData() закомментирована. Не понятно зачем в строке находится функция CreateFile()? Она же сотрет содержимое файла при закрытии программы.
Должно быть примерно так. Код #COM_Port = 1 ; Идентификатор COM порта.
Procedure Select_ComPort() Protected Port.s, Text.s, Color If IsSerialPort(#COM_Port) ; С таким ИД уже открыт порт. CloseSerialPort(#COM_Port) ; Закрываем его. EndIf Port = GetGadgetText(3) If OpenSerialPort(#COM_Port, Port, 19200, #PB_SerialPort_NoParity, 8, 1, #PB_SerialPort_NoHandshake, 255, 255) Text="Порт "+Port+" открыт" : Color=RGB(46, 137, 36) Else Text="Не удалось открыть порт "+Port : Color=RGB(255,0,0) EndIf SetGadgetText(5, Text) SetGadgetColor(5, #PB_Gadget_FrontColor, Color) EndProcedure
Procedure InData() ; Прием данных. Protected InBytes, String.s If IsSerialPort(#COM_Port) ; С таким ИД порт открыт. InBytes = AvailableSerialPortInput(#COM_Port) If InBytes>0 ; Получены данные. Protected Dim InBuffer.a(InBytes), RealInBytes RealInBytes = ReadSerialPortData(#COM_Port, @InBuffer(), 4) ; InBytes заменил на 4 байта If RealInBytes>0 String=PeekS(@InBuffer(), RealInBytes, #PB_Ascii) AddGadgetItem(4, -1, String) WriteStringN(0, String) FlushFileBuffers(0) EndIf EndIf EndIf EndProcedure
Procedure ComOut(Send_data.s) ; Передача данных в порт. If IsSerialPort(#COM_Port) ;если порт открыт WriteSerialPortData(#COM_Port,@send_data,4) ;Посылаем в порт данные из переменной Out Else ; Выводим сообщение об ошибке. MessageRequester("Ошибка","Текущий порт не доступен!",16) EndIf EndProcedure
OpenFile(0, "SHT.log") FileSeek(0, Lof(0))
If OpenWindow(0, 300, 100, 420, 370, "COM программа для SHT21") ButtonGadget(1, 90, 300, 100, 45, "Запрос состояния", #PB_Button_MultiLine) TextGadget(2,10,310,25,15,"Порт") ; Выводим в окно надпись "Порт". ComboBoxGadget(3, 10, 325, 70, 21, #PB_ComboBox_Editable) For i=1 To 99 AddGadgetItem(3,-1,"COM"+Str(i)) Next i SetGadgetState(3,0); Делаем активным нулевой пункт выпадающего списка. EditorGadget(4, 8, 10, 305, 280,#PB_String_ReadOnly) TextGadget(5,10,350,200,15,"") ;Здесь будет отображаться результат открытия порта. ButtonGadget(6, 200, 300, 100, 45, "Запрос влажности и температуры", #PB_Button_MultiLine) ButtonGadget(9, 310, 300, 100, 45, "Запись в файл памяти", #PB_Button_MultiLine) Select_ComPort() Repeat Event = WaitWindowEvent() InData() ;принимаем данные из UART If Event=#PB_Event_Gadget ;если произошло срабатывание гаджета Gadget = EventGadget ( ) ;узнаем какой гаджет был активирован If Gadget=1 ;если нажата кнопка ComOut("2101") ;Переходим на процедуру передачи байта. InData() ElseIf Gadget=3 ;если был активирован выпадающий список ComboBox.s=GetGadgetText(3) ; Считываем текст из текущего пункта выпадающего списка. ; Переходим на процедуру, закрывающую текущий порт и открывающую выбранный. Select_ComPort() ElseIf Gadget=6 ;нажата кнопка очистки ComOut("2102") ;Переходим на процедуру передачи байта. InData() ElseIf Gadget=9 ;нажата кнопка файл ComOut("2103") ;Переходим на процедуру передачи байта. InData() ; Прием данных в файл. ;WriteSerialPortData(#COM_Port, *Buffer, 255) EndIf EndIf Until Event=#PB_Event_CloseWindow EndIf
CloseFile(0)
;Result = CreateFile(0, "SHT.log")
End
|
|
| |
AlekS | Дата: Воскресенье, 10.03.2013, 23:06 | Сообщение # 39 |
Группа: Проверенные
Сообщений: 247
Статус: Offline
| Спасибо. Это запись WriteStringN(0, String) FlushFileBuffers(0) А как определяется длина записи в байтах?
|
|
| |
Петр | Дата: Воскресенье, 10.03.2013, 23:09 | Сообщение # 40 |
Группа: Проверенные
Сообщений: 47
Статус: Offline
| В данном случае, длина записи равна длине строки, плюс символы новой строки. http://purebasic.ru/manual.php?id=405&lng=rus
|
|
| |
AlekS | Дата: Воскресенье, 10.03.2013, 23:15 | Сообщение # 41 |
Группа: Проверенные
Сообщений: 247
Статус: Offline
| Спасибо, буду еще читать.
|
|
| |
AlekS | Дата: Воскресенье, 10.03.2013, 23:19 | Сообщение # 42 |
Группа: Проверенные
Сообщений: 247
Статус: Offline
| Где примеры посмотреть, что б с коментами были.
|
|
| |
Петр | Дата: Воскресенье, 10.03.2013, 23:45 | Сообщение # 43 |
Группа: Проверенные
Сообщений: 47
Статус: Offline
| Примеры чего? Записи в файл? По моему в справке нормальное описание. http://purebasic.ru/manual.php?id=374&lng=rus
|
|
| |
AlekS | Дата: Четверг, 14.03.2013, 20:27 | Сообщение # 44 |
Группа: Проверенные
Сообщений: 247
Статус: Offline
| Ненашел как здесь передать $1501 число вместо 2101
If Gadget=1 ;если нажата кнопка ComOut("2101") ;Переходим на процедуру передачи байта. InData()
Есть только команда Vol ( data )
Сообщение отредактировал AlekS - Четверг, 14.03.2013, 20:29 |
|
| |
Петр | Дата: Пятница, 15.03.2013, 00:04 | Сообщение # 45 |
Группа: Проверенные
Сообщений: 47
Статус: Offline
| Так нужно передать данные в виде числа или в виде строки? В тексте речь идет вроде про число, а в коде - строка.
|
|
| |
AlekS | Дата: Суббота, 16.03.2013, 14:11 | Сообщение # 46 |
Группа: Проверенные
Сообщений: 247
Статус: Offline
| В простой терминалке передаю $15 $01 код Hex, или десятичном 21 01 это два числа. Мк должно принять $15 как адрес устройства, а $01 команда. Т.е. два числа.
|
|
| |
Петр | Дата: Суббота, 16.03.2013, 15:16 | Сообщение # 47 |
Группа: Проверенные
Сообщений: 47
Статус: Offline
| Тогда код передачи будет таким: Код Dim OutPort.a(1) ; Создали массив однобайтовых переменных (два элемента).
OutPort(0)=$15 OutPort(1)=$01
WriteSerialPortData(#COM_Port, @OutPort(), 2)
|
|
| |
AlekS | Дата: Суббота, 16.03.2013, 16:22 | Сообщение # 48 |
Группа: Проверенные
Сообщений: 247
Статус: Offline
| Спасибо, понял.
|
|
| |
Aleks8383 | Дата: Понедельник, 27.05.2013, 11:37 | Сообщение # 49 |
Группа: Проверенные
Сообщений: 104
Статус: Offline
| Немного не в тему,но спрошу.Не кто не делал в ПУРИКЕ индикатор уровня,те я буду контроллером снимать напряжения и передовать в комп.На этом этапе всё понятно,а вот как в программе нарисовать сам индикатор не как не разберусь.Вопрос наверное больше к Петру,но если кто знает тоже спасибо.
|
|
| |
Петр | Дата: Вторник, 28.05.2013, 13:18 | Сообщение # 50 |
Группа: Проверенные
Сообщений: 47
Статус: Offline
| Как внешне должен выглядеть индикатор? Как стрелочный или цифровой или как-то по другому?
Стрелочный индикатор. http://purebasic.fr/english/viewtopic.php?f=12&t=54117
Сообщение отредактировал Петр - Вторник, 28.05.2013, 13:19 |
|
| |