RS485 question (Argon)

Hi all - this is maybe a boneheaded question regarding RS485, but I’ve got an Argon hooked up to a ALMOCN TTL to RS485 Adapter Module, trying to get data from a Signineer 6000w solar inverter via RS485.

Argon rx/tx are connected to the above module - per the q/a - rx<->rx, tx<->tx (not crossed), using a short section of cat5 twisted pair going to what should be the A/+ : B/- pins on the rj45…I’m using the Modbus-particle lib, and at least per the code, all seems right except I’m getting 226 timeouts - no answer.

I put a scope on the a/b lines, and see what looks to be (to me) a healthy signal on the line, but no replies coming back - I’m not an EE and there might be a subtlety here that I’m just not seeing:

CH1 is A/+, CH2 is B/-.

Does this look right? Should I have a terminating resistor? Any other pointers? Are the docs just lying about what pins are the right a/b pins?

( https://www.sigineer.com/wp-content/uploads/2022/01/Sigineer-Power-M6048D-M12048D-Solar-Inverter-Manual-20211231.pdf )

/*
 * Project inverter_monitor
 * Description:
 * Author:
 * Date:
 */

#include <ModbusMaster-Particle.h>
#include "PublishQueuePosixRK.h" //background cloud publishing

SYSTEM_THREAD(ENABLED); //enable threads

ModbusMaster slave;
unsigned long interval = 0;
unsigned long base_T = 1000;

SerialLogHandler logHandler(LOG_LEVEL_INFO);

void preTransmission() {
    // set interface to TX
}

void postTransmission() {
    // set interface to RX
}

void idle() {
    delay(10); // in case slave only replies after 10ms
    Particle.process(); // avoids letting the connection close if open
}

void setup() {
	slave.begin(1,Serial1); // slaveID=1, serial=Serial1
  slave.setSpeed(9600,SERIAL_8N1);

  //slave.enableDebug(); // to catch the logs
  slave.preTransmission(preTransmission);
  slave.postTransmission(postTransmission);
  slave.idle(idle);

	Log.info("Starting Modbus Transaction");

  // start async cloud-publish thread
  PublishQueuePosix::instance().setup();
  PublishQueuePosix::instance().withRamQueueSize(10); // hold 10 messages in memory before going to flash
}

void loop() {
	uint8_t j, result;
	uint16_t data[10];

  if (millis() - interval > base_T) {
    interval = millis();

		result = slave.readHoldingRegisters(0,1);
    
	  // do something with data if read is successful
	  if (result == slave.ku8MBSuccess) {
		  Log.info("Success, Received data...");
		  for (j = 0; j < 2; j++) {
			  data[j] = slave.getResponseBuffer(j);
			  Log.info("%i", data[j]);
        log_to_cloud(result);
		  }
        base_T = 1000;
	    } else {
		    Log.info("Failed, Response Code: %i", result);
		    base_T = 5000; //if failed, wait for bit longer, before retrying!
        //log_to_cloud(result);
	    }
    }
    PublishQueuePosix::instance().loop(); // let the system publish
}

void log_to_cloud(int i) {
  char buf[256];
  JSONBufferWriter writer(buf, sizeof(buf));

  writer.beginObject();
    writer.name("error_code");
    writer.beginObject();
        writer.name("value").value(i);
        writer.endObject();
    writer.endObject();

  // I think this is a terminator for the buffer - not sure
  writer.buffer()[std::min(writer.bufferSize(), writer.dataSize())] = 0;

  // en-queue the message, and the "Ubidots" event name will trigger the
  // webhook over to ubidots on the particle end
  PublishQueuePosix::instance().publish("Ubidots", buf, PRIVATE | NO_ACK);
}

Removed Argon and used one of these guys connected to a/b pins on the rj45, no answer there either. Inverter is set as slave 1, but gonna let the s/w walk to see if it finds it somewhere else.

Turns out, the pinout is in fact incorrect. Luckily I saw wiggles on pins 4&5 of the RJ45 (not 1&2) - did a poke-and-hope, and et voila.

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.