Parsing a String

Hello everyone,

What program should do:
Receive a string on a USB from an external serial monitor program (I’m using Brays terminal) and if the string received is “output:1” or “output:0” it should send a message back to the terminal program saying “YES” or “NO”. Everytime a character is received it is stored into a buffer. When a character is received a “flag” is set which is being polled in loop().

When this flag is set I use “strstr” to look for the command in the buffer as well as if a 0 or 1 was written.

What program is doing:
I make an LED turn on in the main loop just so I could see if it enters or not. It turns on so I know the code enters into that if-statement. I am not seeing anything being written back to the terminal. I can’t use the Serial library with arduino since the hardware serial is being used from this third-party terminal. I have tried puts, printf, and puts_P but can’t see anything. I thought that hardware serial would be the stdout for arduino…but I guess not?

Insights into printing to a third-party serial monitor would be greatly appreciated. I can’t use the arduino Serial either.

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#define USART_BAUDRATE 9600
#define UBBR_VALUE (((F_CPU / (USART_BAUDRATE * 16UL))) -1)
#define BUF_SIZE 20

#define FRAMING_ERROR (1<<FE0)
#define PARITY_ERROR (1<<UPE0)
#define DATA_OVERRUN (1<<DOR0)

// Variables needed for storing serial data
byte rx_buffer_overflow; // Set when USART receiver buffer overflowed 
unsigned char my_variable; // Variable used to receive data from USART 
const char command[] = "output:"; // Command located in FLASH memory
const char answer1[] = "YES\n\r"; // Answer located in FLASH
const char answer0[] = "NO\n\r"; // Answer located in FLASH

#define RX_BUFFER_SIZE 20 
char rx_buffer[RX_BUFFER_SIZE];
unsigned char rx_wr_index, rx_rd_index,rx_counter;

unsigned char character_received = 0;

void setup()
{

      // Initialize UART
      UBRR0H = (uint8_t)(UBBR_VALUE >> 8); // Setting baud rate
      UBRR0L = (uint8_t)UBBR_VALUE;           // Setting baud rate
      UCSR0C |= (1<<UCSZ01)|(1<<UCSZ00);   // Setup framing
      UCSR0B |= (1<<RXEN0)|(1<<RXCIE0);    // Enable receiver and RX interrupt
      UCSR0B |= (1<<TXEN0);                       // Enable transmitter
      // LED for test 
      pinMode(13, OUTPUT);
      
      // Enable global interrupts 
      sei();
}

void loop()
{
    if (character_received == 1)
    {
        digitalWrite(13, HIGH);
        character_received = 0; 
        if (strstr(rx_buffer, command))
        {
            if (*(strstr(rx_buffer,command)+strlen(command)) == '1')
            {
                printf(answer1);
                puts(answer1);
                puts_P(answer1);
                
                clear_buffer();
            }
            if (*(strstr(rx_buffer,command)+strlen(command)) == '0')
            {
                puts(answer0);
                clear_buffer();
            }
        }
    }
    
}

ISR(USART_RX_vect) 
{
    char status;
    char data;
    status=UCSR0A;
    data=UDR0;
    if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN)) == 0)
    {
        character_received=1;//enables parsing only if something is received
        rx_buffer[rx_wr_index]=data;
        if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
        if (++rx_counter == RX_BUFFER_SIZE)
        {
            rx_counter=0;
            rx_buffer_overflow=1;
        };
    };
}

If you want to log output, you’ll have to use Serial.print() and Serial.println() as there’s no terminal emulator for printf() to access STDOUT via.

If you’re using an Arduino Mega, you can use Serial1.println(), Serial2.println(), and Serial3.println() as it has 4 separate Serial ports.

Why can't you use Arduino Serial? Aren't you using the same hardware that it would use anyway?

Pete

Why can’t you use Arduino Serial? Aren’t you using the same hardware that it would use anyway?

Pete

I might be able to . I am developing this board to interface with a tablet which will send commands to it. I feel that if I use Arduino Serial it doesn’t emulate what the end-product will actually be. I feel like if I develop not using the Arduino Serial it will make my life easier later in the project. I also want to stay away as much as I can from Arduino libraries and focus on the processor on the board and its registers. This way I can develop a PCB later on with the processor and just burn the code to it.

I’ve managed to get it going actually, if you’re interested:

void loop()
{
    if (character_received == 1)
    {

        character_received = 0; 
        if (strstr(rx_buffer, command))
        {
            if (*(strstr(rx_buffer,command)+strlen(command)) == '0')
            {
                digitalWrite(13, HIGH);    
                            
                for (int i = 0; i<sizeof(answer1) - 1; i++)
                {
                    while (!(UCSR0A & (1<<UDRE0)))
                    {};
                    UDR0 = answer0[i];
                }                
                clear_buffer();
            }
            
            if (*(strstr(rx_buffer,command)+strlen(command)) == '1')
            {
                for (int i = 0; i<sizeof(answer0) - 1; i++)
                {
                    while (!(UCSR0A & (1<<UDRE0)))
                    {};
                    UDR0 = answer1[i];
                }                
                clear_buffer();
            }
        }
    }
    
}

Still look forward to any and all insights as I’m pretty new at firmware/hardware engineering :slight_smile: