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

Thread: Serial.read() not working when printing

  1. #1
    Junior Member
    Join Date
    Jun 2020
    Posts
    11

    Serial.read() not working when printing

    Hello,
    I'm using the Teensy 3.6 with PC (windows) as communication over Serial at baud 9600

    I'm having trouble with Serial.read, I'm trying to provide an input through Serial but at the same time using serial.print, I guess you can't do both things at the same time and this is why it doesn't go as expected (it does not get the input from serial). I have entered the code I use below.

    Code:
    char string[4]        = {0, 0, 0, 0};
    float Serial_input[4] = {0, 0, 0, 0};
    int val               = 0;
    volatile int cycles;
    
    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      Serial.setTimeout(1);
      ARM_DEMCR |= ARM_DEMCR_TRCENA;
      ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
    }
    
    void loop() {
      uint32_t startCycleCPU;
      startCycleCPU = ARM_DWT_CYCCNT;
    
      if (Serial.available() > 0) {
        for (int i = 0; i < 4; i++) {
          string[i] = Serial.read();
        }
        int temp100 = ((int)string[1] - 48) * 100;
        int temp10 = ((int)string[2] - 48) * 10;
        int temp1 = (int)string[3] - 48;
        val = temp100 + temp10 + temp1;
    
        switch (string[0]) {
          case 'L':
            Serial_input[0] = val;
            Serial.println("im here - Left");
            break;
          case 'R':
            Serial_input[1] = val;
            Serial.println("im here - Right");
            break;
          case 'F':
            Serial_input[2] = val;
            Serial.println("im here - Front");
            break;
          case 'B':
            Serial_input[3] = val;
            Serial.println("im here - Back");
            break;
    
    
            cycles = (ARM_DWT_CYCCNT - startCycleCPU);
            while (cycles < 360000) { // 360000 = 2 milli sec @ 180Mhz
              cycles = (ARM_DWT_CYCCNT - startCycleCPU);
              Serial.print(millis());
              Serial.print(",");
              Serial.print("somePrint");
              Serial.print(",");
              Serial.print("somePrint");
              Serial.print(",");
              Serial.print("somePrint");
    
            }
        }
      }
    }
    Last edited by hillerup; 06-20-2020 at 03:08 PM. Reason: code edit

  2. #2
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,959
    Yes you can do Serial inputs as well as serial outputs.

    Note: 9600 means nothing here as you simply run at USB speed...

    Also looking at your code it is hard to know exactly what is going on, as it is not complete. Maybe just missing two }s at end? Or somewhere else?

    Also I don't often use the ARM registers like this, so not sure how well you have all of that initialized and if that works.

    Also not sure about code like:
    Code:
    cycles = (ARM_DWT_CYCCNT - startCycleCPU);
        while (cycles < 360000) { // 360000 = 2 milli sec @ 180Mhz
          cycles = (ARM_DWT_CYCCNT - startCycleCPU);
          Serial.print(millis());
    
        }
    When cycles is declared as an int... So not sure what happens when ARM_DWT_CYCCNT wraps around... Again I have used C/C++ for decades, but at times I am not fully sure of when it converts an operation like the subtraction of two unsigned values to then assign to signed value... So I usually do casting just to be safe... (Or use signed or unsigned)... In this case I would use unsigned as the math handles wrap around.

    Other note: the Serial.setTimeout(1);
    I believe does nothing, unless you call one of the Stream timed read functions, like: readBytes...

  3. #3
    Junior Member
    Join Date
    Jun 2020
    Posts
    11
    Hello KurtE,
    thanks for your reply,
    You are right! sorry there was missing a }} at the end. It should be fixed in the posted code now. The ARM register is just keeping the loop at 2ms, this is no problem, it can also be removed, it will still not work, and im not sure why. The timeout in serial.read should be 1000 when nothing is done so far i can read.

  4. #4
    Member
    Join Date
    Apr 2020
    Location
    DFW area in Texas
    Posts
    98
    Quote Originally Posted by hillerup View Post
    Hello,
    I'm using the Teensy 3.6 with PC (windows) as communication over Serial at baud 9600

    I'm having trouble with Serial.read, I'm trying to provide an input through Serial but at the same time using serial.print, I guess you can't do both things at the same time and this is why it doesn't go as expected (it does not get the input from serial). I have entered the code I use below ("SomeStuff" is just something random to print).
    hillerup:

    You should certainly be able to read from serial & print to serial in the same program . . . I have used this successfully in a number of Teensy sketches. I do not specifically have a Teensy 3.6 (I use T4s & T4.1s), but I took a quick look at your code. Not sure if it's just a cut & paste problem, but several closing braces seem to be missing.

    I took liberties in assuming what you intended in the following (slightly modified) code:

    Code:
    char string[4]        = {0, 0, 0, 0};
    float Serial_input[4] = {0, 0, 0, 0};
    int val               = 0;
    volatile int cycles;
    
    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      Serial.setTimeout(1);
      ARM_DEMCR |= ARM_DEMCR_TRCENA;
      ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
    }
    
    void loop() {
      uint32_t startCycleCPU;
    
      if (Serial.available() > 0) {
        for (int i = 0; i < 4; i++) {
          string[i] = Serial.read();
        }
        int temp100 = ((int)string[1] - 48) * 100;
        int temp10 = ((int)string[2] - 48) * 10;
        int temp1 = (int)string[3] - 48;
        val = temp100 + temp10 + temp1;
    
        switch (string[0]) {
          case 'L':
            Serial_input[0] = val;
            Serial.println("im here - Left");
    //        delay(1000);
            break;
          case 'R':
            Serial_input[1] = val;
            Serial.println("im here - Right");
    //        delay(1000);
            break;
          case 'F':
            Serial_input[2] = val;
            Serial.println("im here - Front");
    //        delay(1000);
            break;
          case 'B':
            Serial_input[3] = val;
            Serial.println("im here - Back");
    //        delay(1000);
            break;
          default:
            Serial.print("default - read: '");
            Serial.print(string[0]);
            Serial.println("'");
    //        delay(1000);
            break;
        }
    
        startCycleCPU = ARM_DWT_CYCCNT;
        cycles = (ARM_DWT_CYCCNT - startCycleCPU);
        while (cycles < 360000) { // 360000 = 2 milli sec @ 180Mhz
          cycles = (ARM_DWT_CYCCNT - startCycleCPU);
          Serial.println(millis());
    
        }
      }
    }
    Notes:

    - I assumed that you intended the cycle printing loop to be outside the switch statement (I added one of the "missing" closing braces to the end of the switch statement)
    - I moved the "startCycleCPU = ARM_DWT_CYCCNT;" statement to just before the start of your cycle printing loop so it is not hindered by any delay() statements added (currently commented out in each case of the switch) from the time it is set to the time it is used
    - if you uncomment the delay(1000) statements, you'll see that your "im here..." statements are printing in the serial monitor as expected
    - even without uncommenting the delay(1000) statements, if you scroll back in the serial monitor, you should still see your "im here..." statements printed
    - I added a default case to the switch statement so you can see what was detected as you type different characters

    Hope this helps, hope I properly interpreted your intent, & feel free to continue this discussion if/as needed.

    Good luck & have fun !!

    Mark J Culross
    KD5RXT

    EDIT: I see that KurtE posted while I was composing . . . sorry for the double-up !! MJC
    Last edited by kd5rxt-mark; 06-20-2020 at 03:12 PM. Reason: delayed post !!

  5. #5
    Junior Member
    Join Date
    Jun 2020
    Posts
    11
    Hello Mark,
    Thank you for the reply,
    yes sorry there was a copy past problem.
    The solution was not exactly the one you gave and "startCycleCPU = ARM_DWT_CYCCNT;" needs to be in the beginning of the loop to be used as a timer for the total loop time,
    however the code you posted led me on the track to my error deeper into the code and i have solved my problem, so thank you so much

  6. #6
    Member
    Join Date
    Apr 2020
    Location
    DFW area in Texas
    Posts
    98
    Quote Originally Posted by hillerup View Post
    Hello Mark,
    Thank you for the reply,
    yes sorry there was a copy past problem.
    The solution was not exactly the one you gave and "startCycleCPU = ARM_DWT_CYCCNT;" needs to be in the beginning of the loop to be used as a timer for the total loop time,
    however the code you posted led me on the track to my error deeper into the code and i have solved my problem, so thank you so much
    hillerup:

    You are welcome . . . glad to help (directly or otherwise) !!

    Mark J Culross
    KD5RXT

Posting Permissions

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