Forum Rule: Always post complete source code & details to reproduce any issue!
Page 2 of 2 FirstFirst 1 2
Results 26 to 43 of 43

Thread: Teensy 3.2 UART0 Receive Lockup after first Write in RS485 circuit

  1. #26
    Member BradleyC's Avatar
    Join Date
    Mar 2018
    Location
    Houston Area
    Posts
    27
    Quote Originally Posted by PaulStoffregen View Post
    Looks like I forgot the 10K resistor, in my first quick attempt. Indeed it does make quite a difference.

    I added the resistor, and connected my scope to those 3 signals and to the A signal (pin 6 of the MAX487).

    Attachment 14815

    With the 10K resistor, here's what I see in the serial monitor.

    Attachment 14816

    Here's what my scope sees:

    Attachment 14817
    Ok, now I see we have identical results. That's good.

  2. #27
    Member BradleyC's Avatar
    Join Date
    Mar 2018
    Location
    Houston Area
    Posts
    27
    Quote Originally Posted by PaulStoffregen View Post
    For this application, I'd recommend adding three 4.7K resistors.

    Resistor #1: RS485 signal A to +5V
    Resistor #2: RS485 signal B to GND
    Resistor #3: RO (RX1) to +5V

    The first 2 keep the RS485 signals in a proper idle state when they're not driven. Here's a page with more detail and a schematic.

    https://electronics.stackexchange.co...-bidirectional

    The 3rd resistor helps keep the RO signal from the MAX483 / MAX487 at a valid logic high when the receiver is turned off.

    Here's how the reset looks on my scope.

    Attachment 14819

    Here's the 4.7K resistors connected on my breadboard.

    Attachment 14820
    I will make these changes and re-test. I'll also read the reference you provided. Thank you very much for spending your limited time to look at this and give me such specific guidance.

    I hope I will be able to return the favor with dividends.

  3. #28
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    18,679
    Looks like Serial1 (and probably the other ports) do have less-than-ideal recovery from framing errors.

    This came up a month or two ago, on another thread about a not-so-well-designed RS485 network where the devices were made with those idle bias resistors connected backwards (holding the RS485 lines in the active state when undriven).

    Because this is the 2nd time it's come up recently, I decided to put a little more work into investigating how we're dealing with serial framing errors. Came up with this code today:

    Code:
    // Test Serial1 ability to recover from framing errors
    // Short pins 0 and 2 for this test
    //
    // Pin 2 transmits serial data, sometimes with framing errors
    // Pin 0 (RX1) attempts to receive.
    
    IntervalTimer bitTimer;
    
    #define BITTIME (1e6 / 9600.0)
    
    int bitcount;
    uint32_t data;
    
    void setup()
    {
    	pinMode(2, OUTPUT);
    	digitalWrite(2, HIGH);
    	bitTimer.priority(0);
    	Serial1.begin(9600);
    	while (!Serial) ; // wait
    	Serial.println("Serial framing error test");
    }
    
    void transmit(uint32_t bits, int count)
    {
    	bitTimer.end();
    	data = (bits | (1 << count)) << 1; // add start & stop bits
    	bitcount = count + 2;
    	bitTimer.begin(update, BITTIME);
    	delayMicroseconds(1500);
    }
    
    void update()
    {
    	digitalWrite(2, data & 1);
    	data = data >> 1;
    	if (--bitcount == 0) bitTimer.end();
    }
    
    void loop()
    {
    	static unsigned int loopcount=0;
    	Serial.printf("loop %u:\n", ++loopcount);
    	delay(10);
    	transmit(0, 8);
    	transmit(0xA5, 8);
    	transmit(0, 9);
    	//delayMicroseconds(525); // 525 or higher allows receiving following bytes
    	transmit(0xA5, 8);
    	transmit(0, 8);
    	wait(2500);
    }
    
    void wait(uint32_t msec)
    {
    	elapsedMillis elapsed;
    	while (elapsed < msec) {
    		if (Serial1.available()) {
    			Serial.printf("receive: %02X\n", Serial1.read());
    		}
    	}
    }
    Indeed, without that extra 525 us delay, it prints this in the serial monitor:

    Serial framing error test
    loop 1:
    receive: 00
    receive: A5
    receive: 00
    loop 2:
    receive: 00
    receive: A5
    receive: 00
    loop 3:
    receive: 00
    receive: A5
    receive: 00
    But of course, those other bytes are present. Here's what my oscilloscope sees...

    Click image for larger version. 

