|
|
View previous topic :: View next topic |
Author |
Message |
thenorthstar
Joined: 06 Mar 2010 Posts: 24
|
Modbus Master Cart Problem. Please Help me |
Posted: Sun May 22, 2011 11:26 am |
|
|
Hello Friends.
I did two Slave and Master Card.
The first trial:
The first card is slave and the pc as a master , when I try running the code, I also heated the slave on the LM35 and the temperature reading from the PC with Modbus Poll Master simulation program.
The second trial:
The second card is master and the pc as a slave , when I try running the code,
and test in the pc with Modbus Slave simulation Program master code did not work.
The third trial:
Master and Slave cards to each other Connect with Modbus but the communication did not work.
I set up as a slave on the two cards and PC as a master. Two cards work as a slave.
Is there an error codes? I could not find.
Look you have the possibility Please.
However, it works flawlessly in Proteus.
My Master code:
Code: |
#include <18f4620.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay(clock=10000000)
#use fast_io(a)
#use fast_io(d) //Port yönlendirme komutları D portu için geçerli
#define MODBUS_TYPE MODBUS_TYPE_MASTER
#define MODBUS_SERIAL_TYPE MODBUS_RTU
#define MODBUS_SERIAL_RX_BUFFER_SIZE 64
#define MODBUS_SERIAL_BAUD 38400
#define MODBUS_SERIAL_RX_PIN PIN_C7
#define MODBUS_SERIAL_TX_PIN PIN_C6
#define MODBUS_SERIAL_ENABLE_PIN PIN_D2
#define MODBUS_SERIAL_INT_SOURCE MODBUS_INT_RDA
#include <modbus.c>
#define MODBUS_SLAVE_ADDRESS 01
#include "2x16_4x20_LCD.c"
int i;
int1 HataVar = 0;
int1 HataEkrani = 0;
/*This function may come in handy for you since MODBUS uses MSB first.*/
int8 swap_bits(int8 c)
{
return ((c&1)?128:0)|((c&2)?64:0)|((c&4)?32:0)|((c&8)?16:0)|((c&16)?8:0)
|((c&32)?4:0)|((c&64)?2:0)|((c&128)?1:0);
}
void read_all_holding()
//!{
//!
//!if(!(modbus_read_holding_registers(MODBUS_SLAVE_ADDRESS,0,8)))
//! {
//! //*Started at 1 since 0 is quantity of coils
//! LCD_gotoxy(1,1);
//! printf(lcd_putc,"Write/Read OK");
//! for(i=1; i < (modbus_rx.len); ++i)
//! LCD_gotoxy(2,2);
//! int16 Sicaklik = (int16)modbus_rx.data[1] * 256 + (int16)modbus_rx.data[2];
//! int16 Sicaklik2 = (int16)modbus_rx.data[3] * 256 + (int16)modbus_rx.data[4];
//! int16 Sicaklik3 = (int16)modbus_rx.data[5] * 256 + (int16)modbus_rx.data[6];
//!
//! printf(lcd_putc,"Temp=%3.1f ",(float)Sicaklik/10);
//! LCD_gotoxy(2,3);
//! printf(lcd_putc,"Temp=%3.1f ", (float)Sicaklik2/10);
//!// LCD_gotoxy(2,4);
//!// printf(lcd_putc,"Temp=%3.1u", modbus_rx.data[6]);
//!
{
int SLAVE_ID;
int16 Temp1,Temp2;
if(!(modbus_read_holding_registers(MODBUS_SLAVE_ADDRESS,0,8))) // Burda tüm word dataları okuyor
{
/*Started at 1 since 0 is quantity of coils*/
Temp1=(int16)modbus_rx.data[1] * 256 + (int16)modbus_rx.data[2];//(modbus_rx.data[1]*256)+modbus_rx.data[2];
Temp2=(int16)modbus_rx.data[3] * 256 + (int16)modbus_rx.data[4];//(modbus_rx.data[3]*256)+modbus_rx.data[4];
SLAVE_ID=modbus_rx.data[6];
LCD_gotoxy(1,1); printf(lcd_putc,"Write/Read OK");
LCD_gotoxy(1,2); printf(lcd_putc,"SLAVE ID=%d",SLAVE_ID);
LCD_gotoxy(1,3); printf(lcd_putc,"Temp1=%3.1f",(float)Temp1/10);
// }
}
else
{
HataVar = 1;
HataEkrani = 0;
}
}
/*void write_coils()
{
int8 coils[1]={0};
int Role;
if(input(PIN_D0)==0) // Read the switch
{
(bit_set(coils[0],1));
role=1;
}
else
{ (bit_clear(coils[0],1));
role=0;
}
delay_ms(10); // Debounce period
if(!(modbus_write_multiple_coils(MODBUS_SLAVE_ADDRESS,0,8,coils)))
{
if(Role==1) // Read the switch
{
LCD_gotoxy(2,4);
printf(lcd_putc,"Role1=%i Açık ",Role,);
}
else
{
LCD_gotoxy(2,4);
printf(lcd_putc,"Role1=%i Kapalı",Role,);
}
}
else
{
HataVar = 1;
HataEkrani = 0;
}
}*/
//=============================================================================
//!void read_all_inputs()
//!{
//!
//! if(!(modbus_read_discrete_input(MODBUS_SLAVE_ADDRESS,0,8)))
//! {
//!
//! /*Started at 1 since 0 is quantity of coils*/
//! for(i=1; i < (modbus_rx.len); ++i)
//!
//! }
//! else
//! {
//!
//! }
//!}
//=============================================================================
void main()
{
setup_adc_ports(NO_ANALOGS);
set_tris_d(0b00000011);
modbus_init();
lcd_init();
while ( true )
{
if (HataEkrani ==0 && HataVar == 1)
{
LCD_gotoxy(2,3);
printf(lcd_putc,"\fModbus Hata");
LCD_gotoxy(3,4);
printf(lcd_putc,"Error=%D ", modbus_rx.error);
HataEkrani = 1;
}
read_all_holding();
// write_coils();
}
}
|
My slave Code:
Code: |
//================================================================================
#include <18F452.h>
#device ADC=10 // 10 bitlik ADC
#fuses HS, NOWDT,NOLVP, NOPROTECT,NOBROWNOUT, NOPUT, STVREN, NODEBUG, NOWRT, NOWRTD, NOWRTB, NOWRTC, NOCPD, NOCPB, NOEBTR, NOEBTRB
#use delay(clock=10000000)
#use fast_io(a)
#define MODBUS_TYPE MODBUS_TYPE_SLAVE
#define MODBUS_SERIAL_RX_BUFFER_SIZE 64
#define MODBUS_SERIAL_BAUD 38400
#define MODBUS_SERIAL_RX_PIN PIN_C7
#define MODBUS_SERIAL_TX_PIN PIN_C6
#define MODBUS_SERIAL_ENABLE_PIN PIN_C5
#define MODBUS_SERIAL_RX_ENABLE PIN_C5 // Controls RE pin for RS485 transceiver
#define MODBUS_SERIAL_INT_SOURCE MODBUS_INT_RDA
#define MODBUS_SERIAL_TYPE MODBUS_RTU // use MODBUS_ASCII for ASCII mode
#include <modbus.c>
#define MODBUS_ADDRESS 01
#include "2x16_4x20_LCD.c"
//=============================================================================
#define OUT1 PIN_C0
#define OUT2 PIN_C1
#define OUT3 PIN_E1
#define OUT4 PIN_E2
//=============================================================================
int8 coils = 0b00000000;
int8 inputs = 0b00000000;
int16 hold_regs[] = {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000};
int16 input_regs[] = {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000};
int16 event_count = 0;
unsigned long int Ham_Deger,Ham_Deger2;
float Temp,sicaklik,Temp2,sicaklik2;
int32 sayi=0; // Tamsayı tipinde değişken tanımlanıyor
int a,i;
/*This function may come in handy for you since MODBUS uses MSB first.*/
int8 swap_bits(int8 c)
{
return ((c&1)?128:0)|((c&2)?64:0)|((c&4)?32:0)|((c&8)?16:0)|((c&16)?8:0)
|((c&32)?4:0)|((c&64)?2:0)|((c&128)?1:0);
}
void LM35_Oku ()
{
set_adc_channel( 0 );
delay_us(10);
Ham_Deger=read_adc();
Temp=(0.0048828125*Ham_Deger)*1000; // Dijitale çevirme işlemine uğrayan sinyalin mV olarak gerilimi hesaplanıyor
sicaklik=(Temp/10); // Her 10mV'ta 1 derece artma
LCD_gotoxy(1,2); // gönderilmek
printf(lcd_putc,"Temp1=%5.1f'C",sicaklik);
}
void LCD_OKU ()
{
LCD_gotoxy(3,1);
printf(lcd_putc,"SLAVE ID=%d",MODBUS_ADDRESS);
}
void main()
{
setup_adc(adc_clock_div_32); // ADC clock frekansı fosc/32
setup_adc_ports(ALL_ANALOG);
delay_ms(10); //1 sn bekle
modbus_init();
lcd_init();
OUT2==0;
while(TRUE)
{
LM35_Oku ();
LCD_OKU ();
// Sicaklik = Sicaklik * 10;
hold_regs[0]=Sicaklik*10;
hold_regs[1]=Sicaklik2*10;
hold_regs[2]=MODBUS_ADDRESS;
//! if (INPUT(OUT1) == 1)
//! bit_set(inputs,0);
//! else
//! bit_clear(inputs,0);
if (bit_test(coils,0) == 1)
OUTPUT_HIGH(OUT1);
else
OUTPUT_LOW(OUT1);
if (bit_test(coils,1) == 1)
OUTPUT_HIGH(OUT2);
else
OUTPUT_LOW(OUT2);
if (bit_test(coils,2) == 1)
OUTPUT_HIGH(OUT3);
else
OUTPUT_LOW(OUT3);
if (bit_test(coils,3) == 1)
OUTPUT_HIGH(OUT4);
else
OUTPUT_LOW(OUT4);
while(!modbus_kbhit());
delay_us(50);
//check address against our address, 0 is broadcast
if((modbus_rx.address == MODBUS_ADDRESS) || modbus_rx.address == 0)
{
switch(modbus_rx.func)
{
case FUNC_READ_COILS: //read coils
case FUNC_READ_DISCRETE_INPUT: //read inputs
if(modbus_rx.data[0] || modbus_rx.data[2] ||
modbus_rx.data[1] >= 8 || modbus_rx.data[3]+modbus_rx.data[1] > 8)
modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS);
else
{
int8 data;
if(modbus_rx.func == FUNC_READ_COILS)
data = coils>>(modbus_rx.data[1]); //move to the starting coil
else
data = inputs>>(modbus_rx.data[1]); //move to the starting input
data = data & (0xFF>>(8-modbus_rx.data[3])); //0 out values after quantity
if(modbus_rx.func == FUNC_READ_COILS)
modbus_read_coils_rsp(MODBUS_ADDRESS, 0x01, &data);
else
modbus_read_discrete_input_rsp(MODBUS_ADDRESS, 0x01, &data);
event_count++;
}
break;
case FUNC_READ_HOLDING_REGISTERS:
case FUNC_READ_INPUT_REGISTERS:
if(modbus_rx.data[0] || modbus_rx.data[2] ||
modbus_rx.data[1] >= 8 || modbus_rx.data[3]+modbus_rx.data[1] > 8)
modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS);
else
{
if(modbus_rx.func == FUNC_READ_HOLDING_REGISTERS)
modbus_read_holding_registers_rsp(MODBUS_ADDRESS,(modbus_rx.data[3]*2),hold_regs+modbus_rx.data[1]);
else
modbus_read_input_registers_rsp(MODBUS_ADDRESS,(modbus_rx.data[3]*2),input_regs+modbus_rx.data[1]);
event_count++;
}
break;
case FUNC_WRITE_SINGLE_COIL: //write coil
if(modbus_rx.data[0] || modbus_rx.data[3] || modbus_rx.data[1] > 8)
modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS);
else if(modbus_rx.data[2] != 0xFF && modbus_rx.data[2] != 0x00)
modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_VALUE);
else
{
//coils are stored msb->lsb so we must use 7-address
if(modbus_rx.data[2] == 0xFF)
bit_set(coils,modbus_rx.data[1]);
else
bit_clear(coils,modbus_rx.data[1]);
modbus_write_single_coil_rsp(MODBUS_ADDRESS,modbus_rx.data[1],((int16)(modbus_rx.data[2]))<<8);
event_count++;
}
break;
case FUNC_WRITE_SINGLE_REGISTER:
if(modbus_rx.data[0] || modbus_rx.data[1] >= 8)
modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS);
else
{
//the registers are stored in little endian format ///////======///
hold_regs[modbus_rx.data[1]] = make16(modbus_rx.data[2],modbus_rx.data[3]);
modbus_write_single_register_rsp(MODBUS_ADDRESS,
make16(modbus_rx.data[0],modbus_rx.data[1]),
make16(modbus_rx.data[2],modbus_rx.data[3]));
}
break;
case FUNC_WRITE_MULTIPLE_COILS:
if(modbus_rx.data[0] || modbus_rx.data[2] ||
modbus_rx.data[1] >= 8 || modbus_rx.data[3]+modbus_rx.data[1] > 8)
modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS);
else
{
int i,j;
modbus_rx.data[5] = swap_bits(modbus_rx.data[5]);
for(i=modbus_rx.data[1],j=0; i < modbus_rx.data[1]+modbus_rx.data[3]; ++i,++j)
{
if(bit_test(modbus_rx.data[5],j))
bit_set(coils,7-i);
else
bit_clear(coils,7-i);
}
modbus_write_multiple_coils_rsp(MODBUS_ADDRESS,
make16(modbus_rx.data[0],modbus_rx.data[1]),
make16(modbus_rx.data[2],modbus_rx.data[3]));
event_count++;
}
break;
case FUNC_WRITE_MULTIPLE_REGISTERS:
if(modbus_rx.data[0] || modbus_rx.data[2] ||
modbus_rx.data[1] >= 8 || modbus_rx.data[3]+modbus_rx.data[1] > 8)
modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS);
else
{
int i,j;
for(i=0,j=5; i < modbus_rx.data[4]/2; ++i,j+=2)
hold_regs[i] = make16(modbus_rx.data[j],modbus_rx.data[j+1]);
modbus_write_multiple_registers_rsp(MODBUS_ADDRESS,
make16(modbus_rx.data[0],modbus_rx.data[1]),
make16(modbus_rx.data[2],modbus_rx.data[3]));
event_count++;
}
break;
default: //We don't support the function, so return exception
modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_FUNCTION);
}
}
}
}
//=====================================================================================
|
The files here:
http://www.4shared.com/file/b4p3Js7F/Mod_Master_Slave.html
Last edited by thenorthstar on Mon May 23, 2011 12:41 am; edited 1 time in total |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Sun May 22, 2011 5:46 pm |
|
|
Do yourself a HUGE favour..get RID of Proteus !!
If you hardware is connected as in the schematic, it'll never work. I stopped at 15 , the errors I could easily see.
Cut real code, burn real PICs, test in the real world.Only then will you really learn what's going on.
As far as your code, I wouldn't use Modbus for the task,far easier ways to do it !
Get rid of the use-fast-io code unles you've got 4-5 years of PIC programing, it'll cause you a LOT of problems.
Also I don't see any serial communications...though you're program is 'messy'.
Also how do you handle any of the internal peripherals that share the I/O pins you'r using??? |
|
|
thenorthstar
Joined: 06 Mar 2010 Posts: 24
|
|
Posted: Mon May 23, 2011 12:46 am |
|
|
I'm sorry. Edit Link and codes. I added all the files.
Do you have a problem with the connection? |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|