Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 17 of 17

Thread: Serial communication: Teensy 3.2 received junk from Digispark clone (ATtiny85)

  1. #1

    Serial communication: Teensy 3.2 received junk from Digispark clone (ATtiny85)

    I want a Digispark clone (ATtiny85) to send data to a Teensy 3.2. On the Digispark, I use the SoftSerial library. On the Teensy, I use one of the hardware serial interfaces. The problem is that the Teensy outputs:

    Code:
    DD�D�D�D�D�D�ÔÔD�DÔÔÔÔÔD�ÔÔDD�D�D�ÔD�DÔÔ…
    Expected is:
    Code:
    Hi!Hi!Hi!Hi!Hi!Hi!Hi!Hi!Hi!Hi!Hi!…
    This looks like a timing problem to me, especially considering the randomness. But how do I resolve it?

    What I already tried is playing with the communication speed. At 9600, 4800, 2400, and 1200 baud I got the above garbage. At 300 baud there was nothing received at all.

    sender.ino compiled and uploaded with Digispark (16 Mhz - No USB) selected in the Arduino IDE:
    Code:
    #include <SoftSerial.h>
    #include <TinyPinChange.h>
    
    const uint8_t ledPin = 1;
    const uint8_t rxPin = 0;
    const uint8_t txPin = 2;
    
    SoftSerial mySerial(rxPin, txPin); // RX, TX
    
    void setup() {
      mySerial.begin(4800);
      mySerial.txMode();
      pinMode(ledPin, OUTPUT);
    }
    
    void flashLed() {
      digitalWrite(ledPin, HIGH);
      delay(100);
      digitalWrite(ledPin, LOW);
    }
    
    void loop() {
      mySerial.write("Hi!");
      flashLed();
      delay(1000);
    }
    received.ino, compiled and uploaded to the Teensy 3.2:

    Code:
    const uint8_t ledPin = 13;
    
    void setup() {
      Serial.begin(9600);
      Serial1.begin(4800);
      pinMode(ledPin, OUTPUT);
      digitalWrite(ledPin, HIGH);
    }
    
    void flashLed() {
      digitalWrite(ledPin, HIGH);
      delay(100);
      digitalWrite(ledPin, LOW);
    }
    
    void loop() {
      char c;
    
      if (Serial1.available()) {
        c = Serial1.read();
        Serial.print(c);
        flashLed();
      }
    }
    Circuit:
    Click image for larger version. 

Name:	serial-circuit.jpg 
Views:	120 
Size:	351.3 KB 
ID:	12843

    (Next step is using half-duplex communication, to get rid of one wire.)

  2. #2
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,832
    are your usb cables going to same pc? because i dont see any common grounds between both mcus..

  3. #3
    Quote Originally Posted by tonton81 View Post
    are your usb cables going to same pc? because i dont see any common grounds between both mcus..
    Both were connected to the same USB hub. Anyhow, I added common ground on the breadboard as well, but the issue persists:

    Click image for larger version. 

Name:	common-ground-serial-circuit.jpg 
Views:	122 
Size:	155.3 KB 
ID:	12845

    I forgot to mention: When the Teensy receives “Hi!” from the Digispark, then the Teensy’s LED only flashes once. When I use another Digispark as a receiver, then the LED of that flashes once per character received.

  4. #4
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,600
    On both sides, you use Serialx.begin(Baudrate) without specifying more serial protocol details. On the Teensy, it defaults to 8N1. Perhaps on the other little thing, it defaults to a different number of total bits, start bits, stop bits, and so on...

    BTW: SoftSerial does simple and cheap bit banging on GPIO pins. This is a no-no for serious developers because each interrupt or other unexpected delay in program execution risks to trouble the timing. Today's modern MCUs have mostly more than one hardware UART, thus, there shouldn't be any reason to use older stuff without.

  5. #5
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,600
    To understand what happens in your specific case, simply take your oscilloscope or logic analyzer to show the bit pattern and timing sent by the Digispark

  6. #6
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    24,485
    I don't have a Digispark, but I do have Arduino Uno. So I tried to set up this test using Uno.

    Click image for larger version. 

Name:	DSC_0980_web.jpg 
Views:	78 
Size:	167.1 KB 
ID:	12848

    Here's the result I see from Teensy in the Arduino Serial Monitor.

    Click image for larger version. 

