19 Haziran 2018 Salı

Masaüstü Dijital Saat Yapalım.

Kendi yaptığım cihazların çalışmasını görmeyi ve kullanmayı seviyorum. Şimdi de telefon, bilgisayar ve duvarda saat olmasına karşın kendime çalışma masasında kullanacağım  bir saat yapmayı istiyorum.
Sadece saat olarak tasarlamaya başladım ama şu da olsun bu da olsun derken proje sadece saat olmaktan çıktı. PCB tasarlarken aşağıdaki özellikleri ekledim. Aslında saatten çok hava tahmin istasyonuna döndü diyebilirim.

PCB tasarımda eklenen donanımlar:
* DS1307 saat çipi
* 24C64 eeprom
* SHT11 Nem ve Sıcaklı Sensörü
* DS18B20 sıcaklık sensörü
* LDR yada Foto Diyotla ışık seviyesi ölçümü
* HMTRP - XBee kablosuz bağlantısı için port
* Buzzer
* 5 adet button
* USB bağlantısı
* 4*20karakter LCD
* 18 Adet GPIO içeren soket


PCB çizim işlemi bittikten sonra PCBWAY ile iletişime geçtim. PCB üretimi 5$ tuttu. Diğer PCBlerle beraber kargosu 17$ tuttu. Adetli üretim için yerli PCB üreticileri ile iletişime geçilmesini tavsiye ederim ama numune üretimi için hızı ve fiyatlandırması açısından PCBWAY'i tek geçerim.

Her pcb toplama yazımda ister istemez PCBWAY'den bahsediyorum çünkü pcb üretimi konusunda yazı, video başına bonus veriyor. Omega2+ konulu yazı için pcb maliyeti kadar bonus verdi. Eğer bu yazılardan birine daha bonus verirse bir sonraki 3-4 pcbnin üretimi ve kargosu bedavaya gelecek. Yalan yok :)

Dijital Saat Projesi'nde yukarıda bahsettiğim donanımların hepsini devreye alıp ortam hakkında nem, sıcaklık, ışık seviyesi bilgilerini hem okuyup hem de RF ile bir merkeze aktarmayı ve bilgisayarda log tutmayı planlıyorum. 18 adet GPIO soketini de biraz bunun için yerleştirdim. Soket sayesinde Dijital Saat I2C, SPI, UART, IO, CANBUS iletişimi kurabilecek kapasiteye sahip. Başka bir devreyi kontrol etmek yada uzaktan kontrol sağlamak için başka projelerle birleştirilebilir. Bu sayede bir PCB ile birden çok proje çıkartılabilir. Benim gibi hobi amaçlı elektronikle uğraşanlar için bu iyi bir özellik.

Kartta hem DS18B20 hem de SHT11  bulunması mantıklı gelmeyebilir. Bu yerleşimin amacı elimde elimde 1 adet bulunan SHT11 in pahalı olması. Yaklaşık 12$ + KDV. Amaç elimdekini kullandıktan sonra daha sonra kullanacağım pcblerde DS18B20 ile devam etmek. Hem malzeme değerlenecek hem de her kart için yüksek fiyatlı malzeme alınmamış olacak.


Krem lehim ve SMD malzeme dizimi


Fırınlama


Soketler ve DIP kılıf Malzeme Lehimleme İşlemleri



Yükseltme ayağı ve LCD Ekran Montajı








Şimdilik sadece montaja ait görüntüler var. Programlama safhasına geçince hem açıklama hem de kodları paylaşmaya çalışacağım. 

MC60 GSM / GNSS PCB ve Malzeme Listesi, OMEGA2+ Geliştirme Kartı ve Malzeme Listesi ve Dijital Saat Projesi PCB ve Malzeme Listesini  buradan paylaşmayı düşünüyorum. Aynı şekilde PCBWAY üzerinden kartları anonim üretime de açmak niyetindeyim. Maksat ihtiyacı olan kullansın. 

  Faydalı olması umuduyla...



18 Haziran 2018 Pazartesi

Python GPS verisi işleme uygulaması yapalım.

Omega2+ ile yazılım geliştirme bordunun üretimini ve seri port, veritabanı uygulamalarını daha önceki yazılarımda anlatmıştım.
Şimdi de Omega2+ üzerinde Python ile Gps verisi işleme kısmını anlatmaya çalışacağım. Burada GSM/GNSS destekli modül kullandığım için GPS/Glonass verileri  komut gönderince gelecek. Normalde seri porta bir GPS alıcısı bağladığınız zaman 1PPS yani saniyede 1  defa GPS/Glonass verisini gönderecektir. GSM modülle veri alıyorsanız GPS konumu için komut gönderin, GPS alıcısından veri alıyorsanız sadece seri portu kontrol edin.


