kasbert / epsolar-tracer

Tools for EPsolar Tracer BN solar charge controller
Apache License 2.0
120 stars 76 forks source link

Getting more than one value from the Tracer in one request #8

Closed matthubbert100 closed 1 year ago

matthubbert100 commented 8 years ago

Hi there I was wondering if it was possible to get multiple values using one request from the Tracer? I don't know if this is normal, but my Raspberry Pi takes about 4 seconds per each data request. I need 5 values from the Tracer, so the whole process takes about 16 seconds. Is this a restriction in the pymodbus library, the Tracer itself, or your code? My data monitor is here: www.solarpoweredhome.co.uk - but as you may notice I can only get 4 complete sets of data per minute due to the time each request takes. Thanks for your work Matt

kasbert commented 8 years ago

The protocol allows fetching a range of registers. For simplicity that is not implemented in this client.

It shouldn't be that slow. Can you measure the RS-485 signal in any way, like using a logic analyzer or a led in wires ?

matthubbert100 commented 8 years ago

Do you mean by an LED, placing one within the communication wire to see when communication is occurring? Unfortunately I've no experience with a logic analyzer.

Do you know of any information or documentation that might show me how I would read multiple registers? There's certainly no mention of it in the modbus address tables you've kindly provided, though it must be possible since the windows software achieves it with no problem.

Thanks Matt

kasbert commented 8 years ago

Yes, the delay could be on any phase; in Raspberry sending, Tracer responding or Raspberry receiving. There might be buffering somewhere.

In the pymodbus client there is the method:

def read_input_registers(self, address, count=1, **kwargs):
    '''
    :param address: The starting address to read from
    :param count: The number of registers to read
    :param unit: The slave unit this request is targeting
    :returns: A deferred response handle
  '''

Just give the address of the first register and count of registers to read them all.

ygator commented 8 years ago

Just a FYI. I just started writing my own program for modbus under OpenWrt on a HooToo Nano (360 MHz CPU). I just got a VS2024BN. I can get 19 readings a second with it. Each reading consists of 0x9013 0x03 - the date and time and 0x3100 0x13 - most relevant information. I will need to put in some slight delays where appropriate according to modbus rtu protocol to make it more robust. With that said your Pi has almost twice the CPU power of the Nano so you should easily be able to get readings once a second.

wrybread commented 7 years ago

Could you post the code you're using? I'm using the same basic code as Matt (I think), which is:

from pymodbus.client.sync import ModbusSerialClient as ModbusClient

client = ModbusClient(method = 'rtu', port = '/dev/ttyUSB0', baudrate = 115200) client.connect()

result = client.read_input_registers(0x3100,6,unit=1) solarVoltage = float(result.registers[0] / 100.0) solarCurrent = float(result.registers[1] / 100.0) batteryVoltage = float(result.registers[4] / 100.0) chargeCurrent = float(result.registers[5] / 100.0)

print solarVoltage print solarCurrent print batteryVoltage print chargeCurrent

Do something with the data

client.close()

That takes about 10 seconds to execute. I think there's a missing step there somewhere.

wrybread commented 7 years ago

Aha! I think I figured out what's causing the slowness. You need to add a timeout value to your client:

client = ModbusClient(method = 'rtu', port = '/dev/ttyUSB0', baudrate = 115200, timeout=1)

If I understand what's happening correctly, for some reason the ModbusClient always waits for the timeout before returning information. It appears to have a default timeout of 3 seconds, so if left unspecified it will take 3 seconds for each query.

This project (epsolar-tracer) uses a timeout of 1 second. I set a timeout of .1, which worked for single registers but sometimes returned errors with multi register readings, so I went back to 1 second, but you might want to experiment.

I wonder if there's some way to read the registers without waiting for the timeout though. It sounds like @ygator is able to read them without waiting for timeouts, for example.

kasbert commented 1 year ago

Won't be implemented. Flakiness seems a hardware problem.