SoftwareSerial doesn't compile for Teensy 3 it seems

Status
Not open for further replies.

taskman

Well-known member
I downloaded the newest version of the IDE
I set the board to Teensy 3.

I get the following error
arduino-1.0.3-teensy3\libraries\SoftwareSerial\SoftwareSerial.cpp:128: error: #error This version of SoftwareSerial supports only 20, 16 and 8MHz processors

Code:
#include <SoftwareSerial.h>

void setup(void) {
}

void loop() {
}
 
I am looking at their code. Maybe it isn't rocket science. They just pass (SoftwareSerial &serial) to a setter and then use _serial. So I could maybe change the parameter and just pass Serial1, Serial2 or Serial3 depending on which pins I use for the RadioBlock and it should work
 
I removed the passing in the serial and just hard code in the RadioBlock to use Serial1 for now to get it to compile.
 
I'm looking at their code now.... yup, they hard-coded it to the SoftwareSerial object type.

I think maybe the best solution might be if Teensy 3.0 provided a SoftwareSerial that actually uses the real serial. It would only work with specific pins. Internally it would use Serial1, Serial2, or Serial3.... but it would present the SoftwareSerial object type, for libraries like this one that depend on linking to SoftwareSerial.
 
I removed the passing in the serial and just hard code in the RadioBlock to use Serial1 for now to get it to compile.

I picked up a few RadioBlocks to play with. Did you get the RadioBlock library to work with Teensy 3? Care to give us an update and share your changes?
 
Here's my first attempt at a SoftwareSerial stand-in which uses the real HardwareSerial, but lets you compile with libraries like RadioBlocks which have hard-coded a dependency on SoftwareSerial.

http://www.pjrc.com/teensy/beta/SoftwareSerialReal_test1.zip

To use this, replace the 2 SoftwareSerial files in libraries/SoftwareSerial. This should allow RadioBlocks to compile.

You MUST edit the pin numbers. In the examples, you'll find this:

Code:
//Pins connected to RadioBlock pins 1/2/3/4
RadioBlockSerialInterface interface = RadioBlockSerialInterface(5,4,3,2);

The last 2 pin numbers are TX and RX. You must change these to 1,0 or 10,9 or 8,7, and of course actually connect the signals to those pins. Only those 3 combinations will work on Teensy 3.0, because those are the hardware serial pins.

This is untested. Please let me know if it works for you?
 
Paul that reminds me, for doing bluetooth, I want to write my own wrapper library that would abstract the particular bluetooth card that I have (I have two different bluetooth cards at present) and its control sequences and the pins it uses to communicate over. I discovered that Serial1/Serial2/Serial3 are different superclasses over the HardwareSerial base class. That means you can't abstract which stream you are talking to. Sometimes it is nice to have that abstraction and use virtual functions to call the particular base class, and sometimes you don't want it in the name of eliminating every extra cycle.

In addition to bluetooth, I also want to extend it to radioblock, but at present, I haven't even unboxed my two radioblocks yet.

Now, I could solve my particular problem by having 4 separate types like you do (one for each of Serial1, Serial2, and Serial3, as well as SoftwareSerial for use on the AVR processors), and create my own virtual functions to do the indirection. But I tend to think it is cleaner to have the indirection available in the standard library.
:cool:
 
Last edited:
Serial1/Serial2/Serial3 are different superclasses over the HardwareSerial base class. That means you can't abstract which stream you are talking to.

You should design your abstract class to accept a Stream reference, either in the constructor or passed to a begin() function.

For the constructor approach, see Firmata (which is included with Arduino).

For the begin() approach, look at XBee 0.4.

It is indeed possible to build an abstract communication library, as those 2 libraries demonstrate.
 
Ok, though I tend to prefer begin functions over using constructors, since I often want to disable some things based on the settings of dip switches. I just need to dig through all of the classes.
 
I tend to prefer begin functions over using constructors

Ok, that's perfectly fine. Both work perfectly well (but someday a future gcc link-time optimization might make the constructor approach optimize to directly accessing the actual class).

Just look at XBee 0.4 for an example. If fact, here's the code you'll see in XBee.cpp:

Code:
// Support for SoftwareSerial. Contributed by Paul Stoffregen
void XBee::begin(Stream &serial) {
        _serial = &serial;
}

void XBee::setSerial(Stream &serial) {
        _serial = &serial;
}

bool XBee::available() {
        return _serial->available();
}

uint8_t XBee::read() {
        return _serial->read();
}

void XBee::flush() {
        _serial->flush();
}

void XBee::write(uint8_t val) {
        _serial->write(val);
}
 
Last edited:
I also made an attempt to add an alternate constructor to RadioBlock, to remove the dependency on SoftwareSerial.

http://www.pjrc.com/teensy/beta/radioblock_patched.zip

This is also untested.....

I believe I have it working now. At least the blinkLED demo sketch. I could not keep myself from making a few additional changes, mainly to reduce the hard coupling to the SoftwareSerial library:

(1) setSerial() now takes a Stream instead of a SoftwareSerial argument.
(2) RadioBlock.h no longer #includes SoftwareSerial.h.
(3) I reworked the blinkLED example sketch to first setup a HardwareSerial (basically, just set the baud rate), then create RadioBlockSerialInterface using that Stream.

setSerial() is now consistent with the new constructor, plus it allows the removal of the dependency of RadioBlocks.h on SoftwareSerial.h.

http://markonian.org/dl/RadioBlock/radioblock-msa.zip Please forgive the Mac metadata in the zip file. I was lazy. Just delete it if it annoys you.

Also, I think I tracked down the author of this library to let him know about this thread.

It is really exciting to see a blinking LED!! I'm writing this before trying the sendData example sketch. I hope this helps somebody. You have surely helped me.
 
Last edited:
Ok, that's perfectly fine. Both work perfectly well (but someday a future gcc link-time optimization might make the constructor approach optimize to directly accessing the actual class).

Just to clarify, for some things, I didn't want a particular device to be used if I have a dip switch set that is read when I power on the system. It might not even be connected. This might be whether for instance dump out debug information via the USB serial port or bluetooth, or whether to use a buzzer to make sounds, etc. So I generally want to control when things got set up. As a matter of style, I prefer explicit begin functions to doing a lot in the constructor which is always run for static/global items. Auto types and types allocated via new are different, since you control when the item is created/exited.
 
Thank you for spending time on this guys. I know you aren't doing it for me, but it is going to save alot of time when I get to this point

markonian here are a couple commands that I will need to send using RF

#define HIT_TAKEN 1
Hit taken will be command + team + playerid + battlegroup. Each value will be of type uint16_t

#define SET_TEAM 2
Set team will have one value and that will be the team. The value will be of type uint16_t

#define END_PLAYER_GAME 3
End player game will not take any values

If you are really bored would you mind seeing if you can send commands with the values from one radioblock to another?
 
Status
Not open for further replies.
Back
Top