Yazılım geliştirmek için Quectel MC60 modülü kullanıyorum. GSM modül üzerinden GPS verisi alıp işleme olayına başlayalım.



Seri porta veri yazmak için bir fonksiyon tanımladım.

def seriPortYaz(veri,bekle=1,bildir=""):

 ser.write(veri.encode('utf-8'))

 sayac=0

 while(ser.in_waiting==0) and  (sayac<bekle):

  sleep(0.1)

  sayac+=1

 if (sayac>bekle):

  print("Cevap yok: {}...\r\n".format(veri))  


  if bildir!="":

  print("SER: {}\r\n".format(bildir))



 temp=ser.read(ser.in_waiting)

 gsmRespText=temp.decode('utf-8')

 print("Ser Read: {}\r\n".format(gsmRespText))



Burada veri bekle ve bildir parametreleri var.

veri; seri porta yazılacak komutu,

bekle; komut için beklenecek timeout süresini,

bildir ise komut ile ilgili python etkileşimli kabuğuna bildirim yapılmasını sağlıyor. bekle ve bildir default parametre aldığı için fonksiyonun kullanımı esnasında pas geçilebilir.



while döngüsü ile komut gsm modüle gönderildikten sonra seri porta veri gelene kadar yada timeout olana kadar beklenmesi sağlanıyor.

Eğer veri gelirse döngüden çıkıyor.

Gelen veriyi temp değişkenine alıp decode işlemi uyguluyor. decode önemli çünkü yapılmayınca \r (return) \n (new line) karakterleri ascii formatta değil normal yazı olarak çıkıyor ve bunlarla işlem yapılması zorlaşıyor.



Komut göndermek için bir fonksiyon daha tanımladım.



def atGonder(komut):

    if "AT+QGNSSRD" in komut:

  gelen=seriPortYaz(komut,30,komut)

  # gelen veri GNSS verisi ise

  if "+QGNSSRD:" in gelen:

   

   global latitude

   global longitude

   global rakim

   global yon

   global kms

   global knots

   global uydu

   global gnssTarihSaatListe

   global gnssTarih

   global gnssSaat

   global longitudeGo

   global latitudeGo

   

   

   GNSSListe=gelen.split()

   #print("GNSS: {}\r\n".format(GNSSListe))

   for i in GNSSListe:

    if "VTG" in i:

     VTGListe=i.split(",")

     print("liste: {}\r\n".format(VTGListe))

    if "RMC" in i:

     RMCListe=i.split(",")

     print("liste: {}\r\n".format(RMCListe))

    if "GSA" in i:

     GSAListe=i.split(",")

     print("liste: {}\r\n".format(GSAListe))

    if "GLL" in i:

     GLLListe=i.split(",")

     print("liste: {}\r\n".format(GLLListe))

    if "GSV" in i:

     GSVListe=i.split(",")

     print("liste: {}\r\n".format(GSVListe))

    if "GGA" in i:

     GGAListe=i.split(",")

     print("liste: {}\r\n".format(GGAListe))

   #RMCListe[3] elamanın uzunluğu 3 ten büyükse öyle işlem yap

   if len(RMCListe[3])>3:

    latitude.clear()

    latitude.append(RMCListe[3])

    latitude.append(RMCListe[4])

    longitude.clear()

    longitude.append(RMCListe[5])

    longitude.append(RMCListe[6])

    print("latitude: {} ; longitude: {}\r\n".format(latitude, longitude))

    

    longDeg=longitude[0][:3]

    longMn=longitude[0][3:5]

    longSec=longitude[0][6:8]

    longMs=longitude[0][8:10]

    

    latDeg=latitude[0][:2]

    latMn=latitude[0][2:4]

    latSec=latitude[0][5:7]

    latMs=latitude[0][7:9]

    

    print("degrees: deg:{} mn:{} sec:{} ms:{}\r\n".format(longDeg,longMn,longSec,longMs))

    print("degrees: deg:{} mn:{} sec:{} ms:{}\r\n".format(latDeg,latMn,latSec,latMs))

    

    longStr=longMn+"."+longSec+longMs

    longitudeGo=float(longStr)

    longitudeGo=longitudeGo/60

    longitudeGo=longitudeGo+int(longDeg)

    

    latStr=latMn+"."+latSec+latMs

    latitudeGo=float(latStr)

    latitudeGo=latitudeGo/60

    latitudeGo=latitudeGo+int(latDeg)

    

    

    print("longitudeGo:{}\r\n".format(longitudeGo))

    print("latitudeGo:{}\r\n".format(latitudeGo))

    

    

    

    yon=float(RMCListe[8])

    knot=float(RMCListe[7]) # knot cinsinden hız

    kms=float(VTGListe[7]) # km/s cinsinden hız

    rakim=float(GGAListe[9])

    print("hız: {:.2f} knots, {:.2f} km/s, yon: {:.2f} derece, rakım: {:.2f} mt\r\n".format(knot,kms,yon,rakim))

    gnssSaat=(RMCListe[1].split("."))[0]

    print("gnssSaat: {}\r\n".format(gnssSaat))

    gnssTarih=RMCListe[9]

    

    gnssTarihSaatListe.clear()

    gnssTarihSaatListe.append(gnssTarih[4:6])

    gnssTarihSaatListe.append(gnssTarih[2:4])

    gnssTarihSaatListe.append(gnssTarih[:2])

    gnssTarihSaatListe.append(gnssSaat[:2])

    gnssTarihSaatListe.append(gnssSaat[2:4])

    gnssTarihSaatListe.append(gnssSaat[4:6])

    

    print("gnssTarihSaatListe: {}\r\n".format(gnssTarihSaatListe))


