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..
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.
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.
Youtube’da izleyebilirsin..
Soru veya görüşlerini Youtube yorumlarına yazabilirsin..