Mock Serial.println() behavior

Hello,

Original nano, Arduino IDE 1.8.13, and Windows 7 computer used here.

Currently working through a PIC Application Note and adapting that to AVR/Arduino. Background, for the PIC program, there is a command interpreter function that allows the user to enter the specific program control data in an ASCII terminal. The main loop polls the USART interrupt flag to see if there is any incoming ASCII data, if there that is, once received, stored in the input buffer (inpbuf[ ]). A comma is used to delimit each command sequence and the function called to interpret the required response. The command interpreter finds which portion of the command is in the input buffer, by counting the number of delimiters, since the last received.

I foresee that this very literal interpretation, as of the stepping through and getting a handle on the PIC code, will most likely be changed once my understanding has improved on how best to adapt.

Nonetheless in the transfer testing process I was curious to see if it was possible to do a simple Serial.println(), which is as far as I can see is - return write("\r\n"); Easy to implement, I thought it looked straight forward enough, why not and added - const char ln[ ] = "\x0d\x0a"; //print line, to the little test program, thinking all is well. I don’t anticipate using this at all, and perhaps its use not as intended, however was curious that if it would behave similarly in AVR/Arduino.

What is happening is that a null is added, the exact print out of the test program from RealTerm is as below:

nulnulCRLF
AVR USART SERIAL TESTnulLFCR
READY>nulCRLF

nulCRLF
nul segnum: 2CRLF
firstseg: 12CRLF
lastseg: 13CRLF
parameter:4CRLFCRLF

nul segnum: 2CRLF
firstseg: 12CRLF
lastseg: 13CRLF
parameter:4CRLFCRLF

nul segnum: 2CRLF
firstseg: 12CRLF
lastseg: 13CRLF
parameter:4CRLFCRLF

I suspect this is misuse on my behalf, and something to do with the buffer or pointer, but really am too green at all this, to actually understand why the nulls are added. Test program follows, any ideas of why this behavior?

char inpbuf[8];
const char ready[] = "\n\rREADY>";
const char error[] = "\n\rERROR!";
const char ln[] = "\x0d\x0a"; // Print line 'Windows 7' <CRLF>

unsigned char
firstseg, // Test data
lastseg,
segnum,
parameter;


void setup() {
  // put your setup code here, to run once:
  UBRR0 = 103; // 9600 baud rate
  UCSR0B = (1 << RXEN0) + (1 << TXEN0); // Enable transmitter & reciever
  UCSR0C = (3 << UCSZ00); // 8 bits, 1 stop bit, no parity

  delay(1000);

  firstseg = 12; // Initialize test variables
  lastseg = 13;
  segnum = 2;
  parameter = 4;

  memset(inpbuf, 0, 8); // Clear the input buffer
  putrsUSART("\r\nAVR USART SERIAL TEST");
  putrsUSART(ready);
  putrsUSART(ln); // null?

}

void loop() {
  // put your main code here, to run repeatedly:
  delay(1000);

  putrsUSART(ln); // null?
  //Serial.println();

  // Print test data
  Serial.print(F("segnum: "));
  Serial.println(segnum);
  Serial.print(F("firstseg: "));
  Serial.println(firstseg);
  Serial.print(F("lastseg: "));
  Serial.println(lastseg);
  Serial.print(F("parameter: "));
  Serial.println(parameter);

}

//--------------------------------------------------------------------------------------------------
// putrsUSART()
//
// Puts a string of characters in program memory to the USART
// ADAPTED TO AVR 328p 2022/02/10 (Eeprom subroutines excluded here)
//--------------------------------------------------------------------------------------------------
void putrsUSART(const char *data)
{
  do
  {
    while (!(UCSR0A & (1 << UDRE0)));
    UDR0 = *data;
  }
  while (*data++);
}

Thanks in advance...

*(data++)

or

(*data)++

?

ln is null terminated. All char[] are null terminated. It looks like the purtsuUSART is treating it as three binary bytes, including the nukk.

The "putrsUSART()" function is sending null characters at the end of each string. I would change it to this to only send the contents of the string:

void putrsUSART(const char *data)
{
  while (*data)  // Until we reach the terminating NULL
  {
    // Wait for Data Register Empty
    while (!(UCSR0A & (1 << UDRE0)));
    // Put the character in the output buffer
    UDR0 = *data++;
  }
}
1 Like

Thank you all, yes that makes sense @johnwasser , that change did the trick! Glad for the advice.

Or maybe this would work (but the while (*data) form is much more common):

do
  {
    while (!(UCSR0A & (1 << UDRE0)));
    UDR0 = *data;
  }
  while (*++data);

[/quote]

Thank you @westfw , I had tried

 do
  {    
    while (!(UCSR0A & (1 << UDRE0)));   
    UDR0 = *data++;
  }
  while (*data);

Which also works, but don't know yet what is bad practice.

Not if the string is empty. It will send the null character at the start of the buffer and then send any non-null bytes until it finds the SECOND null.

This version has the same problem, just incrementing the pointer in a slightly different place. The "do/while" versions will send a byte, even if there are none to send.

Thank you @johnwasser .

By nature of the do/while loop, it will execute once, then check the condition/s.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.