else:  # eğer komut yukardaki komutlardan biri değilse normal işleme devam et   

  gelen=seriPortYaz(komut,3,komut)



Burada

atGonder("AT+QGNSSC=1\r") #GNSS Power On

atGonder("AT+QGNSSCMD=0\r")   #GNSS NMEA Tipi



komutları ile MC60 modülün GNSS'yi aktif ettim ve GPS verisi tipini en çok kullanılan standartlardan biri olan NMEA olarak seçtim.



Yukarıda fonksiyon içinde eğer gelen komut  AT+QGNSSRD ise şartı var. Eğer komut AT+QGNSSRD ise seri porta bu komutu verdikten sonra gelen cevabı alıp parçalamaya başlıyor. Yazımıza konu olan kısım da aslında burası.



global olarak tanımlamanın sebebi fonksiyon içinde tanımlanan değişkenlerin ana program bloğunda, ana blokta tanımlanan değişkenlerinde fonksiyon içinde çalışmaması.



Yani fonksiyon içinde tanımladığım a=5 bütün program genelinde geçerli değil. Aynı şekilde program başında tanımladığım a=3 fonksiyon içinde geçerli değil. Global ile bu sorunu aşıyorum.



GSM modüll değil de GPS ile veri alanlar komut gönderme yapısı ile ilgili işlemleri atlayabilirler.



GPS / GNSS verisi yaklaşık olarak aşağıdaki gibi bir cümledir:


$GPRMC,000009.800,V,,,,,0.00,0.00,060180,,,N*43

$GPVTG,0.00,T,,M,0.00,N,0.00,K,N*32

$GPGGA,000010.800,,,,,0,0,,,M,,M,,*41

$GPGSA,A,1,,,,,,,,,,,,,,,*1E

$GPRMC,000010.800,V,,,,,0.00,0.00,060180,,,N*4B

$GPVTG,0.00,T,,M,0.00,N,0.00,K,N*32

$GPGGA,000011.800,,,,,0,0,,,M,,M,,*40

$GPGSA,A,1,,,,,,,,,,,,,,,*1E

$GPRMC,000011.800,V,,,,,0.00,0.00,060180,,,N*4A

$GPVTG,0.00,T,,M,0.00,N,0.00,K,N*32

$GPGGA,000012.800,,,,,0,0,,,M,,M,,*43

$GPGSA,A,1,,,,,,,,,,,,,,,*1E

$GPGSV,1,1,00*79


GPRMC: minimum gerekli GPS verisi bilgisi

GPVTG: hareket bilgisi

GPGSA: Uydu bilgilerini içermektedir.


Bizim için enlem, boylam, saat, tarih, hız, yön ve rakım bilgileri yeterli olacaktır.

Saat konusunda da saatin Greenwich saati olduğunu belirteyim. Local saat değil. Bu yüzden saati kullanırken yerel saat eklemesini varsa gün / ay hatta yıl düzeltmesi yapılması gerektiğini belirteyim.


