PB -1- Arduino ile LED kontrolü

PureBasic ile hazırlayacağımız, arayüz veya kullanıcı formu ile Arduino’yu kontrol edeceğiz. Bir tane ucuzundan Arduino Uno alıp, bu dili öğrenmek daha faydalı ve eğlenceli olacaktır.

Linkteki klon Arduino’yu aldıysan CH340 sürücü kurulumunu da yapman gerekiyor. CH340, klon kartlarda usb-seri çevirici entegresidir.

PC ile Arduino arasında haberleşme için (seri bağlantı) Arduino’nun kendi usb kablosunu kullanacağız. Kablo dışında bir LED ve 220 ohm ile 1K arası bir dirence ihtiyaç olacak. Benim gibi yazılıma merak sarmış elektronikçilerin yanısıra elektroniğe merak sarmış yazılımcılar da bu yazıyı okuyabilir. O yüzden breadboard’dan biraz bahsedeyim. Breadboard üzerinde bulunan her 5 delik kısa devredir, malzemeleri birbirine bağlamak için kullanılır. Şemadaki gibi bağlantı yaparsan devre çalışmayacaktır. Arduino GND’den gelen kablo, direncin girdiği 5 delikten birine girmelidir. Ayrıca LED’i ters bağlarsan yanmaz. Evet, bu şema için breadboard’a gerek yok ama başka şemalarda ihtiyacın olabilir.

Seri port, yeni bir dizüstü PC alınca göremeyeceğin, en eski bağlantı tipi olmasına rağmen halen fabrikalarda ve yeni üretilen endüstriyel cihazlarda kullanılmaktadır. En yaygın seri port soketi 2 sıra, 9 pin olandır. Bağlantı yapacağın cihaza göre pin bağlantıları değişebilir.

_config.yml
Çalışmayan devre şeması 😄

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

void setup() {
  pinMode(8, OUTPUT);
  Serial.begin(19200);
}

void loop() {
  if(Serial.available())
  {
    char c = Serial.read();
    if(c == '1')
    {
    digitalWrite(8,HIGH);
    Serial.println("LED IS ON");
    }
    else if(c == '0')
    {
    digitalWrite(8,LOW);
    Serial.println("LED IS OFF");
    }
  }
}


Arduino IDE’de Araçlar ➡️ Seri Port Ekranı menüsünden, aşağıdaki pencereyi açıyoruz. Arduino’ya 1 yollarsak led yanacak, 0 yollarsak sönecektir. Görüldüğü gibi Arduino bize, bilgiyi aldığını teyit eden bir cevap da yollayacaktır.

image

Bu işleri yapmak için Arduino IDE 1.8.19 sürümünü indirdim. (Gerekenden daha büyük yazılımları bilgisayara yükleyerek, onu kastırmaya oldum olası karşı çıkmışımdır. O yüzden ısrarla, son sürüm olan 2.3.2’yi indirmiyorum.) PureBasic son sürüm Demo programını, buradan indirebilirsin.. Bilgisayarın, Windows ise 64-bit sürümü indirebilirsin.. Tabii, Mac OS veya Linux kullanıyorsan, sana uygun sürümü indirebilirsin. PB kurulum dosyası, Arduino IDE’den daha küçük farkettiysen. PB Demo ile en fazla 800 satır büyüklüğünde bir program yazabilirsin. Bu da, bu tip projeler için gayet yeterli bir satır sayısıdır..


Bu Arduino kodu, ne işe yarayacak, çok basit demeyin. Burada amacımız PB’i tanımak olsa da bu kodu bir projede kullanmıştık. Konveyör bantta ilerleyen ürünlerin üzerine etiketleme için yaz ve uygula makinası yerleştirmiştik. Makinadan geçen, etiketi uygulanan ürünler sonrasında bir barkod okuyucunun altından geçiyordu. Barkod okununca, bu bilgi PC’de bulunan SQL sunucuya kaydediliyordu. Barkod’un okunamaması durumunda, konveyörün durması gerekir. İşte bu noktada, Arduino’ya şemadaki led yerine bir SSR bağlamıştım. SSR çıkışını da konveyör motorunun sürücüsüne bağladık. Bu sayede, PC’de yazılım geliştiren arkadaş konveyörü durdurup, harekete geçirebiliyordu. SSR, yerine bir röle de bağlanabilirdi. Bu tip işlerde, normalde PLC kullanılır.. Bir tane kontak için de PLC’ye gerek yok diye düşünmüştüm.

Aşağıdaki kodu PB IDE’ye kopyalayıp yapıştırın.. Öncesinde New butonuna basarak boş bir sayfa açın. Artık Arduino IDE’yi kapatabilirsin. Çünkü, seri portu, aynı anda ancak bir program kullanabilir..

EnableExplicit

Enumeration
  #win_main
  #txt
  #txt_status
  #btn_on
  #btn_off
  #cmb_comPort
  #serial_portNr
EndEnumeration

Global PortsFound = 0, Event, COMPort.s="", DataReceived.s
Global StartTime, Timeout = 1000, Result
Global *Buffer = AllocateMemory(128)

#FLAGS = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
OpenWindow(#win_main, 0, 0, 200, 180, "Arduino LED control", #FLAGS) 
ComboBoxGadget(#cmb_comPort, 110, 15, 80, 23)

TextGadget(#txt, 10, 25, 280, 20, "Serial Port :")
TextGadget(#txt_status, 0, 140, 200, 40, "Status comes from Arduino", #PB_Text_Center)
ButtonGadget(#btn_on, 10, 70, 80, 50, "LED ON")
ButtonGadget(#btn_off, 110, 70, 80, 50, "LED OFF")


Procedure Find_Ports()
  Protected i
  For i = 0 To 255
    COMPort="COM"+Str(i+1)
    If OpenSerialPort(i, COMPort, 19200, 0, 8, 1, #PB_SerialPort_NoHandshake, 1, 1)        
      AddGadgetItem(#cmb_comPort,-1, COMPort)
      CloseSerialPort(i) 
    EndIf
  Next
  PortsFound=1
EndProcedure


Procedure Port_Control()
  If  IsSerialPort(#serial_portNr) : CloseSerialPort(#serial_portNr) : EndIf
  
  COMPort = GetGadgetText(#cmb_comPort)
  If COMPort = ""
    SetGadgetText(#txt_status, "First select port !")
    ProcedureReturn #False
  Else
    If IsSerialPort(#serial_portNr); if port open
      ProcedureReturn #True
    Else                            ; if port closed
      OpenSerialPort(#serial_portNr, COMPort, 19200, 0, 8, 1, #PB_SerialPort_NoHandshake, 1, 1)
      SetGadgetText(#txt_status, "Port is open.. Wait 2-3 secs" + #LF$ + 
                                 "for the arduino to be ready..")
      
      If IsSerialPort(#serial_portNr)
        ProcedureReturn #True
      Else
        MessageRequester("Error","Port can't be opened !", #PB_MessageRequester_Error)
        ProcedureReturn #False
      EndIf 
    EndIf     
  EndIf
EndProcedure


Procedure Receive_Response()
  Repeat
    Event = WaitWindowEvent(20)
    Result = AvailableSerialPortInput(#serial_portNr)      
    If Result 
      ;While Result 
      ReadSerialPortData(#serial_portNr, *Buffer, Result) 
      DataReceived = PeekS(*Buffer, -1, #PB_Ascii)
      ;Result = AvailableSerialPortInput(#serial_portNr) 
      ;Wend
      SetGadgetText(#txt_status, DataReceived)
      Break 
    EndIf
    Delay(1)  ; Let system do other things 
  Until ElapsedMilliseconds() - StartTime > Timeout
  
  If ElapsedMilliseconds() - StartTime > Timeout
    MessageRequester("Error","Usb cable is disconnected or.." + 
                             #LF$ + "Arduino isn't connected to the selected port or.." + 
                             #LF$ + "You didn't wait 2-3 seconds when the port was first opened..",
                     #PB_MessageRequester_Error)
    CloseSerialPort(#serial_portNr)
  EndIf                 
EndProcedure


Repeat
  Event = WaitWindowEvent()
  
  If PortsFound=0
    Find_Ports()
  EndIf
  
  Select Event
    Case #PB_Event_Gadget
      Select EventGadget()
          
        Case #btn_on
          If IsSerialPort(#serial_portNr)
            WriteSerialPortString(#serial_portNr, "1", #PB_Ascii)
            StartTime = ElapsedMilliseconds()
            Receive_Response()
          Else 
            Port_Control()
          EndIf  
          
        Case #btn_off 
          If IsSerialPort(#serial_portNr)
            WriteSerialPortString(#serial_portNr, "0", #PB_Ascii)
            StartTime = ElapsedMilliseconds()
            Receive_Response()
          Else 
            Port_Control()
          EndIf 
          
        Case #cmb_comPort
          Port_Control()
          
      EndSelect
  EndSelect
Until Event = #PB_Event_CloseWindow

FreeMemory(*Buffer)
End


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

Programı test etmek için aslında Arduino’ya da ihtiyacın yok. Bu durumda Arduino’nun yaptığı işi senin yapman gerekecek. Eski blog sayfamda anlattığım com0com sanal seri port programını kullanabilirsin.

Programı çalıştırınca küçük bir pencere açılacaktır..

image

Herhangi bir komutla ilgili bilgi almak istersen, o komutun üstüne tıkla.. Klavyeden F1 tuşuna bastığında yardım sayfası açılacaktır. Kodlardan biraz bahsedelim. Enumeration bölümünde bize ait sabitleri tanımlıyoruz. Bize ait dedim, çünkü #PB_ ile başlayan sabitler PB’e aittir. PB’e ait sabitleri ve yapıları (structure) görmek için Tools ➡️ Structure Viewer menüsüne tıklayabilirsin. Kodumuzda, en üstteki sabit 0, en alttaki 6 değerini almış oluyor. Bu sabitleri, gadget’leri kimliklendirmede kullanıyoruz. Onun altında pencereyi ve gadget’leri oluşturuyoruz. Formu bu şekilde kodlarla hazırlamak daha çok hoşuma gidiyor. Böylece herşey tek sayfada gözüküyor. Find_Ports() prosedürü, PC’de bulunan seri portları bulup ComboBox’a kaydediyor. Port_Control() prosedürü, kullanıcı port değiştirince çalışıyor. Receive_Response(), butona tıklayınca Arduino cevap verecektir, bu cevapı okumak için kullanılan prosedürdür. Repeat-Until gibi döngülerde, pencere için oluşan olayların sifonunu çekmeniz gerekir. (İngilizcesi flush olan kelimenin Türkçesi sifon 😃) Aksi halde pencere donacak, yanıt vermeyecektir. Bu amaçla burada WaitWindowEvent(20) komutu kullanıldı. Bu komuta parametre vermezsek, program bir olay oluşana kadar bu komutta bekler. Parantez içinde 20 yazdım ki, beklemesin, 20 milisaniye sonra devam etsin.. Gerçi buradaki döngü kısa ama uzun bir döngü içinde, Delay(1) gibi bir komut kullanmanız gerekiyor. Bu da CPU’i fazla meşgül etmemek için gerekli. Sanırım, şimdilik bu kadar tiyo yeterli olacaktır. 😵‍💫 Dediğim gibi, Youtube yorumlarına, görüş veya sorularını yazmaktan çekinme lütfen.

Written on August 29, 2024