1
\$\begingroup\$

I wrote the following code to trouble shouting the RS485 communication aspect of my firmware.

I use either a Beaglebone black or AI equipped with the cape COMMS 2 (which as a built-in A/B RS485 interface) as the host for this nodejs test code.

[UPDATE A] The cape COMMS description is right there : https://github.com/beagleboard/capes/tree/master/beaglebone/Comms

[UPDATE B]

As with any intermittent problem, have you been able to discern anything you can do that makes comms with the smart battery more, or less, likely to succeed?

No. What I can say is that if I simultaneously plug another (different) software on the bus that also ask for the frames, my code get answers properly too.

[UPDATE C]

Has comms to the battery ever been reliable (different code, different hardware etc.)?

Yes. I have another firmware that runs on a custom PCB I designed (against the same battery hardware) and I always have the communication up and running, with no problem.

Unfortunately, I don't received communication from the slave device (a smart LIFP battery).

The logs are:

$ npm run testRs485

> [email protected] testRs485 /home/debian/Desktop/devel/iot
> node testRs485.js

Opening serial port…
Terminating test
Successfully open
In port.open(): true
About to send message #1: <Buffer a5 40 90 08 00 00 00 00 00 00 00 00 7d>
Send returned true
Sent message successfuly
About to send message #2: <Buffer a5 40 90 08 00 00 00 00 00 00 00 00 7d>
Send returned true

==>etc.

But sometime, this very same code did worked. But I can't pinpoint what trigger on or off the communication.

I'd like to have advice or clue about how to solve the issue.



setInterval(function() {
    console.log("timer that keeps nodejs processing running");
}, 1000 * 60);


var SerialPort = require('serialport')


var port = new SerialPort('/dev/ttyS4', {
    autoOpen: false,
    baudRate: 9600,
    dataBits: 8,
    stopBits: 1,
    parity: 'none'
}, false)

function open () {
    if (port.isOpen) return;
    console.log('Opening serial port…')
    port.open(err => {
        if (!err) return

        console.log('Port is not open:', err)
        
        // next attempt to open after 10s
        setTimeout(open, 10000)
    });
}

// == On open…
port.on('open', () => {
    console.log('Successfully open')
    console.log("In port.open():", port.isOpen);

    const messagetoSend = new Buffer.from([0xa5,0x40,0x90,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7d])//pack('001', '00', '740', '=?')
    let counter = 1;
    setInterval(function() {
        console.log(`About to send message #${counter++}:`, messagetoSend)
        const sent = port.write(messagetoSend, err => {
            if (err) {
                return console.error('Send error:',err)
            }
            console.log('Sent message successfuly')

            if (false) {
                console.log('Draining serial')
                port.drain(() => console.log('Drain done'))
            }
        })
        console.log('Send returned', sent)
        
    }, 15000)
})

port.on('data', data => {
    console.log('Received data: ' + data);
})

port.on('close', () => {
    console.log('Serial port closed')
    console.log('Reopening')
    open()
})

port.on('error', err => {
    console.error('Error:', err);
})

open()



console.log("Terminating test")
```
\$\endgroup\$
6
  • 1
    \$\begingroup\$ So what is controlling the transceiver transmit enable if you have no handshake? Do you know which pin controls it, RTS? \$\endgroup\$
    – Justme
    Commented Jan 7, 2022 at 21:32
  • \$\begingroup\$ @justme: Sorry that was a last minute addition. Let me remove it from the question \$\endgroup\$ Commented Jan 7, 2022 at 21:33
  • \$\begingroup\$ In the past I've run into trouble with code looking for a response from the client device before it was ready. Maybe try giving your device a bit of time to prepare the response before polling it. \$\endgroup\$
    – vir
    Commented Jan 7, 2022 at 21:38
  • \$\begingroup\$ @vir ok. But here I write every 15 secs, and only wait for the read callback to fire. \$\endgroup\$ Commented Jan 7, 2022 at 22:40
  • 1
    \$\begingroup\$ @StéphanedeLuca do you understand what Justme is asking you above? That's a question which needs to be answered before you're likely to get much help. \$\endgroup\$
    – brhans
    Commented Jan 8, 2022 at 0:16

1 Answer 1

1
\$\begingroup\$

Summary: This may be just a stepping-stone towards you finding the full solution, but the recent update gives some clear debugging opportunities.

You have configurations which work, as well as your current configuration which doesn't work reliably, so you have opportunities to compare & contrast, find differences, consider how those differences could affect the RS-485 comms, and synthesize tests to check those hypotheses.

I recommend that you also further investigate the behaviour of the specific Maxim RS-485 transceiver used on the cape interface board (see below).


In your update, you said:

What I can say is that if I simultaneously plug another (different) software on the bus that also ask for the frames, my code get answers properly too.

and

I have another firmware that runs on a custom PCB I designed (against the same battery hardware) and I always have the communication up and running, with no problem.

Good, so you have configurations which do work, for you to be able to compare RS-485 signals between working and non-working configurations.

  • From the schematic of the BBB cape which you linked, it seems that the RS-485 120 Ω termination resistor (R7) is disabled by default (enabled by soldering across solder jumper SJ3). While not always needed with short cable runs, it should be enabled on the two devices at the ends of the bus.

  • Very important: The cape uses a Maxim MAX13487 RS-485 transceiver with Maxim's "AutoDirection control" which explains why you don't have an RTS-type Tx-enable signal being controlled by your software. The linked datasheet explains that, for the automatic direction control to work properly, there need to be biasing resistors on the RS-485 bus (one pulling the A signal high, the other pulling the B signal low) BUT those resistors are not shown on the schematic diagram for that cape!

This suggests, for that RS-485 transceiver to work reliably, it is relying on suitable biasing resistors elsewhere on the RS-485 bus! If you have not knowingly checked this, then one hypothesis to consider is that the bus only works when specific other devices are attached, which have biasing resistors built-into them, or have other behaviour (around how and when they drive the bus vs. it being undriven / idle) which then allows the MAX13487 on the BBB cape to work correctly.

IMHO your troubleshooting will likely involve:

  • Using an oscilloscope on the RS-485 data signals A/B in the various working and non-working configurations, to capture and understand the differences.

  • A detailed reading of the datasheet for that Maxim RS-485 transceiver, and investigation and comparison of the RS-485 signals with the requirements of that transceiver, in each configuration.

  • One "quick fix" to investigate could be adding suitable biasing resistors onto the RS-485 bus, to satisfy the requirements of that Maxim RS-485 transceiver.

\$\endgroup\$
2
  • \$\begingroup\$ Activating the resistor thru SJ3 does not make any difference (actually it might help for long distance transmission). Still investigating. \$\endgroup\$ Commented Jan 12, 2022 at 13:20
  • \$\begingroup\$ Adding the pull up and pull down resistor on A/B lines was the solution \$\endgroup\$ Commented Mar 1, 2022 at 7:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.