PB -4- Arduino ile mesafe ölçümü

PureBasic ile Arduino’ya bağlı HC-SR04 ultrasonik sensörden gelen bilgiyi yine seri port üzerinden okuyoruz fakat seri port için ayrı bir thread kullanarak..

image

Aşağıdaki kodu Arduino’ya yüklüyoruz..

 const int trigPin = 5, echoPin = 6;
 long distance;
 long duration;
 void setup() {
   pinMode(trigPin, OUTPUT);
   pinMode(echoPin, INPUT);
   Serial.begin(19200);
 }
 void loop() {
 digitalWrite(trigPin, LOW);
   delayMicroseconds(5);
   digitalWrite(trigPin, HIGH);
   delayMicroseconds(10);
   digitalWrite(trigPin, LOW);
   duration = pulseIn(echoPin, HIGH); //microseconds
   distance = duration / 2 / 29.1; //cm
   if(distance > 200)
   distance = 200;
 Serial.println(distance);
   delay(100);
 }


Bu kodu Arduino’ya yükledikten sonra, her 100 milisaniyede bir mesafe bilgisi cm olarak seri port ile Purebasic’e iletilecektir. Arduino üzerindeki led’in yanıp sönme hızından aktarımın ne kadar hızlı olduğunu görebilirsin. Seri portu, thread ile kullanmak için github hesabımdaki, Purebasic forumundan bulduğum kodu kullanacağız. Böylece seri port işlerini halleden kısım thread olarak çalışacağından, ana programı meşgül etmeyecek..
Kodu, comPort.pb olarak belgelerim dizini altında yeni oluşturacağın bir dizine kaydedebilirsin.

SR04 Bu resmi de SR04.PNG olarak aynı dizine kaydet.

Kodu çalıştırırken “Use Option Threadsafe!” hatası alırsan Compiler ➡️ Compiler Options ➡️ Create threadsafe executable seçeneğini işaretlemen gerekir. Aşağıdaki kod ise ana programı oluşturacak. XIncludeFile komutu ile comPort.pb dosyasını ana programa dahil ediyoruz.

XIncludeFile "comPort.pb"

EnableExplicit

Global ComData.udtComData

Enumeration EventCustomValue #PB_Event_FirstCustomValue
  #My_Event_NewData
  #My_Event_NewState
EndEnumeration

; ---------------------------------------------------------------------------

Procedure ReceiveCB(Text.s)
  PostEvent(#My_Event_NewData, 0, 0, 0, AllocateString(Text))
EndProcedure

Procedure MyEventNewDataCB()
  Protected Text.s
  Text = FreeString(EventData())
  SetGadgetText(1, Text + " cm")
  SetGadgetState(2, Val(Text))
EndProcedure

BindEvent(#My_Event_NewData, @MyEventNewDataCB())

; ---------------------------------------------------------------------------

Procedure StatusCB(Status, *ComData.udtComData)
  PostEvent(#My_Event_NewState, 0, 0, Status, *ComData)
EndProcedure

Procedure MyEventNewStateCB()
  Protected Text.s, Status, *ComData.udtComData
  Status = EventType()
  *ComData = EventData()
  Select Status
    Case #ComStatus_OpenPort
      Text = "ComStatus: Open Port " + *ComData\Port
    Case #ComStatus_ClosePort
      Text = "ComStatus: Close Port " + *ComData\Port
    Case #ComStatus_ErrorOpenPort
      Text = "ComError: Open Port " + *ComData\Port
    Case #ComStatus_ErrorSend
      Text = "ComError Send: Port " + *ComData\Port + " - " + SerialPortErrorText(*ComData\SendError)
    Case #ComStatus_ErrorReceive
      Text = "ComError Receive: Port " + *ComData\Port + " - " + SerialPortErrorText(*ComData\ReceiveError)
    Case #ComStatus_ErrorDataSize
      Text = "ComError Send: Port " + *ComData\Port + " - Send data size to big."
  EndSelect
  If Bool(Text)
    StatusBarText(0, 0, Text)
  EndIf
EndProcedure

BindEvent(#My_Event_NewState, @MyEventNewStateCB())

; ---------------------------------------------------------------------------

Procedure InitComport()
  With ComData
    If \Status
      ProcedureReturn 2 ; Always running
    EndIf
    \Port = "COM3"
    \Baud = 19200
    \Parity = #PB_SerialPort_NoParity
    \DataBit = 8
    \StopBit = 1
    \Handshake = #PB_SerialPort_NoHandshake
    \BufferSize = 2048
    \EndOfText = #CRLF$
    \StatusCB = @StatusCB()
    \ReceiveCB = @ReceiveCB()
    \ThreadID = CreateThread(@thComport(), ComData)
    If Not \ThreadID
      ProcedureReturn 0 ; Error create thread
    Else
      ProcedureReturn 1 ; ok
    EndIf
  EndWith
EndProcedure

LoadFont(0, "Arial", 12) ; , #PB_Font_Bold)
SetGadgetFont(#PB_Default, FontID(0))
UsePNGImageDecoder()
Define Event, Text.s, img
#win_flags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
OpenWindow(0, #PB_Ignore, #PB_Ignore, 400, 250, "Distance Meter", #win_flags)
CreateStatusBar(0, WindowID(0))
AddStatusBarField(#PB_Ignore)

LoadImage(0, "SR04.PNG")
ImageGadget(0,  10, 10, 100, 83, ImageID(0))
TextGadget(1, 120, 135, 150, 30, "")
ProgressBarGadget(2, 110, 95, 280, 30, 0, 200)
ButtonGadget(3, 300, 190, 90, 30, "On/Off")

Repeat
  Event = WaitWindowEvent()
  Select Event
    Case #PB_Event_CloseWindow
      If ComData\Status
        MessageRequester("Info", "Comport Is Open!", #PB_MessageRequester_Warning)
      Else
        Break
      EndIf
      
    Case #PB_Event_Gadget
      Select EventGadget()       
        Case 3 ; on/off button
          If ComData\Status
            ComData\Exit = 1
          Else
            If Not InitComport()
              StatusBarText(0, 0, "Comport " + ComData\Port + ": Error Create Thread")
            EndIf
          EndIf
      EndSelect       
  EndSelect
ForEver


Mk-soft’un hazırladığı seri port thread programını küçük dokunuşlarla kendimize adapte etmiş olduk.. InitComport() prosedüründe bulunan COM portu ayarlamayı unutma.

image

Youtube’da izleyebilirsin..
Soru veya görüşlerini Youtube yorumlarına yazabilirsin..

Written on September 13, 2024