CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

RS485 With MAX3085 & PIC16F15356
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Backfire



Joined: 12 Oct 2020
Posts: 44

View user's profile Send private message

RS485 With MAX3085 & PIC16F15356
PostPosted: Tue Jan 31, 2023 4:47 am     Reply with quote

Hello all,
I've a question on RS485, which admittedly may be more hardware-focused at the moment, but I also want to ensure my PIC configuration is correct...

I have a Waveshare USB->RS485 driver that is generating the signals shown on the 'scope trace below, these are the signals as measured into a MAX3085 chip at the A & B chip pins, on a custom PCB.

This trace was also captured with a GND/0V signal bias on the B line (via a 715R resistor) and a +5V signal bias (again, via resistor) on the A line, also applied near the MAX3085 driver IC itself.

The trace was captured when including both the 120R termination resistor near the A/B output (currently only attempting data reception by the PIC) of the Waveshare module, and another termination resistor at the A/B pins of the MAX3085.



The yellow trace is the 'A' signal, and the blue trace 'B', using the MAX3085 nomenclature. The purple/pink trace is the oscilliscope math function of 'A-B'.

My current PIC configuration is as follows;
Driving the DE and (NOT)RE pins of the MAX3085 low, and my PIC is running other code without issue from the internal oscillator, @ 32MHz, with the RS485 serial port configured with the following parameters;

Code:
#use rs232(STREAM=RS485, BAUD=9600, BITS=9, LONG_DATA, ENABLE=RS485_DE, XMIT=PIN_C6, RCV=PIN_C7, STOP=1, ERRORS)



And my Rx'd data ISR is:

Code:

#INT_RDA
void  RDA_ISR(void)
{
    int8 RxdByte = 0;
   
    if(kbhit(RS485))
        RxdByte = fgetc(RS485);
   
    fprintf(DEBUG, "%c\r", RxdByte);
}


So my theory is, I should at least see some data output from the MAX3085 RO pin with this setup on my 'scope, when I send data through the Waveshare module, but instead I see no voltage at any point, regardless of the signals shown above being present at the A/B terminals of the RS485 transceiver.

Any help would be gladly appreciated!
Ttelmah



Joined: 11 Mar 2010
Posts: 19218

View user's profile Send private message

PostPosted: Tue Jan 31, 2023 5:14 am     Reply with quote

First, your INT_RDA, wants:
Code:

#INT_RDA
void  RDA_ISR(void)
{
    int8 RxdByte = 0;
   
    //if(kbhit(RS485)) //Not needed. The fact the interrupt
    //has occurred says there is data.
        RxdByte = fgetc(RS485);
   
    fprintf(DEBUG, "%c\r", RxdByte);
    //This is a problem. You are sending two characters when
    //one is received. Result the code will stay inside this
    //interrupt longer than one character time. Can easily
    //result in the input UART buffer overflowing
    //So you really need to only send one character.
}


On your RE/DE wiring. Connect these together, and connect both to
the RS485_DE pin on the PIC. You should have a pull up resistor
on the RO pin of the MAX driver otherwise you can see garbage when
you transmit.
How is the GND of the PIC board connected?. It needs to go to the GND
of the Waveshare board.
Backfire



Joined: 12 Oct 2020
Posts: 44

View user's profile Send private message

PostPosted: Tue Jan 31, 2023 6:33 am     Reply with quote

Hi Ttelmah,
thanks for your reply.

I can confirm that the devices all share a well-established common ground.

I have made the modifications to my ISR, but presently that never triggers, hence my suspicion I've a hardware issue currently.

Can I ask why you recommed that the (NOT)RE & DE pins are tied together? I can see this is a common implementation, but surely if the PIC can drive those pins to any state, or combination of states I should still have a valid reception?

As for a pull-up on RO, I've not seen one mentioned in the datasheet as being required... As this device is already soldered to a custom PCB, would the PIC's internal WPU likely to work, for testing at least?

Many thanks again for your advice.
temtronic



Joined: 01 Jul 2010
Posts: 9102
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Jan 31, 2023 7:06 am     Reply with quote

comment...
if you tie both -RE and DE together ,only ONE pic pin is needed to control BOTH receive and transmit of the RS485 device....otherwise you need 2 pins and we always run out of pins before the end of the project....

to make RS-485 bus 'bullet proof', you use 750r pullup, pull down AND the 125r bias resistor. While you 'may' get away with fewer resistors,sooner or later, depending on chips used, PCB layout, wiring, gremlins...you WILL have a 'problem'...... So spending 3 cents for 3 parts makes sense .

in the end, you want to design/build RELIABLE equipment,and no amount of costly and clever software will FIX faulty hardware.
Backfire



Joined: 12 Oct 2020
Posts: 44

View user's profile Send private message

PostPosted: Tue Jan 31, 2023 7:13 am     Reply with quote

Hi temtronic,
I agree with you 100%, I have run out of pins on many projects, and the frustration is real!

That said, I don't believe my schematic is electrically incorrect, just maybe inefficient regarding the separated drives for (NOT)RE and DE.

As for the RS485 'side' of the circuit, on my target PCB I have the full biasing and termination network, and have terminated at the driver-end also.

Are you suggesting I need to add the biasing resistors at the point where the signal is introduced by the Waveshare module, as well as the termination resistor that is already present?

Many thanks for your input!
Ttelmah



Joined: 11 Mar 2010
Posts: 19218

View user's profile Send private message

PostPosted: Tue Jan 31, 2023 7:26 am     Reply with quote

The point is that chips vary. Some RS485 receivers will receive if RE is
low, whatever the state of DE. Problem is then that the device will receive
what is being sent. In your case if RE is high and DE low it goes into a
shutdown mode. Much safer to use just the two states. RE and DE both low,
which receives, and RE and DE both high for transmit. This saves a pin on
the PIC and avoids the possibility of receiving while transmitting, and of
going into the shutdown mode.
Backfire



Joined: 12 Oct 2020
Posts: 44

View user's profile Send private message

PostPosted: Tue Jan 31, 2023 7:35 am     Reply with quote

Hi Ttelmah,
I completely understand, the two pins tied together is a more elegant solution, and inherently avoids some possible pitfalls.

But I have driven both (NOT)RE and DE low, am sending data into the MAX3085 as shown above, and I am still seeing no output from the RO pin of the MAX3085.

Is my configuration of the UART correct for RS485 reception?

Here's my current config;

Code:

#define RS485_NRE PIN_A6
#define RS485_DE PIN_A7

#use rs232(STREAM=RS485, BAUD=9600, BITS=9, LONG_DATA, ENABLE=RS485_DE, XMIT=PIN_C6, RCV=PIN_C7, STOP=1, ERRORS)


And in the code body I drive both low in my device initialisation also.
Ttelmah



Joined: 11 Mar 2010
Posts: 19218

View user's profile Send private message

PostPosted: Tue Jan 31, 2023 7:47 am     Reply with quote

No.

This is a PPS chip. Look at the sticky at the head of the forum on how
to use the UART with this.
Backfire



Joined: 12 Oct 2020
Posts: 44

View user's profile Send private message

PostPosted: Tue Jan 31, 2023 7:53 am     Reply with quote

Hi Ttelmah,
I have already attempted configuration as follows, including the below;

Code:

#pin_select U1TX = PIN_C6
#pin_select U1RX = PIN_C7


And then including the 'UART1' parameter in the #use rs232(), rather than specifying the pins directly in the #use rs232() statement.

I can't see an obvious #pin_select for the enable pin...
Ttelmah



Joined: 11 Mar 2010
Posts: 19218

View user's profile Send private message

PostPosted: Tue Jan 31, 2023 8:11 am     Reply with quote

The enable pin is done in software, not part of the UART hardware.
The PIN_SELECT and UART1 way is the correct configuration for your chip.

Unplug the MAX3085, and check the RX pin is high to the PIC. I must
admit I suspect you have something like a whisker preventing the line
going low.
Backfire



Joined: 12 Oct 2020
Posts: 44

View user's profile Send private message

PostPosted: Tue Jan 31, 2023 8:44 am     Reply with quote

Hi Ttelmah,
thanks again for all your input thus far. Do you mean disconnecting the RS485 driving module? Sadly the MAX3085 in question is a SMD, so simply unplugging it is not an option. I have probed the voltage at the PIC pin 18 (UART1 default Rx) and seen ~0.15-0.2V.

Just for completeness, here's all the RS485-related code, as I'm running it at this moment;

In main.h I have the following configuration;
Code:

#pin_select U1TX = PIN_C6
#pin_select U1RX = PIN_C7

#define RS485_NRE PIN_A6
#define RS485_DE PIN_A7

#use rs232(STREAM=RS485, BAUD=9600, BITS=9, LONG_DATA, ENABLE=RS485_DE, UART1, STOP=1, ERRORS)


And in main.code, the following routines;

Code:

#INT_RDA
void  RDA_ISR(void)
{
    int8 RxdByte = 0;
    RxdByte = fgetc(RS485);
   
    fprintf(DEBUG, "%c", RxdByte);
}

void RS485EnableRx(void)
{
   // Set up our RS485 reception...
   while(kbhit(RS485)) {getc();} // Clear RX buffer, RDA interrupt flag & overrun flag
 
   setup_uart(UART_ADDRESS, RS485);
   setup_uart(TRUE, RS485);
   
   output_low(RS485_NRE);
   output_low(RS485_DE);
   
   enable_interrupts(INT_RDA);
}


After calling RS485EnableRx() from my main routine, I then enable global interrupts and go into a while(TRUE) loop, which just dumps out some status info in a loop; the ISR simply never fires, and I can see no data at the RO output of the MAX3085.
temtronic



Joined: 01 Jul 2010
Posts: 9102
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Jan 31, 2023 9:22 am     Reply with quote

curious...
is it just me or is there a lot of 'noise' on those lines in the 'scope' screen ?

also
i see bits=9, so how do you read the 9th incoming bit ?
Backfire



Joined: 12 Oct 2020
Posts: 44

View user's profile Send private message

PostPosted: Tue Jan 31, 2023 9:51 am     Reply with quote

Hi temtronic,
my 'scope is truly a bottom of the line unit, to give some context, heres my scope as pulling from its own calibration output;



I work with what I have, ever-deaming of being able to afford an upgrade!

Both the PIC and the MAX3085 have local high-frequency decoupling (0.1uF) and small tank capacitors (10uF) though.

The example code in the CCS supplied rs485.c example file has 'bits=9', its reading through that file I was using as my starting point.
gaugeguy



Joined: 05 Apr 2011
Posts: 288

View user's profile Send private message

PostPosted: Tue Jan 31, 2023 10:18 am     Reply with quote

Your code appears to be trying to echo a received byte, but you are probably not receiving properly formatted data, so nothing will be sent out.
Try just sending a known character at a periodic rate.
Ttelmah



Joined: 11 Mar 2010
Posts: 19218

View user's profile Send private message

PostPosted: Tue Jan 31, 2023 10:28 am     Reply with quote

There is another problem. You are specifying long_data, so you don't
receive an int8, you receive an int16....
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2, 3  Next
Page 1 of 3

 
Jump to:  
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