Arduino Uno - Multiple Serial based functions

Im fairly unpracticed with Arduino and C.

Ive got several BT Arduino based MCUs (Bluno Beetle) 3 as peripheral devices, 1 as a central hub.

I need to know when any of the 3 peripheral devices comes online and send out serial data (Simple Strings) to labview in order to send emails etc.

I have the sketch working, in terms of rotating through devices one at a time (mainly bc the beetle doesnt support mesh etc).

As soon as I connect the hub to labview via usb, where the program is trying to read incoming serial data for a set string,

The sketch stalls and no longer switches between devices. My thought is that the commands used to reboot the MCU and re-pair to other devices are getting read by the pc and either failing to get to the Arduino or get corrupted etc.

I have tried to start and stop the serial com, but the only way I see to prevent this is to have the pc read the serial port ONLY when the data is intended for the PC.

I dont know too much about serial based comm, wondering if anyone has any tips.

At this point the sketch only switches between arduino devices, once I figure out how to prevent labview from halting the sketch I can start performing actions based on the result of pairing to each peripheral device.

Of course I'll put it all in functions etc to clean it up, but this is more of a trial.

Ive also tried to switch the baud rate ie:. Start at 115200, and set the PC to read at 9600 etc, but that doesnt help.

TIA

Please see the sketch below:

/*
Periph 1 0xF045DA10B98F
Periph 2 0xF045DA10B9E5
Periph 3 0xF045DA10B382
Hub 0xF045DA10B03D
*/

void setup() {
Serial.begin(115200);
pinMode(13, OUTPUT);
delay(100);
}

void loop() {

digitalWrite(13, HIGH);
Serial.println("AT+EXIT");
delay(1000); //Make sure we're not in AT Mode (Send commands to MCU Mode) Do this 1x. Could put in Setup..

while(1){
Serial.print("+++");// Enter AT mode of itself
delay(1000);
Serial.println("AT+BIND=0xF045DA10B98F"); //Bind to Periph 1

delay(100);
Serial.println("AT+RESTART");

delay(5000);

delay(15000); //Once restart, wait for pairing

//Do stuff here for Periph 1

//Switch to Periph 2

Serial.print("+++");// Enter AT mode of itself
delay(1000); // 700 milliseconds MUST be added or AT ode not work
Serial.println("AT+BIND=0xF045DA10B9E5");

delay(100);
Serial.println("AT+RESTART");
delay(5000);

delay(15000);

//Do stuff here for Periph 2

//Switch to Periph 3

Serial.print("+++");// Enter AT mode of itself
delay(1000); // 700 milliseconds MUST be added or AT ode not work
Serial.println("AT+BIND=0xF045DA10B382");
//Serial.println("0xF045DA10B382");
delay(100);
Serial.println("AT+RESTART");
delay(5000);

delay(15000); //delay 15 seconds to allow MCU to link up

//Do stuff here for Periph 3
}

}

I could use another arduino to act as a link to hub.

The 1st hub connects via BT to peripheral devices etc as shown and simply outputs High on 1 of 3 terminals when a connection is successful.

Hub #2 can just wait for a High input on 1 of 3 terminals and send serial strings via usb to the PC.

This would solve the problem I’m sure, but I want to make sure there isnt a more elegant solution.

You need to get rid of all the delay() calls at least in the main unit. That should let you handle all 3 peripherals "at the same time".

There are many tutorials in this forum and on the web. In my signature space at the bottom of this post I provide links to Nick Gammon's blog tutorials, the 1st is about making waits without using delay() code and how that allows "many things run at once".

delay( X ) --- makes the code stop right there until X millis passes. NO OTHER CODE runs for all that time, wasting 16000 cpu cycles per millisecond. That is known as BLOCKING. Until you get past that, you will have a hard time with running more than 1 task at a time.

Yes, Arduino is capable of running many tasks "at once" smoothly at speeds that can run motors, etc. It's simple to code once you've learned some new ideas.

The demo Several Things at a Time illustrates the use of millis() to manage timing without blocking. It may help with understanding the technique.

Have a look at Using millis() for timing. A beginners guide if you need more explanation.

...R

Thanks,

For the replies.

To clarify, It is the firmware of the arduino based device, that is not able to connect to multiple devices at once. This forces me to repeatedly connect, query, and restart the hub unit in order to work around this limitation.

The delays are intended as blocks.

I need to literally wait there in order for things to go smoothly. When sending a command to the hub unit ie:. +++ which will enter me into its config mode, I have to wait at least 700ms before trying to submit a command.

Like wise, once I've assigned a new MAC to bind to, I have to restart and then I need to wait a sufficient amount of time for the peripheral device to pair.

Once pairing is ok, only then can I send a query etc.

All of that seems to be working ok.

The hub communicates to the peripheral devices via BT. The hub communicates the results of this paring process to the PC via USB.

My hang up is that once I start the program on the PC which reads the USB for a certain string, while the PC is reading (Which is constant), The arduino ceases to progress through the main loop.

As soon as I stop the PC, the loop continues without issue.

I hope that makes sense.

I will reference what you've indicated in the meantime.

Thanks

I can't help feeling the Bluetooth is not really suitable for what you want to do because it is a 1-to-1 system which only communicates after it is paired. The nRF24L01+ transceivers, on the other hand, can be listening all the time and can send or receive a message without pairing - provided the sender knows the address allocated to the receiver.

Also I am still not very clear about your requirement.

