Go Down

Topic: How to program Due serial ports (Read 11833 times) previous topic - next topic

grimdon

In my own clumsy way, I quote here from the Serial section of the Language reference.

"The Arduino Due has three additional 3.3V TTL serial ports: Serial1 on pins 19 (RX) and 18 (TX); Serial2 on pins 17 (RX) and 16 (TX), Serial3 on pins 15 (RX) and 14 (TX). Pins 0 and 1 are also connected to the corresponding pins of the ATmega16U2 USB-to-TTL Serial chip, which is connected to the USB debug port. Additionally, there is a native USB-serial port on the SAM3X chip, SerialUSB'. "
This is all of interest to me but useless if I don't know how to program the several ports. There is no hint that I could see on the associated functions/methods appropriate to these Due ports. There should be some kind of hyperlink here. I also get the feeling that some of these ports have different names in other places.

Are pins 0 and 1 really connected to two different ports?
Where is more documentation of the debug port? Is this the Serial Monitor?
How is the word SerialUSB related to the native port? Is it a software keyword?
From browsing documentation for other boards I gather that, for example, Serial1.begin() would activate pins 18 and 19. Is that correct?

Thank you for any information.

jmparatte

Hi grimdon,

I think all answers are in these 3 links:
http://arduino.cc/en/Main/ArduinoBoardDue
http://arduino.cc/en/Reference/Serial
http://arduino.cc/en/uploads/Main/arduino-Due-schematic.pdf

But I'm right with you, it's difficult to understand, it's complex schemas.
I've tried some cases and I can confirm that docs are right.

Case of Serial1, Serial2 and Serial3 are simple: The pins 14 to 19 are connected to the AVR and can have other usages.

Case of Serial is more complex: Pins 0 and 1 are connected to the AVR and to the USB programming port. If the USB programming port is in use (when you program the AVR or when you communicate with the AVR), pins 0 and 1 are connected to the programming port and don't be used for any other usages.

Case of SerialUSB is different: No pins are used and you must use the native USB port to communicate with the AVR.

Take care of special RESET/ERASE actions at 1200Bps on the USB programming port and the USB native port.

Take care of NO RESET action at open/close of the USB native port.

KevinA

#2
Sep 07, 2017, 01:13 am Last Edit: Sep 07, 2017, 01:32 am by KevinA
I have to agree with @grimdon, this is crap;
sketch serialpassthrough does not work on the Due. As configured it has serial and serial1 configured BUT the USB programming port shows up on the PC as COM11 and the USB (AB is the only thing I found) shows up on the PC as COM12 BUT (again) what do you call the USB (AB) in the sketch?

A simple pass through loop that fails out of the box... I am not getting a warm and fuzz with the Due...
More GoogleFu produced: http://copperhilltech.com/blog/how-to-use-the-native-usb-of-the-arduino-due-for-highspeed-communication/
and that resulted in modification of MultiSerial:
<CODE>
 /*
  Multple Serial test

 Receives from the main serial port, sends to the others.
 Receives from serial port 1, sends to the main serial (Serial 0).

 This example works only with boards with more than one serial like Arduino Mega, Due, Zero etc

 The circuit:
 * Any serial device attached to Serial port 1
 * Serial monitor open on Serial port 0:

 created 30 Dec. 2008
 modified 20 May 2012
 by Tom Igoe & Jed Roach
 modified 27 Nov 2015
 by Arturo Guadalupi

 This example code is in the public domain.
Modified 9/7/2017 for Due support with SerialUSB
 */


void setup() {
  // initialize both serial ports:
  Serial.begin(9600);
  SerialUSB.begin(9600);    // Initialize Native USB port
}

void loop() {
  // read from port 1, send to port 0:
  if (SerialUSB.available()) {
    int inByte = SerialUSB.read();
    Serial.write(inByte);
  }

  // read from port 0, send to port 1:
  if (Serial.available()) {
    int inByte = Serial.read();
    SerialUSB.write(inByte);
  }
}
</CODE>

ard_newbie

#3
Sep 07, 2017, 06:48 am Last Edit: Sep 07, 2017, 06:56 am by ard_newbie
This sketch works (BTW post your code between code tags).

SerialUSB is the communication function used with the native USB port, Serial with UART (RX/TX) and Serialn(RXn/TXn) with the corresponding USARTp (Serial1 for USART0, Serial2 for USART1, Serial3 for USART3 and Serial4 for USART2 with a few more lines of code for this last one).

In a first Arduino IDE window, select Arduino DUE(Programming Port), Connect the board to your PC, select a Com port accordingly, i.e. for me it's "Port: Com4 (Arduino DUE Programming Port)". Upload this skectch.

Then in another IDE window opened with a right click in your short-cut IDE, select Arduino DUE (Native USB Port), connect the board to your PC with a USB cable, select a Com port accordingly, i.e. for me it's Com 8 (Arduino DUE Native USB Port)".

Sometimes the correct port doesn't show the first time you connect your cable, unconnect and connect again your cable until the correct port shows in Menu > Tools > Port.




Bigoldsofty

Whilst Serial1 and Serial2 light up orange when you have them in the code, when you try to compile it results in and 'undefined' error.  So that is not much help when you wish to use pins 18 and 19 to communicate with another device using that port.
How does one make sure Serial1 is actually defined and assigned to the correct pins?

ard_newbie


Prior compiling your sketch, select the correct board in Menu>Tools>Boards (Arduino Due) !

Bigoldsofty

Well I can't get a Due, using Serial1 to talk to a ProMini (3.3V version).  Triple checked the connection but the Due is not receiving few bytes that are sent by the ProMini.

Is there something special that needs to be done?  Debug messages from the ProMini are turned off so they cannot interfere.

ard_newbie


Check each side separately.

Have you checked Serial1 on the DUE side ?  The sketch below checks Serial1 and Serial2: connect a jumper wire between RX1/TX2 and another one between RX2/TX1, connect your DUE to the PC side via the programming port:



Code: [Select]

char c = 0;
void setup() {
 
  Serial.begin(250000);
  Serial1.begin(250000);
  Serial2.begin(250000);

  Serial2.print("Hello");
}


void loop() {
  String s;
  s = "";

  while (Serial1.available() > 0) {
    c = Serial1.read();
    s += c;

  }
  if (s.length() > 0) {
    Serial.println(s);
    Serial2.print(s);
  }
  delay(1000);
}


Have you connected the grounds together ?

Have you connected RX1(DUE) to TX(Pro Mini) and RX1(DUE) to TX(Pro Mini) ?


Bigoldsofty

Yes grounds are connected.  The ProMini side works independently.
RX1(DUE) is connected TX(Pro Mini) and RX1(DUE) is connected to TX(Pro Mini).\; checked multiple times to make sure I hadn't accidentally connected TX to TX etc.

I tried testing the Due by looping Serial1 back to Serial2 or 3 and that never worked either.
Everything else works: as in the 7" LCD display, FontIC etc.

I have even reduced the baud rate in case the ProMini was having problems with it.

I can't understand why something that should be so simple is causing me such a hassle.

The Due handles all the LCD driving and the ProMini handles the programmable configuration data and the LocoNet interface.  Not a huge amount of data has to flow between them; mostly touch screen info to the ProMini and a few screen change instructions the other way.

ard_newbie


If the sketch in my reply #7 doesn't work, I guess your board is out of order.

Bigoldsofty

Am I allowed to swear on here?
I finally found the problem.  A dry solder join on the header on the Due board.  It may have even been through plating fault.  Reapplying a little flux on both sides and resoldering has fixed it.  I gave the board to a friend who inspected it under a microscope at work and just phoned me that it now works.

Thanks for your suggestions.

OzZemberek


Hi , I'm a new starter in a way.

I'm working on a project that uses a laser range finder that communicates with arduino  through TTL, and I have this sketch obtained by the seller of the LRF and it is for UNO which works fine ....
And it uses SoftwareSerial...

How ever I'd like to be able to run it un DUE, as far as I know (as Due has 3 other native serial ports or for some other reason) SoftwareSerial can not be loaded to Due.

I changed some definitions. (ex: portOne => Serial1 ) and some functions to make the sketch compatible with Due.

It loads without errors. When I enter the commands through serial monitor, all I get is errors defined in sketch.

What I tried is to change Softwareserial commands with the compatible ones which will work on Serial1 but my knowledge is limited. Thus it failed ...

If someone could convert this sketch to work on Due it will be mush appreciated. Thanks in advance...

Original Sketch is like this (for UNO and using SoftwareSerial)


#include <Wire.h>
#include <Arduino.h>
#include <SoftwareSerial.h>
//ARDUNIO Serial control command

#define LASER_OPEN "O"//Open the module
#define MEASURE_ONE "D"//Single measurement
#define MEASURE_CONTINUE "C"//Continuous measurement
#define STOP_MEASURE "S"//Stop measuring
// software serial : TX = digital pin 7, RX = digital pin 6
SoftwareSerial portOne(7, 6);
//Measuring state machine status
#define STEP_LASER_OPEN 0//Open the module
#define STEP_MEASURE_ONE 1//Single measurement
#define STEP_MEASURE_CONTINUE 2//Continuous measurement
#define STEP_STOP_MEASURE 3//Stop measuring

#define MEASURE_CONTINUE_N 200//Continuous measurement

#define SUCCESS 0//measurement
#define FAIL -1//measurement

unsigned char measure_continu_cnt=0;
unsigned char measure_continue_flag=0;
//Function declaration
String ReadData(char Length);
String Serial_One_ReadData(char Length);
void Measure(char MEASURE_COMMEND);//distance measurement
String LaserOpen();
String MeasureOne();
String MeasureContinue();
void measure_continue_data();
String StopMeasure();

void setup() {
  // put your setup code here, to run once:
    Serial.begin(9600);//Serial debug baud rate
    while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
   // Start both software serial ports
  portOne.begin(115200);  //Laser ranging module baud rate
}

void loop() {
  String temp="";
  temp= ReadData();
  if(temp == LASER_OPEN)
   Measure(STEP_LASER_OPEN);
  else if(temp == MEASURE_ONE)
  Measure(STEP_MEASURE_ONE);
  else if(temp == MEASURE_CONTINUE)
  Measure(STEP_MEASURE_CONTINUE);
  else if(temp == STOP_MEASURE)
  Measure(STEP_STOP_MEASURE);
  else if(temp != "")
  Serial.print("UNDEFINED COMMEND\r\n");
  if(measure_continue_flag==1)
  {
    measure_continue_data();
  }
 ;
}

void Measure(char STEP_MEASURE_COMMEND)//distance measurement
{
  String temp="";
  switch(STEP_MEASURE_COMMEND)
  {
    case STEP_LASER_OPEN:
    temp = LaserOpen();
    if(temp!= "-1")
    {
      Serial.print("LASER OPEN SUCCEED\r\n");
    }
    else
    {
      Serial.print("LASER OPEN FAILD\r\n");
     }
    break;
    case STEP_MEASURE_ONE:
    temp = MeasureOne();
    if(temp!= "-1")
    {
      if(temp.indexOf("&")==9 | temp.lastIndexOf("$")==10)
      {
        temp=temp.substring(20,22)+"."+temp.substring(22,27);
      }
      else
      {
        temp=temp.substring(10,12)+"."+temp.substring(12,17);
      }
      temp="distanc="+temp+"m"+"\r\n";
      Serial.print(temp);
     }
     else
     {
      Serial.print("MEASURE_ONE FAILD\r\n");
      }
    break;
    case  STEP_MEASURE_CONTINUE:
      Serial.print("MEASURE_CONTINUE START\r\n");
      temp=MeasureContinue();
      measure_continu_cnt=0;
      measure_continue_flag=1;
     if(temp!= "-1")
     {
      if(temp.indexOf("&")==9 | temp.lastIndexOf("$")==10)
      {
        temp=temp.substring(24,26)+"."+temp.substring(26,29);
      }
      else
      {
        temp=temp.substring(14,16)+"."+temp.substring(16,19);
      }
      temp="distanc="+temp+"m"+"\r\n";
      Serial.print(temp);
     }
     else
     {
      Serial.print("MEASURE_ONE FAILD\r\n");
      }     
    break;
    case STEP_STOP_MEASURE:
     temp = StopMeasure();
     measure_continu_cnt=0;
     measure_continue_flag=0;
    Serial.print("MEASURE STOP\r\n");   
    break;           
    default:
    break;
  }
}

//Turn on the laser pointer
String LaserOpen()
{
  String return_data="";
  unsigned char temp=0;
  portOne.listen();

  if (portOne.isListening()) {
   portOne.flush();
   portOne.print("$0003260130&");
   return_data = Serial_One_ReadData(22);
   return  return_data;//Turn on the laser module
  }
}

//Single range measurement
String MeasureOne()
{
  String return_data="";
  unsigned char temp=0;
  portOne.listen();
  if (portOne.isListening()) {
   portOne.flush();
   portOne.print("$00022123&");
   return_data = Serial_One_ReadData(28);
   return  return_data;
   }
}

//Continuous ranging
String MeasureContinue()
{
    String return_data="";
  unsigned char temp=0;
  portOne.listen();

  if (portOne.isListening()) {
   portOne.flush();
   portOne.print("$00022426&");
   return_data = Serial_One_ReadData(48);
   return  return_data;
}
}

void measure_continue_data()
{
        String temp="";
        temp=Serial_One_ReadData(38);
        measure_continu_cnt++;
        if(temp.substring(17,19)=="15"|temp.substring(17,19)=="16"|temp.substring(17,19)=="")
        {
          Serial.print( measure_continu_cnt);
          Serial.print("ERROR\r\n");
          temp=MeasureContinue();
          temp=temp.substring(24,26)+"."+temp.substring(26,29);;//¼ÓÈëĞ¡Êıµã
          Serial.print( measure_continu_cnt);
          temp="  distanc="+temp+"m"+"\r\n";
        }
        else
        {
          temp=temp.substring(14,16)+"."+temp.substring(16,19);;//¼ÓÈëĞ¡Êıµã
          Serial.print( measure_continu_cnt);
          temp="  distanc="+temp+"m"+"\r\n";
        }
        Serial.print(temp); 
}
//Stop measurement
String StopMeasure()
{
  String return_data="";
  unsigned char temp=0;
 
  portOne.listen();

  if (portOne.isListening()) {
   portOne.flush();
   portOne.print("$0003260029&");
   return_data = Serial_One_ReadData(22);
   return  return_data;
}
}

//Read serial port to return data
String ReadData()
{
  int wait_time=0;
  String return_data="";
  do
  {
    delay(1);
    wait_time++;
    while(Serial.available()>0)//serial data read
    {
      char CharRead=Serial.read();
      if(CharRead!=10&&CharRead!=13)
      {
         return_data +=CharRead;
      }
      wait_time=0;
    }
  }
  while(wait_time<500);  //Wait for 1 second, no data is returned, the read is finished.
  return return_data;
}

//Read serial port to return data
String Serial_One_ReadData(char Length)
{
  int wait_time=0;
  String return_data="";
  do
  {
    delay(1);
    wait_time++;
    while( portOne.available()>0)//serial data read
    {
      char CharRead= portOne.read();
      if(CharRead!=10&&CharRead!=13)
      {
          return_data +=CharRead;
      }
      wait_time=0;
      if(return_data.length()>=Length)
      {
         wait_time=6000;
      }
    }
  }
  while(wait_time<2000);  //Wait for 1 second, no data is returned, the read is finished.
  unsigned char last_byte=(unsigned char)return_data.charAt(return_data.length()-1);
  if( wait_time == 6000)
  {     
  }
  else
  {
    return_data="-1";
  }
  return return_data;
}
[/b]


Go Up