Thread overview
D seri iletişim ile veri okuma
Jul 07, 2020
erdem
Jul 07, 2020
erdem
Jul 08, 2020
erdem
July 07, 2020

D ile seri iletişim köprüsünden mikro denetleyicinin gönderdiği verileri okuyan ufak bir program yazdım.

import std.stdio;
import core.thread;
import serialport;

void main()
{
   void[1024*4] veriler = void;
   auto iletişim = new SerialPortNonBlk("/dev/ttyACM0", "9600:8N1");
   stdout.writeln("Port ayarları: ", iletişim.config);

   while (true)
   {
       void[] okunan;

       while (okunan.length == 0)
       {
           okunan = iletişim.read(veriler);
           Thread.sleep(1000.msecs);
       }
       writeln("-- okunan\n", cast(string)okunan);
       writeln();
   }
}

Bu verileri daha sonra veritabanına kaydedip sunucu üzerinde göstermek istiyoruz. Ancak ufak bir eksiklik gözüme çarptı. Bazen okunan veriler bölünebiliyor.

https://programlama.tk/static/resim/sicaklikoku.png

Screen programı ile

'$ screen /dev/ttyACM0'

şeklinde test ettiğimde sanırım verileri bölmeden okuyabiliyor.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

July 08, 2020

Herhalde saat sinyalı olmadığına göre eş zamansız ("asynchronous") seri iletişim.

https://learn.sparkfun.com/tutorials/serial-communication/all

Aslında veriler ham olarak kaydedilip daha sonra belki Audacity gibi bir programla incelenebilir. Ama şimdilik pratik bir çözüm buldum.

import std.stdio;
import core.thread;
import serialport;

void main()
{
   void[1024*4] veriler = void;
   auto sayaç = 0;
   auto iletişim = new SerialPortNonBlk("/dev/ttyACM0", "9600:8N1");
   stdout.writeln("Port ayarları: ", iletişim.config);

   while (true)
   {
       void[] okunan;

       while (okunan.length == 0)
       {
           okunan = iletişim.read(veriler);
           Thread.sleep(500.msecs);
       }

       char[] okuduğum = (cast(string) okunan).dup;

       if (okuduğum.length > 40)
       {
           writeln(okuduğum[0..38]);
       }

   }
}

Bu şekilde (ilk okunan bir kaç veri hariç) verileri düzgün bir şekilde okutabiliyorum.

Hatta Nginx sunucusu üzerinde koşan vibe.d uygulaması bile hazır ;-)

http://gelistir.tk/

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

July 08, 2020

Veri aktarımının bir protokolü yok mu? Örneğin, ilk 4 bayt mesajın uzunluğunu belirtebilir. Veya mesaj sonunda '\0', '\n', vs. bir karakter vardır. Mesajın geri kalanını buna göre beklemek gerek.

Belki aynı durumu screen de yaşıyordur ama karakterleri art arda yazdırdığı için parçalı alındığı farkedilmiyordur.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

July 08, 2020

Veri okumada sıkıntı yok ama vibe.d maceram biraz kısa sürdü.

Sabahtan beri çok basit bir hatayı çözmeye çalışıyorum.

import vibe.vibe;

void main()
{
       auto settings = new HTTPServerSettings;
       settings.port = 3000;
       settings.bindAddresses = ["::1", "127.0.0.1"];
       auto listener = listenHTTP(settings, &hello);
       scope(exit)
               listener.stopListening();

       logInfo("Please open http://127.0.0.1:3000/ in your browser.");
       runApplication();
}

void hello(HTTPServerRequest req, HTTPServerResponse res)
{
       res.writeBody("Hello, World!");
}

Görüldüğü üzere basit bir merhaba dünya uygulaması. Sorun şu ki kot ilk kere derleniyor çalışıyor. Uygulamadan C-c ile çıkıyoruz. İkinci çalıştırmada ise bir bakıyorsunuz ki arka planda aynı portta çalışan bir uygulama olduğuna dair ipucu veren bir hata veriyor.

'Failed to listen for incoming HTTP connections on any of the supplied interfaces.'

Gerçekten de uygulamadan çıkış yapılamamış.

'$ ps -ux | grep dolap
erdem 6507 0.0 0.3 77152 12536 pts/2 S 21:54 0:00 ./dolap'

'$ kill -9 PID'

şeklinde her seferinde uygulama temizlenebiliyor. Ama bu bir sunucu uygulaması için pek mantıklı değil. Örneğin elektrik kesilse sunucu tekrar başlasa ne olacak. Hatanın teknik ayrıntılarından burada bahsetmişler.

https://github.com/vibe-d/vibe.d/issues/2245

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]