Name:	sc.png 
Views:	89 
Size:	20.5 KB 
ID:	12847

    I ran the exact same code you posted on Teensy.

    For Arduino Uno, I had to adapt your code slightly. Seems on Digispark the library is SoftSerial versus SoftwareSerial. I also had to change to pin 3 for transmit and 13 for the LED, since Uno reserves pins 0 & 1 for its serial port. Here's the exact code I ran on Uno for this test.

    Code:
    #include <SoftwareSerial.h>
    
    const uint8_t ledPin = 13;
    const uint8_t rxPin = 3;
    const uint8_t txPin = 2;
    
    SoftwareSerial mySerial(rxPin, txPin); // RX, TX
    
    void setup() {
      mySerial.begin(4800);
      pinMode(ledPin, OUTPUT);
    }
    
    void flashLed() {
      digitalWrite(ledPin, HIGH);
      delay(100);
      digitalWrite(ledPin, LOW);
    }
    
    void loop() {
      mySerial.write("Hi!");
      flashLed();
      delay(1000);
    }

  7. #7
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    24,485
    Quote Originally Posted by feklee View Post
    I forgot to mention: When the Teensy receives “Hi!” from the Digispark, then the Teensy’s LED only flashes once.
    I was able to reproduce this problem. It's caused by lack of any delay when turning the LED off. What you're seeing is 3 "blinks" which run together, visually appearing to be 1 longer blink.

    You can solve this problem by changing this:

    Code:
    void flashLed() {
      digitalWrite(ledPin, HIGH);
      delay(100);
      digitalWrite(ledPin, LOW);
    }
    to this:

    Code:
    void flashLed() {
      digitalWrite(ledPin, HIGH);
      delay(50);
      digitalWrite(ledPin, LOW);
      delay(50);
    }
    I uploaded the code to Teensy with this change and I can confirm I'm seeing 3 blinks.

  8. #8
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    24,485
    One more quick thing, this is indeed a known problem.

    Quote Originally Posted by feklee View Post
    At 300 baud there was nothing received at all.
    300 baud does not work on Teensy 3.2, unless you slow the clock to only 24 MHz in Tools > CPU Speed. When running at 96 MHz, the serial port just can't do baud rates that slow.

    1200 and faster work fine.

    Detailed documentation here:

    https://www.pjrc.com/teensy/td_uart.html

    If you *really* need 300 baud on Teensy 3.2, you can get it with AltSoftSerial.

  9. #9
    Thanks for all the help! In particular thanks to @PaulStoffregen for trying to reproduce the issue using an Arduino Uno, for debugging my code, and for explaining 300 baud support!

    Finally, I got the circuit to work. The board that I used as sender was broken. Replacing it solved the issue.

    (This is a typical beginner issue. I was assuming that I was doing something wrong. 8N1 serial communication is pretty much voodoo to me. Only after realizing that communication between the Digispark clones also doesn’t work, I tried replacing one. See also my topic SoftSerial does not work (with clones) in the Digistump forums.)

    Quote Originally Posted by Theremingenieur View Post
    On both sides, you use Serialx.begin(Baudrate) without specifying more serial protocol details. On the Teensy, it defaults to 8N1.
    Quote from Softserial.h: <SoftSerial> library is exactly the same as the <SoftwareSerial> library but used with the <TinyPinChange> library which allows to share the Pin Change Interrupt Vector.

    And the SoftwareSerial library does use 8N1.

    Today's modern MCUs have mostly more than one hardware UART, thus, there shouldn't be any reason to use older stuff without.
    Suggestions are welcome! Requirements:
    • dirt cheap, as I need a couple dozen boards
    • four serial channels that support half-duplex communication


    This is for an experimental construction kit, where I want to have one microcontroller in each node: Github repo (not much there yet)

  10. #10
    I’m back at receiving junk on the Teensy. But this time, I think it’s my code. I added another ATtiny85 as a relay:

    Click image for larger version. 