Name:	file.png 
Views:	9 
Size:	27.3 KB 
ID:	14824

    When that extra delay is added, all 5 bytes are properly received.

    I've put this issue on my list of bugs to fix for version 1.45. I do consider this a high priority bug. But I still can't promise any timeframe for a fix.

    For now, on your application I'd suggest adding those 4.7K resistors. In your application, those resistors and the regular idle times (following collisions) between packets should be enough to work around the problem.

  4. #29
    Member BradleyC's Avatar
    Join Date
    Mar 2018
    Location
    Houston Area
    Posts
    27
    Quote Originally Posted by PaulStoffregen View Post
    Looks like Serial1 (and probably the other ports) do have less-than-ideal recovery from framing errors.

    This came up a month or two ago, on another thread about a not-so-well-designed RS485 network where the devices were made with those idle bias resistors connected backwards (holding the RS485 lines in the active state when undriven).

    Because this is the 2nd time it's come up recently, I decided to put a little more work into investigating how we're dealing with serial framing errors. Came up with this code today:

    Code:
    // Test Serial1 ability to recover from framing errors
    // Short pins 0 and 2 for this test
    //
    // Pin 2 transmits serial data, sometimes with framing errors
    // Pin 0 (RX1) attempts to receive.
    
    IntervalTimer bitTimer;
    
    #define BITTIME (1e6 / 9600.0)
    
    int bitcount;
    uint32_t data;
    
    void setup()
    {
    	pinMode(2, OUTPUT);
    	digitalWrite(2, HIGH);
    	bitTimer.priority(0);
    	Serial1.begin(9600);
    	while (!Serial) ; // wait
    	Serial.println("Serial framing error test");
    }
    
    void transmit(uint32_t bits, int count)
    {
    	bitTimer.end();
    	data = (bits | (1 << count)) << 1; // add start & stop bits
    	bitcount = count + 2;
    	bitTimer.begin(update, BITTIME);
    	delayMicroseconds(1500);
    }
    
    void update()
    {
    	digitalWrite(2, data & 1);
    	data = data >> 1;
    	if (--bitcount == 0) bitTimer.end();
    }
    
    void loop()
    {
    	static unsigned int loopcount=0;
    	Serial.printf("loop %u:\n", ++loopcount);
    	delay(10);
    	transmit(0, 8);
    	transmit(0xA5, 8);
    	transmit(0, 9);
    	//delayMicroseconds(525); // 525 or higher allows receiving following bytes
    	transmit(0xA5, 8);
    	transmit(0, 8);
    	wait(2500);
    }
    
    void wait(uint32_t msec)
    {
    	elapsedMillis elapsed;
    	while (elapsed < msec) {
    		if (Serial1.available()) {
    			Serial.printf("receive: %02X\n", Serial1.read());
    		}
    	}
    }
    Indeed, without that extra 525 us delay, it prints this in the serial monitor:



    But of course, those other bytes are present. Here's what my oscilloscope sees...

    Click image for larger version. 

