Modbus master for Propellor Spin
willeert
Posts: 14
I am very new to Propellor but have some Arduino experience. I have code in Arduino C that uses a Modbus master library (=Object?) that lets me communicate with my solar system controller for a diversion control that I have developed. I would like to change to the Propellor using Spin to communicate with the controller. The Propellor would be the master. I can find 2 slave objects in the object exchange but not a master object. Might there be a modbus master object for Spin already developed that I have not found?
Thanks
Will
Thanks
Will
Comments
Thanks again
Will
I used it to talk to a Morningstar MPPT, and it only has the methods I needed for that, which includes Read Multiple Holding Registers, Read Multiple Input Registers, and Write Single Holding Register.
Note that the serial driver it uses can do 4 serial ports in a single cog. I highly recommend using the 4 port serial driver for all of your serial ports to save cogs. There are some other 4 port serial drivers floating around, and they should probably all work. The one I included has 512 byte receive buffers, which is the biggest of all of the versions I know of.
Will
I downloaded, extracted all the files in the archive, and the serial object looks fine but the modbusmaster file size is zero K and there is no data in it.
I fixed it. Try downloading it again. Thanks.
I had opened modbusmaster.spin via a symlink, and BST must not have liked that when I made the first Propeller Archive. I opened the original in BST and told it to create a Propeller Archive from that, and then verified that it was all there.
You can certainly have two instances of the modbus library running. But that would require using two of the four serial ports in the serial cog and would also require four IO lines. Also, see the mb.setport method in my library.
I had to talk to two Morningstars at once (a TS-45 and a TS-60), and I got away with using only one instance of my modbus library with both of them with some circuitry. I don't remember that they used rs485 - I used a rs232 level shifter and it worked fine. First, I gave the two MPPTs different station IDs - I made one station 1 and the other station 2. Then, I hooked the Prop's modbus TX pin into one of TX units of the level shifter chip and sent that output to both MPPTs, and I connected the two receives first through their own units of the level shifter chip, and then I used diodes and a resistor to act as an OR gate. They didn't ever interfere with each other, since only one MPPT was ever transmitting at a time, since they had different station IDs.
I've implemented methods 3 (readmhr), 4 (readmir), and 6 (writeshr). But since you only write one register at a time, you should be fine with my writeshr function.
There's a broken implementation of method 16 (writemhr) that's included in my library but is commented out, since it doesn't work. I don't have time now to fix and test method 16. Fixing it shouldn't be too complicated, but I don't have time to test and fix it now.
Note that part of the reason I have so many helper functions is so that they can abort on error. In Spin, errors can only be caught at function boundaries.
Thanks. Much better.
Will
I noticed Electrodude's Modbus object uses the serial driver I modified. I personally don't use that driver anymore. I much prefer Tracy Allen's four port object which allows the size of each buffer to be individually set.
I know some Modbus protocols use even parity. I modified Tracy's driver to use even parity on one of the ports.
I'll post my version with even parity if there's interest.
I have a bunch of QuickStart boards myself. For a while I attempted to keep track of some of the projects done with QuickStart Boards in this thread.
I'm pretty sure my Modbus object will work with anything descended from Tracy Allen's four port object.
Why don't you use your driver anymore? It's nice being able to reuse the hub memory that had the cog image. Couldn't you make a version that both lets you individually set the buffer sizes and reuses the cog image in hub ram?
I would like to see your even parity driver. Thank you. I don't have a lot of experience so the more examples I can look at and compare differences the more I learn. My diversion control modbus configuration is 8N1 so I don't have a parity bit if I understand the configuration correctly. I think that I am going to learn a lot more about Modbus with this project - trying to get the Propellor to read and write to the Classic.
Thanks again
Will
I like to think making a version with individually set buffer sizes and reusable cog image is within my skill set and I may have already done something like that. My "cogject" version of a serial driver requires one to indicate where the buffers are located.
The attached code adds even parity to port #1. The even parity is not checked with the incoming data. The parity bit is ignored.
I added a bunch of debugging aids to the attached code. Many of the common methods have copies which allow one to set or clear a lock. For example ".Strs" is very much like a normal ".Str" method but it also sets a log and identifies the cog calling the method. There are other methods with this add "s" which makes it easier to set a lock. Methods with an added "e" clear the lock.
The object can be included in multiple child objects. The start method should only be called once but other than that, multiple cogs and multiple objects can share the serial driver by making use of the lock.
I generally try to use a cleaner version of the serial driver in my final code. In general a single cog should be responsible for all serial communication. I try to limit locks on a serial driver to debugging versions of the code.