Go Down

Topic: Arduino Zero - SoftwareSerial library (Read 15848 times) previous topic - next topic

MartinL

#15
Jun 22, 2016, 04:24 pm Last Edit: Jun 22, 2016, 04:52 pm by MartinL
Hi Urs,

I had a look a Adafruit's shield compatibility guide: https://cdn-learn.adafruit.com/downloads/pdf/adafruit-shield-compatibility.pdf

The Zero isn't mentioned, but as it mentions the Due, I assume that the GPS Data Logger Shield is 3.3V compatible.

This guide states that this shield uses D0 and D1 for hardware serial, or D7 and D8 for software serial. Unfortunately, D7 and D8 on the Zero don't share the same Serial Communications (SERCOM) port, so configuring them as a hardware serial port isn't possible. However, the Zero's "Serial1" port is on D0 and D1, so your best bet is to move the switch to hardware serial and in Adafruit's example code redefine "mySerial" to "Serial1":

Code: [Select]
//SoftwareSerial mySerial(8, 7);
#define mySerial Serial1
Adafruit_GPS GPS(&mySerial);

Another issue (if you're using it) is going to be your SPI, micro SD card data logger. The Arduino SPI library for the Zero doesn't use digtal pins D10-D13 like the Uno, but instead uses the 6-pin ICSP header. Fortunately it's possible to configure the Zero to use the same pins as the Uno, by following Adafruit's SERCOM guide here: https://learn.adafruit.com/using-atsamd21-sercom-to-add-more-spi-i2c-serial-ports/creating-a-new-spi

It's for their Feather M0 board, but it's similar to the Zero, (they use the same processor).

By the way, here's the schematic: https://learn.adafruit.com/assets/8127

MartinL

#16
Jun 22, 2016, 05:47 pm Last Edit: Jun 23, 2016, 09:20 am by MartinL
Hi Urs,

Looking at the schematic, it appears as though Adafruit have reversed their Rx and Tx pins that go to digital pins 0 and 1. Reversing these pins and loading the Uno with a blank sketch allows a direct connection from the GPS to your PC. Using this method the GPS's NMEA data can be displayed on the Arduino IDE's console. Unfortunately, this won't work with the Zero.

To get the board to work with Serial1 on the Zero's D0 and D1 pins, your going to have to use the "Direct Connection with Jumpers on Leonardo" method:



This requires you  to select "Software Serial" on the switch and directly connect the GPS's Tx to the Zero's Rx (D0) and the GPS's Rx to the Zero's Tx (D1) using jumper wires. Doing this however means that you can't use D7 or D8.

Urs_Effi

Hi Martin
Thank you for this investigation and your answer.
Best Regards
  Urs

Miq1

Hi all,

I have to pick up this thread as I think you may be the right audience for my issue.

I would like to use pins 2/3 for Serial2 and 4/5 for Serial3 on the Zero for easier cabling. Is that possible without modifying the variant files? Just with local code in my sketch?

Any help is appreciated :-)

MartinL

#19
Nov 09, 2016, 06:44 pm Last Edit: Nov 09, 2016, 06:48 pm by MartinL
Hi Miq1,

If you're using an Arduino.cc's Zero then D2/D5 and D3/D4 make TX/RX sercom pairs, whereas on an Arduino.org's M0/M0 Pro it's D2/D3 and D4/D5. This is because on Arduino.cc's Zero, pins D2 and D4 are swapped.

The Adafruit article: https://learn.adafruit.com/using-atsamd21-sercom-to-add-more-spi-i2c-serial-ports/creating-a-new-serial, shows how it's possible to access the sercom ports using the pinPeripheral() function. This function gives the pins sercom functionality without having to modify the variant files.

Assuming that you're using the Arduino.cc's Zero, then D2 and D5 use sercom2, or if you're prepared to forgo the SPI port on sercom4. Pins D3 and D4 use sercom0 or sercom2, however sercom0 is already used by D0 and D1.

Miq1

The pins you mention read differently in the page reference you linked. I will try to understand what is written there and experiment a bit ;)

MartinL

#21
Nov 11, 2016, 12:32 pm Last Edit: Nov 11, 2016, 12:33 pm by MartinL
Hi Miq1,

Quote
The pins you mention read differently in the page reference you linked.
If you look at the bottom of the linked page, you'll find an example that exactly matches your requirement, namely using sercom2 on pins D3 and D4. Here's the code from adafruit's page:

