Can I read two RX ports on two boards in parallel from one USB port

Hi,

Before I start I have this issue to be cleared.
I did googled for it but no satisfying result.

Two Uno's doing 2 different tasks.

One Uno is connected to the PC by USB and is sending data like temperatures and force to the PC by Serial.print commands to an VB6 app.

The second Uno is controlling a steppermotor and only needs to receive some serial data from the PC to control the steppermotor speed.

I cant combine both tasks in one Uno and I do not want two USB cables connected.

So can I connect in parallel the two RX ports of both Uno's so the data received by the Uno with USB connection send it also to the Uno without USB connection?

Thanks for thinking with me.

Paco

If you did connect them in parallel, what is your plan to ensure one board doesn't get the data belonging to the other board?

Paul

If you connect them in parallel both boards will get the same data. Make sure that Tx from the slave board is NOT`` connected to Rx on the master Arduino (the one connected to the PC).

If the programs on both Arduinos are capable of figuring which data they should ignore then it should work.

Another option is for the Master to receive and interpret everything and then send the appropriate messages onwards to the slave using a SoftwareSerial port. That would have the advantage that the slave could also send data to the master.

The examples in Serial Input Basics may be useful.

...R

I cant combine both tasks in one Uno

Yes you can.

Thanks for the answers,

I start with Grumpy_Mike to answer. Serial.print and controlling a steppermotor at the same time does not work. That is a past station. As soon as serial.print is activated the steppermotor slows down. The Serial.print is the cause for that. I have posted this problem before and there was no solution. Therefor I splitted both functions over to two boards. The Slave Uno controls the speed of the stepper and the Master Uno send serial.print to the PC. I use a TB6560 steppercontroller.

The Master Uno will send data to the PC by USB. It will receive data from the PC by USB by serial.read.The Master Uno will only listen to letter A to enable or disable the stepper motor. No other functions connected.
The Slave Uno will only receive data through the Master Uno by the parallel RX port. The code on the Slave Uno with Serial.read will only use parse.int and listen to S and a figure to set the stepper speed like "S123456".

Paco

Serial.print and controlling a steppermotor at the same time does not work.

Of course it does. You are probably not controlling the stepping motor correctly. There are plenty of ways of screwing it up.

Grumpy_Mike:
Of course it does. You are probably not controlling the stepping motor correctly. There are plenty of ways of screwing it up.

Enlight my life and if possible tell how not to screw up in this case! :slight_smile:
What are the DONTS?

For your information.
Accelstepper.h in use with TB6560.
Code wise simple.
3 lines to be controlled.
Accelstepper.h controls the STEPS.
2 other outputs
1 for direction
1 for enable/disable the stepper
one line with serial.print

If I remember well.
I used this basic code that showed the problem.

// ConstantSpeed.pde
// -*- mode: C++ -*-
//
// Shows how to run AccelStepper in the simplest,
// fixed speed mode with no accelerations
/// \author  Mike McCauley (mikem@open.com.au)
// Copyright (C) 2009 Mike McCauley
// $Id: HRFMessage.h,v 1.1 2009/08/15 05:32:58 mikem Exp mikem $

#include <AccelStepper.h>

AccelStepper stepper; // Defaults to 2 pins on 2, 9, 10

void setup()
{  
   // open the serial port at 9600 bps:
  Serial.begin(9600); 	
}

void loop()
{  
    stepper.setSpeed(1000); //1-1 steps
    stepper.runSpeed();
    Serial.print("TEST");
}

Paco

What are the DONTS?

Don't use the Accelstepper.h because that requires a regular call to keep it going and as you found if you take too long between calls then it doesn't work like it should.

Don't set the speed EVERY time round the loop.

backbone:
If I remember well.
I used this basic code that showed the problem.

That is not sufficient. You need to test the code and tell us exactly what is wrong. It is just a waste of our time if we study code that does not demonstrate the problem.

I have a program on an Uno that controls 3 stepper motors on a small lathe and the moves are sent to it using Serial. I have it organized so that the next instruction arrives in the background while a move is in progress.

...R

Robin I am not at home so cant give full code. Will do next time with video.

Grumpy tells not to use Accelstepper.h but what would be the correct way then in basic?

Robin if you use Accelstepper.h too then please explain basic to perform stepper motor and serial.print together. Take care I need Serial.print and Serial.read together in one Uno (preferable) and also controlling the stepper speed.

Confusion?

The steppermotor is used as continous rotation motor. Only speed needs to be variable.

Paco

I don't use any library - I wrote my own code very like this Simple Stepper Code

My own CNC application is not continuous.

How many steps per second do you need to generate?

...R

but what would be the correct way then in basic?

The Arduino runs off C not basic.

There are many ways to do this.

The first one that springs to mind is to pulse the driver's step input with one of the hardware timers normally used for PWM. You can change the speed using the timer's compare register for fine control and the pre scale registers for coarse control.

However you might not need to go there, what happens if you use a fast baud rate, say 250000 baud?
You could even drive the "looking if it is time to step a motor" from an interrupt service routine driven by a timer.

There are lots of ways, just because a certain libiary doesn't work there is no need to immediately switch to using two processors. You still have to communicate between the processors and that is likely to be as time expensive as the Serial.print.

void loop()


    stepper.setSpeed(1000); //1-1 steps
    stepper.runSpeed();
    Serial.print("TEST");
}

This quickly fills up the Serial output buffer and blocks the next print call until enough space is available. So runSpeed() doesn't get called often enough. Easy mistake to make, but now you've made it, you know more about serial buffering.

Even Serial can benefit from the Blink-Without-Delay technique. Or you can use the (unfortunately undocumented) availableForWrite()...

void loop()
{  
    stepper.setSpeed(1000); //1-1 steps
    stepper.runSpeed();
    if(Serial.availableForWrite()>=4) Serial.print("TEST");
}

How fast does this (unspecified) stepper motor need to turn? What is the maximum steps per second? Does it need to synchronise with anything else? That will help you choose to do it with a timer, an interrupt or BWoD.

OK,

Thanks for all hints.

Stepper needs to run from 240 to around 1000 rpm.
It is a 200 steps 3 A version motor currently running full steps.
240 rpm is 800 steps if I am correct.
No need to synchronize with anything else. Just run Forest Gump, just run :slight_smile:
I can life with a 1 second interval Serial.print in this case of this project for sending data to the PC.

I tested Serial.begin at 115200 with this test code and that works fine........but

#include <AccelStepper.h>
#include <MultiStepper.h>

// debug code for steppermotor using serial monitor
// the control is done by an Arduino Nano board in conjunction with a TBS6050 stepperboard.
// set to 3 amp
// 200 steps per rotation

AccelStepper stepper(1, 9, 10); // step-dir  set up the stepper as 4 wire bipolair on pin 9,10 for TB6560 DRIVER or other driver board
boolean StepPin = 9; // output
boolean DirPin = 10; // output
boolean MotorPin = 11;  //output

void setup()
{

  Serial.begin(115200);

  //*******************
  pinMode(StepPin, OUTPUT);
  pinMode(DirPin, OUTPUT);
  pinMode(MotorPin, OUTPUT);
  //*******************
  digitalWrite(StepPin, LOW);
  digitalWrite(DirPin, LOW);
  digitalWrite(MotorPin, LOW);

  //*******************

  digitalWrite(DirPin, LOW); //change this if direction is wrong
  stepper.setMaxSpeed(1200);
}

void loop()
{
  digitalWrite(StepPin, LOW);
  digitalWrite(DirPin, LOW);

  stepper.setSpeed(800); // 240 prm 1/1 steps
  stepper.runSpeed();
  Serial.print(123456");

} //  end void loop

as soon as I add

  Serial.print(12);
  Serial.println(12);

I am back where I started..

I know Serial.print cost speed.

I read a loadcell and one infrared MLX90614 temperature sensor that need to be ported to the PC. So I need the Serial.print.

So serial.print is like this

  Serial.print ("A,");
  Serial.println (ValueOut1); // weigth 6 digits
  Serial.print ("B,");
  Serial.println(mlx.readObjectTempC(), 0); // two digits
  Serial.print ("C,");
  Serial.println(mlx.readAmbientTempC(), 0); // two digits

Basic as the word, not in the code lanquage :wink:

Paco

You were given an explanation for this problem earlier - in Reply #12

void loop()
{
 digitalWrite(StepPin, LOW);
 digitalWrite(DirPin, LOW);

 stepper.setSpeed(800); // 240 prm 1/1 steps
 stepper.runSpeed();
 Serial.print(123456");

} //  end void loop

You are sending far too much stuff and overwhelming the serial system. Just send a message once per second, or maybe 5 times per second.

...R

Go back and read https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay then copy that exact code into your code, except put the serial output where the LED was blinking. You could probably use the same interval.

Robin2:
You were given an explanation for this problem earlier - in Reply #12

void loop()

{
digitalWrite(StepPin, LOW);
digitalWrite(DirPin, LOW);

stepper.setSpeed(800); // 240 prm 1/1 steps
stepper.runSpeed();
Serial.print(123456");

} //  end void loop




You are sending far too much stuff and overwhelming the serial system. Just send a message once per second, or maybe 5 times per second.

...R

Robin I know I am sending a lot, but that is what I need for this project.
Remember my original question and why I am using two controllers! ?

Morgan,
Will try to add the blink code option tomorrow and see where it brings me.
Your if(Serial.availableForWrite() function does not work in my case as I need to send three seperate serial.println's that need to be decoded at the PC side. Therefor also the letters ABC and the comma.

Thanks, Paco

Why does it not work? If you have 27 bytes ready to send, then check availableForWrite() to see if it has 27 spaces available. Change the number to whatever is appropriate for your particular application.

backbone:
Robin I know I am sending a lot, but that is what I need for this project.

You need to say how many times per second you need to send data. At the moment your code would send 1000 (or more) messages per second if the Arduino was capable of that. I find it hard to believe that that is needed.

Another thought is that maybe you need to make decisions on the Arduino rather than sending data to the PC for it to make decisions.

Please give us a description of the overall project and then we may be able to give more useful advice. At the moment it is just an XY problem

...R

Currently at work so other priorities.

Morgan, I think I misunderstood the function. Will test this evening.

if(Serial.availableForWrite()>=14)

{
  Serial.print ("A,"); two4 digits
  Serial.println (ValueOut1); // weigth 6 digits
  Serial.print ("B,"); two digits
  Serial.println(mlx.readObjectTempC(), 0); // two digits
  Serial.print ("C,"); two digits
  Serial.println(mlx.readAmbientTempC(), 0); // two digits

}[/code]

Robin, check the video of the prototype using 2x uno and only fixed speed @ 240 RPM.
Reading @ 1 second interval is enough.

password: DYNO

Paco