Author Topic: SoftSerial.h not working?  (Read 17783 times)

digi_guy

  • Jr. Member
  • **
  • Posts: 87
SoftSerial.h not working?
« on: December 04, 2014, 08:51:11 pm »
I can't seem to get any of the softserial examples to compile, has anyone else experienced this? When I try to load softserialexample.ino I get the following error:


Arduino: 1.5.8 (Windows 8), Board: "Digispark Pro (16 Mhz)"

In file included from C:\Users\...\Arduino\hardware\digistump\avr\cores\pro/Arduino.h:163:0,
                 from C:\Users\...\Arduino\hardware\digistump\avr\libraries\SoftSerial\SoftSerial.cpp:51:
C:\Users\...\Arduino\hardware\digistump\avr\libraries\SoftSerial\SoftSerial.cpp: In member function 'void SoftSerial::begin(long int)':
C:\Users\...\Arduino\hardware\digistump\avr\variants\pro/pins_arduino.h:108:62: error: 'GIMSK' was not declared in this scope
 #define digitalPinToPCICR(p)    (((p) >= 0 && (p) <= 10) ? (&GIMSK) : ((uint8_t *)NULL))
                                                              ^
C:\Users\...\Arduino\hardware\digistump\avr\libraries\SoftSerial\SoftSerial.cpp:434:9: note: in expansion of macro 'digitalPinToPCICR'
     if (digitalPinToPCICR(_receivePin))
         ^
Error compiling.

RC Navy

  • Jr. Member
  • **
  • Posts: 54
  • When you like, even too much, it is not enough!
Re: SoftSerial.h not working?
« Reply #1 on: December 08, 2014, 12:12:53 pm »
Hi,
Quote
C:\Users\...\Arduino\hardware\digistump\avr\variants\pro/pins_arduino.h:108:62: error: 'GIMSK' was not declared in this scope
 #define digitalPinToPCICR(p)    (((p) >= 0 && (p) <= 10) ? (&GIMSK) : ((uint8_t *)NULL))
It seems the arduino core is not fully ported yet for the ATtiny187 which is the heart of the Digispark Pro.

The macro:
Code: [Select]
#define digitalPinToPCICR(p)    (((p) >= 0 && (p) <= 10) ? (&GIMSK) : ((uint8_t *)NULL))
shall be replaced by:
Code: [Select]
#define digitalPinToPCICR(p)     (&PCICR) //all the digital pins of the ATtiny167 support pin change interrupts which are controlled by this register
in pins_arduino.h file located in C:\Users\...\Arduino\hardware\digistump\avr\variants\pro directory.

This is the first step. After this step, it should compile ... but it won't work yet.

The second step consists of defining the right registers for the digital pins in TinyPinChange library.
For that, I need the symbol used at compilation time for the ATtiny167 (for example, for the ATtiny85, it is __AVR_ATtiny85__).
Maybe it is __AVR_ATtiny167__ for the ATtiny167? Can someone confirm?
I don't have any Digispark Pro, so I'm not very aware of the ATtiny167 and I haven't downloaded the Digistump Arduino modified IDE.

As soon as I will have the symbol used at compilation time for the ATtiny167, I will add support for the ATtiny167 for TinyPinChange.

TinyPinChange supports currently arduino UNO, ATtiny85, ATtiny85, MEGA.
After having added the support for ATtiny167, it will still support arduino UNO, ATtiny85, ATtiny85, MEGA.

As SoftSerial relies on TinyPinChange, it should also work with ATtiny167.
« Last Edit: December 20, 2014, 09:11:45 am by RC Navy »

RC Navy

  • Jr. Member
  • **
  • Posts: 54
  • When you like, even too much, it is not enough!
Re: SoftSerial.h not working?
« Reply #2 on: December 20, 2014, 11:22:24 am »
@ Erik:

I have added support for Digispark pro in <TinyPinChange.h> library which is needed for <SoftSerial.h> library.

Something bothers me in Digistump\Arduino\hardware\digistump\avr\variants\pro\pins_arduino.h in your Git repository:

1) If I refer to the Digispark pro pinout, for example, Digital pin #4 is assigned to PB6.
Now, if I look at the table in digital_pin_to_port_PGM[ ], Pin#4 gives PA rather than PB.
It seems this table is not up to date with the Digispark pro pinout for all the pins.

2) If I refer to the Digispark pro pinout and the ATtiny167 datasheet, macros related to pin change should be like below:
Code: [Select]
#define digitalPinToPCICR(p)    (&PCICR)
#define digitalPinToPCICRbit(p) (((p) >= 6 && (p) <= 13) ? PCIE0 : PCIE1)
#define digitalPinToPCMSK(p)    (((p) >= 6 && (p) <= 13) ? (&PCMSK0) : (&PCMSK1))
#define digitalPinToPCMSKbit(p) (((p) >= 6 && (p) <= 13) ? ((p) - 6) : (((p) >= 0 && (p) <= 3) ? (p) : ((p) + 2)))

Could you please confirm the Digispark pro pinout is not yet up to date in pins_arduino.h file according to the Digispark pro pinout.

I'm ready to release the new <tinyPinChange.h> library including Digispark pro support.
Since I haven't any Digispark pro, I will propose the new library <TinyPinChange.h> for the ones who have it (to validate the Digispark pro support).

Regards,

digistump

  • Administrator
  • Hero Member
  • *****
  • Posts: 1465
Re: SoftSerial.h not working?
« Reply #3 on: December 21, 2014, 04:51:01 pm »
@RC Navy

There is an error in the diagram which we will fix shortly - and is now fixed in the code. I also changed out the macros for pin change to what you listed - though I think this other error might mean we need to adjust them once more:

The actual mapping of the pro pins to port and pins are as follows:

PB0->0
PB1->1
PB2->2
PB6->3
PB3->4
PA7->5
PA0->6
PA1->7
PA2->8
PA3->9
PA4->10
PA5->11
PA6->12
PB7->Reset

Happy to make any changes needed for that to work with tinyPinChange and I'd love to put an updated compatible tinyPinChange in the next release

As always- thanks for your work!

RC Navy

  • Jr. Member
  • **
  • Posts: 54
  • When you like, even too much, it is not enough!
Re: SoftSerial.h not working?
« Reply #4 on: December 22, 2014, 03:45:03 am »
Hi Erik,
Quote
though I think this other error might mean we need to adjust them once more
please find below the up to date macros needed for "pin change" according to the latest pinout you gave for Digispark pro (to put in\Arduino\hardware\digistump\avr\variants\pro\pins_arduino.h):

Code: [Select]
#define digitalPinToPCICR(p)    (&PCICR)
#define digitalPinToPCICRbit(p) ( ((p) >= 5 && (p) <= 12) ? PCIE0 : PCIE1 )
#define digitalPinToPCMSK(p)    ( ((p) >= 5 && (p) <= 12) ? (&PCMSK0) : (&PCMSK1) )
#define digitalPinToPCMSKbit(p) ( (((p) >= 0) && ((p) <= 2))  ? (p) :       \
                                ( (((p) >= 6) && ((p) <= 13)) ? ((p) - 6) : \
                                ( ((p) == 3) ? 6 :                          \
                                ( ((p) == 4) ? 3 :                          \
                                ( 7) ) ) ) ) /* pin 5 */

I have to make minor changes in <TinyPinChange.h> library and add some new examples for Digispark pro support.
I will provide it very soon.

Regards,
« Last Edit: December 22, 2014, 04:49:53 am by RC Navy »

digistump

  • Administrator
  • Hero Member
  • *****
  • Posts: 1465
Re: SoftSerial.h not working?
« Reply #5 on: December 23, 2014, 01:05:10 am »
Thanks! That fix will be in the next release

If you send me/upload the updated TinyPinChange when it is ready I will update that in the next release too.

And send me an email if you'd like some Pros - we'll be happy to send you some for testing!

RC Navy

  • Jr. Member
  • **
  • Posts: 54
  • When you like, even too much, it is not enough!
Re: SoftSerial.h not working?
« Reply #6 on: December 23, 2014, 08:20:24 am »
Hi Erik,

the <TinyPinChange> library with Digispark pro support is available in my GitHub, feel free to integrate it in the next release.
https://github.com/RC-Navy/DigisparkArduinoIntegration/tree/master/libraries
I didn't comit the "Tiny RC Scope " (http://digistump.com/board/index.php/topic,1628.msg7514/topicseen.html#msg7514) example since I found a potential issue for some kind of receiver (pulses started together or back to back pulse). I will comit this potential issue has been fixed.
As some names of method have changed, I also updated <SoftRcPulseIn> library.
Quote
And send me an email if you'd like some Pros - we'll be happy to send you some for testing!
I will contact you after Christmas, I will be back in few days.

Regards,

digistump

  • Administrator
  • Hero Member
  • *****
  • Posts: 1465
Re: SoftSerial.h not working?
« Reply #7 on: December 23, 2014, 01:13:22 pm »
Thanks - this will be updated in the next release!

Johnex

  • Newbie
  • *
  • Posts: 3
Re: SoftSerial.h not working?
« Reply #8 on: December 24, 2014, 02:52:54 am »
@RC Navy:
The TinyPinChange and the SoftRCPulseIn are really interesting for me, i have been working on navigation lighting and animations for my tricopter and have come up with this so far:

https://www.youtube.com/watch?v=ACBZeSdbbV0

I'm using regular PulseIn and it works fine, but as you know it takes up alot of CPU cycles for nothing. I contacted Erik about wrong pinout and also about the interrrupts and he sent me here, happy he did your class looks amazing :)

Johnex

  • Newbie
  • *
  • Posts: 3
Re: SoftSerial.h not working?
« Reply #9 on: December 26, 2014, 04:01:32 am »
So a quick update. I replaced the pulseIn with the your library RC Navy and that worked fine, i was able to pulse in the RC value like it should, but unfortunately i couldn't get the NeoPixels from Adafruit to work with your library. I tried to do TinyPinChange_DisablePin before drawing to the led's but i couldn't get them to light up, only some did and couldn't get any animations going at all. So unfortunately back to pulseIn for me :(

RC Navy

  • Jr. Member
  • **
  • Posts: 54
  • When you like, even too much, it is not enough!
Re: SoftSerial.h not working?
« Reply #10 on: December 27, 2014, 05:55:15 am »
Hi,

I'm back.

Johnex, your problem is probly due to the show() method of the NeoPixels library which disables the interrupts during the update of the pixels.
If you read a single RC signal with SoftRcPulseIn, I  think you can easily fix the problem by synchronizing the update of the pixels just after you receive the RC pulse.
Code: [Select]
// Which pin on the Arduino is connected to the NeoPixels?
#define PIN 1

// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS 16Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

#define MY_RC_CHANNEL_PIN 0

SoftRcPulseIn MyRcChannel;

void setup()
{
  pixels.begin(); // This initializes the NeoPixel library.
  MyRcChannel.attach(MY_RC_CHANNEL_PIN);
  ...
}

void loop()
{
  if(MyRcChannel.available())
  {
    //Read the pulse width using MyRcChannel.width_us()
    //use the pulse with for whatever you want to tune
    pixels.show(); // <-- This update the pixels just after the RC pulse (synchronized with the RC pulse). The update process shall end BEFORE the next RCpulse otherwise the measurement will be corrupted since the interrupts are disabled during pixels.show()
    ....
    ....
  }
}
The pixels.show() shall be called inside the if(MyRcChannel.available()).
As it works with pulseIn(), it shall also work with SofRcPulseIn library.
« Last Edit: December 27, 2014, 05:57:04 am by RC Navy »

Johnex

  • Newbie
  • *
  • Posts: 3
Re: SoftSerial.h not working?
« Reply #11 on: December 27, 2014, 06:30:53 am »
Hi!

The problem is the the lights dont draw after just doing attach. Not even reading the pulse or anything. I also have animations going every few milliseconds so even if a read the pulse and save it, there is enough time doing the animations for the next pulse to come. Im following the example as you wrote now, i have a function that checks the mode change for the animations via the rc channel, checking the pulse range and then changing the animation mode if required, or just doing the animation.

When i tried to use the built in arduino interrupts i had the same issue. as soon as a attached a function Int0 or Int1, not even doing anything, the lights would not work.

digistump

  • Administrator
  • Hero Member
  • *****
  • Posts: 1465
Re: SoftSerial.h not working?
« Reply #12 on: December 30, 2014, 02:52:19 pm »
I wanted to make one thing clear to anyone following this - while there are many uses for SoftSerial - please note that the Pro (unlike the original DIgispark) has hardware Serial as well.

Use it like on any arduino:
Serial.begin(9600);
Serial.print("123");

It uses pins 6 and 7 with 6 as RX and 7 as TX

Remember it doesn't print to the serial terminal though - it is strictly for talking to other serial ports.
Use DigiCDC for USB Serial.


RC Navy

  • Jr. Member
  • **
  • Posts: 54
  • When you like, even too much, it is not enough!
Re: SoftSerial.h not working?
« Reply #13 on: December 31, 2014, 08:32:10 am »
@Johnex:
Quote
I tried to do TinyPinChange_DisablePin before drawing to the led's
This should be equivalent to remove the TinyPinChange, so, your NeoPixels should work as usual. Without the full sketch, it's not possible to investigate.


@digispark (original or pro) users:

To complete the remark of Erik (digistump) about Hardware Serial versus Software Serial, find below in what cases it's interesting to use Hardware built-in serial and softserial:

1) When do you need to use built-in HardwareSerial:

  a) in priority, use hardware resource such as the built-in HardwareSerial available in the Digispark pro (not available in the original). This will reduce the microcontroller load (MCU load). The TX and RX pins are using TTL levels (0/5V).

  b) if you need to interface directly with another TTL Serial port (some GPS, another Digispark by crossing TX and RX, etc). The 1K resistors are not mandatory, but are recommended: they protect the TX outputs if they are connected together with opposite levels.
