What Are My Options Of Two Props Outputting To The Same Display?
idbruce
Posts: 6,197
As the title implies, I am looking for good ideas pertaining to having two different Propellers outputting to the same display. Messages from Propeller 1 are not time critical, but the messages from Propeller 2 will be time critical.
Propeller 1 and 2 will already be serially linked, but this serial link will be quite busy, and I wouldn't want to interfere with that communication system.
I suppose my only option is another serial line.
Propeller 1 and 2 will already be serially linked, but this serial link will be quite busy, and I wouldn't want to interfere with that communication system.
I suppose my only option is another serial line.
Comments
Or set up a separate serial link between the props.
Or switch to packet based com between the props, using Beau's 14mbps code.
Thanks for the response.
Let's say that I decide to use the existing serial comm to send a display message from 1 to 2, would I be looking at a refresh / 2, providing the speed from 1 to 2 are equal to the speed of 2 to the display? So in other words.... Twice as long?
That depends on how much data you are sending right now per second (worst case), and how many bytes per second you will need for your display refresh (worst case).
The reason I keep saying worst case is that if you add the two worst case numbers togeather, and multiply by 10, you will have a good idea of the minimum bit rate you will need for your comm
Propellers will easily run serial at up to 2mbps, and if you packetize your data, you could use Beau's 14mbps code.
In case you don't know your current maximum data transfers, you could instrument the code to keep track of how much it is transmitting, and receiving, as a running total, and print it every second.
Personally, I'd switch to Beau's code, packetize everything into "virtual channels" to make it simple for you to encode/decode multiple streams between the props. As I recall, Beau's code works based on 32 bit values, so something like the following packet structure should work fine:
header byte chan,length,chksum, spare
buffer long 0[length]
To send, place your data into the buffer, set the channel number, packet length, checksum in the header, and transmit 1+(length+3)/4 longs with Beau's code.
On the receiving side, have a cog constantly listening, and when it sees a packet come in, place it into one of N channels buffers, as indicated by the channel number.
You could basically set up circular buffers for each channel, and use a serial compatible api.
If so you could easily just bump up the serial link speed a small amount, and use the existing serial link no trouble. If you have to display graphics, then you may wish to develop a graphics byte code to reduce the amount of data sent.
14 mbps??? Can you link us?
As mentioned, two Propeller design.....
Propeller 1 reads GCODE from a file source or receives GCODE serially from a source. Calculations are performed on the GCODE and the results of these calculations are then inserted into a GCODE struct. The GCODE struct is then sent to Propeller 2, which is basically the controller for the machine. Print outs will occur as processed by Propeller 2. All this is fine and dandy......
The problem that I am looking to resolve, is that at startup, I want to be able to display a menu for various potential options, for machine setup, in a timely fashion.
To compound the difficulty of a resolution to this problem, I am now thinking about different options, pertaining to Propeller 1 and VGA support, since I will have many left over pins.
So I am thinking about serial LCD support on Propeller 2 and VGA support on Propeller 1. And the appropriate display would be chosen by a configuration setting. However, displaying the current GCODE command, current location, and target location on the VGA, could make things a bit complicated.
http://forums.parallax.com/showthread.php/99222-Propeller-DEMO-%2814.5-Meg-Baud%29-High-Speed-Prop-to-Prop-Serial-Communication
Am I missing something? Did he ever post the code? I found files that others uploaded, but none by Beau.
Two displays can make sense, as one can be a machine report, and one a Diagnostics and Mode focused one.
The displays only need to match a human eye, so it does not need to refresh every XYZ change ?
ie a simpler, slower report back would let the main display follow progress, but not in 'real time'
I've seen code designed for very fast operation, reserve a ~40ms refresh rate for the human watching.
This seems to be the latest verified version ?
http://forums.parallax.com/showthread.php/99222-Propeller-DEMO-%2814.5-Meg-Baud%29-High-Speed-Prop-to-Prop-Serial-Communication?p=880644&viewfull=1#post880644
My apologies, perhaps I did not explain it well enough.....
There will only be one display. The selection of display would be determined by a define, such as:
//#define USE_SLAVE_LCD
#define USE_MASTER_VGA
One would be defined and the other would be commented out. The code that would run or be compiled, would be dependant upon the define chosen.
Referring to the illustration below, wouldn't it be possible to control the LCD from both the master and the slave? I would think that the LCD is just looking for data.
Does it really need to be that difficult?
Consider the following scenario.....
During machine setup, Slave 0 would be held low and Master 0 would have control of the data. At machine startup time, Master 0 would be set to low and held low and ownership would be transfered to Slave 0 to enable the transfer of data. The only time that this would change would be in case of an emergency stop or something like that, in which case, the situation would be reversed. I have no intention of wanting them both to communicate during machine setup or runtime, but I want each to have access at different times.
I don't understand why you haven't hooked them up that way then to make them work? While it is possible one could float it's I/O line when not needed it is probably better to insert a series resistor in each line for the "just in case" which is infinitely more likely during development and testing. If as you have stated that you want each to have access at different times then this is the way to do it.
BTW, I manufacture my own 20x4 serial FSTN LCDs mostly for OEMs and they have both serial inputs and I2C so there is probably no reason that both cannot be used even at the same time (with a little tweak to the firmware). In fact looking at the schematic for this I had installed an XOR gate into the UART receive line and while one input is the receive the other is the inversion control (for RS232 or logic). So if you feed inverted data from each Prop into each of these lines then you won't have to worry about resistors or floating etc. If I changed the single gate to an AND gate then that would mean you could feed standard logic active low serial into it otherwise the XOR would have to be changed to an XNOR anyway. The backpack on these is a thin surface mounted pcb so it's really low profile.
EDIT: thinking about the setup as is you could probably use the SCL line as a second receive with the UART implemented in software. There is not much for the backpack CPU to do except receive, interpret, and write so both software and hardware UART can easily be interleaved as the write to the LCD is very minimal.
The other approach is like i2c, where you open-drain the lines with a pullup, and check the pin after each write.
If the (readback <> what you expected), there is bus contention.
Of course, what happens next, gets complicated in multi-master, but you could have one have priority.
No, it doesn't have to be that complicated if you transfer ownership like that (a form of token passing, and the prop with the token can send). In that case I would suggest a series resistor (100 > 150 ohms) on each prop comm pin and a pullup resistor (2 > 4.7K) on the display end to simulate an open collector comm line.
I wanted to respond last night, but I got sidetracked.
Anyhow, I read all of your comments and have put some additional thought into this subject. Assuming the wiring that I illustrated above, with the addition of several resistors, here is a chronological sequence of events, according to my current line of thinking:
1. Power up both Propellers.
2. Set Slave 0 - DIRA 1, OUTA 0
3. Open Half Duplex Serial driver for Master 0
4. Master 0 communicates with LCD
5. Close Half Duplex Serial driver for Master 0
6. Set Master 0 - DIRA 1, OUTA 0
7. Open Half Duplex Serial driver for Slave 0
8. Slave 0 communicates with LCD
IF STOP_CONDITION (halt slave program execution)
9. Close Half Duplex Serial driver for Slave 0
10. Set Slave 0 - DIRA 1, OUTA 0
11. Open Half Duplex Serial driver for Master 0
12. Master 0 communicates with LCD
ELSE (run slave program until finished)
9. Close Half Duplex Serial driver for Slave 0
10. Set Slave 0 - DIRA 1, OUTA 0
11. Open Half Duplex Serial driver for Master 0
12. Master 0 communicates with LCD
Items 9 through 12 are the same, but based upon different conditions.
Does this sound reasonable, in accordance with the illustration above?
Yes, that would work as long as the conditions (stop and run) can be communicated between the master and slave. Perhaps some non printing characters or holding the comm line low can be used. That's why I suggested the series and pullup resistors.
Thanks for the schematic.
In addition to the half duplex serial connections for the LCD, I will also have full duplex serial between the two Propellers. This full duplex serial will be used to send GCODE structs, from the master to the slave, but I can also add code to establish ownership of the LCD signal. I was going to pass all Master LCD data through the full duplex serial connections, but since this should work, I will now simply pass an LCD ownship flag through the full duplex serial connection, and let the half duplex serial connections do the actual updating of the LCD. I believe this might be faster for updating the LCD, plus it removes most of the burden from the GCODE processing.
I do not know how soon I can get around to actual implementation, but I will let you know how it goes.
Thanks kwinn, and thank you to everyone else.
I'm a bit late to the discussion, but here's more food for thought:
Since it's often best do do whatever is simplest (at least to start), and is often simplest to use or copy existing code, maybe take a look at how this is done in propforth.
Each IO-channel has a word that contain an "in-byte" and an "out-byte". Look at the pointer to that channel, and read or write to those bytes.
Each channel always sends (and recieves) 96 bit packets at full speed. The channel and protocol are such that the channel sends at the max we could ever write to it. The protocol includes parity bits (or whatever) and just sends full blast. All we have to do is dump one or more bytes into the channel and they pop out the other side. I belive both Beau's and Sal's methods use counters, so they are operating at the ablsoulte max for the prop based on the clock speed. Both Beau and Sal report that they can use very long cable with no errors detected. So the packet communication ends up faster than most anything happening external to the prop.
The display driver is usually set up to send data at the max that the display can recieve (i.e a serial link only can update at the baud rate). So we have one cog spitting data to the panel at that speed. The driver just reads whatever values are in memory, and spits those to the screen. You don't care if the actual data is changing faster than the display, since you could n't see those values anyway. You only see, and can only see the current value at any given instant realtime, if you actuall want all values (that are happening faster than the display's data rate) you probably have to long them. In thisuch a case we log to SD, and beause we write a full SD block per write, we have not problem keeping up with the data stream (at least so far).