1 Mega Master, 4 slaves - Communication strategy

I have a project whereby I have a Mega serving as the main CPU where the main program execution lies. Connected to it I have a TFT display using SPI, 2 ATTINY85 chips, each communicating by interrupts only and a Nano, which I was going to use 8 I/O pins to do some awkward parallel 8 bit communication thing but now I'm second-guessing myself. Need a bit of a sanity check:

TFT Display - I have no reason to believe that anything is wrong with using SPI for this. I've already wired it and it's working fantastic

Tiny 1 - This needs to communicate an integer somehow to the Mega. Presently, I have a PWM pin producing a varying frequency pulse, which goes to an interrupt pin on the Mega. Then for a short time, I measure the interval of time between pulses to infer the frequency and therefore the integer I'm trying to transmit. So 7000 Hz would equate to the number 7000 for example. This method has so far been more attractive to me than say trying to figure out the duty cycle of a PWM signal and getting integer info from that or by using SPI (already used) or I2C.

Tiny 2 - This also needs to communicate an integer but whereas the above signal is being constantly generated, this one is random and needs to interrupt from the Tiny side rather than polling from the Mega side.

Nano - Originally I had saved 8 digital pins on both the Mega and Uno and planned to connect them so that I could use them to produce an 8 bit number. This 8 bit number would represent a "code", that would invoke a specific subroutine in the mega, for each code. However it's messy both in terms of wiring and coding.

I've got all these UARTs not being used on the Mega. I'm wondering if I can at least use one of them with the Uno to send/receive the 8 bit number. Now I need the UART to program the Nano but (correct me if I'm wrong) the UART can be reused as long as it's not doing 2 things at the same time? My big question is whether I should do this instead of my current idea and if so, how to safely do it so as not to conflict with anything. Would I need to worry about any other conflicts like the UART using some other resources that could already be in use (like a timer) ?

Thank you.

How far apart are these devices? If it's under 1m then perhaps I2C will work. Check if your Tiny's have I2C.

Depending on how big their real program is, you may be able to put SoftwareSerial on the Tiny's and use the real UARTs on the Mega to talk to them.

The Nano should be using UART. You just have to unplug it from your circuit (or disconnect the wire going to Rx) to reprogram it with the PC.

The reason why you usually want to measure duty cycle instead of pulse duration is if you don't trust the clock on the transmitter. For a tiny temperature sensor (that's probably in a high or low temperature) or any other cheap sensor, the clock can drift quite significantly compared to your master's clock. If you measure both parts of the PWM cycle then your duty cycle measurement no longer depends on the absolute clock speed.

The entire project is on a proto board about 6" in length so I don't see a degradation problem, as I think you are referring to. However, 1 of the 2 Tinys is using one of the pins needed for I2C because it is also shared with AIN for the comparator that I'm using. On the other Tiny, I could in theory use I2C.

I'm troubled by the idea of having to measure duty cycle. Is there an elegant way to invoke this in code? The only way I can think to do it is to have 2 interrupts, one on the leading edge and one on the trailing edge and to have timers determine the duration between edges however this seems like a very processor heavy operation with a lot of code needed to do it. My application needs to be extremely responsive with minimal down time from the main program loop.

Maybe software serial is not such a bad idea? If it's like hardware serial, I'm assuming you can still use the print() method to send a byte? I have to admit ignorance on how to use the UARTs... it's something I haven't used before. Is there anything I should be cognizant of on the Nano side? When you say I need to disconnect the nano from the circuit, this wouldn't be possible as everything is soldered in place. Can I not program the nano when there's no power coming from the VIN pin? In other words, if I disconnect the entire board from its power supply and plug into the nano through the USB, won't the wires connected to the TX/RX pins be ignored since they are not powered?

No. The wires can't be ignored, even when unpowered. They are connected to ground and the unpowered 5V through the protection diodes in the Mega. Basically tied to ground.

...that's why CHANGE interrupts exist.

Does this also mean I can never program any of my boards again via usb if I have multiple soldered interconnects between them? I didn't consider that I'd be grounding out my boards by having digital/analog pins connected between them.

Sounds like a bad system design to me, if you'll forgive my bluntness. But it's all part of the learning process, I guess.