Name:	file.png 
Views:	9 
Size:	27.3 KB 
ID:	14824

    When that extra delay is added, all 5 bytes are properly received.

    I've put this issue on my list of bugs to fix for version 1.45. I do consider this a high priority bug. But I still can't promise any timeframe for a fix.

    For now, on your application I'd suggest adding those 4.7K resistors. In your application, those resistors and the regular idle times (following collisions) between packets should be enough to work around the problem.
    I've added the 3 resistors and unfortunately it did not fix the problem but showed a new one and led to an interesting discovery.
    Short story is that the Rx pullup changed nothing on the scope or in the output of the sketch.
    Adding the Failsafe pull-down caused transmits to fail completely. Serial1.write() make it to the TX line but on the output of the MAX483 my design uses, A is normal but B stays grounded so there's no inverted signal.
    Adding the failsafe pull-up causes (apparently) or allows (?) the receive to continue after the transmit but transmits aren't really working at the same time.
    But one other happy accident: the 9th byte garbage on my home-built RS485 monitor disappears. All frames are 8 bytes with the fail-safe pull-up. ANd this is true weather I put the pull-up on the Teensy MAX483 pin or if I put it on the home-built monitor MAX483 pin. But in both cases, teensy can't transmit an RS485 byte though it can continue to receive bytes.

    I have some notes I wrote with several images. If you feel they would help the community I will spend the time to add them -- but right now the better half called me to dinner and I better not linger here!

  5. #30
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    18,679
    Quote Originally Posted by BradleyC View Post
    ANd this is true weather I put the pull-up on the Teensy MAX483 pin or if I put it on the home-built monitor MAX483 pin. But in both cases, teensy can't transmit an RS485 byte though it can continue to receive bytes.
    Sounds like something is wrong with your circuitry. Those RS485 chips should be able to drive 100 or even 50 ohms. Adding 4.7K resistors should not prevent it from transmitting.

  6. #31
    Member BradleyC's Avatar
    Join Date
    Mar 2018
    Location
    Houston Area
    Posts
    27
    Quote Originally Posted by PaulStoffregen View Post
    Sounds like something is wrong with your circuitry. Those RS485 chips should be able to drive 100 or even 50 ohms. Adding 4.7K resistors should not prevent it from transmitting.
    I was wondering about this the whole time -- even before I posted the first note.

    Is the RTS pin for UART0 available in Teensy 3.2.

    I might try hardware transceiver control using the modem register like the NXP training slide suggested if I can use the RTS pin.

  7. #32
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    18,679
    I don't see how that's going to help. If the DE pin is high and TX1 is sending data, but that chip isn't managing to transmit it on the A+B pins, how will driving DE differently make any difference?

    But if you want to try, yes, that signal is available. If you look in the big table of chapter 10, it's ALT3 on PTB2, which is pin 19 on the schematic.

  8. #33
    Member BradleyC's Avatar
    Join Date
    Mar 2018
    Location
    Houston Area
    Posts
    27
    Quote Originally Posted by PaulStoffregen View Post
    I don't see how that's going to help. If the DE pin is high and TX1 is sending data, but that chip isn't managing to transmit it on the A+B pins, how will driving DE differently make any difference?

    But if you want to try, yes, that signal is available. If you look in the big table of chapter 10, it's ALT3 on PTB2, which is pin 19 on the schematic.
    You make the same point I made to myself. But here's my thinking. With this circuit it's been able to receive reliably and transmit reliably but not switch back and forth. So I conjectured that maybe there's something inside the MCU FIFO logic / state machine related to half-duplex control and using RTS is the way to manage it. Just a guess and a different experiment to try.

    I trust your Teensy (hw and sw) 9000% more than my hw or sw. One other thing I can do more easily than switching pins is to try my third prototype with the same sketch(es). Thanks for being engaged with me on this investigation - your confidence and directions are immensely valuable to narrow my choices for my search for the fix.

  9. #34
    Member BradleyC's Avatar
    Join Date
    Mar 2018
    Location
    Houston Area
    Posts
    27
    Quote Originally Posted by PaulStoffregen View Post
    I don't see how that's going to help. If the DE pin is high and TX1 is sending data, but that chip isn't managing to transmit it on the A+B pins, how will driving DE differently make any difference?

    But if you want to try, yes, that signal is available. If you look in the big table of chapter 10, it's ALT3 on PTB2, which is pin 19 on the schematic.
    I found that and believed it might work -- but I noticed in my current design pin 19 and 18 are being used for SCL0 and SDA0 respectively (temp/humidity sensor). So now I get to find out how to assign the other pins you allow for I2C (17 and 16 for SDA and SCL respectively)! Cool. Learning more than I expected. Time to go read the forum about pins and the reference about the port control register details.

  10. #35
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    18,679
    Wire.setSCL() and Wire.setSDA()

    https://www.pjrc.com/teensy/td_libs_Wire.html

  11. #36
    Senior Member
    Join Date
    May 2017
    Posts
    148
    I also don't see how changing to using RTS is going to change anything, but if you view it as a learning experience then learning something new is always fun.

    It sounds to me that you solved one problem but introduced a different one.

    Scoping one side of a balanced driver may not be a valid test if you have just added one resistor. The other signal will just vary above and below the one that you have coupled to ground.

    One thing you could try is higher value resisters on the A and B signals. I would try 49K, getting that value from a very quick scaling of the values shown in the wiki page.

    Your new problem could be caused by ground loops since your system is distributed throughout your house ( I assume from your descriptions ). You could try the resistors at the center of your network.

    Unknown is if the existing design has some kind of signal detection circuit that detects when the A and B lines are being driven ( like a carrier detect circuit ) and adding the resistors that solve the original problem has upset that. ( Just really guessing here ).

    Paul may fix the issue with framing errors soon and you could just go back to your original circuit although I suggest keeping the pullup on the RX line.

    You could try the drivers with the built in failsafe.
    https://www.maximintegrated.com/en/p...MAX13080E.html
    Last edited by rcarr; 09-27-2018 at 04:18 PM.

  12. #37
    Member BradleyC's Avatar
    Join Date
    Mar 2018
    Location
    Houston Area
    Posts
    27
    Quote Originally Posted by rcarr View Post
    I also don't see how changing to using RTS is going to change anything, but if you view it as a learning experience then learning something new is always fun.

    It sounds to me that you solved one problem but introduced a different one.

    Scoping one side of a balanced driver may not be a valid test if you have just added one resistor. The other signal will just vary above and below the one that you have coupled to ground.

    One thing you could try is higher value resisters on the A and B signals. I would try 49K, getting that value from a very quick scaling of the values shown in the wiki page.

    Your new problem could be caused by ground loops since your system is distributed throughout your house ( I assume from your descriptions ). You could try the resistors at the center of your network.

    Unknown is if the existing design has some kind of signal detection circuit that detects when the A and B lines are being driven ( like a carrier detect circuit ) and adding the resistors that solve the original problem has upset that. ( Just really guessing here ).

    Paul may fix the issue with framing errors soon and you could just go back to your original circuit although I suggest keeping the pullup on the RX line.

    You could try the drivers with the built in failsafe.
    https://www.maximintegrated.com/en/p...MAX13080E.html

    Rcarr, Thanks for mentioning the ground loop issue. I did not mention this because I thought more complexity would confuse rather than clarify. However, I do believe that I have an AC ground loop in this house and I wondered if that could affect this rs485 design when it's connected to the PC for debugging. I noticed it years ago when I plugged in a DVD that was grounded through the satellite coax and then also grounded by the 3-prong power cord. The circuit breaker tripped. I measured a few volts AC between the two grounds. Ended up ignoring it because this was the only functional issue because I was able to swap out a DVD with a 2-prong power cord and no ground loop problem.

    I don't expect the RTS to fix my issue -- but it is a learning experience (having to reassign my I2C pins to access the RTS).

    Thanks especially for the suggestion about changing resistors. I wondered if that could help in some way. But I didn't want to shoot in the dark so I didn't try yet.

    Thanks too for the pointer to the max13080E. I'll look into it.

    I think I'm learning more (about hardware) than I expected to when I started this pro-bono effort to help my friend and you and Paul are great to help!

    For now, I'm going to do two things before I rewire the prototype for RTS tranceiver control.

    1. I'm going to test and scope the second prototpye. It has a different physical design but same electrical design.

    2. I'm going to decouple from the home AC network and connect the two teensy prototypes to each other and scope the rs485 network.

    I intend to report both results to the Forum because my learning experience might help others and I'm not ashamed of my ignorance. Ignorance is curable. Only stupidity is congenital. So I'm expecting to be cured if i work hard enough on this and get it working.

    Never give up! Never surrender!

  13. #38
    Quote Originally Posted by BradleyC View Post
    Rcarr, Thanks for mentioning the ground loop issue. I did not mention this because I thought more complexity would confuse rather than clarify. However, I do believe that I have an AC ground loop in this house and I wondered if that could affect this rs485 design when it's connected to the PC for debugging. I noticed it years ago when I plugged in a DVD that was grounded through the satellite coax and then also grounded by the 3-prong power cord. The circuit breaker tripped. I measured a few volts AC between the two grounds. Ended up ignoring it because this was the only functional issue because I was able to swap out a DVD with a 2-prong power cord and no ground loop problem.

    That is a problem.

    Unless there is a fault there is zero current in the safety grounds other than perhaps some high frequency hash from input filters on equipment. With no current and everything tied to the same bus bar back at the circuit breaker, the voltage difference should be close enough to zero as makes no difference. If there is a voltage between two safety grounds that indicates current in at least one of them that shouldn't be there. It is possible that an outlet (or two) has swapped the ground and neutral.

    Or you could have a failure somewhere that is shunting current into the safety ground but not enough to trip the breaker. Aside from paying for power that isn't doing anything, this is a safety hazard.


    Jumping in late so I may have missed something...

    RS485 is a three wire system but your initial diagram shows only A and B from your transceiver being connected to the net. You need a ground reference too. Circuit Cellar magazine ran a nice article in July 1999: "The Art and Science of RS-485" by Bob Perrin. You should be able to find a pdf somewhere and I highly recommend reading it.

  14. #39
    Member BradleyC's Avatar
    Join Date
    Mar 2018
    Location
    Houston Area
    Posts
    27
    Quote Originally Posted by UhClem View Post
    That is a problem.

    Unless there is a fault there is zero current in the safety grounds other than perhaps some high frequency hash from input filters on equipment. With no current and everything tied to the same bus bar back at the circuit breaker, the voltage difference should be close enough to zero as makes no difference. If there is a voltage between two safety grounds that indicates current in at least one of them that shouldn't be there. It is possible that an outlet (or two) has swapped the ground and neutral.

    Or you could have a failure somewhere that is shunting current into the safety ground but not enough to trip the breaker. Aside from paying for power that isn't doing anything, this is a safety hazard.


    Jumping in late so I may have missed something...

    RS485 is a three wire system but your initial diagram shows only A and B from your transceiver being connected to the net. You need a ground reference too. Circuit Cellar magazine ran a nice article in July 1999: "The Art and Science of RS-485" by Bob Perrin. You should be able to find a pdf somewhere and I highly recommend reading it.
    Thanks for confirming the AC grounding difference as a potential issue. I will investigate that again. This was years ago and I've learned a bit more about hardware since then so I might have been wrong in some details. I am questioning all of the assumptions I realize that I'm making. (Problem with assumptions is that they are usually subconscious and difficult to surface for re-evaluation).

    With respect to 2-wire vs 3 wire: I believe that this is 3 wire too (but I probably drew the schematic incorrectly) because the DC ground for the +12V Power from the attic controller where the central RS485 node is located is shared with the ground for the +5V power rail coming from the DC-DC buck converter I used in the prototype to bring the 12V down to 5V for power to the MAX483 and Teensy 3.2.

    However, I have had some email consultation yesterday with an EE who also has one of these high-efficiency multi-zone custom home AC systems here in houston. I asked him this question:

    Question: I was reviewing the MAX483 data sheet and noticed that their circuit shows a capacitor between the 5V pin and GND.

    I donít have a capacitor in my prototype in that circuit location. See below (red circles the cap.)
    Click image for larger version. 

