Renewable energy device monitoring


maicol1

Recommended Posts

Greetings,

I'm developing an HMI for a renewable energy Inverter, the protocol is a lot like Modbus protocol (Poll and receive data in Hex format).

I've tried to code a protocol as the manual describes, but nearly all the examples I've encountered on manual and forum describes ASCII protocols. I'm very confused how to correctly parse the data from the Hex string received.

The protocol looks like this:

POLL= {0x80,0x80,0x80,0x00,0x00,0x00,0x03,0x03}

Where the first 3 0x80 are opening characters, the next byte is data field length (none for a poll), then a device identifier, then device number, then a data address, finally a 8-bit cheksum is appended to the string (excluding opening characters and data length)

The response for this poll should be like:

RESPONSE = {0x80,0x80,0x80,0x01,0x00,0x00,0x03,0x0A,0xD}

Where the useful data is 0x0A

I've successfully sent the string to the device, here is the code:

return(Poll(chr(128)+chr(128)+chr(128)+chr(00)+chr(00)+chr(00)+chr(03)+chr(03),0))

and the poll routine was changed in one line for:

Write(out)

in = Read(NoBytes)

UnlockPort()

I've changed the readuntil for a read function. The argument NoBytes is the number of bytes to receive, I'm passing zero to retrieve the full string.

Tried Mid function to parse the data, but no luck. I'm stuck.

How can I retrieve the useful info and convert it to a decimal number?

Is there a way to code more efficiently the polling string?

There will be data with 10 base exponents divided on 2 bytes, for example 8 x 10^3 (0x08,0x03). Any recommendations to pass the value correctly (maybe a long variable)?

Thanks for your help!

Link to comment
Share on other sites

In binary protocols, its often easiest to use the chra() and asca() functions. Use chra() to convert an array of bytes into a string for your write() function:

return(poll(chra({128, 128, 128, 0, 0, 0, 3, 3}),0))

Remember you can use 0x80 instead of 128 too.

Use asca() on the result to convert the string into an array of bytes. Then you can easily just index into the array to parse your data.

BTW: you might consider developing the script in a sequence or two first, then put it into a user protocol if you expect to reuse it. Its easier to debug sequences than user protocols.

Link to comment
Share on other sites

Thank you very much, I've debugged the code as you recommended and the device is communicating now. However, I'm getting bogus data at the end of the day. It think the reason is the device slowly powering down while still polling (the comm device shuts off with the last rays of sun), so the last data received is like this: 0, 0, 0, 4x10^25. Is there a way to filter this kind of value with an script?.

Im thinking on something like this:

if(data[0]>100000)

data[0]=0

endif

However i'm wondering, how is the best way to trigger this script?

Thanks!

Link to comment
Share on other sites

You've got the right idea, but you don't want to return 0. Its better just to not return anything, which in the case of a user device or protocol typically means throw()'ing an error. Try just:



if (data[0] > 1e6)
throw("invalid data")
endif

[/CODE]

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.