Why not communicate with the Nano using SPI? The Mega as master and Nano as slave. Re-use MOSI, MISO and CLK lines connected to the display and one extra line as the Select line for the Nano. Faster than Serial, especially Software Serial.

Gahhhrrrlic:
Does this also mean I can never program any of my boards again via usb if I have multiple soldered interconnects between them? I didn't consider that I'd be grounding out my boards by having digital/analog pins connected between them.

Try a 4K7 resistor between pin RX1 and the peripheral attached to it (see Brokking.net - Your Arduino Balancing Robot (YABR) - Home. note the connection of R1) for a description. I have borrowed this technique several times, on nanos, with mostly good results.

Paul:

I would say more of an omission due to not understanding what's in the black box so to speak. I did the whole board layout up in Tina and checked it multiple times for problems but I guess I wasn't looking for all the right problems.

I suppose I could use SPI, although I still don't understand how the slave select pin works. I tried to get 2 OLEDs on SPI once and that was an utter failure for me. Also, I need only transmit 1 byte, no faster than every couple hundred mS so I wouldn't say speed is an imperative for transfer, only for looping the main program it's a big deal.

123:

So am I understanding that the main concern is with the RX pin having a path to ground by going to the TX of the other device? With all the AVRs on this board, they are all tied to the same VIN, the same GND and the only other connections they have are either to op-amps for isolation to sensors or to each other via their I/O, which I thought were high impedance unless set to output mode. Although now I'm wondering about that... if the boards are off, are they still high impedance or do they fall into low impedance state?

My worry is without external power, if I plug USB into any of the AVRs, the voltage will flow to all the AVRs because their VINs are all ganged, and it will try to power everything up, just for the sake of programming one board. This is an automotive application with temperature fluctuations and vibration so I wanted everything soldered tight. Is it necessary that I separate all AVR power lines from each other with jumper wires or something? I guess the correct thing to do would have been to have a socket for all the AVRs... damn.

Wha? You do not have to remove external power to re-program the Arduino.

Most of what is in your Original Post describes how you think your project should be implemented but nowhere do you describe what the project is intended to do.

If you describe the project somebody might have a good idea to help you implement it.

...R

It might be easier to post the schematic. This project has been in design for almost a year and all the BOM sourced already, half the soldering done. It's past the time when I can make a major design change. What I could do is employ a different method for communication or reconsider how I'm powering the device as I haven't done those interconnects just yet.

Gahhhrrrlic:
It might be easier to post the schematic.

That is not going to tell us what your project is intended to do.

It is much easier to help when we know what you are trying to do.

...R

Well I can attempt an explanation:

The entire board is a control module for an electric supercharger. It monitors several sensors in the car, which are all buffered by op-amps and most of which come in through the Mega's A/D. It also monitors switches and batteries, also coming into either A/D or digital I/O on the Mega.

The TFT is a touch panel colour GUI that provides an MFD for all the subsystems and a touch interface to select menues and change options. It's connected via SPI at the moment, through the Mega.

One of the Tinys is a co-processor that does FFT on the knock sensor all day long. It runs constantly and does nothing else. If it detects knock, it communicates the voltage level via a number to the Mega (at the moment using PWM and interrupts on the Mega)

The other Tiny is just to measure RPM because that is a PITA compared to other sensors. It has to interpret a PWM signal from the ECU and convert that into a number which, again, has to be given to the Mega. At the moment I'm using interrupts on the mega to measure the PWM frequency from the Tiny. The reason I'm using an AVR to convert PWM to PWM is because the signal from the ECU sucks and I want to reconstruct it and also do a bit of math on the Tiny side.

The Nano is for temperature sensing using the onboard thermistor and error reporting through voice. It just barks warnings using the Talkie library when an error code byte is transmitted to it from the Mega or reports the temperature of the AVR when requested by the Mega.

All AVR VINs and GNDs are ganged to a low pass filter, voltage regulator going to a switched capacitor thingie (makes split supply) at 12V. The +/- feeds all the op amps while the + only goes to the AVRs.

