Russell's Blog

New. Improved. Stays crunchy in milk.

Trouble with SoftSerial on the Arduino Leonardo

Posted by Russell on May 25, 2012 at 12:05 p.m.
While I was wandering around at Maker Faire last weekend, I heard someone say, "Woah, is this the Leonardo?" And lo, there was a handful of Arduino Leonardo boards lined up on a shelf for sale. I instantly grabbed one, and bundled it home to play with it.

The Leonardo is Arduino's latest board, announced last September. It uses the Atmega32u4 chip, which has onboard USB. This has two important implications; first, the Leonardo costs less than the Uno, and second it will be able to operate in any USB mode. That means people can make Human Interface Devices (HID), like mice and keyboards and printers, with Arduino, and present themselves to the host using the standard USB interfaces for those devices. That means you can build things that don't need to talk via serial, and use the host's built-in drivers for mice and printers and whatnot. This is a big step forward for Open Hardware.

Anyway, I'm developing an little remote environmental data logger to use for part of my dissertation project, and I thought I'd see if I could use the Leonardo board in my design. I'm using the Arduino board to talk to an Atlas Scientific pH stamp, which communicates by serial. It works fine on the Uno with SoftwareSerial (formerly known as NewSoftSerial until it was beamed up into the Arduino Core mothership).

Unfortunately, it didn't go so well on the Leo. The board can send commands to the pH stamp, but doesn't receive anything. I swapped in an FTDI for the pH stamp, and confirmed that the Leonardo is indeed sending data, but it didn't seem to be able to receive any characters I sent back. I tried moving the rx line to each the digital pins, and had no luck. Here is my test program :

#include <SoftwareSerial.h>

#define rxPin 2
#define txPin 3

SoftwareSerial mySerial( rxPin, txPin );

byte i;
byte startup = 0;

void setup() {

  mySerial.begin( 38400  );
  Serial.begin(   9600   );
}

void loop() {
  
  if( startup == 0 ) {             // begin startup
    for( i = 1; i <= 2; i++ ) {
      delay( 1000 );
      mySerial.print( "l0\r" );    // turn the LED off
      delay( 1000 );
      mySerial.print( "l1\r" );    // turn the LED on
    }
    startup = 1;                   // don't re-enter
  }                                // end startup

  Serial.println( "taking reading..." );
  mySerial.print( "r\r" );
  delay(1000);
  
  Serial.println( mySerial.available() );
  
}
On the Uno, I see the number increasing as the read buffer fills up :
taking reading...
0
taking reading...
0
taking reading...
7
taking reading...
16
taking reading...
16
On the Leo, it seems that nothing ever gets added to the read buffer, no matter how any characters I send over from the FTDI or which pins I used for the rx line :
taking reading...
0
taking reading...
0
taking reading...
0
taking reading...
0
taking reading...
0
taking reading...
I really wanted to see if I was crazy here, but I'm one of the first people among the General Public to get their hands on a Leonardo board. So, I started talking with Ken Jordan on #arduino on Freenode (he goes by Xark) who has a similar board, the Atmega32u4 Breakout+. It's based on the same chip as the Leonardo, but it has different pinouts and a different bootloader. He flashed the Leonardo bootloder onto his board, and worked out the following pin mapping :
Arduino 1.0.1     Adafruit         ATMEL
digitalWrite pin  atmega32u4+ pin  AVR pin function(s)
----------------  ---------------  ------------------
D0                D2               PD2 (#INT2/RXD1)
D1                D3               PD3 (#INT3/TXD1)
D2                D1               PD1 (#INT1/SDA)
D3#               D0               PD0 (#INT0/OC0B)
D4/A6             D4               PD4 (ICP1/ADC8)
D5#               C6               PC6 (OC3A/#OC4A)
D6#/A7            D7               PD7 (T0/OC4D/ADC10)
D7                E6 (LED)         PE6 (INT6/AIN0)
D8/A8             B4               PB4 (PCINT4/ADC11)
D9#/A9            B5               PB5 (OC1A/PCINT5/#OC4B/ADC12)
D10#/A10          B6               PB6 (OC1B/PCINT6/OC4B/ADC13)
D11#              B7               PB7 (OC0A/OC1C/PCINT7/#RTS)
D12/A11           D6               PD6 (T1/#OC4D/ADC9)
D13#  (LED)       C7               PC7 (ICP3/CLK0/OC4A)
D14   (MISO)      B3               PB3 (PDO/MISO/PCINT3)
D15   (SCK)       B1               PB1 (SCLK/PCINT1)
D16   (MOSI)      B2               PB2 (PDI/MOSI/PCINT2)
D17   (RXLED)     B0               PB0 (SS/PCINT0)
D18/A0            F7               PF7 (ADC7/TDI)
D19/A1            F6               PF6 (ADC6/TDO)
D20/A2            F5               PF5 (ADC5/TMS)
D21/A3            F4               PF4 (ADC4/TCK)
D22/A4            F1               PF1 (ADC1)
D23/A5            F0               PF0 (ADC0)
-     (TXLED)     D5               PD5 (XCK1/#CTS)
-     (HWB)       -  (HWB)         PE2 (#HWB)
This was derived from the ATmega 32U4-Arduino Pin Mapping and ATMEL's datasheet for the ATmega32U4 chip. Once that was worked out, he flashed my test program onto his board, and also found that SoftwareSerial could transmit fine, but couldn't receive anything.

Ken rummaged around a little more, and had this to say :

The SoftSerial seems to use PCINT0-3 so there seems to me a minor problem in Leo-land in that only PCINT0 appears to be supported (and it is on "funky" output for RXLED). Hopefully I am just misunderstanding something (but it imay be the interrupt remap table is incorrect for Leo).
Then he disappeared for a little while, and came back with :
I have confirmed my suspicion. When I disassemble SoftSerial.cpp.o I can see that only __vector_9 is compiled (i.e., one of 4 #ifdefs for PCINT0-3) and the interrupt vector 10 is PCINT0 (0 is reset vector so offset by one makes sense). So, unless you hook serial to RXLED pin of CPU I don't believe it will work with the current libs.

Also I believe the Leo page is just wrong when it says pins 2 & 3 support pin change interrupts (I think this was copied from Uno but it is incorrect, the only (exposed) pins are D8 D9 D10 and D11 that support PCINT according to the ATMEL datasheet (and these are PCINT 4-7 not the ones in the interrupt mapping table AFAICT).

I believe this is where I can stop worrying that I'd be wasting the time of the core Arduino developers, and say quod erat demonstrandum; it a bug in SoftwareSerial. Hopefully they can update the Arduino IDE before the boards hits wider distribution.

Update : So, it turns out that this is a known limitation of the Leonardo. David Mellis looked into it, and left this comment :

You're right that the Leonardo only has one pin change interrupt, meaning that the software serial receive doesn't work on every pin. You should, however, be able to use pins 8 to 11 (inclusive) as receive pins for software serial. Additionally, the SPI pins (MISO, SCK, MOSI) available on the ICSP header and addressable from the Arduino software as pins 14, 15, and 16 should work.
He is, of course, correct. I'm not sure why my testing didn't work on pins 8-11, but they do indeed work fine. Unfortunately, this means that the Leonardo is not compatible with a number of cool shields. The Arduino SoftSerial Library Reference documentation has been updated with a more detailed list of limitations.
sizegenetics on April 02, 2014 at 1:49 p.m.

I'm often to running a weblog and i truly admire your content material. The article has truly peaks my interest. I am going to bookmark your website and maintain checking for new info.sizegenetics discount

stellar phoenix photo recovery on April 02, 2014 at 1:51 p.m.

Can I lately say thats a relief to discover a person who basically knows what theyre preaching about on the internet. You essentially comprehend the right way to bring a challenge to light and function out it critical. The most beneficial approach to should see this and see why side of your story. I cant think youre no a great deal more common basically due to the fact you completely hold the gift.stellar phoenix photo recovery

wondershare dr fone on April 02, 2014 at 1:52 p.m.

Blasphemy! LOL Just kidding. Ive read similar items on other blogs. Ill take your word by utilizing this. Remain solid! your buddy.wondershare dr fone

sizegenetics coupon on April 02, 2014 at 1:59 p.m.

Sorry for the significant assessment, but I'm honestly loving the new Zune, and hope this, together with the wonderful evaluations some other persons have written, will assist you to make a decision if it is the right choice for you.sizegenetics

ross on April 05, 2014 at 12:06 p.m.

Excellent post. I was checking continuously this blog and I'm impressed! How do you become this good? It's incredible to find out someone place such a lot of interest towards a topic. Wow! Thank you! Wonderful post! www.rebelmouse.com/venusfactor_diet/ | www.rebelmouse.com/mi40reviewed/ | www.rebelmouse.com/leanhybridmusclereviewed/

mobile payment consultant on April 13, 2014 at 5:39 a.m.

Over years experience in delivering successful products launches and start ups in the mobile and digital industries. mobile payment consultant

manis on April 14, 2014 at 3:54 p.m.

really exciting write-up in addition to I do believe it is required. hopefully later on it gets a handy, hopefully. I truly enjoy people for making this short article. many thanks with the valuable write-up. cara memakai jilbab

Amazon Coupon Code on April 17, 2014 at 9:17 a.m.

Sorry for the significant assessment, but I'm honestly loving the new Zune, and hope this, together with the wonderful evaluations some other persons have written, will assist you to make a decision if it is the right choice for you. Amazon Coupons

Lowongan Kerja Terbaru 2014 on April 17, 2014 at 9:19 a.m.

Sorry for the significant assessment, but I'm honestly loving the new Zune, and hope this, together with the wonderful evaluations some other persons have written, will assist you to make a decision if it is the right choice for you. Lowongan Kerja | Lowongan Kerja 2014 | Lowongan Kerja SMK

tabela on April 18, 2014 at 4:36 p.m.

Over years experience in delivering successful products launches and start ups in the mobile and digital industries.

gxdsfvx on April 18, 2014 at 6:54 p.m.

May 3 is the date of kentucky derby 2014 the link is here. http://www.kentuckyderby2014s.com Happy derby

mobile payment banking consulting on April 19, 2014 at 7:15 a.m.

Developed and launched new digital business (payment & content) strategy and proposition from scratch for a multinational client. mobile payment banking consulting

Ignore this field:
 optional; will not be displayed
Don't put anything in this field:
 optional
Don't put anything here:
Leave this empty:
URLs auto-link and some tags are allowed: <a><b><i><p>.