How do you send information from one Mega to multiple Pro Minis?

Hi all:

Disclaimer: I'm a noob--feel free to explain in more detail if you think I might need it.

I would like to send a message from one Mega to 28 Pro Minis.

The Mega will have multiple sonars attached to it. The information from those sonars will be collected and analyzed once per second to find out the "Zone Status" of the installation (e.g. is someone in Zone 1, 2, 3, or 4). When analyzed, the Mega will store one number that represents the current Zone Status (a 1, 2, 3, or 4). I want to pass that number on to the Pro Minis.

The Mega will send out 1 message once every second: It will be telling each ProMini the Zone Status. This will be sent in the form of a 1, 2, 3, or 4.

Could someone tell me how to do this? I've never sent information from one Arduino to another before.

I'm fairly certain I need to hook up the TX and RX on the Mega to each Pro Mini. I don't know how to write the code though.

Thanks!

SheCurvesMobius:
I would like to send a message from one Mega to 28 Pro Minis.

You have two fundamental choices, neither of which can be made by somebody else on the information given. They are wired or wireless. You start from there

Having 28 Pro Minis is likely to involve a lot of the former, so the latter may be a sensible option.

Then you talk about power supply....

How far apart are those Pro Minis from each other and from the Mega?

Is there any need for feedback towards the Mega?

For wired, indeed I was thinking about linking the Tx of the Mega with the Rx of all the Micros. It's one way, and they'd all be listening to the same signal (you need a second wire to link all the grounds, but no need to link Rx of the Mega with the Tx of the Micros for one-way communication). As you'll have to power all of them, that's basically one extra wire.

But whether this can work will depend on the total bus capacitance. This many devices and this many wires may make it hard for the master to actually put a signal on the line.

There may be other ways - your post suggests there are just four different options for the communication, in which case you may communicate through an analog signal: 1.25V = 1, 2.5V = 2, 3.75V = 3, 5V = 4. (0V = no signal), and connect it to an analog input of the Micros. Communication would be asynchronous this way, with the Micros checking the signal when they feel like it, and the Mega updating it as needed.

if wired have a look at the RS485 bus which can support 32 devices

I was thinking RS485 but based on the info provided by OP it's probably overkill - and it requires additional hardware, as an Arduino can't connect to RS485 directly.

My solution would only need some resistors and maybe a few filtering caps (those long wires will act as antennas, putting quite some noise on the line, maybe messing up an analog reading).

If there is no need for data to flow from the Pro-Minis to the Mega AND if the distance is relatively short then a simple connection from a Tx pin on the Mega to the Rx pins on the Pro-Minis should work. I don't know if the signal strength from on Mega I/O pin could drive 28 Rx pins. But the Mega has 3 spare Hardware Serial ports so you could connect 9 or 10 Rxs to each Tx.

If the Pro-Minis do need to talk to the Mega then that could probably also be organized using Serial - but it would require extra components.

A Master talking to mutiple slaves could also easily be done using nRF24L01+ wireless modules. It may even be an easier solution if two-way data is required. This Simple nRF24L01+ Tutorial may be of interest.

...R

Hi guys, thanks for all of this input.

So if I wanted to send, say a 4 from the Mega to the Mini, what's the code for that?

Thanks!

Serial1.print("<4>");

See Serial Input Basics - simple reliable ways to receive data.

...R

Amazing!! Thank you :slight_smile:

I've looked at your link (which is great, thank you), and I've been trying to get a test working, but I'm missing something still.

Here is my sending code:

int delayTime = 3000;

void setup() {
  Serial1.begin(9600);
}

void loop() {
  delay(delayTime);
  Serial1.print("<1>");
  delay(delayTime);
  Serial1.print("<2>");
  delay(delayTime);
  Serial1.print("<3>");
  delay(delayTime);
  Serial1.print("<4>");
}

And here is my receiving code:

// Example 1 - Receiving single characters

char receivedChar;
boolean newData = false;

void setup() {
    Serial.begin(9600);
    Serial.println("<Arduino is ready>");
}

void loop() {
    recvOneChar();
    showNewData();
}

void recvOneChar() {
    if (Serial.available() > 0) {
        receivedChar = Serial.read();
        newData = true;
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(receivedChar);
        newData = false;
    }
}