The main loop has to be as small as possible so as to react quickly to car conditions. As such, it regularly polls the sensors, compares the values to prescribed limits and decides what to turn on and off. At more infrequent intervals it runs a touch sensor routine to detect screen presses and a refresh routine to paint the screens. Also for the same reason, interrupts cannot be a regular occurrence. They have to be controlled tightly, comm traffic controlled tightly and only permitted when the Mega demands an update for something. Knock should be the only sensor allowed to interrupt the Mega on its own at any time. Everything else should be set up to allow an interruption when it is convenient to do so. Since the data is extremely simple and very infrequent, bandwidth and speed are not important IMO. More important that the form of communication used takes advantage of parallel hardware that doesn't consume CPU runtime. UARTs seem attractive for that reason, if my understanding is correct that they run in parallel with the CPU.

Gahhhrrrlic:
UARTs seem attractive for that reason, if my understanding is correct that they run in parallel with the CPU.

Using some form of serial communication seems a lot more sensible than trying to convey data with PWM and interrupts.

As everything is close together SPI seems the obvious way to communicate - and it puts the Mega in charge. If your knock-sensing Attiny needs to get the attention of the Mega it can do that by making a single I/O pin HIGH which triggers a simple ISR that alerts the Mega to seek data from the Attiny.

You could probably also use I2C but I have not used it myself.

And then there is Serial communication using the 3 spare USARTs on the Mega.

From what you have said my first instinct (whatever communication system is used) would be for the "slaves" to remain silent unless asked for data by the Mega. And the only exception would be (as I have said) the ability of the knock-sensing Attiny to alert the Mega when it has data for it.

...R

Powering the board via the Nano's USB while programming should not be a problem.

But... The powered-up Mega will be trying to talk to it while you are programming, causing programming to fail. You need some way of disconnecting the Nano's Rx during programming.

Multiple CPUs on one board is very complex. But it sounds like you have it under control.

Actually, I can't think of a scenario when any of the AVRs would be on at the same time as the one you are programming. There is a master DC quick connect going into the box that houses the board. It powers the board which feeds all the AVRs simultaneously. If I disconnect the power, either through the master power switch or by disconnecting the DC quick connect, everything loses power.

My only concern was that, if I connect USB to the Nano for example, it would supply 5V to that AVR, energize the VIN pin, which would then attempt to power all the other AVRs ganged with it. This would severely load the USB and may also cause program execution without anything being connected normally, which might cause anomalies or electrical shorts that aren't intended to happen. It's just an idea but I can't say I've thought of every contingency.

Attached is a draft of my circuit. I didn't finish drawing everything yet but it's 90% completed I'd say and I found that there were diminishing returns in trying to finish it without actually starting on the construction. This back and forth ideology has helped in the past, as I sometimes come across problems that force a revision, when I can still afford to change things.

My only concern was that, if I connect USB to the Nano for example, it would supply 5V to that AVR, energize the VIN pin, which would then attempt to power all the other AVRs ganged with it. This would severely load the USB and may also cause program execution without anything being connected normally

Yes. That is a problem.

Is there a convention for programming boards that have to be connected like this? I can't imagine I'm the first to have such a dilemma. I mean I could put every VIN line on a switch or jumper but that would make for a pretty big nuisance.

The convention is you use an ISP (in-system programmer). That is what those extra groups of 6 pins do on your UNO board.

The ISP pins are either dedicated to programming or a shareable bus such as SPI.

So, in order to use correct syntax to have a Tiny85 send a literal across to the Mega, do I need to sync the send and receive somehow on both devices? I don't understand from the available examples, how to work both sides correctly. I see the following lines of code being important:

#include <SoftSerial.h>     
#include <TinyPinChange.h>  

int RPM = 7000;

SoftSerial mySerial(2, 3);

mySerial.begin(4800);
mySerial.println(RPM);

So can I assume that the above code is only good on the Tiny side and that all it does is send the int to a buffer, waiting to be picked up on the Mega side? How then do I request or otherwise handle the incoming data on the Mega side? I guess I don't get how the handshaking works between the 2 devices and how the key lines of syntax ought to work. The only thing I need to do is send an int from the Tiny to the Mega when the Mega "asks" for it. I'm not even sure I need full duplex for this. Can someone help me with the minimum barebones syntax please?

On the Mega side, can I also assume that I can connect pin 3 (Tiny) to pin 15 (Mega) and pin 2 (Tiny) to pin 14 (Mega)?

Thank you.