راه اندازی دو Uart یا بیشتر با آردوینو

سلام و عرض اب خدمت شما دوستان
بنده می خواستم با آردوینو اونو دو ارتباط uart بر قرار کنم . به عبارت دیگر می خوام به یه برد آردوینو اونو و دو تا ماژول AT command دار وصل و با هر یک از اونها ارتباط بر قرار کنم . سه تا سوال دارم:

  1. آیا این امکان در آردوینو اونو هست؟
  2. اگر جواب سوال بالا بله هست چطور باید این کار رو انجام بدم؟
  3. آیا آموزش مرتبط با این موضوع هست که بتونم یاد بگیرم؟

سلام
اینکار شدنی هست
شما باید ببینید خود برد آردوینویی که دارید چه تعداد رو به صورت سخت افزاری پشتیبانی میکنه
بیشتر از اون رو هم میتونید به صورت نرم افزاری پیاده کنید

فقط اگر بیش از دو یوآرت نرم افزاری داشتید باید برای دریافت دیتا روی هر کدوم از uart های نرم افرازی تابع listen رو فراخوانی کنید .
این یه کدی هست که من قبلا نوشتم و در اون از دو یوآرت نرم افزاری استفاده شده
میتونید از این کمک بگیرید

#include <SoftwareSerial.h>
#include "ELMduino.h"

/// DEFINES /////////////////////////////////////////////////////////
#define ELM_PORT SSerial_1
#define ELM_PORT_rxPin 12
#define ELM_PORT_txPin 11

#define HMI_PORT SSerial_2
#define HMI_PORT_rxPin A1
#define HMI_PORT_txPin A0

#define BUZZ_Pin 10

#define DBG_PORT Serial


/// DISTANCE METER ////////////////////////////////////////////////
bool DM_CONNECTED  = true;

#define SRF_LFT_rx 4 // Trigger
#define SRF_LFT_tx 5 // Echo

#define SRF_RGT_rx 6 // Trigger
#define SRF_RGT_tx 7 // Echo

float temp_In_C = 20.0;  // Can enter actual air temp here for maximum accuracy
float speed_Of_Sound;          // Calculated speed of sound based on air temp
float distance_Per_uSec;

long duration;
/// @ELM   ////////////////////////////////////////////////////////
const bool DEBUG          = true;
const int  TIMEOUT        = 2000;
bool ELM_CONNECTED  = false;

ELM327 myELM327;

typedef enum { ENG_RPM, SPEED, COOLANT } obd_pid_states;
obd_pid_states obd_state = ENG_RPM;

float rpm = 0;
int32_t kph = 0;
float coolant = 0;

SoftwareSerial ELM_PORT(ELM_PORT_rxPin, ELM_PORT_txPin);



/// HMI   /////////////////////////////////////////////////////////
char buff[100];


SoftwareSerial HMI_PORT(HMI_PORT_rxPin, HMI_PORT_txPin);



/// @OTHER ////////////////////////////////////////////////////////


long out_speed;
long out_rpm;
long out_temp;

long out_distance_l;
long out_distance_r;



unsigned long previousMillis = 0;  // will store last time LED was updated
// constants won't change:
const long interval = 1000;  // interval at which to blink (milliseconds)

void setup() {
  // Define pin modes for TX and RX
  pinMode(ELM_PORT_rxPin, INPUT);
  pinMode(ELM_PORT_txPin, OUTPUT);
  pinMode(HMI_PORT_rxPin, INPUT);
  pinMode(HMI_PORT_txPin, OUTPUT);
  pinMode(BUZZ_Pin, OUTPUT);

  DBG_PORT.begin(115200);
  ELM_PORT.begin(9600);
  HMI_PORT.begin(9600);

  randomSeed(analogRead(5));
  pinMode(LED_BUILTIN, OUTPUT);

  pinMode(SRF_LFT_tx, OUTPUT);
  pinMode(SRF_LFT_rx, INPUT);
  pinMode(SRF_RGT_tx, OUTPUT);
  pinMode(SRF_RGT_rx, INPUT);

  digitalWrite(BUZZ_Pin, LOW);


  speed_Of_Sound = 331.1 + (0.606 * temp_In_C);
  distance_Per_uSec = speed_Of_Sound / 10000.0;

  DBG_PORT.println("Attempting to connect to ELM327...");

  ELM_PORT.listen();
  if (!myELM327.begin(ELM_PORT, DEBUG, TIMEOUT)) {
    ELM_CONNECTED = false;
    DBG_PORT.println("Couldn't connect to OBD scanner");

  } else {
    ELM_CONNECTED = true;
    DBG_PORT.println("Connected to ELM327");
  }


}