Name:	dsexcerpt.png 
Views:	5 
Size:	61.8 KB 
ID:	14862

    In my prototype, the +5 v output from the buck converter is connected directly to the 5V Ďrailí in the PCA (powers the MAX483, the Teensy and the digital temp/humidity sensor (AM2320).
    There Is no capacitor.

    Could this be part of the trouble Iím seeing?

    Should I add one?

    Whatís its purpose?
    Here is his response to this question and a previous one where I asked about the difference in termination resistance used in our home AC RS485 network (which is 10K Ohms) vs the values I've seen in various app notes and online articles about RS485 (which is often 120 Ohms):

    This capacitor on the power rail should be located as close as possible to the power pin on the chip you are bypassing. Its purpose is to reduce fluctuations of voltage on the device as its power demands fluctuate in operation. If the device is not properly bypassed, it can lead to erratic or inconsistent behavior. Normally devices are bypassed with a 0.1uf ceramic capacitor. If you have significant impedance in the connection from the power source to the power pin and/or ground pin of a device that delivers high slew rate outputs especially in a prototype board connected with wires, you may (in addition to the 0.1uf ) bypass with a 10 uf electrolytic capacitor which will filter out the lower frequency voltage fluctuations. Just solder the capacitors (in parallel) directly from the power and ground pins on the device if possible. Note the polarity of the 10uf electrolytic as it can melt down if installed incorrectly. The ceramic capacitor is not polarized.

    The termination resistors in a serial bus system become increasingly important as the frequency and/or length of the nodes of the system increases. As the wave travels down the serial bus, reflections will appear if the "transmission line" bus encounters changes in bus impedance resulting from an improperly terminated or unterminated node (or other sources of impedance change) . Significant reflections can interfere with the bus signals. Since you have a prototype system with low frequencies and short node lengths, this is unlikely a reason for the issue you are experiencing.
    Thanks again for sharing your knowledge in this context.

  15. #40
    OK, it wasn't clear from your drawing but it looks like you have the RS-485 ground reference covered.

    One thing to check is the power supply. Just how much current can you get from the 12V supply?

    Decoupling caps on the RS-485 driver would help with edge speeds and probably not much else. At your low bit rate it wouldn't be at the top of my list.

    I can't say much about the Teensy drivers. I am more a go it alone type. When I run into trouble it is at a much lower level. My last dive into RS-485 resulted in TI issuing an errata on the USART.


    Looking back I see that the line idles with a "0" state. This could cause trouble when you switch from transmit to receive. While in transmit mode the receiver is disabled and the Teensy should see a "1". Then when you switch off the transmitter it is enabled and that idle line state of "0" comes through. A start bit. The receiver dutifully runs through its paces but when it comes time for the stop bits, it sees "0". Framing error.

    Idle state biasing would seem to be in order so long as the existing hardware is happy with an idle state of "1".

  16. #41
    Member BradleyC's Avatar
    Join Date
    Mar 2018
    Location
    Houston Area
    Posts
    27
    Quote Originally Posted by UhClem View Post
    OK, it wasn't clear from your drawing but it looks like you have the RS-485 ground reference covered.

    One thing to check is the power supply. Just how much current can you get from the 12V supply?

    Decoupling caps on the RS-485 driver would help with edge speeds and probably not much else. At your low bit rate it wouldn't be at the top of my list.

    I can't say much about the Teensy drivers. I am more a go it alone type. When I run into trouble it is at a much lower level. My last dive into RS-485 resulted in TI issuing an errata on the USART.


    Looking back I see that the line idles with a "0" state. This could cause trouble when you switch from transmit to receive. While in transmit mode the receiver is disabled and the Teensy should see a "1". Then when you switch off the transmitter it is enabled and that idle line state of "0" comes through. A start bit. The receiver dutifully runs through its paces but when it comes time for the stop bits, it sees "0". Framing error.

    Idle state biasing would seem to be in order so long as the existing hardware is happy with an idle state of "1".
    Thanks again for sharing your knowledge and providing guiding questions.
    I'm not sure how much current the 12V supply can provide but it is protected by a 3AMP fuse on the main board. The 4-wires run to each of a maximum of 8 thermostats are no more than 50-75 feet long in any normal home. This is pretty short for RS485 I believe but I haven't measured the resistance in the wires.
    I'm not used to Arduino. I'm more used to building up from raw hardware with or without RTOS and doing the drivers myself -- like you -- and in those cases I learn bottoms up instead of top down like with Arduino where you skip the BSP development and have no JTAG debugger AND you get to skip reading thousands of pages of register programming model. But when you face a problem like this - debugging (for me) is more difficult without all of that 'tedious' pre-work. So I'm doing my learning (and stumbling) in public here. No shame in learning is there?

    Since you bring up the possible issue with the idle state of the RX being at zero volts and this was mentioned by rcarr in #9 in this thread, I want to discuss the idle state a bit.

    For more context, here is a schematic of the Old Thermostat which I'm trying to replace with an electrically and functionally compatible design so I can remove the old thermostats and install the new ones with better UI in their place but do not have to replace the central controller (which would require another completely different design too). This desire (and my ignorance of real hardware design) is why I used the same MAX483CPA transceiver and the same (10K) termination resistance. I just hoped copying it would work and all I needed to do was firmware! If wishes had horses beggars would ride, eh? Anyway, here's the 15 year old schematic.
    Click image for larger version. 

Name:	OLD TSTAT SCHEMATIC.jpg 
Views:	11 
Size:	109.7 KB 
ID:	14868
    I circled the part of the circuitry (in red) that I copied in my (currently) breadboard based prototype. The MCU used is a PIC16F876A. The design uses through-hole PCA. In this design there is no pull-up resistor on either the Rx or Tx line. But there are bypass capacitors on the 5V output from the voltage regulator that converts 12V to 5V for the design. I didn't know about those until recently so my prototype breadboard based design does not yet have them. There are no failsafe resistors in the network. All rs485 thermostat nodes have a 10K termination resistor about .5" from the terminal block. The central controller does NOT have termination resistor. I don't know why. My house is connected in a 'star' topology with the central controller in the center. I'm told by the inventor of this system (who hired a contractor in 2002 to convert his mercury switch based analog design he'd sold for years into the digital one) that some homes are connected in a daisy chain. The communication works reliably except for the software protocol used for half-duplex communication which sometimes glitches and takes multiple 10s of seconds or longer to stabilize into normal reliable steady state operation. My new design doesn't need to improve on the communication but should work at least as good.


    In this older PIC design, the RX line idles low. The TX line however idles high.

    I disconnected my prototype from the home network and collected these scope traces this morning.
    One thing I noticed right away about the transmit trace: The transceiver signal drops to zero between bytes in most but not all frames. In the Teensy design using the Serial1.transmitEnable() for pin control, the signal stays high for all 8 bytes of the frame. Here are 5 images:

    Receiver Idle trace (channel 2, ignore channel 1 signal. I forgot to turn off the channel 1 waveform)
    Click image for larger version. 

