Bu yazımızda arduino kontrolcüsü kullanarak modbus ( rs485 ) haberleşme üzerinden bldc motor sürücüsüne hareket komutları nasıl gönderilir bunu öğreneceğiz.Robot projelerinde sıklıkla kullanılan bldc motorların bazı sürücüleri modbus yada canbus üzerinden haberleşme sağlamaktadır bu nedenle standart sürücüler gibi arduino kartımızın dijital pinleri üzerinden süremeyiz.
Modbus Nedir?
Modbus, endüstriyel alanlardaki farklı cihazların iletişim ihtiyacını karşılamak için kullanılan, en eski seri iletişim protokollerinden biridir.
Modbus, PLC (Programmable Logic Controller) sektörünün öncülerinden olan Modicon tarafından 1979 yılında geliştirilmiş bir haberleşme protokolüdür. PLC sistemler ile veri transferi arasındaki iletişim köprüsüdür. Basit ve esnek olması ile hızlı, kolay ve üreticilere açık olması günümüzde endüstriyel anlamda kullanım alanlarını genişletmiştir. İstatistiklere göre, Modbus protokolü dünya çapında 7 Milyon endüstri kuruluşu tarafından veri toplama sistemlerine sinyal iletimi için kullanılmaktadır. Örnek olarak, PDU’lardan aldığı voltaj, frekans ve gerilim verilerini bu protokol aracılığı ile çağırabilirsiniz.
Modbus Nasıl Çalışır?
Modbus, cihazlar arasındaki seri hatlar üzerinden iletilerek çalışır. En basit kurulum şekli, seri portları bir Master ve bir Slave olmak üzere iki cihaza bağlayan tek bir seri kablo olacak şekilde kurulan sistemdir.Modbus iletişim protokolünde veriler, Bit olarak gönderilir ve her bir Bit de voltaj olarak gönderilir.
CRC Nedir ?
CRC çevrimsel hata denetimi (Cyclic Reduncany check) manasına gelmektedir. CRC’nin farklı kombinasyonları farklı haberleşme kontrolleri için kullanılabilir. Modbus haberleşmesi için kullanıldığında mesajın sonuna eklenen iki byte’dan oluşur. Mesajdaki her byte CRC’yi hesaplamak için gönderilmektedir. Ayrıca alıcı cihaz da CRC’yi hesaplar ve onu gönderici cihazdan gelen CRC ile karşılaştırır. Eğer mesajdaki bir bit bile yanlış alınmışsa, CRC’ler farklı olacaktır ve bir hata oluşacaktır.
CRC yönteminde bir blok içindeki veriler tek tek toplanır, bu toplam belirli bir sayıya bölünür (bu sayıya P diyelim) ve bölüm sonucunda çıkan kalan sayısı verilere eklenir. Karşı tarafta veri alındığında yine veriler tek tek toplanır ve bu toplamdan bölüm kalanı çıkartılır. Çıkartma sonucundaki sayı da P’ye bölünür. Eğer veriler hatasız iletilmişse kalan sıfır olmalıdır.
//////////////////// Proje Hocam - RS485 BLDC Servo Kontrol ///////////////////
// Serial 3 kullanılmalı 115200 baud hızı için
#define RTS_pin 2 //RS485 kontrol pini
#define RS485Transmit HIGH
#define RS485Receive LOW
//////////////////// CRC Hesaplama ///////////////////
uint16_t CalcCRC(byte * data, uint8_t datlen){
uint16_t CRC=0xFFFF; // Init CRC
uint8_t xor_flag;
for(uint8_t n=0; n<datlen;n++){
CRC = CRC ^ data[n];
for(uint8_t i=0;i<8;i++){
if(CRC & 0x0001) {
xor_flag = 1;
}
else {
xor_flag = 0;
}
CRC = CRC >> 1;
if (xor_flag) {
CRC = CRC ^ 0xA001;
}
}
}
return CRC;
}
void SendCmd( byte * data, uint8_t datlen){
uint16_t CRC=CalcCRC(data, datlen);
for(uint8_t i=0;i<datlen;i++){ // TX modunu set et
Serial.print(data[i],HEX);
Serial.print(", ");
}
Serial.print(lowByte(CRC),HEX); // Lowbyte al
Serial.print(", ");
Serial.println(highByte(CRC),HEX); // highbyte al
}
//////////////////// CRC Hesaplama ///////////////////
void setup() {
Serial.begin(115200); // Serial Monitor başlatma
Serial3.begin(115200); // Modbus serial Port başlatma
pinMode(RTS_pin, OUTPUT);
Serial.println("Nartech");
delay(1000);
}
void loop() {
byte rpmyuz[] = {0x05, 0x06, 0x20, 0x3A, 0x00, 0x64, 0xA2, 0x68}; // 50 rpm ( hex : 32 ) de motor dönsün
byte rpmonbes[] = {0x05, 0x06, 0x20, 0x3A, 0x00, 0x0F, 0xE3, 0x87}; // 50 rpm ( hex : 32 ) de motor dönsün
byte request[] = {0x05, 0x06, 0x20, 0x3A, 0x00, 0x0F, 0xE3, 0x87}; // 50 rpm ( hex : 32 ) de motor dönsün
byte request2[] = {0x05, 0x03, 0x20, 0x24, 0x00, 0x02, 0x8E, 0x45}; // enkoder verisi
byte motora[] = {0x05, 0x06, 0x20, 0x3A, 0x00, 0x0F, 0xE3, 0x87}; // 50 rpm ( hex : 32 ) de motor dönsün
byte motorb[] = {0x04, 0x06, 0x20, 0x3A, 0xFF, 0x0F, 0xA3, 0xA6}; // 50 rpm ( hex : 32 ) de motor dönsün
Serial.print("SendCMD : ");
SendCmd(request,6);
Serial.println(CalcCRC(request,6),HEX);
// motor döndürme
digitalWrite(RTS_pin, RS485Transmit); // Veri gönder
Serial3.write(motora, sizeof(request));
Serial3.flush();
digitalWrite(RTS_pin, RS485Receive); // Veri al
delay(10);
digitalWrite(RTS_pin, RS485Transmit); // Veri gönder
Serial3.write(motorb, sizeof(request));
Serial3.flush();
digitalWrite(RTS_pin, RS485Receive); // Veri al
delay(10);
// Veri dinleme kodu
byte buf[8];
Serial3.readBytes(buf, 8);
Serial.print("Motor Donus : ");
for( byte i=0; i<8; i++ ) {
Serial.print(buf[i], HEX);
Serial.print(" ");
}
Serial.println();
delay(100);
//enkoder veri alma
digitalWrite(RTS_pin, RS485Transmit); // Veri gönder
Serial3.write(request2, sizeof(request2));
Serial3.flush();
digitalWrite(RTS_pin, RS485Receive); // Veri al
delay(100);
// Veri dinleme kodu
byte buf2[8];
Serial3.readBytes(buf2, 8);
Serial.print("Encoder : ");
for( byte i=0; i<8; i++ ) {
Serial.print(buf2[i], HEX);
Serial.print(" ");
}
Serial.print(" ==> ");
Serial.print(buf2[5]);
Serial.print(".");
Serial.print(buf2[6]);
Serial.print(" rpm");
Serial.println();
delay(100);
}




















































