Python ile çalışmanın en sevdiğim taraflarında biri listeler. Veriyi alıp a.split(",") virgüllerinden ayırıp listeye ekle gibi basit bir  komutla bütün işi sizin yerinize hallediyor. 

Burada da yaptığımız iş bu. 


$GPRMC,194530.000,A,3051.8007,N,10035.9989,W,1.49,111.67,310714,,,A*74


gelen veriyi \r\n karakterlerinden bölüp listeye attık.


GNSSListe=gelen.split()


sonra GNSSListe içindeki her bir eleman için döngü kurduk.


for i in GNSSListe:


eğer cümle RMC içeriyorsa;


if "RMC" in i:

    RMCListe=i.split(",")

    print("liste: {}\r\n".format(RMCListe))


RMCListe adında bir birlisteye içeriği virgüllerle böl.


Sonra Listenin birinci elemanı saat, ikinci elamanı enlem, boylam, hız, yön, rakım vs sırasıyla değişkenlere alıp işi bitiriyoruz. 


Listenin hangi elemanı hangi değeri tutuyor kodlara bakarak anlaşılabilir.


longDeg=longitude[0][:3]

    longMn=longitude[0][3:5]

    longSec=longitude[0][6:8]

    longMs=longitude[0][8:10]

    

    latDeg=latitude[0][:2]

    latMn=latitude[0][2:4]

    latSec=latitude[0][5:7]

    latMs=latitude[0][7:9]

    

    print("degrees: deg:{} mn:{} sec:{} ms:{}\r\n".format(longDeg,longMn,longSec,longMs))

    print("degrees: deg:{} mn:{} sec:{} ms:{}\r\n".format(latDeg,latMn,latSec,latMs))

    

    longStr=longMn+"."+longSec+longMs

    longitudeGo=float(longStr)

    longitudeGo=longitudeGo/60

    longitudeGo=longitudeGo+int(longDeg)

    

    latStr=latMn+"."+latSec+latMs

    latitudeGo=float(latStr)

    latitudeGo=latitudeGo/60

    latitudeGo=latitudeGo+int(latDeg)



Yukarıdaki satırlarda klasik GPS cümlesi ile google maps'ın kullandığı GPS sistemi arasında 60lık sistem 100lük sistem çevrimi var.

Olay şu:

 3051.8007 koordinatları google maps sistemine çevrilirken 30 derece sabit kalıyor. 51.8007 kısmı alınıp 60'a bölünüyor. Sonra 30 ile toplanıyor. Sonuç 30,863345 çıkıyor.


Buradan sonra GPS  / GNSS verilerini istediğiniz şekilde kullanabilirsiniz.


Faydalı olması umuduyla...


12 Haziran 2018 Salı

Dual Dimmer SMD Reflow (Çift Dimmerli SMD Fırın) Yapalım. PART 1

NOT: Bu yazı

PART 1 Elektronik kısımın montajı,
PART 2 Mekanik kısmın oluşturulması
PART 3 Yazılım Geliştirme

olarak 3 ana başlıkta incelenecektir.

Daha önce SMD malzemeleri lehimlemek için halihazırda da kullandığım SMD fırını yaptım. Kullanışlı oldu ama malzeme sadece alttan ısıtıldığı için üstten sıcak hava tabancası ile hem ısıtma hem de sıcaklık takibi yapmak gerekiyordu.

Bunu bir adım öteye taşıyıp hem kendimi geliştirmek hem de diğer projelerin üretiminde kullanmak için Dual Dimmer SMD Reflow projesine hazırlanmaya başladım.

Projede aşağıdaki hedeflere ulaşmayı planlıyorum.

1) Bağımsız olarak hem alttan hem de üstten ve alt - üst beraber ısıtma yapabilmek.
2) Dimmer fonksiyonu ile önce SMD malzemeleri 110°C kadar ön ısıtma yapıp sonra 200-230°C çıkarıp fırınlamak.
3) Çift PT100  sensorle ısıtma işini otomatik yaptırmak.
4) Proses başlangıcı, durumu ve değerleri LCD ekrandan takip etmek.
5) Butonlarla menü, ısıtma, süre ayarları yapıp profil olarak kaydetmek.
6) RF modül ile bilgisayardan kumanda / takip / kontrol etmek

Devrede LCD hariç 4 ayrı pcb var.
Bunlar:
1) Zero Crossing Detector (Bir önceki yazıya konu olan Sıfır Geçiş Dedektörü - ZCD)
2) XBee kılıfında HMTRP-433 modülü
3) MCU bordu
4) Dimmer Bordu

PCB çizimi bittikten sonra üretim için PCBWAY ile temasa geçtim. 30 Mayıs'ta verdiğim sipariş 11 Haziran'da PTT aracılığıyla elime geçti.
Pcblerin üretim kalitesi ve fiyatlandırması gerçekten çok iyi.

XBee-HMTRP shiled, MCU Bordu, Dimmer Bordu ve diğer bir yazımda üretimini anlatacağım Masaüstü Dijital Saat pcbleri toplamda kargo dahil 35$ tuttu.

4 PCB 5er $, 17$ kargo, 3$ Aliexpress komisyonu ve 5$ PCBWAY üyelik indirimi ile toplam 35$ ödedim.
Driver bordu 1.6mm kalınlıkta olduğu için kargo fazla tutmasın diye 5 adet sipariş ettim. Sadece 5 adetlik azalma kargoya 4$ olarak yansıdı. Buradan PCBWAY üreticilerine de teşekür etmek istiyorum.
Thanks a lot for your high quality and fast pcb production and shipping.

 






Pcblere krem lehim çekip malzeme dizmekle işe başladım.



Header lehimlerinden sonra XBee - HMTRP Shield artık hazır. Bu modülü hem USB - XBee Shield ile kullanmak hem de kendi devremde ister orjinal Xbee ister HMTRP modül kullanabilmek için tasarladım.

En üstteki parça USB-XBee çeviriciye takılmış hali.

Sonra Dimmer Bordum Krem lehim ve üretim aşamaları var.


Röle, Triyak, Konnektör, Buzzer, Sigorta, Optokuplor vs montajı





MCU bordu için krem lehim ve diğer dizgi aşamaları...





MCU bordunda işlemci olarak dspic33fj128MC804 kullandım. Belki bu proje için fazla özellikli bir işlemci gibi gelebilir ama elimde birkaç tane vardı. Yemeği elde malzeme ile yapmak istedim. Fırsat bulunca yazılımını da geliştirmeye başlayacağım. Onu da başka bir yazıda işleyip paylaşacağım. 


Sonra bordları vidalar ve daha önce bahsettiğim yükseltme ayakları ile toparladım.







Fırın rezistansı olarak aslında en uygun olanı düzgün ısı akışı özelliğinden dolayı Seramik rezistans. Türkiye'de birçok malzemeyi bulmakta güçlük yaşadığımız gibi seramik rezistansların uygun boyut ve güçte tipini bulmakta da zorluk yaşıyoruz. Birkaç yerden fiyat araştırması yapınca ortalama 200Tl/Adet gibi fiyatla karşılaştım. Aliexpresste 240*120mm boyutlarında 300-400Watt modelleri var. Onlardan kullanmak istiyorum. tanesi 15-20$ civarinda. Şimdilik daha önceki SMD fırında da kullandığım 1,5KW Infaruj UFO rezistansından 2 tane kullanmayı planlıyorum.

Mekanik işçiliği ve ürün yazılımının geliştirilmesini hem zamana yaymak hem de ayrı bir yazıya konu etmek istiyorum. Hatta yazılım geliştirma kısmı bittikten sonra picproje.org forumundaki  @elektroemre'nin panelduino projesinde yaptığı gibi hem PCBWAYde pcbyi paylaşıma açmayı hem de kodları burayı yükleyip isteyenlerin kullanımına açmayı planlıyorum.

Umarım faydalı olur.




Zero Crossing Detector (Sıfır Noktası Geçiş Dedektörü) yapalım.

Sıfır Noktası Geçiş Dedektörleri (bundan sonra kısaca ZCD ismiyle bahsedeceğim) dimmer uygulamalarında zamanlama referansı almak için kullanılır.

 Şehir şebekesinin 0 noktasını her geçişinde çıkış vererek zamanlama başlangıcı için referans alınmasını sağlarlar.
Aşağıdaki şema için PCB hazırladım.

Çizim görüntüleri



PCBye plastik elek kullanarak krem lehim çektim ve malzemeye dizimine başladım.


Fırınlayıp krem lehimle malzemeleri sabitledim.
Sonra diğer yüzdeki diyot, direnç ve kondansatorleri dizip fırınladım. 90 derece headerları lehimleyince devrem bitmiş oldu.


Bu devreyi Dual Dimmer SMD Reflow (Çift Dimmerli SMD Dizgi Fırını ) kullanmayı düşünüyorum.