void loop() {
  //out_speed = random(120);
  //out_rpm   = random(7000);
  //out_temp  = random(150);

  //out_distance_l = random(110);
  //out_distance_r = random(110);

  if (DM_CONNECTED) {
    out_distance_l = read_distance(SRF_LFT_tx, SRF_LFT_rx);
    out_distance_r = read_distance(SRF_RGT_tx, SRF_RGT_rx);
  }

  if (ELM_CONNECTED) {
    ELM_PORT.listen();
    read_ELM();
    out_speed = (long)kph;
    out_rpm   = (long)rpm;
    out_temp  = (long)coolant;
  }

  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval || true) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    sprintf(buff, "Car Data: speed:%ld,rpm:%ld,temp:%ld , %ld , %ld", out_speed, out_rpm, out_temp, out_distance_l, out_distance_r);
    DBG_PORT.println(buff);
    sprintf(buff, "%ld,%ld,%ld,%ld,%ld,0", out_speed, out_rpm, out_temp, out_distance_l, out_distance_r, 0);
    HMI_PORT.println(buff);
    DBG_PORT.println("Data Sent");
  }
}

long read_distance(int tx_pin, int rx_pin) {

  digitalWrite(tx_pin, HIGH);
  delayMicroseconds(20);
  digitalWrite(tx_pin, LOW);
  duration = pulseIn(rx_pin, HIGH);

  return ((duration / 2) * distance_Per_uSec);
}

void read_ELM() {
  switch (obd_state) {
    case ENG_RPM: {
        float lrpm = myELM327.rpm();

        if (myELM327.nb_rx_state == ELM_SUCCESS) {
          rpm = lrpm;
          DBG_PORT.print("rpm:");
          DBG_PORT.println(rpm);
          obd_state = SPEED;
        } else if (myELM327.nb_rx_state != ELM_GETTING_MSG) {
          myELM327.printError();
          obd_state = SPEED;
        }

        break;
      }

    case SPEED: {
        int32_t lkph = myELM327.kph();

        if (myELM327.nb_rx_state == ELM_SUCCESS) {
          kph = lkph;
          DBG_PORT.print("kph:");
          DBG_PORT.println(kph);
          obd_state = COOLANT;
        } else if (myELM327.nb_rx_state != ELM_GETTING_MSG) {
          myELM327.printError();
          obd_state = COOLANT;
        }

        break;
      }
    case COOLANT: {
        float lcoolant = myELM327.engineCoolantTemp();


        if (myELM327.nb_rx_state == ELM_SUCCESS) {
          coolant = lcoolant;
          DBG_PORT.print("cool:");
          DBG_PORT.println(coolant);
          obd_state = ENG_RPM;
        } else if (myELM327.nb_rx_state != ELM_GETTING_MSG) {
          myELM327.printError();
          obd_state = ENG_RPM;
        }

        break;
      }
  }
}

سلام و ممنون از اینکه وقت میذارین :pray: :rose:
آردوینویی که بنده استفاده می کنم اونو هست و یدونه یوآرت سخت افزاری داره .
بنده هم مثال هایی تو خود سایت آردوینو نگاه کردم و همونطور که فرمودید از دستور listen استفاده میکنه. بنده هم یه کد زدم منتها کار نکرد. من می خواستم با یدونه آردوینو به یه ماژول مثل mc60 که با at command کار می کنه و یک برد آردوینو دیگه (پرو میکرو) رو با دو پورت uart مجازی راه اندازی کنم که متاسفانه کار نکرد پایین کدی که زدم رو براتون میذارم.

#include <SoftwareSerial.h>

SoftwareSerial promic(10, 11);



SoftwareSerial mc60(8, 9);
int device_1 = 13; // attach pin D13 of Arduino to Device-1
int device_2 = 12; // attach pin D13 of Arduino to Device-2

// defines variables
int index = 0;
String number = "";
String message = "";

char incomingByte;
String incomingData;
bool atCommand = true;
int x = 0;

void setup() {
  Serial.begin(9600);

  while (!Serial) {

    ; 

  }

  promic.begin(9600);

  mc60.begin(115200);
}

void loop() {
  promic.listen();


  promic.print("1");
  delay(2000);
  promic.print("0");
  delay(2000);

  while (promic.available() > 0) {
  promic.print("1");
  delay(2000);
  promic.print("0");
  delay(2000);

    char inByte = promic.read();

    Serial.write(inByte);

  }


  Serial.println();


  mc60.listen();


    if (mc60.available()) {
    delay(100);

    // Serial buffer
    while (mc60.available()) {
      incomingByte = mc60.read();
      incomingData += incomingByte;
    }

    delay(10);
    if (atCommand == false) {
      receivedMessage(incomingData);
      
    } else {
      atCommand = false;
    }

    //delete messages to save memory
    if (incomingData.indexOf("OK") == -1) {
      mc60.println("AT+QMGDA= \"DEL ALL\"");
      delay(1000);
      atCommand = true;
 
    }

    incomingData = "";
  }

  while (mc60.available() > 0) {

    char inByte = mc60.read();

    Serial.write(inByte);

  }
  x++;
  Serial.print(x);
}
void receivedMessage(String inputString) {
    /*digitalWrite(device_2,HIGH);
    delay(100);
    digitalWrite(device_2,LOW);*/
  //Get The number of the sender
  index = inputString.indexOf('"') + 1;
  inputString = inputString.substring(index);
  index = inputString.indexOf('"');
  number = inputString.substring(0, index);
  Serial.println("Number: " + number);

  //Get The Message of the sender
  index = inputString.indexOf("\n") + 1;
  message = inputString.substring(index);
  message.trim();
  Serial.println("Message: " + message);
  message.toUpperCase(); // uppercase the message received


  //turn Device 1 ON
  if (message.indexOf("D1 ON") > -1) {
    digitalWrite(device_1, HIGH);
    delay(1000);
    Serial.println("Command: Device 1 Turn On.");
  }

  //turn Device 1 OFF
  else if (message.indexOf("D1 OFF") > -1) {
    digitalWrite(device_1, LOW);
    Serial.println("Command: Device 1 Turn Off.");
    delay(1000);
  }

  //turn Device 2 ON
  else if (message.indexOf("D2 ON") > -1) {
    digitalWrite(device_2, HIGH);
    delay(1000);
    Serial.println("Command: Device 2 Turn On.");
  }

  //turn Device 2 OFF
  else if (message.indexOf("D2 OFF") > -1) {
    digitalWrite(device_2, LOW);
    Serial.println("Command: Device 2 Turn Off.");
    delay(1000);
  }
  else{
    Serial.println("Invalide message.");
  }

  delay(50);// Added delay between two readings

}

اول که همونطور که قبلا هم گفتم ، دقیق ذکر کنید که کدوم بخش کد مشکل داره و کار نمیکنه
دوم اینکه سرعت software serial رو بالاتر 9600 نزارید

الان سریال mc60 مشکل داره ؟
سریال promic مشکل داره ؟
سریال اصلی مشکل داره ؟

و اینکه مشکلش چی هست دقیقا
ارسال نمیکنه ؟
دریافت نمیکنه ؟
…؟