View previous topic :: View next topic |
Author |
Message |
Tony Stark
Joined: 20 Aug 2021 Posts: 5
|
how to transfer 1 data variable to PC and to slave by rs485 |
Posted: Fri Aug 20, 2021 7:25 pm |
|
|
Hi All,
i want to communicate 3 PIC microcontroller using rs485.
i want to trans a variable trans =400 to the slave, but in the slave i am not getting the correct value on the lcd, where did i go wrong? is there any other way?
In the near future, I want to send it to winform basic, is there anything I should note?
sorry for my English not good
any help would be awesome,thanks in advance.
[img] proteus simulator:
https://bit.ly/3gmhWD7
Code: |
#include <18f448.h> //master trans
#device *=16
//#ignore_warnings 201, 216
#fuses NOWDT
#use delay(crystal = 10MHz) // Usar 20 MHz para montaje en f�sico.
//#use rs232(baud=9600, xmit=PIN_B2, rcv=PIN_B1, stream=PC)
#define RS485_RX_BUFFER_SIZE 64
#define RS485_USE_EXT_INT TRUE
int8 OUR_RS485_ID = 0;
#define RS485_ID OUR_RS485_ID
#include <rs485.c>
#include <stdlib.h>
int8 msg[10];
void RS485send(char* s, int8 id) // HAM TRANS COMMON
{
int8 size;
for(size=0; s[size]!='\0'; ++size);
rs485_wait_for_bus(FALSE);
while(!rs485_send_message(id, size, s))
delay_ms(OUR_RS485_ID);
}
void main()
{
enable_interrupts(GLOBAL);
rs485_init();
int8 trans =400;
int i;
// int *msg;
while (true)
{
//-----------------------------------------------------------------
if(!input(PIN_E0))
{
msg[0] = trans;
// putc(1);
RS485send(msg, 0x01);
while(!input(PIN_E0));
}
//putc('1');
//fputc('U',RS485);
// printf('1');
}
}
///////////////////////////////////////// SLAVE ///////////////////////////////////
#include <18f448.h> // slave rcv
#device *=16
#fuses NOWDT
#use delay(crystal = 10MHz) // Usar 20 MHz para montaje en f�sico.
#define RS485_RX_BUFFER_SIZE 64
#define RS485_USE_EXT_INT TRUE
int8 OUR_RS485_ID = 0x01;
#define RS485_ID OUR_RS485_ID
#include <rs485.c>
#include<lcd_tm.c>
int1 flag_rs485 = 0;
int8 msg[10];
int i;
#INT_TIMER0
void timer0_isr()
{
if(rs485_get_message(msg, FALSE))
{
flag_rs485 = 1;
}
}
void clean_msg (void)
{
for(i=0;i<sizeof(msg);i++)
{
msg[i] = 0x00;
}
}
void main()
{
output_low(PIN_A0);
SETUP_TIMER_0(T0_INTERNAL | T0_DIV_16); //xap xi 26ms
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
rs485_init();
lcd_init();
int8 temp;
while (true)
{
if(flag_rs485)
{
disable_interrupts(INT_TIMER0);
flag_rs485 = 0;
output_high(PIN_E0);
// temp=getc();
temp=msg[2];
lcd_gotoxy (2,2);
lcd_putc("trans value= ");
printf(LCD_PutC,"%d",temp);
clean_msg();
enable_interrupts(INT_TIMER0);
}
}
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19591
|
|
Posted: Sat Aug 21, 2021 12:56 am |
|
|
Without looking any further, a key 'glaring' line:
int8 trans =400;
What is the biggest number an int8 can hold?. Given that all transfers
are in bytes, and this is a byte, I'd expect the receiver to see 144 (the
low 8 bits of '400').
For a number this large, you need to be storing it in an int16 everywhere,
and sending a two byte message instead of one byte. |
|
|
Tony Stark
Joined: 20 Aug 2021 Posts: 5
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19591
|
|
Posted: Sat Aug 21, 2021 3:25 am |
|
|
Two things:
RS485send(&msg, ??? )
Note the &.
RS485send, expects the memory address of what it is to send.
Then the ??? depends on what 'address' your target has on the bus.
Your code specifies the addresses of the devices. In the example,
RS485_ID. You set this to a different value in each device, and then to
send to device 4, you put this for the ???.
The RS485send function is not suitable for sending a number as you
are trying to do. It is designed to send a _string_, so an array that has
a null terminator at the end. Currently it could end up trying to send
thousands of bytes. |
|
|
Tony Stark
Joined: 20 Aug 2021 Posts: 5
|
|
Posted: Sat Aug 21, 2021 4:00 am |
|
|
if I transmit to 1 slave then I will set that slave with address RS485_ID=4. but now I transmit to PC (virtual terminal), how can I set the address for virtual terminal? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9272 Location: Greensville,Ontario
|
|
Posted: Sat Aug 21, 2021 4:56 am |
|
|
You have a 'master' PIC, 3 'slaves' and a PC.
The PC will be the 4th 'slave'. You'll need to add RS-485 to the PC, using a USB<>RS-485 module. You also need to configure the PC to be RS-485 slave address #4 both in the PC terminal program as well as the PIC Master code.
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19591
|
|
Posted: Sat Aug 21, 2021 11:40 am |
|
|
Also, you would need code other than a virtual terminal to handle the
PC. The RS485 programs expect to talk to other RS485 programs, which have the code in them to decode the ID being talked to. A virtual terminal does
not so this. You would have to have either a custom PC program to do this
or a PIC as an interface running the RS485 code, which when it sees a
suitable packet, forwards this to the PC. |
|
|
|