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

Thread: Teensy USB-Serial Flow control

  1. #1
    Junior Member
    Join Date
    Jul 2018
    Posts
    12

    Teensy USB-Serial Flow control

    O.K. I have built a quick device to be able to drip feed CNC programs to my CNC machine. It has an old control and the floppy drive has broken with zero hope for repair. Enter: Teensy, since Teensy has a real UART and hardware serial, i figured it would make a great fit. For the most part it has done well, it is able to send data to the CNC and get it to start running. On the CNC, I enter "Tape mode", and just press start to start receiving a file. I have this working correctly with another computer that also has a hardware serial. The goal is to get rid of USB-Serial eventually and be able to dump programs from the SD card, replacing the floppy. So far I am able to start dumping the file to the CNC machine and it runs for a bit, but it (seems) like it gets hung up on flow control. Software flow control refuses to work, whereas, on the other test system, it doesn't seem to matter which type of flow control i set but it works. RTS/CTS is available on the CNC and I am aware that you are supposed to connect RTS on the Teensy to CTS on the CNC and Vice Versa. The first question I have is there any code that needs to be written to further implement RTS/CTS beyond the serial1.attachRts(pin) and serial1.attachCts(pin)?

    Code:
    /* USB to Serial - Teensy becomes a USB to Serial converter
       http://dorkbotpdx.org/blog/paul/teensy_as_benito_at_57600_baud
    
       You must select Serial from the "Tools > USB Type" menu
    
       This example code is in the public domain.
    */
    
    // set this to the hardware serial port you wish to use
    #define HWSERIAL Serial1
    
    unsigned long baud = 4800;
    const int reset_pin = 4;
    const int led_pin = 13;  // 13 = Teensy 3.X & LC
                             // 11 = Teensy 2.0
                             //  6 = Teensy++ 2.0
    const int rts_pin = 2;
    const int cts_pin = 18;
    
    void setup()
    {
      pinMode(led_pin, OUTPUT);
      digitalWrite(led_pin, LOW);
      digitalWrite(reset_pin, HIGH);
      pinMode(reset_pin, OUTPUT);
      // Next 4 lines debug Tx/Rx 
      //pinMode(0, OUTPUT);
      //digitalWrite(0, LOW); 
      //pinMode(1, OUTPUT);
      //pinMode(1, LOW);
      // Next four lines Debug RTS/CTS 
      //pinMode(rts_pin, OUTPUT);
      //digitalWrite(rts_pin, HIGH);
      //pinMode(cts_pin, OUTPUT);
      //digitalWrite(cts_pin, HIGH);
      //
      Serial.begin(baud);	// USB, communication to PC or Mac
      HWSERIAL.begin(baud, SERIAL_7E1);	// communication to hardware serial
      HWSERIAL.attachRts(rts_pin);
      HWSERIAL.attachCts(cts_pin);
    }
    
    long led_on_time=0;
    byte buffer[80];
    unsigned char prev_dtr = 0;
    
    void loop()
    {
      unsigned char dtr;
      int rd, wr, n;
    
      // check if any data has arrived on the USB virtual serial port
      rd = Serial.available();
      if (rd > 0) {
        // check if the hardware serial port is ready to transmit
        wr = HWSERIAL.availableForWrite();
        if (wr > 0) {
          // compute how much data to move, the smallest
          // of rd, wr and the buffer size
          if (rd > wr) rd = wr;
          if (rd > 80) rd = 80;
          // read data from the USB port
          n = Serial.readBytes((char *)buffer, rd);
          // write it to the hardware serial port
          HWSERIAL.write(buffer, n);
          // turn on the LED to indicate activity
          digitalWrite(led_pin, HIGH);
          led_on_time = millis();
        }
      }
    
      // check if any data has arrived on the hardware serial port
      rd = HWSERIAL.available();
      if (rd > 0) {
        // check if the USB virtual serial port is ready to transmit
        wr = Serial.availableForWrite();
        if (wr > 0) {
          // compute how much data to move, the smallest
          // of rd, wr and the buffer size
          if (rd > wr) rd = wr;
          if (rd > 80) rd = 80;
          // read data from the hardware serial port
          n = HWSERIAL.readBytes((char *)buffer, rd);
          // write it to the USB port
          Serial.write(buffer, n);
          // turn on the LED to indicate activity
          digitalWrite(led_pin, HIGH);
          led_on_time = millis();
        }
      }
    
      // check if the USB virtual serial port has raised DTR
      dtr = Serial.dtr();
      if (dtr && !prev_dtr) {
        digitalWrite(reset_pin, LOW);
        delayMicroseconds(250);
        digitalWrite(reset_pin, HIGH);
      }
      prev_dtr = dtr;
    
      // if the LED has been left on without more activity, turn it off
      if (millis() - led_on_time > 3) {
        digitalWrite(led_pin, LOW);
      }
    
      // check if the USB virtual serial wants a new baud rate
      if (Serial.baud() != baud) {
        baud = Serial.baud();
        if (baud == 57600) {
          // This ugly hack is necessary for talking
          // to the arduino bootloader, which actually
          // communicates at 58824 baud (+2.1% error).
          // Teensyduino will configure the UART for
          // the closest baud rate, which is 57143
          // baud (-0.8% error).  Serial communication
          // can tolerate about 2.5% error, so the
          // combined error is too large.  Simply
          // setting the baud rate to the same as
          // arduino's actual baud rate works.
          HWSERIAL.begin(58824);
        } else {
          HWSERIAL.begin(baud);
        }
      }
    }

  2. #2
    Junior Member
    Join Date
    Jul 2018
    Posts
    12
    Furthermore, today I was able to do some testing. So it seems RTS/CTS is working fine on this device I built because I was able to short RTS/CTS on the Teensy board I built and the Teensy device just kept streaming data (an indicator LED was also added) over serial1. Of course this is not the intended operation, as flow control is required to allow the (old) CNC to stay in sync with this newer technology. It seems that I am not getting a CTS signal from the CNC. The Teensy board is running off of the 5 volt supply on the CNC, so as to avoid any grounding issues. Hopefully I'm doing all of this correctly, from my other experience with Beaglebone, etc. When I put my Serial Software in CTS/RTS mode, it stops after just one line of code waiting for the RTS signal of the CNC to trigger the CTS signal of the Teensy board (cable is wired (CNC) RTS >> (Teensy) CTS and (Teensy) RTS >> (CNC) CTS). The indicator LED does not light up. So I suppose the next step is to check the CNC paramaters file and adjust, but also possibly make another indicator light for CTS signal on the CNC. Any input is appreciated... As well as any insight into the RTS/CTS handshake that I might be missing
    Click image for larger version. 

Name:	IMG_20180712_152840268.jpg 
Views:	23 
Size:	108.0 KB 
ID:	14188

  3. #3
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    18,511
    To check the Teensy side, you could just connect a switch or wire to the CTS input. When high, Teensy should send serial output normally. When you connect it low, Teensy should stop transmitting. If you connect a LED+resistor between the transmit output and 3.3V (looks like you probably already have this), it's easy to see when data is transmitting.

    As far as the old CNC equipment is concerned, can't really help much there. But one possibility to consider is it may simply be able to keep up with the baud rate and data stream you're transmitting. In that case, you'd expect it to keet the CTS signal high all the time.

  4. #4
    Junior Member
    Join Date
    Jul 2018
    Posts
    12
    Sorry for the long delay, I was working on several other projects. But anyhow, I was able to create a cable tester (Breakout jumper box style) AND also made a new cable. I was also able to find the parameters for the CNC machine in question. I tried turning on CTS/RTS, but checked the pins and there is no high signal (apparently 3.3v on this machine) when CTS/RTS handshaking is used (on a known working test bed machine that works for this purpose, but only with software flow control). A couple other issues with the machine is that it only has an 8 byte buffer, which should probably be matched and then an XON/XOFF signal sent and received. Are there any libraries that deal with these functions(it looks like changing buffer byte size is trivial)? or should it be hardcoded with an if statement and a couple variables pointing to a hex value? and the else going back to the beginning?

Posting Permissions

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