How to filter duplicate input from Serial monitor?

Hi! I am new in posting forum.
Please point my mistakes if there happen to be one.I have been debugging this problem for 3 days with no solution avails.
I have a python scripts that detect face and will post the detected face id to Serial. Arduino will read the Serial port and process the data to detect the user by its id. My problem is when the Python scripts detect faces, it will send a stream of face id of the user. When the Arduino want to read the Serial, it detect many face id have been detected because python scripts have been coded like this:

if(face detected):
    serialWrite(id)

When the face detected, python scripts will write many faceId to the Serial port. When the arduino want to read this, its read like many face have been detected.

This is the code to read the Serial Monitor. Don't worry the about ACCESS:: because it's in the other file.

void ACCESS::recvSerial()
{
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;
    

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

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

char *ACCESS::getData()
{
    if (newData == true) 
    {
        Serial.print("\nData from python: ");
        Serial.println(receivedChars);
        newData = false;
    }
    return receivedChars;
}

char *faceConformation(int ID)
{
    detectedFaces = true;
    access = true;

    char* temp_name = userAccess.GetUserName(0, name);   // get user name

    Serial.print( *temp_name + "face detected");

    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(temp_name);
    lcd.setCursor(0,1);
    lcd.print("Face detected");

    return temp_name;

}

i'm calling the function like this:

ACCESS userAccess;

void loop ()
{
    userAccess.recvSerial();
    receivedChars = userAccess.getData();

        if(strcmp(receivedChars, "1") == 0)         // one is the id
        {
            username = faceConformation(0);

        }else if(strcmp(receivedChars, "2") == 0)
        {
            username = faceConformation(1);

        }else if(strcmp(receivedChars, "3") == 0)
        {
            username = faceConformation(2);

        }else if(strcmp(receivedChars, "4") == 0)
        {
            username = faceConformation(3);

        }

if(access)
    {
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("    Welcome");
        lcd.setCursor(0,1);
        lcd.print(username);

        Serial.print("\nAuthorized\n");
        delay(3000);            // maybe change this delay to a beep or delay with a beep
        
        lcd.clear();

    }
}


When the face is detected, the lcd.print("Welcome "); print many time until the faced from serial port is readed.

How to filter duplicate input from serial monitor to only detect single face detected?

sorry for my bad english :slight_smile:

would be helpful to see an example of the output

if the output is simply a repeat of the preceding out, couldn't you just keep track of the preceding output and ignore it if it is the same?

Only print the welcome message when a boolean variable is set to true. Once printed, set the boolean to false to prevent the message being printed again. When you detect a change of face ID change the boolean to true to allow the message to be printed

This problem could be avoided by preventing Python from sending the face id more than once

So the problem only can be solved on the arduino side code?

i tried by doing putting these line of code:

if(strcmp(receivedChars, lastChars) == 0){}     // loop for detecting duplicate of face id
    else
    {
        if(strcmp(receivedChars, "1") == 0)         // face recognized = kamil
        {
            username = faceConformation(0);

        }else if(strcmp(receivedChars, "2") == 0)
        {
            username = faceConformation(1);

        }else if(strcmp(receivedChars, "3") == 0)
        {
            username = faceConformation(2);

        }else if(strcmp(receivedChars, "4") == 0)
        {
            username = faceConformation(3);

        }
    }
    lastChars = receivedChars;

but i don't what's the problem this code. By using Serial.prinln() to check the var before and after the lastChars is declared, i found that last char is have been declared before even lastChars = receivedChars; executed. Here's is the output of the Serial Monitor:

Last Chars before : 1
lasChars after : 1

lastchars before face detected
lastChars after face detected

you are aware the strcmp() is != 0 when there is match?

consider the rec() in the code below (run on my laptop). it produced the following output

1
faceConformation: 1
2
faceConformation: 2
2
2
1
faceConformation: 1
3
faceConformation: 3
3
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void
faceConformation (
    int id )
{
    printf ("%s: %d\n", __func__, id);
}


void
rec (
    const char * receivedChars )
{
    static char lastChars [80] = "";

    if (strcmp (lastChars, receivedChars))  {
        strcpy (lastChars, receivedChars);
        faceConformation (atoi (receivedChars)); 
    }
}

int
main ()
{
    char s [80];
    while (gets (s))  {
        rec (s);
    }
}

What do you mean by strcmp != 0 when there is a match? Isn't the other way around?

No. As I said

1 Like

Thank you for the resolution.

if (strcmp (lastChars, receivedChars))  {
        strcpy (lastChars, receivedChars);
        faceConformation (atoi (receivedChars)); 
    }

I don't understand this line. how (strcmp (lastChars, receivedChars)) received as true?
the funtion strcmp does not return boolean.

strcmp() returns 0 if the 2 strings match and a positive or negative number if they do not match

0 is equivalent to false and anything else is is equivalent to true

1 Like

Owh, i just learned a new thing... I think only 1 declared as true.

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