Posted by : MC 17 Ekim 2015 Cumartesi


Daha önce endüstriyel ürünlerin haberleşme metodlarından blogumuzda bahsetmiştik.RS485 endüstride sıkça kullanılan bir haberleşme alt yapısı.Alt yapısı diyorum lakin ne zaman RS485 duyulsa akıllara hemen modbus gelir ki bu yanlış bir düşüncedir.RS485 sadece bir alt yapıdır ve üst yapısında ise yazılımsal olarak protokoller oturur ve en sık kullanılan modbus haberleşme protokolü de bunlardan sadece bir tanesidir.


Bu yazımızda sizlere derin olarak modbus haberleşme metodundan bahsetmeyeceğim.Daha önceki yazılarımızı incelerseniz,bloğumuzda modbus ile ilgili detaylı bilgi edinebilirsiniz.

Yazımızın konusu arduino ile RS485 fiziksel alt yapı üzerinden modbus haberleşme olacak.

Peki ilk olarak hepimizin bildiği ya da şimdi öğreneceği üzere arduino kartlarımızda RX ve TX pinleri bulunmakta ancak RS485 alt yapısı bulunmamaktadır.Bu durumda ihtiyacımız olan rs485 alt yapısından gelecek olan verileri bize rx ve tx pinleri üzerinden aktarabilecek bir arabirim elemanı olacaktır.

Yaklaşık olarak 10Tl civarına edinebileceğiz aşağıdaki resimde görünen rs485 dönüştürücüyü edinebilirsiniz.


Peki bu kart nasıl işler.İlk olarak dikkatinizi çekmiştir üzerinde max485 çipi bulunmakta ve bu çip bize rs485 (A ve B) pinleri üzeriden gelen verileri Rx Tx TTL sinyallerine dönüştürmektedir.

RO: arduino tarafında Rx pinine
RE ve DE ortaklanıp arduinoda bizim belirleyeceğimiz ve haberleşmede enable edeceğimiz pine
DI: arduino tarafında Tx pinine bağlanacak

Yukarıdaki şemada genel olarak modbus haberleşecek cihazlar ve sistemler arasında nasıl bir network oluşturulacağı gösterilmiştir.Burada dikkat edilmesi gereken modbus ağına gelecek her cihaz arasında paralel bir bağlantı olmasıdır.Bu ne demek ? her bir cihazımızın rs485 tarafındaki A pinleri diğer cihazların A pinlerine atlamalı olarak gidecek ve bu durum yine B pini için de tekrarlanacaktır.

Modbus haberleşmede en önemli husus master-slave mantığıdır.Şunu unutmamak gerekir master slave den veri çekebilir ve slavdeki verilere müdahale edebilir.Ancak slave masterdaki verilere müdahale edemez.Yani burada müdür her zaman master dır :)

Diğer önemli husus genellikle bu soru gelir.Bir modbus ağında sadece 1 adet master olabilir slave sayısı ise teorik olarak 255 adet olabilir :) ve her slave farklı bir adrese sahip olmak durumundadır (0-254) arasında.
Birden fazla master kullanmak istediğiniz 2 master arasında farklı bir modbus networkü kurarak masterlardan birini 2. network ağında slave hale getirmeniz mümkün olabilir.Fazlaca mühendislik gerektirebilir endüstriyel bir cihazınız 2. bir seri haberleşme taşımıyor ise.

Gelelim modbus kütüphanelerine ve açıklamalarına:

Modbus master ve slave kütüphanelerine buradan erişebilirsiniz.

Modbus Master Cihaz:

#include <SimpleModbusMaster.h>
#define baud 9600 // haberleşme rate i 
#define timeout 1000// paket zaman aşımı
#define polling 200// ne kadar hızlı veri çekilecek
#define retry_count 10 // hata vermeden önce deneme sayısı

//daha önce bahsettiğimiz enable pin RE ve DE ortak bağlantıya gidecek
#define TxEnablePin 2 

#define LED 9

// master üzerinde kaç adet register tutulacak
#define TOTAL_NO_OF_REGISTERS 1

enum
{
  PACKET1,
  PACKET2,
  TOTAL_NO_OF_PACKETS // değiştirmeyin ekleyeceğiniz registerları yukarı ekleyin
};

//registerlar için paketler oluşturuluyor
Packet packets[TOTAL_NO_OF_PACKETS];

//master registerları izin dizi tanımlandı
unsigned int regs[TOTAL_NO_OF_REGISTERS];

void setup()
{
  // paketler oluşturuluyor
  modbus_construct(&packets[PACKET1], 1, READ_HOLDING_REGISTERS, 0, 1, 0);
  modbus_construct(&packets[PACKET2], 1, PRESET_MULTIPLE_REGISTERS, 1, 1, 0);
  
  // cihaz master olarak ve haberleşme değerlerine bağımlı olarak oluşturuluyor
  modbus_configure(&Serial, baud, SERIAL_8N2, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS, regs);
  
  pinMode(LED, OUTPUT);
}

void loop()
{
  modbus_update();
  
  regs[0] = analogRead(0); // enum içinde 0. indexe tanımlı registera değer yazılıyor
  // her modbus update ile bu değer slave lere gönderiliyor
}

Modbus Slave Cihaz :

#include <SimpleModbusSlave.h>
#define  LED 9  


enum 
{     
  // slave üzerindeki regesterlarımızı tanımlıyoruz.
  // ilk register 0 numaralı adrese sahip olur ve sonrasındaki her register için adres 1 artar.
  ADC_VAL,     
  PWM_VAL,        
  HOLDING_REGS_SIZE // Yine buna dokunmuyoruz.Register sayımızı tutar ve otomatik artar
};

unsigned int holdingRegs[HOLDING_REGS_SIZE]; // register dizisi oluşturu
////////////////////////////////////////////////////////////

void setup()
{
  /* parameters(HardwareSerial* SerialPort,
                long baudrate, 
unsigned char byteFormat,
                unsigned char ID, 
                unsigned char transmit enable pin, 
                unsigned int holding registers size,
                unsigned int* holding register array)
  */
  
  /* modbus parametre açıklamaları:
     SERIAL_8N2: 1 start bit, 8 data bit, 2 stop bits
     SERIAL_8E1: 1 start bit, 8 data bit, 1 Even parity bit, 1 stop bit
     SERIAL_8O1: 1 start bit, 8 data bit, 1 Odd parity bit, 1 stop bit
  */
//
  modbus_configure(&Serial, 9600, SERIAL_8N2, 1, 2, HOLDING_REGS_SIZE, holdingRegs);
  modbus_update_comms(9600, SERIAL_8N2, 1);
  
  pinMode(LED, OUTPUT);
}

void loop()
{
  modbus_update();
  
  holdingRegs[ADC_VAL] = analogRead(A0); // master 0.1.0 paketinde bu değeri okuyor.
  
  analogWrite(LED, holdingRegs[PWM_VAL]>>2); //master 1.1.0 dan gelen veri pwm olarak basılıyor
  
}

{ 27 Comments... read them below or Comment }

  1. bir sorunum var. ben plc deki 44097 registerini master arduino ile okumak istiyorum. bu konuda tardım edermisiniz

    YanıtlaSil
    Yanıtlar
    1. Merhabalar öncelikle geç yanıt verdiğim için özür dilerim.Modbus master modunda sahadan bilgi okuyabilmek için kaynak kodlarında biraz değişikliğe gitmek gerekiyor uygun bir zaman sizin ihtiyacınıza göre kaynak kodları şekilledirip yardımcı olmaya çalışacağım

      Sil
  2. merhaba, aslında yapmak istediğim şey son derece basit birşey ama , acemi olduğum için, biraz kodlardan birşey anlamadım, yapmak istediğim şey su, 711 loadcell modülü ile bir ağırlık okuyup, bunuda plc ye RS485 üzerindenn yollamak, ağırlık değerini, sizce nasıl yapabilirim??? şimdiden çok teşekkür ederim, değerli vaktinizi ayırdığınız için

    YanıtlaSil
    Yanıtlar
    1. loadcell den aldiginiz veriyi aruino tarafinda kg gram olarak yorumlatin ve bir reg icerisine o degeri atin sonraki adiminiz arduino mu master olacak yoksa plc mi ona gorede slave yada master kod bloglarindan birini kullanarak plc tarafina veriyi icerisine attiginiz register adresinden holding register olarak gonderebilirsiniz

      Sil
  3. Besleme voltajı hangi sınırlar arasında olması gerekiyor.

    YanıtlaSil
    Yanıtlar
    1. rs485 entegtesini 3-5vdc araliginda beslemelisini haberlesme mesafeniz uzun ise karsilikli groundlari ortaklayin eger ki ii uctada voltaj dusumu gozlemlereniz bir taraftan a+ ucunu besleme voltajini ve akim limit direnci ile buffer ediniz

      Sil
  4. Merhaba raspberry ile arduino'yu codesys üzerinden kablosuz kontrol etmem gerekiyor yardımcı olabilir misiniz?

    YanıtlaSil
  5. Mehmet Bey Merhabalar;
    Arduino uno içerisinde iki adet veri üretip (0-20000) arasında RS485 MODBUS ile gönderebileceğim SLAVE programı yazmaya çalışıyorum. İçinden çıkamadım yardımcı olabilirseniz çok sevinirim

    YanıtlaSil
  6. Örnek olarak analog girişler readholding regşstet analog çıkışları ise write holding register ve digitai inputlarıda outları ile ilgili bir örnek projesi paylaşabilirseniz,kafamızdaki çoğu sorunları azaltmış oluruz.teşekkür ederim

    YanıtlaSil
  7. tek seferde maximum kaç data okuyabilmem gerekiyor

    YanıtlaSil
  8. mehmet bey merhaba ben bu simplemodbusmaster kütüphanesi kullanarak siemens analizörü okuyoabiliyorum ancak değer ikince kez okunmaya çalışılırken kart reset oluyor ve program baştan başlıyor bunu nasıl engelleyebilirim

    YanıtlaSil
  9. Evlerde bulunan sayçları arduino ile okuyup thingspek e göndermek istiyorum. Bu konuda bir kutuphane yada önerebileceğiniz bir yol varmıdır?

    YanıtlaSil
    Yanıtlar
    1. Sayaçlar modbus Ascii olarak haberleşebilmektedir. Burada paylaşılmış olan kütüphane modbus rtu dur.

      Sil
  10. Merhaba Arkadaşlar
    Motor sürücü delta el serisi RC485 usb ile PC ye bağlı
    Arduino UNO da usb ile PC ye bağlı
    Delta ile Arduino da biribirine bağlı
    Arduino da gerekli kodlar yazılı
    Delta ile haberleştiremedim.YARDIM edin.

    YanıtlaSil
    Yanıtlar
    1. Senin yapmak istediğin uygulama üzerinde çalışıyorum aradan uzun zaman geçmiş son durumun nedir.

      Sil
  11. bir arduino uno ya birden fazla enerji analizörü bağlayıp. Enerji anlizörlerindeki 2000 registerindeki değerlerini almam gerekiyor. Yardımcı olur musunuz.

    YanıtlaSil
  12. crc kodu hangi aşamada hesplıyor acaba? Bana sadece crc hesaplaması gerekiyor diğer kısımları hallettim ama crc kodunun içinden çıkamıyorum

    YanıtlaSil
  13. Merhaba arkadaşlar yukarıda anlatılan modbus haberleşmenin arduino Kablo elektriksel bağlantılar nasıl olacak bilen veya uygulayan varmı

    YanıtlaSil
    Yanıtlar
    1. Merhabalar,
      Geç yanıtım için kusura bakmayın uzun yıllardır blog ile ilgilenemiyorum malesef.

      Modbus bağlantısı side to side yani A dan Aya B den B ye şeklinde olmalı. Bazı diğer bağlantı metodlarında, örnektede olduğu gibi D+ -> D+ ya D- -> D- ye olacak şekilde seri olarak bağlanmalıdır. Burada mesafe önemlidir. Teorik olarak 1 km ye kadar modbus sinyali taşınabilir en azıdan standardın arkasında durduğu değer budur ideal koşulları kapsar. Veri kaybı yaşıyor iseniz, öncelikle blendajlı kablo kullanmanızı tavsiye ediyorum blendaj kısmını tek taraftan topraklamanız gerekir. Yine data kaybınız var ise 120 ohm 2 adet modbus termination resistor kullanmanız gerekir. Biri hattın başına diğeri sonuna bağlanacak şekilde d- ve d+ arasında direnci uygulayabilirsiniz.

      Sil
  14. Merhaba,
    Arduino Uno ile master saat bilgisini hattaki slave arduino uno'lara vermek istiyorum. Master kısmında RTC ile yaptığım sa:dk:sn verilerini slave'lere aktarmak istiyorum yani. Aslında bu uygulamayı yaptım ama kararlı çalışmıyor.

    YanıtlaSil
    Yanıtlar
    1. Modbus haberleşmede normal şartlar altında slave master a sorgu yapmaz. Kararlı çalışmadığı noktayı detaylandırabilirseniz daha net yardımcı olabilirim.

      Slave cihazlardaki datayı güncel tutabilmeniz için belirli aralıklar ile master cihazdan ilgili slave adreslerine veri yazmanız gerekecektir.

      Sil
  15. Merhabalar arduino ile mlx90614 sicaklik sensorunun bilgilerini aliyorum bu aldigim bilgiyi modbus izerinden endustriyel hmi ya gondermek istiyorum bir cok deneme yaptim ama hep cakildim yardimci olursaniz sevinirim

    YanıtlaSil
  16. Merhabalar iki arduino mega kullanarak haberleşme yapmak istiyorum. Her ikisi de birbirinden karşılıklı konum bilgisi alarak hareket edecek(hem kendi konumunu hem de diğer aduino nun konumunu gösteren ledler yanacak). Sadece bir karakter göndermem yeterli. Yardımcı olursanız sevinirim.

    YanıtlaSil
  17. Merhaba iyi günler. Bir dijital manyetik sensör ile motorun her turunda yükselen kenar tetikleme yapan bir cihazdan okuduğum veriyi arduino ile RPM sayısına çevirdim.

    int Pulse;
    unsigned long RPM;
    unsigned long SURE;
    unsigned long SURE2;
    unsigned long micros();
    unsigned long millis();
    unsigned long timeout;
    int RPMSAYI;

    void setup() {
    pinMode(9, INPUT);
    SURE = micros();
    timeout = millis();
    }

    void loop() {
    Serial.print(" ");
    Serial.print(SURE2/RPMSAYI);
    Serial.print(" Mikro Saniye");
    Serial.print(" RPM : ");
    Serial.println(RPM);
    digitalRead(9);



    if(digitalRead(9) == HIGH && Pulse == 0) {
    SURE2 = micros() - SURE + SURE2;
    SURE = micros();
    Pulse = 1;
    RPMSAYI ++;
    }

    if(digitalRead(9) == LOW && Pulse == 1) {
    Pulse = 0;
    }
    if(micros() > timeout + 1000000) {
    timeout = micros();
    RPM = 60000000 / SURE2 * RPMSAYI;
    SURE2 = 0;
    RPMSAYI = 0;
    }

    }

    Yazdığım kod bu, bu kodu r485 kullanarak bir registere kaydetmek istiyorum onuda plc ile okuyacağım. Benim işime yarayabilecek bir örnek hiçbiryerde bulamadım. Youtube'da bir videoya denk geldim (https://www.youtube.com/watch?v=F400FQ5Kv78) Ama kodun tamamını paylaşmamış. Yardımcı olursanız çok memnun olurum.

    YanıtlaSil
    Yanıtlar
    1. Yanlış belirtmişim, RPM değişkenini rs485 kulanarak registere kaydetmek istiyorum.

      Sil
  18. merhaba arduino ile hmi ekranı haberleştirlmek istiyorum konuyla ilgili yardımcı olur musunuz

    YanıtlaSil
  19. Eski bir konu ama sormak istiyorum. Belki bir cevap veren olur. 3 cihazı birbirleri ile haberleştirmek istiyorum. Herkes modbus anlatıyor ama benim ihtiyacım modbus değil iki verici 1 alıcıya ihtiyacım var. Alıcı 1. vericiye mesaj varmı diye soracak gelen mesajı alarak 1. alıcıya tamm diyerek 2. alıcıya sorarak bu döngüyü sürekli olarak devam ettirecek. Böyle bir örnek var mı?

    YanıtlaSil

ELEKTRO BLOGGER A HOŞGELDINIZ

ARAMA YAP

EN COK OKUNANLAR

- Copyright © ELEKTRO-BLOGGER Blogger