Skip to content

Commit 4885bb3

Browse files
authored
Merge pull request #21 from mike-matera/change-serial-device
Enable changing the serial device.
2 parents f4a8c47 + bb13fa8 commit 4885bb3

File tree

4 files changed

+99
-30
lines changed

4 files changed

+99
-30
lines changed

README.md

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ void setup() {
2424
}
2525
```
2626

27-
## Using cin an cout
28-
When you include this header file you automatically get cin and cout based on Serial. There isn't yet a way to select you own device at runtime. Using cin and cout is
27+
## Using ```cin``` an ```cout```
28+
When you include this header file you automatically get cin and cout based on ```Serial```. See below for how to specify your own device. Here's an example sketch using ```cin``` and ```cout``` .
2929

3030
```c++
3131
#include <ArduinoSTL.h>
@@ -47,10 +47,40 @@ void loop() {
4747
}
4848
}
4949
```
50+
## Changing the Serial Port
51+
You can change what serial port that ```cin```, ```cout``` and ```printf()``` use. You can use built-in serial ports (e.g. ```Serial1``` on Leonardo) or you can use software serial ports that implement ```Stream```.
52+
53+
### Using a Built-in Port
54+
In ```src/ArduinoSTL.cpp``` change the value of ```ARDUINOSTL_DEFAULT_SERIAL```. Leave the other defaults uncommented.
55+
56+
### Using a SoftwareSerial port.
57+
Set ```ARDUINO_DEFAULT_SERAL``` to ```NULL```. Comment out the other defaults.
58+
59+
Here's an example sketch that uses SofwareSerial:
60+
61+
```c++
62+
#include <ArduinoSTL.h>
63+
#include <SoftwareSerial.h>
64+
65+
SoftwareSerial mySerial(0, 1);
66+
67+
namespace std {
68+
ohserialstream cout(mySerial);
69+
ihserialstream cin(mySerial);
70+
}
71+
72+
void setup() {
73+
mySerial.begin(9600);
74+
ArduinoSTL_Serial.connect(mySerial);
75+
}
76+
```
77+
78+
## Avoiding Instantiation of ```cin``` and ```cout```
79+
Comment out ```ARDUINOSTL_DEFAULT_CIN_COUT``` and nothing will be instantiated. You must comment out this flag if you intend to select a non-default serial port. There's no appreciable overhead for using ```printf()``` so you cannot currently avoid initializaing it.
5080
5181
## Known Issues
5282
53-
Printing of floats and doubles using cout ignores format specifiers.
83+
Printing of floats and doubles using ```cout``` ignores format specifiers.
5484
5585
uClibc seems to be fairly complete. Strings and vectors both work, even with the limited amount of heap available to Arduino. The uClibc++ status page can be found here:
5686

library.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
name=ArduinoSTL
2-
version=1.0.5
2+
version=1.1.0
33
author=Mike Matera <[email protected]>
44
maintainer=Mike Matera <[email protected]>
55
sentence=A port of uClibc++ packaged as an Arduino library.
6-
paragraph=This library includes important C++ functions, including cout and cin, printf and scanf. It also includes STL containers like vector and algorithms.
6+
paragraph=This library includes important C++ functions, including cout and cin, printf and scanf. It also includes STL containers like vector and algorithm.
77
category=Other
88
url=https://github.com/mike-matera/ArduinoSTL
99
architectures=avr,samd

src/ArduinoSTL.cpp

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,35 @@
11
#include <ArduinoSTL.h>
22
#include <Arduino.h>
33

4+
//
5+
// Configuration Help
6+
//
7+
// If you're using a serial port that's statically declared somewhere in
8+
// Arduino (e.g. Serial1 on Leonardo)
9+
// 1. Set ARDUINOSTL_SERIAL_DEVICE to your device
10+
// 2. Uncomment the ARDUINOSTL_DEFAULT_CIN_COUT flag.
11+
//
12+
// If you're using a sofware serial port:
13+
// 1. Set ARDUINOSTL_DEFAULT_SERIAL to NULL
14+
// 2. Comment out ARDUINOSTL_DEFAULT_CIN_COUT
15+
// Your sketch must contain delarations of cin and cout, and a call to
16+
// ArduinoSTL_serial.connect().
17+
//
18+
19+
#define ARDUINOSTL_DEFAULT_SERIAL Serial
20+
#define ARDUINOSTL_DEFAULT_CIN_COUT
21+
422
using namespace std;
523

24+
#ifdef ARDUINOSTL_DEFAULT_CIN_COUT
625
// Create cout and cin.. there doesn't seem to be a way
726
// to control what serial device at runtime. Grr.
827
namespace std
928
{
10-
ohserialstream cout(Serial);
11-
ihserialstream cin(Serial);
29+
ohserialstream cout(ARDUINOSTL_DEFAULT_SERIAL);
30+
ihserialstream cin(ARDUINOSTL_DEFAULT_SERIAL);
1231
}
32+
#endif // ARDUINOSTL_DEFAULT_CIN_COUT
1333

1434
/*
1535
* Implementation of printf() is highly libc dependent.
@@ -21,22 +41,8 @@ namespace std
2141
* ARDUINO_ARCH_* - ARMs are probably the same as above.
2242
*/
2343
#if defined(ARDUINO_ARCH_AVR)
24-
//
25-
// This is a hack to make C stdio work on "Serial" without
26-
// having to be manually initialized. It works becuase I can
27-
// call a constructor before setup().
28-
//
29-
class __Arduino_STDIO_hack {
30-
public:
31-
__Arduino_STDIO_hack(Stream *u);
32-
Stream *getUart() {
33-
return uart;
34-
}
35-
private:
36-
Stream *uart;
37-
};
3844

39-
static __Arduino_STDIO_hack __stdio_wrapper(&Serial);
45+
ArduinoSTL_STDIO ArduinoSTL_Serial(ARDUINOSTL_DEFAULT_SERIAL);
4046

4147
// arduino_putchar(char, FILE*)
4248
// Output a single character to the serial port.
@@ -46,7 +52,7 @@ static __Arduino_STDIO_hack __stdio_wrapper(&Serial);
4652
// automatically addes a \r when it sees a \n
4753
//
4854
static int arduino_putchar(char c, FILE* f) {
49-
Stream *uart = __stdio_wrapper.getUart();
55+
Stream *uart = ArduinoSTL_Serial.getUart();
5056
if (c == '\n') uart->write('\r');
5157
return uart->write(c) == 1? 0 : 1;
5258
}
@@ -57,18 +63,18 @@ static int arduino_putchar(char c, FILE* f) {
5763
// returns: The character or -1 on a read error
5864
//
5965
static int arduino_getchar(FILE *f) {
60-
Stream *uart = __stdio_wrapper.getUart();
66+
Stream *uart = ArduinoSTL_Serial.getUart();
6167
while (! uart->available()) { /* wait */ }
6268
return uart->read();
6369
}
6470

65-
// Initialize STDIO using a pointer to whatever Serial is.
66-
// Serial.begin() must be called at some point.
67-
//
68-
__Arduino_STDIO_hack::__Arduino_STDIO_hack(Stream *u) {
71+
void ArduinoSTL_STDIO::connect(Stream *u) {
72+
if (file != NULL)
73+
free (file);
6974
uart = u;
70-
fdevopen(arduino_putchar, arduino_getchar);
75+
file = fdevopen(arduino_putchar, arduino_getchar);
7176
}
77+
7278
#else
7379
#warning "printf() will not be functional on this platform."
7480
#endif

src/ArduinoSTL.h

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,37 @@ namespace std
1919
extern ihserialstream cin;
2020
}
2121

22-
#endif
22+
#if defined(ARDUINO_ARCH_AVR)
23+
24+
class ArduinoSTL_STDIO {
25+
public:
26+
// Initialize STDIO using a pointer to whatever Serial is.
27+
// Serial.begin() must be called at some point.
28+
ArduinoSTL_STDIO(Stream *u) : file(NULL) {
29+
connect(u);
30+
}
31+
32+
ArduinoSTL_STDIO(Stream &u) : file(NULL) {
33+
connect(u);
34+
}
35+
36+
Stream *getUart() {
37+
return uart;
38+
}
39+
40+
void connect(Stream *u);
41+
42+
inline void connect(Stream &u) {
43+
connect(static_cast<Stream*>(&u));
44+
}
45+
46+
private:
47+
Stream *uart;
48+
FILE *file;
49+
};
50+
51+
extern ArduinoSTL_STDIO ArduinoSTL_Serial;
52+
53+
#endif // ARDUINO_ARCH_AVR
54+
55+
#endif // ARDUINOSTL_M_H

0 commit comments

Comments
 (0)