diff --git a/examples/SX127x_RTTY_Transmit/SX127x_RTTY_Transmit.ino b/examples/SX127x_RTTY_Transmit/SX127x_RTTY_Transmit.ino index 8312fb74..272c3bae 100644 --- a/examples/SX127x_RTTY_Transmit/SX127x_RTTY_Transmit.ino +++ b/examples/SX127x_RTTY_Transmit/SX127x_RTTY_Transmit.ino @@ -27,14 +27,12 @@ void setup() { // initialize SX1278 Serial.print("[SX1278] Initializing ... "); // carrier frequency: 434.4 MHz - // bandwidth: 125.0 kHz - // spreading factor: 9 - // coding rate: 7 - // sync word: 0x12 - // output power: 17 dBm + // bit rate: 48.0 kbps + // frequency deviation: 50.0 kHz + // Rx bandwidth: 125.0 kHz + // output power: 13 dBm // current limit: 100 mA - // preamble length: 8 symbols - // amplifier gain: 0 (automatic gain control) + // sync word: 0x2D 0x01 int state = fsk.beginFSK(434.4); if(state == ERR_NONE) { Serial.println("success!"); @@ -62,17 +60,41 @@ void setup() { } void loop() { + Serial.println("Sending RTTY data ... "); + // send 500 ms high frequency beep rtty.leadIn(500); // RTTYClient supports all methods of the Serial class - // send the string "Hello World!", followed by - // carriage return and line feed chracters - rtty.println("Hello World!"); + String aStr = "Arduino String"; + rtty.print(aStr); + rtty.println(aStr); + + const char cStr[] = "C-string"; + rtty.print(cStr); + rtty.println(cStr); + + char c = 'c'; + rtty.print(c); + rtty.println(c); + + byte b = 0xAA; + rtty.print(b, HEX); + rtty.println(b, HEX); + + int i = 1000; + rtty.print(i); + rtty.println(i); + + float f = 3.1415; + rtty.print(f, 3); + rtty.println(f, 3); // turn transmitter off fsk.standby(); + Serial.println("done!"); + // wait for a second before transmitting again delay(1000); } diff --git a/src/protocols/RTTY.cpp b/src/protocols/RTTY.cpp index 14457a1c..0b90598e 100644 --- a/src/protocols/RTTY.cpp +++ b/src/protocols/RTTY.cpp @@ -35,30 +35,24 @@ void RTTYClient::leadIn(uint16_t length) { delay(length); } -size_t RTTYClient::print(const String& str) { - return(RTTYClient::print(str.c_str())); -} - -size_t RTTYClient::print(const char* str) { - size_t len = 0; - for(size_t i = 0; i < strlen(str); i++) { - len += write(str[i]); +size_t RTTYClient::write(const char* str) { + if(str == NULL) { + return(0); } - return(len); + return(RTTYClient::write((uint8_t *)str, strlen(str))); } -size_t RTTYClient::println(const String& str) { - return(RTTYClient::println(str.c_str())); -} - -size_t RTTYClient::println(const char* str) { - size_t len = print(str); - len += write('\r'); - len += write('\n'); - return(len); +size_t RTTYClient::write(uint8_t* buff, size_t len) { + size_t n = 0; + for(size_t i = 0; i < len; i++) { + n += write(buff[i]); + } + return(n); } size_t RTTYClient::write(uint8_t b) { + Serial.write(b); + space(); for(uint8_t mask = 0x01; mask; mask <<= 1) { @@ -76,6 +70,115 @@ size_t RTTYClient::write(uint8_t b) { return(1); } +size_t RTTYClient::print(const String& str) { + return(RTTYClient::write(str.c_str(), str.length())); +} + +size_t RTTYClient::print(const char str[]) { + return(RTTYClient::write(str, strlen(str))); +} + +size_t RTTYClient::print(char c) { + return(RTTYClient::write(c)); +} + +size_t RTTYClient::print(unsigned char b, int base) { + return(RTTYClient::print((unsigned long)b, base)); +} + +size_t RTTYClient::print(int n, int base) { + return(RTTYClient::print((long)n, base)); +} + +size_t RTTYClient::print(unsigned int n, int base) { + return(RTTYClient::print((unsigned long)n, base)); +} + +size_t RTTYClient::print(long n, int base) { + if(base == 0) { + return(RTTYClient::write(n)); + } else if(base == DEC) { + if (n < 0) { + int t = RTTYClient::print('-'); + n = -n; + return(RTTYClient::printNumber(n, DEC) + t); + } + return(RTTYClient::printNumber(n, DEC)); + } else { + return(RTTYClient::printNumber(n, base)); + } +} + +size_t RTTYClient::print(unsigned long n, int base) { + if(base == 0) { + return(RTTYClient::write(n)); + } else { + return(RTTYClient::printNumber(n, base)); + } +} + +size_t RTTYClient::print(double n, int digits) { + return(RTTYClient::printFloat(n, digits)); +} + +size_t RTTYClient::println(void) { + return(RTTYClient::write("\r\n")); +} + +size_t RTTYClient::println(const String& str) { + size_t n = RTTYClient::print(str); + n += RTTYClient::println(); + return(n); +} + +size_t RTTYClient::println(const char* str) { + size_t n = RTTYClient::print(str); + n += RTTYClient::println(); + return(n); +} + +size_t RTTYClient::println(char c) { + size_t n = RTTYClient::print(c); + n += RTTYClient::println(); + return(n); +} + +size_t RTTYClient::println(unsigned char b, int base) { + size_t n = RTTYClient::print(b, base); + n += RTTYClient::println(); + return(n); +} + +size_t RTTYClient::println(int num, int base) { + size_t n = RTTYClient::print(num, base); + n += RTTYClient::println(); + return(n); +} + +size_t RTTYClient::println(unsigned int num, int base) { + size_t n = RTTYClient::print(num, base); + n += RTTYClient::println(); + return(n); +} + +size_t RTTYClient::println(long num, int base) { + size_t n = RTTYClient::print(num, base); + n += RTTYClient::println(); + return(n); +} + +size_t RTTYClient::println(unsigned long num, int base) { + size_t n = RTTYClient::print(num, base); + n += RTTYClient::println(); + return(n); +} + +size_t RTTYClient::println(double d, int digits) { + size_t n = RTTYClient::print(d, digits); + n += RTTYClient::println(); + return(n); +} + void RTTYClient::mark() { uint32_t start = micros(); _phy->directMode(_base + _shift); @@ -87,3 +190,65 @@ void RTTYClient::space() { _phy->directMode(_base); while(micros() - start < _bitDuration); } + +size_t RTTYClient::printNumber(unsigned long n, uint8_t base) { + char buf[8 * sizeof(long) + 1]; + char *str = &buf[sizeof(buf) - 1]; + + *str = '\0'; + + if(base < 2) { + base = 10; + } + + do { + char c = n % base; + n /= base; + + *--str = c < 10 ? c + '0' : c + 'A' - 10; + } while(n); + + return(RTTYClient::write(str)); +} + +size_t RTTYClient::printFloat(double number, uint8_t digits) { + size_t n = 0; + + if (isnan(number)) return RTTYClient::print("nan"); + if (isinf(number)) return RTTYClient::print("inf"); + if (number > 4294967040.0) return RTTYClient::print("ovf"); // constant determined empirically + if (number <-4294967040.0) return RTTYClient::print("ovf"); // constant determined empirically + + // Handle negative numbers + if (number < 0.0) { + n += RTTYClient::print('-'); + number = -number; + } + + // Round correctly so that print(1.999, 2) prints as "2.00" + double rounding = 0.5; + for(uint8_t i = 0; i < digits; ++i) { + rounding /= 10.0; + } + number += rounding; + + // Extract the integer part of the number and print it + unsigned long int_part = (unsigned long)number; + double remainder = number - (double)int_part; + n += RTTYClient::print(int_part); + + // Print the decimal point, but only if there are digits beyond + if(digits > 0) { + n += RTTYClient::print('.'); + } + + // Extract digits from the remainder one at a time + while(digits-- > 0) { + remainder *= 10.0; + unsigned int toPrint = (unsigned int)(remainder); + n += RTTYClient::print(toPrint); + remainder -= toPrint; + } + + return n; +} diff --git a/src/protocols/RTTY.h b/src/protocols/RTTY.h index 89c390b2..dd5b575c 100644 --- a/src/protocols/RTTY.h +++ b/src/protocols/RTTY.h @@ -11,6 +11,8 @@ class RTTYClient { // basic methods int16_t begin(float base, uint16_t shift, uint16_t rate, uint8_t dataBits = 8, uint8_t stopBits = 1); void leadIn(uint16_t length); + size_t write(const char* str); + size_t write(uint8_t* buff, size_t len); size_t write(uint8_t b); size_t print(const String &); @@ -22,7 +24,8 @@ class RTTYClient { size_t print(long, int = DEC); size_t print(unsigned long, int = DEC); size_t print(double, int = 2); - + + size_t println(void); size_t println(const String &s); size_t println(const char[]); size_t println(char); @@ -44,6 +47,9 @@ class RTTYClient { void mark(); void space(); + + size_t printNumber(unsigned long, uint8_t); + size_t printFloat(double, uint8_t); }; #endif