Serial.read() not working when printing

Status
Not open for further replies.

hillerup

Member
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:
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...
 
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.
 
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:
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
 
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
 
Status
Not open for further replies.
Back
Top