For wiring I've got:

  1. the Mega's "TX0 -> 1" pin connected to the Uno's (I'm using an Uno for testing) "RX <- 0" pin
  2. the Mega's gnd to the Arduino's gnd
  3. the Mega powered through the gnd and 5V pins
  4. the Uno powered by a USB cable from my laptop

I've got a Serial Monitor open looking at the Uno's output.

when I have used the Mega Serial1 the output serial is on pin18 RX1 and input on pin 19 TX1
I would also recommend you use SoftwareSerial in the Uno for its second serial port

Hi there,

Thanks. I gave your suggestion a try. Still no luck. I get "Goodnight moon!", in my serial monitor, and then nothing else.

New setup:

Here is my sending code (same as before):

int delayTime = 3000;

void setup() {
  Serial1.begin(9600);
}

void loop() {
  delay(delayTime);
  Serial1.print("<1>");
  delay(delayTime);
  Serial1.print("<2>");
  delay(delayTime);
  Serial1.print("<3>");
  delay(delayTime);
  Serial1.print("<4>");
}

And here is my receiving code (different based on Horace's suggestion):

SoftwareSerial mySerial(10, 11); // RX, TX

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(57600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }


  Serial.println("Goodnight moon!");

  // set the data rate for the SoftwareSerial port
  mySerial.begin(4800);
  mySerial.println("Hello, world?");
}

void loop() { // run over and over
  if (mySerial.available()) {
    Serial.write(mySerial.read());
  }
  if (Serial.available()) {
    mySerial.write(Serial.read());
  }
}

For wiring I've got:

  1. (different, based on Horace's suggestions:) the Mega's "TX0 -> 1" pin connected to the Uno's (I'm using an Uno for testing) "11" pin
  2. (same as before:) the Mega's gnd to the Arduino's gnd
  3. (same as before:) the Mega powered through the gnd and 5V pins
  4. (same as before:) the Uno powered by a USB cable from my laptop

I've got a Serial Monitor open looking at the Uno's output.

I think you need to connect the Mega pin 18 to Uno pin 10

SoftwareSerial mySerial(10, 11); // RX, TX

10 is rxPin: the pin on which to receive serial data

also are the Mega and Uno baud rates the same - looking at the code the Mega is 9600 baud and the Uno 4800

sorting out Rx and Tx pins is often a problem with serial devices, i.e. does Tx means transmission from the device or to the device??
I generally check with an oscilloscope
often had to hack PCBs where the person who did the layout got it wrong!

Yes!!! That did it!! Thanks so much guys :slight_smile:

SheCurvesMobius:
And here is my receiving code:

You are using the wrong receiving code. You should be using the 3rd example // Example 3 - Receive with start- and end-markers

...R

Is my interpretation of this code (written in the comments) correct?

void loop() {
  if (mega1Serial.available()) { // looking to see if mega1Serial is recieving data
    Serial.write(mega1Serial.read()); // if so, write to Serial what you are reading from mega1Serial
  }
  if (Serial.available()) { // looking to see if Serial is recieving data
    mega1Serial.write(Serial.read());  // if so, write to mega1Serial what you are reading from Serial
  }
}

Hi Robin 2,

Thanks for pointing me to the third example in your previous post. That's worked well.

However, I added a 'zoneStatus' variable and I've assigned the value of the 'zoneStatus' as 'receivedChars'. I'm doing something wrong though, because when I print the 'receivedChars' I get, say a "2" or a "4", but when I print 'zoneStatus', I always get "332".

How do I move the data in 'receivedChars' into my 'zoneStatus' variable?

Here's the code:

void showNewData() {
  if (newData == true) {
    Serial.print("This just in ... ");
    Serial.println(receivedChars);
    zoneStatus = receivedChars;         //added code
    Serial.print("zoneStatus is: ");       //added code
    Serial.println(zoneStatus);             //added code
    newData = false;
  }
}

SheCurvesMobius:
How do I move the data in 'receivedChars' into my 'zoneStatus' variable?

If you only need to copy a single character and if it is in the first place in receivedChars you could do
zoneStatus = receivedChars[0] (I am assuming zoneStatus is defined as a char variable). If you need to copy several characters then you need to use the strcpy() function. It is used in my parse example (Example 5).

...R

Robin2, thanks for your help; that did the trick!

I'm getting the warning:

"Global variables use 2011 bytes (98%) of dynamic memory, leaving 37 bytes for local variables. Maximum is 2048 bytes."

What's the best way to reduce the global variable dynamic memory? If I can move some global variables to local variables will that help? Are there other or better ways to use less memory?

Thanks!