Code: [Select]
  TTL HARDWARE SERIAL TO TTL SERIAL
  =================================
 ,-----------------------,                              ,------------------------------,
 | Arduino Digispark PRO |                              |    - another Digispark       |
 |                    .--|HwSerialTx    1K*           Rx|--, - GPS                     |
 |                    |  >--------------###------------->  | - TTL serial/USB adapter  |
 |         Sketch     |HS|                              |TS| - etc                     |
 |                    |  <--------------###-------------<  |                           |
 |                    '--|HwSerialRx    1K*           Tx|--'                           |
 |                       |                              |                              |
 |       (VCC=+5V)    GND|------------------------------|GND                           |
 '-----------------------'                              '------------------------------'
    HS: Hardware Serial   *: optional, but recommended   TS: 5V TTL Serial
      It's also possible to interface with some bluetooth modules such as HC05, but even the TTL signals have the right logic (not inverted), a 5.0 <-> 3.3V level shifter is required since HC05 I/O are not 5V I/O tolerant. A simple passive level shifter is given below:
Code: [Select]
        0/3.3V <-> 0/5V TTL LEVEL SHIFTER FOR DIGISPARK PRO AND BLUETOOTH MODULE
        ========================================================================
                  +5V               +5V
                  ---              ---
                   |                |
                   |                #
 ,-----------------+--,             # 4.7K       ,-----------------------,
 |                VCC |             #            | Arduino Digispark PRO |
 |   BLUETOOTH UART   |BT_Tx 1N4148 |  HwSerialRx|--,                    |
 |        HC05      TX>-------|<|---o----####---->  |                    |
 |       Module       |   RS232 TTL      150     |HS|     Sketch         |
 |                  RX<-------o--####------------<  |                    |
 |     (I/0=3.3V)     |BT_Rx  |  2.2K  HwSerialTx|--'                    |
 |                GND |       #                  |      (VCC=+5V)        |
 '----+--------+---+--'       # 3.3K             '-----------------------'
      | Switch |   |          #                   HS: Hardware Serial
      '-.-.----'   |          |
        | |       ---        ---
        '-'       GND        GND
AT Mode<- -> Transparent Mode

  c) If you need to interface with a true RS232 port (eg: COM port of a PC or RS232/USB adpater), it's mandatory to insert a RS232 line driver such as the MAX232 in order to adapt the logic and electric levels (0/5V <-> +12V/-12V). Please note a +5V (TTL) corresponds to a -12V for RS232: the logic is inverted and the absolute electric levels are different. Please, refer to the MAX232 datasheet for the full wiring.
Code: [Select]
  TTL HARDWARE SERIAL TO RS232 SERIAL INTERFACE THROUGH A MAX232 LINE DRIVER
  ===========================================================================
                                                      ____
 ,-----------------------,                           |    \
 |                    GND|-----------------o-----------o5  \
 |                       |                 |         |   9o |
 | Arduino Digispark PRO |                 |         | o4   |
 |                    .--|HwSerialRx  .----+----.    |   8o |
 |                    |  <------------<         <------o3   |    ---> To regular RS232 SubD 9 pins Male of PC
 |        Sketch      |HS|            | MAX 232 |    |   7o |         or to RS232/USB adapter
 |                    |  >------------>         >------o2   |
 |                    '--|HwSerialTx  '----+----'    |   6o |
 |      (VCC=+5V)        |                 |         | o1  /
 |                    +5V|-----------------'         |____/
 '-----------------------'
    HS: Hardware Serial


2) When do you need to use one or several softserial(s):

  a) if the built-in HardwareSerial of the Digispark pro is already used and you need additional serial port

  b) if you do not want to insert a R232 line drive (MAX232) to adapt the logic and the electric levels (AFAIK, it's not possible to invert the logic for the HardwareSerial). In this case,  you have to use a softserial with true for the third optional argument:
Code: [Select]
#define TX_PIN 0
#define RX_PIN 1
SoftSerial MySerial(RX_PIN, TX_PIN, true); //true allows to connect to a regular RS232 without RS232 line driver
Code: [Select]
  TTL SOFTWARE SERIAL TO RS232 SERIAL INTERFACE WITHOUT A MAX232 LINE DRIVER
  ==========================================================================
                                                      ____
 ,-----------------------,                           |    \
 |                    GND|-----------------------------o5  \
 |                       |                           |   9o |
 | Arduino Digispark PRO |                           | o4   |
 |                    .--|SwSerialRx     1K          |   8o |
 |                    |  <--------------###------------o3   |    ---> To regular RS232 SubD 9 pins Male of PC
 |        Sketch      |SS|                           |   7o |         or to RS232/USB adapter
 |                    |  >--------------###------------o2   |
 |                    '--|SwSerialTx     1K          |   6o |
 |      (VCC=+5V)        |                           | o1  /
 |                    +5V|                           |____/
 '-----------------------'
    SS: SoftSerial
  c) If you have to interface with another serial with TTL levels (some GPS, another Digispark by crossing TX and RX, etc):
Code: [Select]
#define TX_PIN 0
#define RX_PIN 1
SoftSerial MySerial(RX_PIN, TX_PIN); // without the 3rd argument, the softserial is configured to interface with another TTL serial
Code: [Select]
  TTL SOFTWARE SERIAL TO TTL SERIAL
  =================================
 ,-------------------------,                              ,------------------------------,
 | Arduino Digispark (PRO) |                              |    - another Digispark       |
 |                      .--|SwSerialTx    1K*           Rx|--, - GPS                     |
 |                      |  >--------------###------------->  | - TTL serial/USB adapter  |
 |          Sketch      |SS|                              |TS| - etc                     |
 |                      |  <--------------###-------------<  |                           |
 |                      '--|SwSerialRx    1K*           Tx|--'                           |
 |                         |                              |                              |
 |       (VCC=+5V)      GND|------------------------------|GND                           |
 '-------------------------'                              '------------------------------'
     SS: SoftSerial         *: optional, but recommended   TS: 5V TTL Serial
It's also possible to interface with some bluetooth modules such as HC05, but even the TTL signals have the right logic (not inverted), a 5.0 <-> 3.3V level shifter is required since HC05 I/O are not 5V I/O tolerant. A simple passive level shifter is given below:
Code: [Select]
        SERIAL<->BLUETOOTH ADPATER VIA A DIGISPARK (Original or PRO)
        ============================================================
                  +5V               +5V
                  ---              ---
                   |                |
                   |                #
 ,-----------------+--,             # 4.7K       ,-------------------------,
 |                VCC |             #            | Arduino Digispark (PRO) |
 |   BLUETOOTH UART   |BT_Tx 1N4148 |  HwSerialRx|--,                      |
 |        HC05      TX>-------|<|---o----####---->  |                      |
 |       Module       |   RS232 TTL      150     |SS|      Sketch          |
 |                  RX<-------o--####------------<  |                      |
 |     (I/0=3.3V)     |BT_Rx  |  2.2K  HwSerialTx|--'                      |
 |                GND |       #                  |      (VCC=+5V)          |
 '----+--------+---+--'       # 3.3K             '-------------------------'
      | Switch |   |          #                   SS: Software Serial
      '-.-.----'   |          |
        | |       ---        ---
        '-'       GND        GND
AT Mode<- -> Transparent Mode

  d) If you need a serial port, but a single pin is available (all the other pins are used), you can configure the softserial to work with a single pin: 
Code: [Select]
#define TX_RX_PIN 0
SoftSerial MySerial(TX_RX_PIN, TX_RX_PIN, true); //true allows to connect to a regular RS232 without RS232 line driver
To interface this single wire soft serial port to a regular RS232 port, you need to build the following adapter: (2 x resistors and a diode)
Code: [Select]
        SINGLE WIRE SOFTWARE SERIAL TO RS232
        ====================================            ____
 ,-------------------------,                           |    \
 |                      GND|-------------------------o---o5  \
 | Arduino Digispark (PRO) |                    47K  | |   9o |
 |                      .--|                 .--###--' | o4   |
 |                      |  |           4.7K  |         |   8o |
 |                      |SSx------------###--o--|<|------o3   |    ---> To regular RS232 SubD 9 pins Male of PC
 |         Sketch       |  |                 | 1N4148  |   7o |         or to RS232/USB adapter
 |                      '--|                 '-----------o2   |
 |                         |                           |   6o |
 |        (VCC=+5V)        |                           | o1  /
 '-------------------------'                           |____/
    SS: Software Serial
    with Tx Pin = Rx Pin

To summarize:

A) Hardware serial:
     - efficient, to be used in priority
     - full duplex: can receive whilst transmitting (TBC)
     - can be connected directly to another TTL serial (eventually through a voltage level shifter for devices I/O in 3.3V)
     - shall be connected to a true RS232 COM port through a MAX232 line driver
     - cannot be connected directly to a true RS232 COM (logic cannot be inverted)

B) Software serial (softserial library):
     - half duplex: cannot receive whilst transmitting
     - same API of the regular arduino <SoftwareSerial> library + some additional methods for usage on a single pin.
     - can be connected directly to another TTL serial (eventually through a voltage level shifter for devices I/O in 3.3V)
     - can be connected directly to a a true RS232 COM port (with true as 3rd argument)
     - can be connected to a true RS232 COM port through a MAX232 line driver (without the 3rd argument)
     - can be used with a single I/O for receiving and transmitting from/to a true RS232 COM port without a MAX232 line driver
     - unlike the regular arduino <SoftwareSerial> library, can be used with pin change interrupt (<TinyPinChange> library)
     - it's not possible to listen simultaneously to several software serial ports
     - less efficient: for receiving, it stays in the ISR for all the 10 bits of the character (1 start, 8 data, 1 stop). For transmitting all the interrupts are disabled
during the 10 bits of the character. It's less intrusive if a high serial data rate is used.

Note:
    All these features are available with <softserial> library (delivered with digistump arduino IDE). Do not be confused with the regular arduino <SoftwareSerial> library which do not allow this.

Hope this clarifies the different use cases.
« Last Edit: December 31, 2014, 08:42:28 am by RC Navy »

defragster

  • Sr. Member
  • ****
  • Posts: 467
Re: SoftSerial.h not working?
« Reply #14 on: December 31, 2014, 02:05:56 pm »
@RC_Navy - good info on serial connects and use - thanks!  The world used to be 232 or 422 then USB started working and evolved and took over and serial (and parallel) went away like PS/2 ports are these days.

Serial in this MCU world still makes good sense as it simply works - given the right application notes.