Do your slave devices initiate the connection with the master when they have something to send, or does the master initiate a connection with each slave in turn to check if it has something to send? In the latter case the intervals necessary to allow the connection to be made will make the system very slow.

I think that if the slaves were to initiate the connection the code in the master could continuously check for Serial.available() without needing to know what it sending the data. (Each message could contain the ID of the sender).

I can't figure the following piece at all.

My hang up is that once I start the program on the PC which reads the USB for a certain string, while the PC is reading (Which is constant), The arduino ceases to progress through the main loop.

As soon as I stop the PC, the loop continues without issue.

In your code I only see connections to the Bluetooth module and no connection to the PC. is it possible that you are trying to use Pins 0 and 1 for two purposes - that is guaranteed to fail. If that is the problem then set up a SoftwareSerial port for the Bluetooth module.

And if you want your Arduino program to receive data from the PC (as opposed to ONLY sending data to it) then get rid of all the delay()s and replace them with millis() as in the links I gave you.

Also have a look at Serial Input Basics - simple reliable non-blocking ways to receive data. That is probably relevant for your Bluetooth communication as for your PC communication.

...R

The way the system works is as follows:

There are 3 peripheral BT Modules that are connected to 3 external devices.

1 peripheral BT module per device.

When any of these external devices turns on, it simply provides power to the BT module.

I need to know when these external devices power on.

It also has to be a wireless solution.

It also has to be as small as possible (Hence the Bluno Beetle).


Im using a 4th Bluno Beetle to attempt to pair to each of 3 external devices in or to deduce whether or not it is ON.

The result of deduction is processed by a PC via a Labview program.

This result is passed to the PC and thus the Labview program via a USB connection to the Hub arduino.

The Hub does 2 things:

Links via BT to external BT devices

and only SENDS data via USB to the PC.


The PC application which monitors the serial input from the Hub arduino can be started, stopped, paused etc.

When arduino hub is running the posted code without being connected to the pc, everything is fine.

As soon as I try to monitor the output from the Hub to the PC, the program hangs.

As as I said, I think this is likely bc the BT com and the USB serial com use the same pins, but Im not sure.

Im sorry for the confusion hopefully this makes sense.

Robin2:
I think that if the slaves were to initiate the connection the code in the master could continuously check for Serial.available() without needing to know what it sending the data. (Each message could contain the ID of the sender).

This was my original approach, but for some reason no matter what even if the hub is just running a blank loop aside from

if (Serial.available() > 0)
{
blink an led
}

with no other devices on, and thus no BT link established, that IF constantly returns true.

The software serial approach looks and sounds like the ideal solution. It should not take very long to implement this hopefully. I will reply with my results as time permits.

You can't send a message to bind device 2 until you've completely finished with device 1?
If they all listened at the same time, serial bus protocol might speed your comms as it doesn't take 100 ms to sort out what is for who.

GoForSmoke:
You can’t send a message to bind device 2 until you’ve completely finished with device 1?
If they all listened at the same time, serial bus protocol might speed your comms as it doesn’t take 100 ms to sort out what is for who.

No, I cant send messages etc to multiple devices at once. So I have to query device 1, change to device 2, restart, and then query device 2

If you used more primitive radio modules then you could send messages that all 3 would receive. 1st part of any message would be which device(s) the message is for. Given the huge delays you have now, NRF units would be magnitudes faster.

GoForSmoke:
If you used more primitive radio modules

I would not consider an nRF24 "more primitive". Just different and "more suitable" And cheap.

With an nRF24 system it would take the master about 5 millisecs to poll each slave and get a response.

...R
Simple nRF24L01+ Tutorial

How are they when you have 3 or 4 pairs operating?

GoForSmoke:
How are they when you have 3 or 4 pairs operating?

Fine.

Put the different pairs on different channels (frequencies). Indeed if they don't transmit too often so the risk of the pairs interfering with each other is low you can run them all on the same channel with different addresses. I have a system with 4 pairs working like that. That was the first system I built and I would probably do it differently now, with a single master and 4 slaves.

...R

Shows how little I know, I didn't know that they can have different channels! Full duplex is possible.

Can some be set up as having the same address?

Can address and frequency be changed by the program?

GoForSmoke:
Shows how little I know, I didn't know that they can have different channels! Full duplex is possible.

If you specifically mean sending and receiving at the same time then you would need two pairs of nRF24s - and I can't see the point of that.

Can some be set up as having the same address?

You can have as many as you want listening on the same address but then you have to disable the auto-acknowledgement feature at both ends, otherwise all the acknowledgements at the same time would create garbage.

Can address and frequency be changed by the program?

Yes.

If you have a master and several slaves with different addresses then the master obviously needs to send a message to the appropriate address.

Changing channels needs more care so that you don't end up with two devices working on different channels and unable to communicate.

...R

Robin2:
You can have as many as you want listening on the same address but then you have to disable the auto-acknowledgement feature at both ends, otherwise all the acknowledgements at the same time would create garbage.

One node could acknowledge, which may be useful.

Acks can be suppressed for a single packet.

Any communication parameter can be changed under program control.

Even a limited promiscuous mode is possible (you can match 6/256 of all addresses at a time).

I was only looking for possible modes, not predicting so much but a radio version of serial ring with 1 pair per chip for a small number of chips could happen. That does need independent channels (or wires with no radio) for RX and TX.

GoForSmoke:
I was only looking for possible modes, not predicting so much but a radio version of serial ring

I wonder if the reason people create serial rings is because they have to be wired together.

With wireless I can't see the need to create a ring.

...R