Code: [Select]
    #include <Arduino.h>   // required before wiring_private.h
    #include "wiring_private.h" // pinPeripheral() function
     
    Uart Serial2 (&sercom2, 3, 4, SERCOM_RX_PAD_1, UART_TX_PAD_0);
    void SERCOM2_Handler()
    {
      Serial2.IrqHandler();
    }
     
    void setup() {
      Serial.begin(115200);
     
      Serial2.begin(115200);
     
      // Assign pins 3 & 4 SERCOM functionality
      pinPeripheral(3, PIO_SERCOM_ALT);
      pinPeripheral(4, PIO_SERCOM_ALT);
    }
     
    uint8_t i=0;
    void loop() {
      Serial.print(i);
      Serial2.write(i++);
      if (Serial2.available()) {
        Serial.print(" -> 0x"); Serial.print(Serial2.read(), HEX);
      }
      Serial.println();
     
      delay(10);
     
    }

The same code can be used as a template to configure sercom4 on D2 and D5.

Miq1

Hi MartinL,

thanks, it worked with sercom2 on D3/D4. For sercom4 on D2/D5, would it be:

Code: [Select]

Uart Serial4 (&sercom4, 2, 5, SERCOM_RX_PAD_1, UART_TX_PAD_0);
    void SERCOM4_Handler()
    {
      Serial4.IrqHandler();
    }

setup()
{
...
 pinPeripheral(2, PIO_SERCOM_ALT);
 pinPeripheral(5, PIO_SERCOM_ALT);
...


then?

MartinL

#23
Nov 11, 2016, 01:39 pm Last Edit: Nov 11, 2016, 01:40 pm by MartinL
Hi Miq1,

You just need to reverse the pins D2=TX, D5=RX and change the PAD definitions. I've also changed Serial4 to Serial3, although this doesn't really matter:

Code: [Select]
Uart Serial3 (&sercom4, 5, 2, SERCOM_RX_PAD_3, UART_TX_PAD_2);
    void SERCOM4_Handler()
    {
      Serial3.IrqHandler();
    }

setup(){}

Miq1

#24
Nov 11, 2016, 02:32 pm Last Edit: Nov 11, 2016, 02:38 pm by Miq1
Hi MartinL,

looks like I am blind - with the code below, the D3/D4 UART ceased working, the Nextion display connected to it shows no reaction anymore. But why?

Code: [Select]

#include <Arduino.h>   // required before wiring_private.h
#include "wiring_private.h" // pinPeripheral() function

...

// Instantiate the Nextion-Serial and Serial2 class
Uart CellOne(&sercom4,  5,  2, SERCOM_RX_PAD_3, UART_TX_PAD_2); 
Uart Nextion(&sercom2,  3,  4, SERCOM_RX_PAD_1, UART_TX_PAD_0);   

void SERCOM2_Handler()    // Interrupt handler for SERCOM2
{
  Nextion.IrqHandler();
}

void SERCOM4_Handler()    // Interrupt handler for SERCOM4
{
  CellOne.IrqHandler();
}
     
void setup() {

...

// Assign pins 3 & 4 for SERCOM2 functionality
  pinPeripheral(3, PIO_SERCOM_ALT);
  pinPeripheral(4, PIO_SERCOM_ALT); 
// Assign pins 2 & 5 for SERCOM4 functionality
  pinPeripheral(2, PIO_SERCOM_ALT);
  pinPeripheral(5, PIO_SERCOM_ALT); 

 ...

  Nextion.begin(9600);

  initNextion("Log"); // no effect :-(

  flashNextion("Nextion init done"); // neither effect

 


Oh, by the way: Serial1 (D0/D1) is in use as well and works.

MartinL

Hi Miq1,

It's because you're calling the pinPeripheral() function before the Serialx.begin(). Call the begin() function for the serial ports first, then it should work OK.

Miq1

You are right! Thanks a lot!

I never would have thought that assigning pins must be done after the initialization  :smiley-eek:

mzayats

I am also looking for SoftwareSerial on Zero.
The reason is support for 9N1... There are forks of SoftwareSerial that implement it.

Can it be achieved with SERCOMs?

MartinL


AloyseTech

Hi mzayats,

Yes it can. It's detailed in Adafruit's tutorial: https://learn.adafruit.com/using-atsamd21-sercom-to-add-more-spi-i2c-serial-ports/creating-a-new-serial.


I'm not sure it is possible as is. if you take a look at HardwareSerial.h, you'll see that the 9N1 config doesn't exist.

Go Up