PB -7- Arduino 2x16 LCD kontrolü
Bilgisayarda forma gireceğimiz yazı, butona tıklayınca, LCD ekranda görülecektir. LCD ekran 2 satırdan oluşuyor. Her satır 16 karakter alabiliyor. PureBasic ile kullanıcının 32 karakterden fazla giriş yapmasını engelliyoruz.
Aşağıdaki devreyi oluşturmak için LCD dışında 220 ohm direnç ve 10K potansiyometre gerekiyor.
Aşağıdaki kodu Arduino’ya yüklüyoruz..
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
String text = "";
bool stringComplete = false;
void setup() {
Serial.begin(9600);
lcd.begin(16, 2);
lcd.print(" enter text");
}
void loop() {
if (stringComplete) {
stringComplete = false;
lcd.clear();
if (text.length() < 16) {
lcd.print(text);
} else {
lcd.print(text.substring(0, 16));
lcd.setCursor(0, 1);
lcd.print(text.substring(16, 32));
}
text = "";
}
}
void serialEvent() {
while (Serial.available()) {
char inChar = (char) Serial.read();
if (inChar == '\n') {
stringComplete = true;
break;
}
text += inChar;
}
}
Arduino’ya seri porttan bilgi geldiğinde, LineFeed karakterine rastlayana kadar gelen karakterleri birleştiriyor. LineFeed geldiğinde gelen bilgiyi LCD ekrana yazdırıyor. Yine PB-5 DHT11 yazısındaki comPort.pb kodunu boş bir dizine kopyalayalım. Aşağıdaki kodu da, Lcd.pb olarak aynı dizine kaydet. Satır sonu karakterini \EndOfText = #LF$ olarak değiştirdim. InitComport() prosedüründe bulunan Baud ve Port ayarlarını kendine göre ayarlaman gerekiyor.
XIncludeFile "comPort.pb"
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())
AddGadgetItem(0, -1, Text)
SetGadgetState(0, CountGadgetItems(0) - 1)
SetGadgetState(0, -1)
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 = 9600
\Parity = #PB_SerialPort_NoParity
\DataBit = 8
\StopBit = 1
\Handshake = #PB_SerialPort_NoHandshake
\BufferSize = 2048
\EndOfText = #LF$
\StatusCB = @StatusCB()
\ReceiveCB = @ReceiveCB()
\ThreadID = CreateThread(@thComport(), ComData)
If Not \ThreadID
ProcedureReturn 0 ; Error create thread
Else
ProcedureReturn 1 ; ok
EndIf
EndWith
EndProcedure
; ---------------------------------------------------------------------------
Procedure SendToArduino(textInfo.s)
If ComData\Status = #ComThread_Running And ComData\SendSignal = #False
ComData\SendText = textInfo
ComData\SendSignal = #True
EndIf
EndProcedure
; ---------------------------------------------------------------------------
Define Event, Text.s, i
OpenWindow(0, #PB_Ignore, #PB_Ignore, 220, 220, "LCD test",
#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CreateStatusBar(0, WindowID(0))
AddStatusBarField(#PB_Ignore)
TextGadget(0, 0, 80, 220, 20, "(1,0)", #PB_Text_Center)
EditorGadget(1, 10, 30, 200, 35, #PB_Editor_WordWrap)
ButtonGadget(2, 65, 110, 90, 30, "SEND")
ButtonGadget(3, 65, 150, 90, 30, "On/Off")
TextGadget(4, 0, 10, 220, 20, "Don't press Enter key", #PB_Text_Center)
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 1
If EventType() = #PB_EventType_Change
counter = Len(GetGadgetText(1))
If counter <= 16
SetGadgetText(0, "(1," + counter + ")")
ElseIf counter > 16 And counter<=32
counter - 16 ; counter = counter - 16
SetGadgetText(0, "(2," + counter + ")")
Else
text = GetGadgetText(1)
ClearGadgetItems(1) ; EditorGadget'i siliyor
SetGadgetText(1, Left(text, 32))
; https://www.purebasic.fr/english/viewtopic.php?t=43583&start=11
; https://learn.microsoft.com/en-us/windows/win32/apiindex/windows-api-list
; Win32 API komutu, işletim sistemine (Mac OS, Linux) göre değişebilir
; Bu komut cursor'u 32. karaktere getiriyor
SendMessage_(GadgetID(1), #EM_SETSEL, 32, 32)
EndIf
EndIf
Case 2 ; SEND button
If ComData\Status = 0
MessageRequester("Warning", "Press On/Off first!", #PB_MessageRequester_Warning)
EndIf
SendToArduino(GetGadgetText(1))
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
Boş kutuya (EditorGadget) her karakter girildiğinde Case 1 altında kodlanan #PB_EventType_Change olayı oluşmaktadır. Bu olay takip edilerek, kullanıcının 32 karakterden fazla giriş yapması engellenmiştir.