Displaying RS232/Serial Data on LCD Screen from Speed Radar Module

Hello everyone. Total newb here. Hoping to learn from the masters. My hobby project is currently turning a speed radar gun module and displaying the data onto the lcd screen. Arduino Zero + Keyestudio 1602 + rs232 ttl module.

The speed radar outputs rs232 data as ascii. I can see the data on the serial monitor, and my code-knowledgeable friend helped me with some preliminary stuff. Unfortunately his time to help me on this is limited so I’ll take any available advice and tips! :slight_smile:

Here is the code my friend conjured up (and I’ve been tinkering around with it since - but only causing issues lol):

#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

int highest = 0;
unsigned long time;

#include <SoftwareSerial.h>

SoftwareSerial mySerial(3,2); // RX, TX

void setup()
{

// set up the LCD’s number of columns and rows:
lcd.begin(16, 2);
Serial.begin(9600);
// Print a message to the LCD.

Serial.begin(9600);
while (!Serial) {
;

}

mySerial.begin(9600);
delay(500);

//SPLASH SCREEEN
Serial.println(“SPEED RADAR”);
lcd.setCursor(0,0);
lcd.print(“SPEED RADAR”);
lcd.setCursor(0,1);
lcd.print(“LOADING…”);
delay(2500);
lcd.setCursor(0,0);
lcd.print(" “);
lcd.setCursor(0,1);
lcd.print(” ");

}

void loop() // run over and over
{

lcd.setCursor(0,0);
lcd.print(“Target Speed”);
lcd.setCursor(0,1);
lcd.print(" ");

int x = 0;

if (mySerial.available())
{

x = mySerial.read();

}

if (x > highest)
{
highest = x;

time = millis();

}

if (millis() > time+5000)
{
lcd.setCursor(4,1);
lcd.write(" ");
highest = 0;
}

Serial.write(x);
Serial.write(" ");
lcd.setCursor(0,1);
lcd.print(x);

lcd.setCursor (4,1);
lcd.print(highest);

}

After the splash screen the lcd screen shows:

TARGET SPEED
0 0

The idea behind the two "0"s is the first one shows realtime speed and second one holds the highest value for whatever time. Problem is the first zero seems to be refreshing stupidly fast and always displays 0 and the second zero will display/hold data but it’s incorrect lol.

I’m ready to try anything to see if I can make this work even further somehow :slight_smile:

Thanks for reading and even more thanks if you happen to invest a bit of brain power into my venture!

-Tim

  • you redraw the LCD title every pass through loop(); do you really want to do that?
  • you erase the first 7 characters of the next line every pass through loop(); do you want to do that?
  • you read a single character (if available) from the gun; is that going to be an actual speed?

I dunno. There's a lot there that can be improved.

Question: What radar device are you using? Can you provide a link to a datasheet?

If the data is truly coming across as ascii, you need to convert the ascii into an actual number. It also means you need to capture more than a single char from the serial port before you process it. A good tutorial about serial is here

Using something like that example gives you this

#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);


const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data

boolean newData = false;


int highest = 0;
unsigned long time;

#include <SoftwareSerial.h>

SoftwareSerial mySerial(3, 2); // RX, TX

void setup()
{
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  Serial.begin(9600);
  while (!Serial);

  mySerial.begin(9600);
  delay(500);

  //SPLASH SCREEEN
  Serial.println("SPEED RADAR");
  lcd.setCursor(0, 0);
  lcd.print("SPEED RADAR");
  lcd.setCursor(0, 1);
  lcd.print("LOADING...");
  delay(2500);
  lcd.setCursor(0, 0);
  lcd.print("                ");
  lcd.setCursor(0, 1);
  lcd.print("                ");
}


void loop() // run over and over
{
  int x = 0;

  if (newData == true)
  {
    newData = false;
    x = atoi(receivedChars);
    Serial.println(x);
    lcd.setCursor(0, 1);
    if ( x < 100 ) lcd.print(" ");
    if ( x < 10 )  lcd.print(" ");
    lcd.print(x);

    if (x > highest)
    {
      highest = x;
      time = millis();
      lcd.setCursor (4, 1);
      if ( highest < 100 ) lcd.print(" ");
      if ( highest < 10 )  lcd.print(" ");
      lcd.print(highest);
    }
  }
  if (millis() - time >= 5000)
  {
    lcd.setCursor(4, 1);
    lcd.print("    ");
    highest = 0;
  }
}



void recvWithEndMarker() {
  static byte ndx = 0;
  char endMarker = '\n';
  char rc;

  while (mySerial.available() > 0 && newData == false) {
    rc = mySerial.read();

    if (rc != endMarker) {
      receivedChars[ndx] = rc;
      ndx++;
      if (ndx >= numChars) {
        ndx = numChars - 1;
      }
    }
    else {
      receivedChars[ndx] = '\0'; // terminate the string
      ndx = 0;
      newData = true;
    }
  }
}

Blackfin:

The radar is an older Houston Radar DR500. If you google and goto fcc site they state the format as ascii ( https://fccid.io/TIADR500/User-Manual/Manual-573498 )

in nnn/n/r format

where nnn is the speed-digits,

n/r: A new line followed by carriage return character.

Blh64 thankyou for the link I am going to do some reading, and I will plunk in your code and see what happens! Will update very soon!

Thanks so much folks :slight_smile: Will chat soon..

BLH64 I put your code in and seems to 'do nothing' after the splash screen. Nothing on lcd nor serial monitor comes in. Whereas before with my code the monitor we can see the data come in (albeit very fast). Your code opens my eyes to what else I will need to do to make this work, and although it seems a bit daunting to me I think I'm slowly getting a grasp on things. I just wished I furthered my coding experience (outside of html) throughout my life so I wouldn't have to be asking the basics :slight_smile:

Try this one:

#include <LiquidCrystal.h>
#include <SoftwareSerial.h>

#define RADAR_MSG_TOUT      4000ul          //4-sec message timeout from radar gun
#define BUFF_SIZE           16
#define MAX_SPEED           255             //maximum allowable speed
#define MSG_TERM_CHAR       '\r'            //incoming msg termination character

int
    nLastMaxSpeed,
    nLastCurrSpeed,
    nMaxSpeed,
    nCurrSpeed;

SoftwareSerial mySerial(3,2); // RX, TX
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

char
    szMsg[BUFF_SIZE];
char
    rxBuffer[BUFF_SIZE];

void setup()
{

    // set up the LCD's number of columns and rows:
    lcd.begin(16, 2);
    Serial.begin(9600);
    while (!Serial);
    
    mySerial.begin(9600);    
    delay(500);
    
    //SPLASH SCREEEN
    Serial.println("SPEED RADAR");
    lcd.setCursor(0,0);
    lcd.print("SPEED RADAR");
    lcd.setCursor(0,1);
    lcd.print("LOADING...");        //kinda bogus but whatevs...
    delay(2500);                    //!
    
    lcd.setCursor(0,0);
    lcd.print( "Target Speed    " );

    nLastMaxSpeed = 0;
    nLastCurrSpeed = 0;
    nMaxSpeed = -1;

}//setup

void loop() // run over and over
{
    DisplaySM();
        
}//loop

//display logic state names
#define ST_DISP_TOUT        0
#define ST_DISP_WAIT        1
void DisplaySM( void )
{
    static unsigned long
        timeMsgTO;
    static byte
        stateDisplay = ST_DISP_TOUT;
    bool
        bMsgStatus;
    unsigned long
        timeNow;

    timeNow = millis();        
    
    switch( stateDisplay )
    {
        case    ST_DISP_TOUT:
            //init or have timed out waiting for a message; display dashes and move to wait for msg state
            lcd.setCursor(0,1);
            lcd.print( "--- ---         " );

            //reset max speed and last speeds
            nMaxSpeed = -1;
            nLastMaxSpeed = 0;
            nLastCurrSpeed = 0;
            timeMsgTO = timeNow;
            
            stateDisplay = ST_DISP_WAIT;
            
        break;
        
        case    ST_DISP_WAIT:
            //waiting for a message from the radar gun here
            if( (timeNow - timeMsgTO) >= RADAR_MSG_TOUT )
            {
                //if we time out, move to timeout state
                stateDisplay = ST_DISP_TOUT;
                                
            }//if
            else
            {
                if( CheckRadarSerial() )
                {
                    //got a message so reset timeout
                    timeMsgTO = timeNow;    
                
                    //new msg update from radar; show it
                    
                    if( nCurrSpeed > MAX_SPEED )
                        nCurrSpeed = MAX_SPEED;
                        
                    if( nCurrSpeed > nMaxSpeed )
                        nMaxSpeed = nCurrSpeed;

                    if( nCurrSpeed != nLastCurrSpeed )
                    {
                        sprintf( szMsg, "%3d", nCurrSpeed );
                        lcd.setCursor(0,1);
                        lcd.print( szMsg );
                        
                        nLastCurrSpeed = nCurrSpeed;
                        
                    }//if

                    if( nMaxSpeed != nLastMaxSpeed )
                    {
                        sprintf( szMsg, "%3d", nMaxSpeed );
                        lcd.setCursor(4,1);
                        lcd.print( szMsg );
                        
                        nLastMaxSpeed = nMaxSpeed;
                                            
                    }//if

                    //to the serial monitor
                    sprintf( szMsg, "%3d %3d", nCurrSpeed, nMaxSpeed );
                    Serial.println( szMsg );
                                                                   
                }//if

            }//else
                        
        break;
        
    }//switch
            
}//DisplaySM

bool CheckRadarSerial( void )
{
    static byte
        rxPtr = 0;
    char
        cRx;
        
    if( mySerial.available() )
    {
        do
        {
            cRx = mySerial.read();
            if( rxPtr < (BUFF_SIZE-1) )
                rxBuffer[rxPtr++] = cRx;

            if( cRx == MSG_TERM_CHAR )
            {
                nCurrSpeed = atoi( rxBuffer );                    
                rxPtr = 0;
                
                return true;
                
            }//if

        }while( mySerial.available() );

    }//if

    return false;
    
}//CheckRadarSerial

Blackfin, just as your title states you are GOD!!! Thank you so very much...it works perfectly!!

Don't think i'd have ever figured this out on my own.

How do i buy you a beer or coffee?!?! :slight_smile:

You can try blh64's code again, adding this near the top of loop():

    recvWithEndMarker();

I think the key thing is to look at his code and/or mine to understand how we approached the reception of a multi-character message with a known structure (e.g. ASCII, terminated with a '/n' or '/r'.)

And the ideas of only updating parts of the LCD and only updating them when they've changed.

Or the idea of timeouts and what you might do if the radar gun (or whatever) stopped transmitting; do you just display the last thing or do you print "---" (as I tried to do.)

Anyway, glad it worked. Hope it helps.