Name:	Old Tstat Rx idle halfres.jpg 
Views:	5 
Size:	65.7 KB 
ID:	14869
    Receiver 1 frame trace (channel 2)
    Click image for larger version. 

Name:	Old Tstat Rx normal halfres.jpg 
Views:	6 
Size:	73.3 KB 
ID:	14870
    Transmitter Idle Trace (channel 2 is TX, channel 1 is transceiver control)
    Click image for larger version. 

Name:	Old Tstat Tx idle B halfres.jpg 
Views:	5 
Size:	73.0 KB 
ID:	14871
    Transmitter frame trace
    Click image for larger version. 

Name:	Old Tstat Tx normal A halfres.jpg 
Views:	6 
Size:	84.5 KB 
ID:	14872
    Transmitter 'glitch' frame trace -- where we don't see the transceiver direction control drop to zero between each transmitted byte.
    Click image for larger version. 

Name:	Old Tstat Tx glitch halfres.jpg 
Views:	6 
Size:	84.1 KB 
ID:	14873

    So with two experts (you and rcarr) concerned about the low idle state and the original designer of this legacy system unavailable for consultation, I'm concerned as well and want to know more about basic USART serial IO so I'm going to be doing some reading today before I change any hardware or firmware in my prototype. I noticed that the Kinetis UART provides separate polarity control for both signals and I was wondering if I needed to do something with that feature for compatibility with this PIC based system. During my work with the scope I found that the trace of an 8 byte frame was captured much better if I used low-to-high edge triggering on the RX signal but used high-to-low edge triggering on the TX signal.

    One other observation I made of the home system running (without my prototype connected) but didn't photograph: The A and B signals coming into the thermostat are voltage-shifted high. At rest A is about 1.0V and B is about 1.3V. The amplitude of the A signal is higher than that of B. A reaches about 4.5V and B reaches 3V. This voltage differential does not seem to harm the reception or transmission of bytes over the RS485 between nodes but I have no actual data from inside the devices to confirm this hypothesis. I just have been using the system for 14 years and it has been working. Biggest glitches occur following a power outage. Sometimes I have to manually reboot the system using the breaker box.

  17. #42
    The absolute levels of A and B don't matter nearly as much as their difference. Capture the difference between A and B for a few data packets.

    Another option besides idle state biasing (which is really pretty simple) is to use one of the fail safe MAXIM parts. They alter the receive thresholds slightly so they output a "1" when no transmitter is active.

  18. #43
    Senior Member
    Join Date
    May 2017
    Posts
    148
    There are two things I notice with the new information.

    >>> At rest A is about 1.0V and B is about 1.3V.
    With B more than 200mv above A, it would seem that the system has been biased opposite from what would be normal. If that is the case, then the other Maxim parts would not be useful as the system is already biased out of the unknown region of +-200mv. When you added the resistors as suggested by Paul, it stopped working which would be another data point that it is already biased.

    In the thermostat schematic I notice that the RX signal also goes to RB0/INT. This could be something simple as using the internal weak pullup on RB0 to provide a pullup on the RX signal and just saving a resistor in the design. Or it could be that the thermostat is detecting the transition from low to high as a carrier detect function as I guessed about earlier. And the fact that it stopped working when you added the resistors as outlined by Paul leads me to lean in this direction.

    As a suggestion on how to proceed, you could use an interrupt pin also wired to RX, enable the UART on Interrupt, recieve a packet, then disable the UART to clear or avoid framing errors.

    ------------------------------------------------------------------------------------
    This is Paul's suggestion for resistors that I have referred back to which holds A above B.
    Resistor #1: RS485 signal A to +5V
    Resistor #2: RS485 signal B to GND
    Resistor #3: RO (RX1) to +5V

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •