Doubt about the Serial port Arduino

I am working with arduino's serial port and I would like to read the datas, in my laptop, that I will receive from Serial port 0 and Serial port 1. Is it possible (to read two serial ports in my latpot)?

and the other thing: I have very trouble because the specifications on internet says that Arduino Due has 103 I/0 interrupts. All pins in this board can be able like interruptions?
For example, if I need use a serial interrupt (Port0-->RX0) must I define this function? --> attachInterrupt(0, Serial0Reception, mode) where mode (that can be 0, 1, 2 or 3) in this case is irrelevant? (Serial0Reception is the name of my serial interrupt).
The first "0" is the Ardino's Pin 0 (Rx0)?
If I need specify other interrupt (for example, Pin RX1 or the interrupt of the pin 51) I need specify in this function the number of this pin?

Thanks!!

I have not used serial interrupts, but you can definitely hook up multiple serial lines.

You don't need to fool around with interrupts, the Serial library does everything for you.

But you do need to provide TTL->USB hardware for the second serial port or it's just talking to thin air.

That begs the question, why do you need two USB connections to a PC?


Rob

Graynomad:
You don't need to fool around with interrupts, the Serial library does everything for you.

But you do need to provide TTL->USB hardware for the second serial port or it's just talking to thin air.

That begs the question, why do you need two USB connections to a PC?


Rob

I will work with two serial ports (serial port 1 and serial port 0) in my aplication. For check the program I need see the datas that I will send for two serial ports.

If I define attachInterrupt(0, Serial0Reception, mode) in the setup fuction I can use the Serial0Reception function If Arduino receive datas from serial port 0??

Thanks

You need no interrupts, as Graynomad already stated!

It would be helpful, if you could describe your planned application. Especially, why you think, that you need two serial connections between the host (notebook) and your DUE.

First,

I am working with arduino's serial port and I would like to read the datas, in my laptop, that I will receive from Serial port 0 and Serial port 1. Is it possible (to read two serial ports in my latpot)?

I would recommend to inspire your self from the multi-serial mega example to copy the data coming from the two port to a third port.

http://arduino.cc/en/Tutorial/MultiSerialMega

So let's say stuff passe thrue your Arduino from serial

0<=¤=>1

Get your self a serial2usb device hook it on serial 2 and send a copy of every thing that come from serial 0 or 1 to serial 2.

2
Î
0<=¤=>1.

This way you can monitor every thing with eaze.

Also,

and the other thing: I have very trouble because the specifications on internet says that Arduino Due has 103 I/0 interrupts. All pins in this board can be able like interruptions?

Yes, each and every pin connected to a bit port on the Due can trigger an interrupt.

And also,

For example, if I need use a serial interrupt (Port0-->RX0) must I define this function? --> attachInterrupt(0, Serial0Reception, mode) where mode (that can be 0, 1, 2 or 3) in this case is irrelevant? (Serial0Reception is the name of my serial interrupt).

The hardware serial port take care of all the interupt that your serial port need. By default you can assume that the interrupt on every Rx(x) is enabled and in function as soon that you initialize the serial port. This is how they make UART such an independant device.

So nop, you don't need to configure any interrupt for the serial port. In fact, if you do, you might cause some conflict with the incoming data detection procedure.

The "serialEvent(x)" event function is the event linked to the Rx(x) interrupt pin, and i believe it's actually called as soon that incoming data is in the buffer AND the current loop() procedure end. This is the interrupt event call linked to those pins when they act as serial port.

Finaly,

The first "0" is the Ardino's Pin 0 (Rx0)?
If I need specify other interrupt (for example, Pin RX1 or the interrupt of the pin 51) I need specify in this function the number of this pin?

Yes, you must use the pin number, unlike the prior version of Arduino.

I hope this make thing more clear.

Thanks for your responses. I need use two serial ports for to see the datas that I send to this ports :slight_smile: I solved this problem.

I have another problem with serial port..... for example when I use delay() function I have problems to receive datas from serial port. I send for TX0 a specific data and , later, I use delay() function for wait another data that will arrive from RX0. If I use delay() function I have very problems with the serial interrupt (I think that If I wait by delay() function the program is blocked in this point). How can I solve this problem?

Thanks :slight_smile: :slight_smile:

This is my program (the specifications are in spanish...sorry).

ProjectArduinoV4.ino (15.6 KB)

void serialEventRun(void) {

  if (Serial.available()) interrupcion_serie0();
  if (Serial1.available()) interrupcion_serie1();

}

//FUNCION ATENCIÓN INTERRUPCIÓN PUERTO SERIE0//

void interrupcion_serie0() {
  while (Serial.available()) {
    char inChar_0 = (char)Serial.read();
    inputString_0 += inChar_0;
    if ((inChar_0 == '\r') || (inputString_0.length() == buffer_0)) {
      stringComplete_0 = true;
    }
  }
}

//FUNCION ATENCIÓN INTERRUPCIÓN PUERTO SERIE1//

void interrupcion_serie1() {
  while (Serial1.available()) {
    char inChar_1 = (char)Serial1.read();
    inputString_1 += inChar_1;
    if ((inChar_1 == '\r') || (inputString_1.length() == buffer_1)) {
      stringComplete_1 = true;
    }
  }
}

This will never be triggered on a serialEvent trigger, unless you have a magic library, that you did not declared, running in background.

This:

extern void serialEventRun(void) __attribute__((weak));

Really exist, but it has no point if it's to call an event in the same program file. The point of this, is to call a function in your program from a library, for example.

I have solved this problem. Now I get enter in the serial interrupt. The following code is a proof (you must enter by serial port in software arduino a data like this "$ADQ,P00,CH0\r" or this"$ADQ,P14,CH1\r" etc and the program will show this data. Is only a proof.... but when I include a Serial.print() in this code the program don't show the daTa if I enter the data. And if I include a big delay (for example delay(1000) I have very problems with the serial interrupt... I don't read this interrupt if the delay is long) The code is the following.

arduino_prueba_pic.ino (4.82 KB)

Ok lets go back to basic :wink:

String inputString = "";         // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete

void setup() {
  // initialize serial:
  Serial.begin(9600);
  // reserve 200 bytes for the inputString:
  inputString.reserve(200);
}

void loop() {
  // print the string when a newline arrives:
  if (stringComplete) {
    Serial.println(inputString);
    // clear the string:
    inputString = "";
    stringComplete = false;
  }
}

/*
  SerialEvent occurs whenever a new data comes in the
 hardware serial RX.  This routine is run between each
 time loop() runs, so using delay inside loop can delay
 response.  Multiple bytes of data may be available.
 */
void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    inputString += inChar;
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}

You see, there is no need to take care of the interrupt. Its all internal stuff. You open the serial port, when stuff come in, the interrupt is triggered and the routine call serialEvent() all by it self.

This is useless

extern void serialEvent(void) __attribute__((weak));

As I stated up there, it is probable that if you try to catch the interruption by your self, you will interfere with the all ready made routine. The serialEvent() event will be call as soon that the Loop() routine is done. Do not worry, you will catch what has come in since there is a buffer to contain the in coming data.

And I wish to point out this part of the example:

/*
  SerialEvent occurs whenever a new data comes in the
 hardware serial RX.  This routine is run between each
 time loop() runs, so using delay inside loop can delay
 response.  Multiple bytes of data may be available.
 */

So learning to Blink without delay() could be a good thing

I believe your problem rely on the fact that you try to program your board like if it was a UNO generation board. You have a DUE, so use the multitasking aspect of your board.

Here, read this it might help:

And especially this page:

And pay a special attention to every part of the code.

// Include Scheduler since we want to manage multiple tasks.
#include <Scheduler.h>

int led1 = 13;
int led2 = 12;
int led3 = 11;

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

  // Setup the 3 pins as OUTPUT
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);

  // Add "loop2" and "loop3" to scheduling.
  // "loop" is always started by default.
  Scheduler.startLoop(loop2);
  Scheduler.startLoop(loop3);
}

// Task no.1: blink LED with 1 second delay.
void loop() {
  digitalWrite(led1, HIGH);

  // IMPORTANT:
  // When multiple tasks are running 'delay' passes control to
  // other tasks while waiting and guarantees they get executed.
  delay(1000);

  digitalWrite(led1, LOW);
  delay(1000);
}

// Task no.2: blink LED with 0.1 second delay.
void loop2() {
  digitalWrite(led2, HIGH);
  delay(100);
  digitalWrite(led2, LOW);
  delay(100);
}

// Task no.3: accept commands from Serial port
// '0' turns off LED
// '1' turns on LED
void loop3() {
  if (Serial.available()) {
    char c = Serial.read();
    if (c=='0') {
      digitalWrite(led3, LOW);
      Serial.println("Led turned off!");
    }
    if (c=='1') {
      digitalWrite(led3, HIGH);
      Serial.println("Led turned on!");
    }
  }

  // IMPORTANT:
  // We must call 'yield' at a regular basis to pass
  // control to other tasks.
  yield();
}

The ability to run the Scheduler library is the true strength of Due.

Yess the use of millis() function is a posible solution in this case. Thanks! But I have another question: If I put a delay in the loop function and inmediately I receibe a data from serial port... the function that attend this interrupt serial port won't be execute until that the delay function ends?? (But the datas receibed are in the buffer serial port ?)

/*
SerialEvent occurs whenever a new data comes in the
hardware serial RX. This routine is run between each
time loop() runs, so using delay inside loop can delay
response. Multiple bytes of data may be available.
*/

Exactly. How ever, if you use the scheduler library, you can run a second routine, loop(), that can get your data from the serial port buffer while the first loop() is waiting for the delay() to end.

okk :slight_smile: :slight_smile: :slight_smile: schedule library is a very good option but If I use two loops and (in the hipotetic case) a SerialEvent function. This SerialEvent function when will be execute? If I have two loops this SerialEvent function will be execute when the two loops end?
thankss

Well in the case that you use 2 loops(), one loop that contain delay(), one that take care of the serial port, like loop1 and loop3 in the multiblink example, then you don't really need the serialEvent() any more, since loop3 empty your serial buffer when data come in.

Example, this guy is stuck in the delay()

// Task no.1: blink LED with 1 second delay.
void loop() {
  digitalWrite(led1, HIGH);

  // IMPORTANT:
  // When multiple tasks are running 'delay' passes control to
  // other tasks while waiting and guarantees they get executed.
  delay(1000);

  digitalWrite(led1, LOW);
  delay(1000);
}

Mean while, this guy empty the buffer:

// Task no.3: accept commands from Serial port
// '0' turns off LED
// '1' turns on LED
void loop3() {
  if (Serial.available()) {
    char c = Serial.read();
    if (c=='0') {
      digitalWrite(led3, LOW);
      Serial.println("Led turned off!");
    }
    if (c=='1') {
      digitalWrite(led3, HIGH);
      Serial.println("Led turned on!");
    }
  }

  // IMPORTANT:
  // We must call 'yield' at a regular basis to pass
  // control to other tasks.
  yield();
}

And both actions are done simultaneously.

Beside the extra ram, flash, and EEPROM, and beside the speed, The real strength of DUE is the 32 bits processor that allow multitasking. Unlike the 8 bits AVR micro-controller, this unit can execute many thing at once.

The memory and speed is nice, but it's just a side-dish. :wink:

I have another questio: What is exacly the use of yield() function in scheduler library? All loops in my program must have yeld() or only the last loop?
Thanks :slight_smile: I don't understand the information of yield() in the example scheduler. Thanks (I'm ending my program :))))

Passes control to other tasks when called. Ideally yield() should be used in function**s** that will take awhile to complete.

In this case, since you are going to use the second loop() to fetch the data in the serial buffer, awhile is infinite so yield there for sure.

So DUE88, anything new? Could Share your latest experience results please. Are you on your way to success? :wink:

Test unit

testunit.JPG