Name:	relay-circuit.jpg 
Views:	132 
Size:	149.5 KB 
ID:	12883

    Every time the relay receives a character from the sender, it sends it right away to the Teensy:

    Code:
    void loop() {
      if (receiveSerial.available()) {
        char c = receiveSerial.read();
        sendSerial.write(c);
        flashLed();
        delay(100);
      }
    }
    This seems to be a bad idea. If I have each ATtiny85 communicate directly with the Teensy, then communication is clean.

    BTW I looked for boards with four UART, but they all seem to be rather expensive. Price limit is around 10 USD. Also, the boards should be not much larger than a Teensy, better smaller.

    Full code on the relay:

    Code:
    #include <SoftSerial.h>
    #include <TinyPinChange.h>
    
    const uint8_t ledPin = 1;
    const uint8_t receivePin = 4;
    const uint8_t sendPin = 0;
    
    SoftSerial receiveSerial(receivePin, receivePin);
    SoftSerial sendSerial(sendPin, sendPin);
    
    void setup() {
      receiveSerial.begin(4800);
      receiveSerial.rxMode();
      sendSerial.begin(4800);
      sendSerial.txMode();
      receiveSerial.listen();
      pinMode(ledPin, OUTPUT);
    }
    
    void flashLed() {
      digitalWrite(ledPin, HIGH);
      delay(100);
      digitalWrite(ledPin, LOW);
    }
    
    void loop() {
      if (receiveSerial.available()) {
        char c = receiveSerial.read();
        sendSerial.write(c);
        flashLed();
        delay(100);
      }
    }

  11. #11
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    9,219
    You can get a Teensy LC for $11.29 https://store.oshpark.com/products/teensy-lc

    There are probably lots of other options (personally I like Teensy...), but for example you can get a Robotis Open CM904A chip $9.95 (http://www.robotis.us/opencm9-04-a-n...ctors-onboard/) which is bigger and has 3 USARTS... Adafruit Feather M0 again larger and more expensive than Teensy LC...

    With your code, I wonder how well SoftwareSerial works at 4800 baud on those boards...

    Again with that code, personally I would change a few things, but again may not mater.
    Code:
    #include <SoftSerial.h>
    #include <TinyPinChange.h>
    
    const uint8_t ledPin = 1;
    const uint8_t receivePin = 4;
    const uint8_t sendPin = 0;
    
    SoftSerial receiveSerial(receivePin, receivePin);
    SoftSerial sendSerial(sendPin, sendPin);
    
    void setup() {
      receiveSerial.begin(4800);
      receiveSerial.rxMode();
      sendSerial.begin(4800);
      sendSerial.txMode();
      receiveSerial.listen();
      pinMode(ledPin, OUTPUT);
    }
    
    void flashLed() {
      digitalWrite(ledPin, HIGH);
      delay(50);
      digitalWrite(ledPin, LOW);
      delay(50);
    }
    
    void loop() {
      if (receiveSerial.available()) {
        while (receiveSerial.available()) {
          char c = receiveSerial.read();
          sendSerial.write(c);
        }
        flashLed();
      }
      delay(100);
    }
    Changed the Flashled as to change the delays, as if you called it a few times in a row it would not show the low state as no delay between low and high.
    And in loop, I transmit everything pending before sleeping.

    Not sure if maybe your software serial is getting corrupted ...

  12. #12
    Quote Originally Posted by KurtE View Post
    3 USARTS...
    Thanks for all your suggestions! In fact I’ve a Teensy LC here. Unfortunately, three UARTs is one too few.

    In the meantime, I’ve read that some boards allow reconfiguring UART pinout. The ESP32 is an example: #152 Quickie: Additional ESP32 Serial Channels in Arduino IDE (Youtube)

    I wonder if there is any board where UART pinout can be reconfigured while a sketch is running. Because, that would be a good solution. While I need four UARTs, the UARTs don’t need to communicate simultaneously. It is fine for them to communicate one after another, in well defined discrete time-slots.

    In fact avoiding doing too much simultaneously also solves the issue that I had with the relay. Now data is relayed only after a full package has been received. Between sending packages Hi\n, the sender pauses for a second. Excerpt from relay.ino:

    Code:
    void loop() {
      if (receiveSerial.available()) {
        char c = receiveSerial.read();
        appendToBuffer(c);
        if (c == '\n') { // end of package received?
          flushBuffer();
          flashLed();
        }
      }
    }
    Find the full code in commit 21ed3151d32b26e0f52df1072b63f64c473c6224 in my GitHub repo feklee/san.

    For a start, SoftSerial could be a solution. Speed likely is an issue, though. 4800 baud is slow to have fun.

  13. #13
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    9,219
    Sounds like a reasonable solution.

    I thought about suggesting something like that as well as to try to minimize other interrupts during the software serial processing.

    As for re-configuring Serial ports while sketch is running, I believe you can do that with most Teensy 3.x/LC boards.

    Example Serial1 defaults to pins 0 and 1 for RX/TX, but you could also use pins 3 and 4(or 5)...

    Not sure how well this would work with your hardware, but I believe it is possible to do things like:
    Code:
        Serial1.begin(...)
        Serial1.setTX(1);
        Serial1.setRX(0);
        // Right now Serial 1 is talking on pins 0 and 1
        ... 
        Serial1.setTX(5);
        Serial1.setRX(3);
        // Now Serial 1 is talking on pins 3 and 5
        ...
    But doing these calls leave the previous pins in default unused (floating?) state... Might not be an issue, but might be... If a problem, may be solvable by using a Pull up or down resistor... Maybe more problem than it is worth...

  14. #14
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,832
    I set the old pins as INPUT_DISABLE and change the RX/TX pin dynamically without calling begin(unless i need to change baud rate too) then begin could be used. the auto ESP flasher i wrote does this. If you plan to not have the old pins floating, for uart, you may assign them (at least on teensy) as INPUT_PULLUP or INPUT_PULLDOWN, both work well for uart during my testing

  15. #15
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    9,219
    The setTX and setRX calls set the previous pins to config 0... like: CORE_PIN1_CONFIG = 0;
    Which is INPUT_DISABLE...

  16. #16
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,832
    good to know, yay redundancy

  17. #17
    Quote Originally Posted by KurtE View Post
    Serial1.setTX(1); […] Serial1.setTX(5); […]
    Very attractive, thanks!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •