Serial communication with serial device

I was trying to get data from a blood glucose meter to my pc… But this glucose meter has its own software which communicates with the device and grab data from… But now i want to grab data from my glucose meter with my arduino mega. But i dont know how to do it? i tried some serial sniffing software to sniff the communication between the software and the device… i got lots of information… Now can any one please help me to programe my arduino to grab data from the device?
Here is the dump file…

<20190901033932.479 SYS>
COM is open
<20190901033932.530 SYS>
Baud rate 1200
<20190901033932.530 SYS>
RTS off
<20190901033932.530 SYS>
DTR off
<20190901033932.530 SYS>
Data bits=8, Stop bits=1, Parity=None
<20190901033932.530 SYS>
Set chars: Eof=0x1A, Error=0x00, Break=0x00, Event=0x1A, Xon=0x11, Xoff=0x13
<20190901033932.530 SYS>
Handflow: ControlHandShake=(), FlowReplace=(), XonLimit=1024, XoffLimit=1024
<20190901033932.581 SYS>
Baud rate 1200
<20190901033932.581 SYS>
RTS off
<20190901033932.581 SYS>
DTR off
<20190901033932.581 SYS>
Data bits=8, Stop bits=1, Parity=None
<20190901033932.581 SYS>
Set chars: Eof=0x1A, Error=0x00, Break=0x00, Event=0x1A, Xon=0x11, Xoff=0x13
<20190901033932.581 SYS>
Handflow: ControlHandShake=(), FlowReplace=(), XonLimit=1024, XoffLimit=1024
<20190901033932.581 SYS>
DTR off
<20190901033932.581 SYS>
Set timeouts: ReadInterval=-1, ReadTotalTimeoutMultiplier=-1, ReadTotalTimeoutConstant=-2, WriteTotalTimeoutMultiplier=0, WriteTotalTimeoutConstant=0
<20190901033932.582 SYS>
In/out queue size 4096/2048
<20190901033932.582 SYS>
Set timeouts: ReadInterval=-1, ReadTotalTimeoutMultiplier=-1, ReadTotalTimeoutConstant=2000, WriteTotalTimeoutMultiplier=0, WriteTotalTimeoutConstant=0
<20190901033932.582 TX>
U
<20190901033933.585 SYS>
DTR off
<20190901033933.585 SYS>
Purge the serial port: RXABORT, RXCLEAR
<20190901033933.585 SYS>
Purge the serial port: TXABORT, TXCLEAR
<20190901033933.672 SYS>
COM is closed
<20190901033933.749 SYS>
COM is open
<20190901033933.801 SYS>
Baud rate 1200
<20190901033933.801 SYS>
RTS off
<20190901033933.801 SYS>
DTR off
<20190901033933.801 SYS>
Data bits=8, Stop bits=1, Parity=None
<20190901033933.801 SYS>
Set chars: Eof=0x1A, Error=0x00, Break=0x00, Event=0x1A, Xon=0x11, Xoff=0x13
<20190901033933.801 SYS>
Handflow: ControlHandShake=(), FlowReplace=(), XonLimit=1024, XoffLimit=1024
<20190901033933.852 SYS>
Baud rate 1200
<20190901033933.852 SYS>
RTS off
<20190901033933.852 SYS>
DTR off
<20190901033933.852 SYS>
Data bits=8, Stop bits=1, Parity=None
<20190901033933.852 SYS>
Set chars: Eof=0x1A, Error=0x00, Break=0x00, Event=0x1A, Xon=0x11, Xoff=0x13
<20190901033933.852 SYS>
Handflow: ControlHandShake=(), FlowReplace=(), XonLimit=1024, XoffLimit=1024
<20190901033933.853 SYS>
DTR off
<20190901033933.853 SYS>
Set timeouts: ReadInterval=-1, ReadTotalTimeoutMultiplier=-1, ReadTotalTimeoutConstant=-2, WriteTotalTimeoutMultiplier=0, WriteTotalTimeoutConstant=0
<20190901033933.854 SYS>
In/out queue size 4096/2048
<20190901033933.854 SYS>
Set timeouts: ReadInterval=-1, ReadTotalTimeoutMultiplier=-1, ReadTotalTimeoutConstant=2000, WriteTotalTimeoutMultiplier=0, WriteTotalTimeoutConstant=0
<20190901033933.854 TX>
<ENQ>
<20190901033934.855 SYS>
DTR off
<20190901033934.855 SYS>
Purge the serial port: RXABORT, RXCLEAR
<20190901033934.855 SYS>
Purge the serial port: TXABORT, TXCLEAR
<20190901033934.943 SYS>
COM is closed
<20190901033935.021 SYS>
COM is open
<20190901033935.073 SYS>
Baud rate 9600
<20190901033935.073 SYS>
RTS off
<20190901033935.073 SYS>
DTR off
<20190901033935.073 SYS>
Data bits=8, Stop bits=1, Parity=None
<20190901033935.073 SYS>
Set chars: Eof=0x1A, Error=0x00, Break=0x00, Event=0x1A, Xon=0x11, Xoff=0x13
<20190901033935.073 SYS>
Handflow: ControlHandShake=(), FlowReplace=(), XonLimit=1024, XoffLimit=1024
<20190901033935.125 SYS>
Baud rate 9600
<20190901033935.125 SYS>
RTS off
<20190901033935.125 SYS>
DTR off
<20190901033935.125 SYS>
Data bits=8, Stop bits=1, Parity=None
<20190901033935.125 SYS>
Set chars: Eof=0x1A, Error=0x00, Break=0x00, Event=0x1A, Xon=0x11, Xoff=0x13
<20190901033935.125 SYS>
Handflow: ControlHandShake=(), FlowReplace=(), XonLimit=1024, XoffLimit=1024
<20190901033935.126 SYS>
DTR off
<20190901033935.126 SYS>
Set timeouts: ReadInterval=-1, ReadTotalTimeoutMultiplier=-1, ReadTotalTimeoutConstant=-2, WriteTotalTimeoutMultiplier=0, WriteTotalTimeoutConstant=0
<20190901033935.127 SYS>
In/out queue size 4096/2048
<20190901033935.127 SYS>
Set timeouts: ReadInterval=-1, ReadTotalTimeoutMultiplier=-1, ReadTotalTimeoutConstant=2000, WriteTotalTimeoutMultiplier=0, WriteTotalTimeoutConstant=0
<20190901033935.128 TX>
<ENQ>
<20190901033935.142 RX>
<SOH>Glucose [len=8]
<20190901033935.142 RX>
<LF><STX>1,2018,07,20,01,00,1.1,mmol_L [len=31]
<20190901033935.175 RX>
<LF>2,2018,07,20,01,00,1.1,mmol_L [len=30]
<20190901033935.208 RX>
<LF>3,2018,07,20,01,37,2.4,mmol_L [len=30]
<20190901033935.242 RX>
<LF>4,2018,07,20,01,36,1.1,mmol_L [len=30]
<20190901033935.276 RX>
<LF>5,2018,07,20,01,35,32.7,mmol_L [len=31]
<20190901033935.309 RX>
<LF><ETX><EOT>
<20190901033936.251 SYS>
DTR off
<20190901033936.251 SYS>
Purge the serial port: RXABORT, RXCLEAR
<20190901033936.251 SYS>
Purge the serial port: TXABORT, TXCLEAR
<20190901033936.266 SYS>
COM is closed

Sifting through the log it looks like the meat of the interface is 9600,N,8,1 and:

TX: <ENQ>
RX: <SOH>Glucose<LF>
RX: <STX>1,2018,07,20,01,00,1.1,mmol_L<LF>
RX: 2,2018,07,20,01,00,1.1,mmol_L<LF>
RX: 3,2018,07,20,01,37,2.4,mmol_L<LF>
RX: 4,2018,07,20,01,36,1.1,mmol_L<LF>
RX: 5,2018,07,20,01,35,32.7,mmol_L<LF><ETX><EOT>

The Arduino would send an character (0x05) to the meter which would respond with a character (0x01) followed by as many characters in the header are required, terminated by a character (0x0A).

A start of text (STX) character (0x02) is followed by as many records as are stored in the device’s memory, each separated by a character. The end of text and and end of transmission character signal the end of the messages from the device.

The content of each STX frame are probably:

FN - frame number
YR - year
MO - month
DY - day
HR - hour
MN - minute
RD - reading
UN - unit (mmol/L

Shouldn’t be hard to write a state machine to read the records out of the device using . There are probably other device-specific commands to erase records (e.g.).

What do you want to do with the records once read?

You’re probably going to need RS232-TTL hardware level translation.

You can try this code as a start:

//../Arduino/glucose meter/glucose_meter
#include <SoftwareSerial.h>

/* Example transaction
 * TX: <ENQ>
 * RX: <SOH>Glucose<LF>
 * RX: <STX>1,2018,07,20,01,00,1.1,mmol_L<LF>
 * RX: 2,2018,07,20,01,00,1.1,mmol_L<LF>
 * RX: 3,2018,07,20,01,37,2.4,mmol_L<LF>
 * RX: 4,2018,07,20,01,36,1.1,mmol_L<LF>
 * RX: 5,2018,07,20,01,35,32.7,mmol_L<LF><ETX><EOT>
 * 
 * 
 */

//prototypes
void ReceiveStateMachine( void );
bool GetSerialChar( char *pDest, unsigned long *pTimer );
bool CheckTimeout( unsigned long *timeNow, unsigned long *timeStart );

//defines
//special characters used for msg framing
#define ENQ                 0x05            //ASCII 0x05 == ENQUIRY
#define STX                 0x02            //START OF TEXT
#define ETX                 0x03            //END OF TEXT
#define EOT                 0x04            //END OF TRANSMISSION
#define LF                  0x0A            //LINEFEED
#define NUL                 0x00            //NULL termination character
//
#define MSG_INTERVAL        5000            //send an enquiry every 5-sec
#define CHAR_TIMEOUT        1000            //expect chars within a second (?)
#define BUFF_SIZE           50              //buffer size (characters)
#define MAX_RX_CHARS        (BUFF_SIZE-2)   //number of bytes we allow (allows for NULL term + 1 byte margin)

#define LED_BLIP_TIME       300             //mS time LED is blipped each time an ENQ is sent

//constants
//pins to be used may vary with your Arduino for software-serial...
const byte pinGlucoseRX = 10;           //to glucose meter TX (level translated as required)
const byte pinGlucoseTX = 11;           //to glucose meter RX (level translated as required)
const byte pinLED = LED_BUILTIN;        //visual indication of life

//globals
char
    rxTextFrame[BUFF_SIZE];    
SoftwareSerial 
    GlucoseSerial( pinGlucoseRX, pinGlucoseTX ); // RX, TX to talk to glucose meter
bool
    bLED;    
unsigned long
    timeLED;


void setup() 
{
    Serial.begin( 9600 );
    GlucoseSerial.begin( 9600 );
    
    pinMode( pinLED, OUTPUT );
    
}//setup

void loop() 
{
    ReceiveStateMachine();      //messaging with meter
    ServiceLED();               //for LED timing
    
}//loop

//state names
#define ST_ENQ              0
#define ST_RX_STX           1
#define ST_RX_TXT           2
#define ST_RX_EOT           3
#define ST_MSG_TIMEOUT      4
//
void ReceiveStateMachine( void )
{
    char
        ch;
    static byte
        rxPtr = 0;
    static unsigned long
        timeMsg=0,
        timeRX;
    unsigned long
        timeNow;
    static byte
        stateNext,
        stateRX = ST_ENQ;

    timeNow = millis();
    switch( stateRX )
    {
        case    ST_ENQ:
            if( (timeNow - timeMsg) >= MSG_INTERVAL )
            {
                //turn on the LED for visual indication
                bLED = true;
                timeLED = timeNow;
                digitalWrite( pinLED, HIGH );
                
                //send an ENQ character
                GlucoseSerial.write( ENQ );
                timeRX = timeNow;           //character timeout
                stateRX = ST_RX_STX;        //wait for the start of text
                
            }//if

        break;

        case    ST_RX_STX:
            //skip over the header; we're looking for the STX character
            if( GetSerialChar( &ch, &timeRX ) == true )
            {
                if( ch == STX )
                {
                    //got it; move to receive body of msg    
                    stateRX = ST_RX_TXT;
                    
                }//if
                
            }//if
            else
            {
                //check for a timeout
                if( CheckTimeout( &timeNow, &timeRX ) )
                    stateRX = ST_MSG_TIMEOUT;
                
            }//else
                        
        break;

        case    ST_RX_TXT:
            //receive characters into rxBuff until we see a LF
            if( GetSerialChar( &ch, &timeRX ) == true )
            {
                //have we received the EOT token?
                if( ch == ETX )
                {
                    //yes; move to look for end of transmission token for alignment
                    stateRX = ST_RX_EOT;
                    
                }//if
                else if( ch == LF )
                {
                    //got a LF; add a NULL termination...
                    rxTextFrame[rxPtr] = NUL;
                    
                    //...then do something with the message
                    Serial.println( rxTextFrame );  //send to serial monitor
                    //...

                    //now reset the buffer pointer; keep RXing and processing messages at the LF delimiter
                    //until we see the ETX token
                    rxPtr = 0;
                    
                }//else if
                else
                {
                    //receive another character into the buffer
                    rxTextFrame[rxPtr] = ch;

                    //protect the buffer from overflow
                    if( rxPtr < MAX_RX_CHARS )
                        rxPtr++;
                                        
                }//else

            }//if
            else
            {
                //check for a timeout
                if( CheckTimeout( &timeNow, &timeRX ) )
                    stateRX = ST_MSG_TIMEOUT;
                    
            }//else
            
        break;

        case    ST_RX_EOT:
            //receive characters into rxBuff until we see a LF
            if( GetSerialChar( &ch, &timeRX ) == true )
            {
                //have we received the EOT token?
                if( ch == EOT )
                {
                    //yes; reset ENQ timer and return to that state
                    timeMsg = timeNow;
                    stateRX = ST_ENQ;
                    
                }//if
                
            }//if
            else
            {
                //check for a timeout
                if( CheckTimeout( &timeNow, &timeRX ) )
                    stateRX = ST_MSG_TIMEOUT;
                    
            }//else
                
        break;

        case    ST_MSG_TIMEOUT:
            //we timed out waiting for a character; display error
            Serial.println( "Timeout waiting for character." );  //send debug msg to serial monitor
            
            //probably not needed since we just timed out but flush the serial buffer anyway
            while( GlucoseSerial.available() )
                ch = GlucoseSerial.read();
                
            //then reset back to ENQ state
            timeMsg = timeNow;
            stateRX = ST_ENQ;
            
        break;
        
    }//switch
    
}//ReceiveStateMachine

bool GetSerialChar( char *pDest, unsigned long *pTimer )
{
    if( GlucoseSerial.available() )
    {
        //get the character    
        *pDest = GlucoseSerial.read();
        
        //and reset the character timeout
        *pTimer = millis();
        
        return true;

    }//if
    else
        return false;
            
}//GetSerialChar

bool CheckTimeout( unsigned long *timeNow, unsigned long *timeStart )
{
    if( *timeNow - *timeStart >= CHAR_TIMEOUT )
        return true;
    else
        return false;    
        
}//CheckTimeout

void ServiceLED( void )
{
    if( !bLED )
        return;

    if( (millis() - timeLED) >= LED_BLIP_TIME )
    {
        digitalWrite( pinLED, LOW );
        bLED = false;
        
    }//if
    
}//ServiceLED

It compiles for a 2560 but I have no idea if it works. It should send an ENQ every 5-seconds over a software serial port (pins 10 and 11) to the meter and, if it receives anything, should print the messages to the serial monitor.

Each ENQ it should flash the built-in LED for 300mS.

If it’s expecting a character it waits a maximum of 1-second before timing out.

@OP

1. Make this hardware setup between MEGA and Glucose Meter:
TX1 (MEGA) ------> RX (Glucose Meter)
RX1 (MEGA) <----- TX (Glucose Meter)
GND (MEGA) <----> GND (Glucose Meter).

2. Upload the following sketch and post the screenshot of the Serial Monitor of MEGA. I simulated the Glucose data pattern of Post#1 in UNO and received that one in the Serial Monitor of MEGA. The message of the Serial Monitor may help to validate/adjust the research works of Post#1 or to adjust the codes of this sketch.

#define ENQ 0x05
#define EOT 0x04
char myData[300] = "";

void setup() 
{
  Serial.begin(9600);
  Serial1.begin(9600);
}

void loop() 
{
  Serial.println("Sending ENQ Code...");
  Serial1.write(ENQ);

  byte n = Serial1.available();
  if(n !=0)
  {
    Serial1.readBytesUntil(EOT, myData, 300);
    Serial.println(myData);  //will show few garbage for SOH, STX, and ETX 
    while(1);
  }
  delay(5000);
}

Blackfin:
You’re probably going to need RS232-TTL hardware level translation.

You can try this code as a start:

//../Arduino/glucose meter/glucose_meter

#include <SoftwareSerial.h>

/* Example transaction

  • TX:
  • RX: Glucose
  • RX: 1,2018,07,20,01,00,1.1,mmol_L
  • RX: 2,2018,07,20,01,00,1.1,mmol_L
  • RX: 3,2018,07,20,01,37,2.4,mmol_L
  • RX: 4,2018,07,20,01,36,1.1,mmol_L
  • RX: 5,2018,07,20,01,35,32.7,mmol_L

*/

//prototypes
void ReceiveStateMachine( void );
bool GetSerialChar( char *pDest, unsigned long *pTimer );
bool CheckTimeout( unsigned long *timeNow, unsigned long *timeStart );

//defines
//special characters used for msg framing
#define ENQ                0x05            //ASCII 0x05 == ENQUIRY
#define STX                0x02            //START OF TEXT
#define ETX                0x03            //END OF TEXT
#define EOT                0x04            //END OF TRANSMISSION
#define LF                  0x0A            //LINEFEED
#define NUL                0x00            //NULL termination character
//
#define MSG_INTERVAL        5000            //send an enquiry every 5-sec
#define CHAR_TIMEOUT        1000            //expect chars within a second (?)
#define BUFF_SIZE          50              //buffer size (characters)
#define MAX_RX_CHARS        (BUFF_SIZE-2)  //number of bytes we allow (allows for NULL term + 1 byte margin)

#define LED_BLIP_TIME      300            //mS time LED is blipped each time an ENQ is sent

//constants
//pins to be used may vary with your Arduino for software-serial…
const byte pinGlucoseRX = 10;          //to glucose meter TX (level translated as required)
const byte pinGlucoseTX = 11;          //to glucose meter RX (level translated as required)
const byte pinLED = LED_BUILTIN;        //visual indication of life

//globals
char
    rxTextFrame[BUFF_SIZE];   
SoftwareSerial
    GlucoseSerial( pinGlucoseRX, pinGlucoseTX ); // RX, TX to talk to glucose meter
bool
    bLED;   
unsigned long
    timeLED;

void setup()
{
    Serial.begin( 9600 );
    GlucoseSerial.begin( 9600 );
   
    pinMode( pinLED, OUTPUT );
   
}//setup

void loop()
{
    ReceiveStateMachine();      //messaging with meter
    ServiceLED();              //for LED timing
   
}//loop

//state names
#define ST_ENQ              0
#define ST_RX_STX          1
#define ST_RX_TXT          2
#define ST_RX_EOT          3
#define ST_MSG_TIMEOUT      4
//
void ReceiveStateMachine( void )
{
    char
        ch;
    static byte
        rxPtr = 0;
    static unsigned long
        timeMsg=0,
        timeRX;
    unsigned long
        timeNow;
    static byte
        stateNext,
        stateRX = ST_ENQ;

timeNow = millis();
    switch( stateRX )
    {
        case    ST_ENQ:
            if( (timeNow - timeMsg) >= MSG_INTERVAL )
            {
                //turn on the LED for visual indication
                bLED = true;
                timeLED = timeNow;
                digitalWrite( pinLED, HIGH );
               
                //send an ENQ character
                GlucoseSerial.write( ENQ );
                timeRX = timeNow;          //character timeout
                stateRX = ST_RX_STX;        //wait for the start of text
               
            }//if

break;

case    ST_RX_STX:
            //skip over the header; we’re looking for the STX character
            if( GetSerialChar( &ch, &timeRX ) == true )
            {
                if( ch == STX )
                {
                    //got it; move to receive body of msg   
                    stateRX = ST_RX_TXT;
                   
                }//if
               
            }//if
            else
            {
                //check for a timeout
                if( CheckTimeout( &timeNow, &timeRX ) )
                    stateRX = ST_MSG_TIMEOUT;
               
            }//else
                       
        break;

case    ST_RX_TXT:
            //receive characters into rxBuff until we see a LF
            if( GetSerialChar( &ch, &timeRX ) == true )
            {
                //have we received the EOT token?
                if( ch == ETX )
                {
                    //yes; move to look for end of transmission token for alignment
                    stateRX = ST_RX_EOT;
                   
                }//if
                else if( ch == LF )
                {
                    //got a LF; add a NULL termination…
                    rxTextFrame[rxPtr] = NUL;
                   
                    //…then do something with the message
                    Serial.println( rxTextFrame );  //send to serial monitor
                    //…

//now reset the buffer pointer; keep RXing and processing messages at the LF delimiter
                    //until we see the ETX token
                    rxPtr = 0;
                   
                }//else if
                else
                {
                    //receive another character into the buffer
                    rxTextFrame[rxPtr] = ch;

//protect the buffer from overflow
                    if( rxPtr < MAX_RX_CHARS )
                        rxPtr++;
                                       
                }//else

}//if
            else
            {
                //check for a timeout
                if( CheckTimeout( &timeNow, &timeRX ) )
                    stateRX = ST_MSG_TIMEOUT;
                   
            }//else
           
        break;

case    ST_RX_EOT:
            //receive characters into rxBuff until we see a LF
            if( GetSerialChar( &ch, &timeRX ) == true )
            {
                //have we received the EOT token?
                if( ch == EOT )
                {
                    //yes; reset ENQ timer and return to that state
                    timeMsg = timeNow;
                    stateRX = ST_ENQ;
                   
                }//if
               
            }//if
            else
            {
                //check for a timeout
                if( CheckTimeout( &timeNow, &timeRX ) )
                    stateRX = ST_MSG_TIMEOUT;
                   
            }//else
               
        break;

case    ST_MSG_TIMEOUT:
            //we timed out waiting for a character; display error
            Serial.println( “Timeout waiting for character.” );  //send debug msg to serial monitor
           
            //probably not needed since we just timed out but flush the serial buffer anyway
            while( GlucoseSerial.available() )
                ch = GlucoseSerial.read();
               
            //then reset back to ENQ state
            timeMsg = timeNow;
            stateRX = ST_ENQ;
           
        break;
       
    }//switch
   
}//ReceiveStateMachine

bool GetSerialChar( char *pDest, unsigned long *pTimer )
{
    if( GlucoseSerial.available() )
    {
        //get the character   
        *pDest = GlucoseSerial.read();
       
        //and reset the character timeout
        *pTimer = millis();
       
        return true;

}//if
    else
        return false;
           
}//GetSerialChar

bool CheckTimeout( unsigned long *timeNow, unsigned long *timeStart )
{
    if( *timeNow - *timeStart >= CHAR_TIMEOUT )
        return true;
    else
        return false;   
       
}//CheckTimeout

void ServiceLED( void )
{
    if( !bLED )
        return;

if( (millis() - timeLED) >= LED_BLIP_TIME )
    {
        digitalWrite( pinLED, LOW );
        bLED = false;
       
    }//if
   
}//ServiceLED




It compiles for a 2560 but I have no idea if it works. It should send an ENQ every 5-seconds over a software serial port (pins 10 and 11) to the meter and, if it receives anything, should print the messages to the serial monitor. 

Each ENQ it should flash the built-in LED for 300mS.

If it's expecting a character it waits a maximum of 1-second before timing out.

You are awosum brooo… Thanks… its working…

GolamMostafa:
@OP

1. Make this hardware setup between MEGA and Glucose Meter:
TX1 (MEGA) ------> RX (Glucose Meter)
RX1 (MEGA) <----- TX (Glucose Meter)
GND (MEGA) <----> GND (Glucose Meter).

2. Upload the following sketch and post the screenshot of the Serial Monitor of MEGA. I simulated the Glucose data pattern of Post#1 in UNO and received that one in the Serial Monitor of MEGA. The message of the Serial Monitor may help to validate/adjust the research works of Post#1 or to adjust the codes of this sketch.

#define ENQ 0x05

#define EOT 0x04
char myData[300] = “”;

void setup()
{
  Serial.begin(9600);
  Serial1.begin(9600);
}

void loop()
{
  Serial.println(“Sending ENQ Code…”);
  Serial1.write(ENQ);

byte n = Serial1.available();
  if(n !=0)
  {
    Serial1.readBytesUntil(EOT, myData, 300);
    Serial.println(myData);  //will show few garbage for SOH, STX, and ETX
    while(1);
  }
  delay(5000);
}

This also works… but i get only the first two lines of my data… how to solve it?

RahulMitra:
You are awosum brooo.... Thanks..... its working...

RahulMitra:
This also works..... but i get only the first two lines of my data..... how to solve it?

When the sketch of Post#2 works, please use that. I can't debug my sketch of Post#3 without a Glucose Meter; you can do the debugging job and report the new/modified sketch.

RahulMitra:
This also works..... but i get only the first two lines of my data..... how to solve it?

Try removing the "while(1);"

Blackfin:
Try removing the "while(1);"

The while(1) should not stop printing the whole message as this line: Serial1.readBytesUntil(EOT, myData, 300); is a blocking code until EOT is found.

This is how I simulated the Glucose Meter using NANO. MEGA received the message (Fig-1); there are two extra lines repeat at the top which is why? that I am tying to figure out.
smGlucose.png
Figure-1: Serial Monitor view of MEGA

MEGA Codes:

#define ENQ 0x05
#define EOT 0x04
char myData[300] = "";

void setup()
{
  Serial.begin(9600);
  Serial1.begin(9600);
}

void loop()
{
  Serial.println("Sending ENQ Code...");
  Serial1.write(ENQ);

  byte n = Serial1.available();
  if (n != 0)
  {
    Serial1.readBytesUntil(EOT, myData, 300);
    Serial.println(myData);  //will show few garbage for SOH, STX, and ETX
   // while (1);
  }
  delay(5000);
}

NANO Codes:

#include<SoftwareSerial.h>
SoftwareSerial SUART(2, 3);
#define ENQ 0x05
#define SOH 0x01
#define LF 0x0A
#define STX 0x02
#define ETX 0x03
#define EOT 0x04

/*
   RX: <SOH>Glucose<LF>
   RX: <STX>1,2018,07,20,01,00,1.1,mmol_L<LF>
   RX: 2,2018,07,20,01,00,1.1,mmol_L<LF>
   RX: 3,2018,07,20,01,37,2.4,mmol_L<LF>
   RX: 4,2018,07,20,01,36,1.1,mmol_L<LF>
   RX: 5,2018,07,20,01,35,32.7,mmol_L<LF><ETX><EOT>
*/
char myArray1[] = "Glucose";
char myArray2[] = "1, 2018, 07, 20, 01, 00, 1.1, mmol_L";
char myArray3[] = "2, 2018, 07, 20, 01, 00, 1.1, mmol_L";
char myArray4[] = "3, 2018, 07, 20, 01, 37, 2.4, mmol_L";
char myArray5[] = "4, 2018, 07, 20, 01, 36, 1.1, mmol_L";
char myArray6[] = "5, 2018, 07, 20, 01, 35, 32.7, mmol_L";

void setup()
{
  Serial.begin(9600);
  SUART.begin(9600);
}

void loop()
{
  byte n = SUART.available();  //getting from FIFO Buffer
  if (n != 0)
  {
    byte x = SUART.read();
    if (x == ENQ)
    {
      SUART.write(SOH);
      SUART.print(myArray1);
      SUART.write(LF);
      //--------------------
      SUART.write(STX);
      SUART.print(myArray2);
      SUART.write(LF);
      //--------------------
      SUART.print(myArray3);
      SUART.write(LF);
      //--------------------
      SUART.print(myArray4);
      SUART.write(LF);
      //--------------------
      SUART.print(myArray5);
      SUART.write(LF);
      //--------------------
      SUART.print(myArray6);
      SUART.write(LF);
      SUART.write(ETX);
      SUART.write(EOT);
      //--------------------
    }
  }
}

smGlucose.png

Blackfin:
You’re probably going to need RS232-TTL hardware level translation.

You can try this code as a start:

//../Arduino/glucose meter/glucose_meter

#include <SoftwareSerial.h>

/* Example transaction

  • TX:
  • RX: Glucose
  • RX: 1,2018,07,20,01,00,1.1,mmol_L
  • RX: 2,2018,07,20,01,00,1.1,mmol_L
  • RX: 3,2018,07,20,01,37,2.4,mmol_L
  • RX: 4,2018,07,20,01,36,1.1,mmol_L
  • RX: 5,2018,07,20,01,35,32.7,mmol_L

*/

//prototypes
void ReceiveStateMachine( void );
bool GetSerialChar( char *pDest, unsigned long *pTimer );
bool CheckTimeout( unsigned long *timeNow, unsigned long *timeStart );

//defines
//special characters used for msg framing
#define ENQ                0x05            //ASCII 0x05 == ENQUIRY
#define STX                0x02            //START OF TEXT
#define ETX                0x03            //END OF TEXT
#define EOT                0x04            //END OF TRANSMISSION
#define LF                  0x0A            //LINEFEED
#define NUL                0x00            //NULL termination character
//
#define MSG_INTERVAL        5000            //send an enquiry every 5-sec
#define CHAR_TIMEOUT        1000            //expect chars within a second (?)
#define BUFF_SIZE          50              //buffer size (characters)
#define MAX_RX_CHARS        (BUFF_SIZE-2)  //number of bytes we allow (allows for NULL term + 1 byte margin)

#define LED_BLIP_TIME      300            //mS time LED is blipped each time an ENQ is sent

//constants
//pins to be used may vary with your Arduino for software-serial…
const byte pinGlucoseRX = 10;          //to glucose meter TX (level translated as required)
const byte pinGlucoseTX = 11;          //to glucose meter RX (level translated as required)
const byte pinLED = LED_BUILTIN;        //visual indication of life

//globals
char
    rxTextFrame[BUFF_SIZE];   
SoftwareSerial
    GlucoseSerial( pinGlucoseRX, pinGlucoseTX ); // RX, TX to talk to glucose meter
bool
    bLED;   
unsigned long
    timeLED;

void setup()
{
    Serial.begin( 9600 );
    GlucoseSerial.begin( 9600 );
   
    pinMode( pinLED, OUTPUT );
   
}//setup

void loop()
{
    ReceiveStateMachine();      //messaging with meter
    ServiceLED();              //for LED timing
   
}//loop

//state names
#define ST_ENQ              0
#define ST_RX_STX          1
#define ST_RX_TXT          2
#define ST_RX_EOT          3
#define ST_MSG_TIMEOUT      4
//
void ReceiveStateMachine( void )
{
    char
        ch;
    static byte
        rxPtr = 0;
    static unsigned long
        timeMsg=0,
        timeRX;
    unsigned long
        timeNow;
    static byte
        stateNext,
        stateRX = ST_ENQ;

timeNow = millis();
    switch( stateRX )
    {
        case    ST_ENQ:
            if( (timeNow - timeMsg) >= MSG_INTERVAL )
            {
                //turn on the LED for visual indication
                bLED = true;
                timeLED = timeNow;
                digitalWrite( pinLED, HIGH );
               
                //send an ENQ character
                GlucoseSerial.write( ENQ );
                timeRX = timeNow;          //character timeout
                stateRX = ST_RX_STX;        //wait for the start of text
               
            }//if

break;

case    ST_RX_STX:
            //skip over the header; we’re looking for the STX character
            if( GetSerialChar( &ch, &timeRX ) == true )
            {
                if( ch == STX )
                {
                    //got it; move to receive body of msg   
                    stateRX = ST_RX_TXT;
                   
                }//if
               
            }//if
            else
            {
                //check for a timeout
                if( CheckTimeout( &timeNow, &timeRX ) )
                    stateRX = ST_MSG_TIMEOUT;
               
            }//else
                       
        break;

case    ST_RX_TXT:
            //receive characters into rxBuff until we see a LF
            if( GetSerialChar( &ch, &timeRX ) == true )
            {
                //have we received the EOT token?
                if( ch == ETX )
                {
                    //yes; move to look for end of transmission token for alignment
                    stateRX = ST_RX_EOT;
                   
                }//if
                else if( ch == LF )
                {
                    //got a LF; add a NULL termination…
                    rxTextFrame[rxPtr] = NUL;
                   
                    //…then do something with the message
                    Serial.println( rxTextFrame );  //send to serial monitor
                    //…

//now reset the buffer pointer; keep RXing and processing messages at the LF delimiter
                    //until we see the ETX token
                    rxPtr = 0;
                   
                }//else if
                else
                {
                    //receive another character into the buffer
                    rxTextFrame[rxPtr] = ch;

//protect the buffer from overflow
                    if( rxPtr < MAX_RX_CHARS )
                        rxPtr++;
                                       
                }//else

}//if
            else
            {
                //check for a timeout
                if( CheckTimeout( &timeNow, &timeRX ) )
                    stateRX = ST_MSG_TIMEOUT;
                   
            }//else
           
        break;

case    ST_RX_EOT:
            //receive characters into rxBuff until we see a LF
            if( GetSerialChar( &ch, &timeRX ) == true )
            {
                //have we received the EOT token?
                if( ch == EOT )
                {
                    //yes; reset ENQ timer and return to that state
                    timeMsg = timeNow;
                    stateRX = ST_ENQ;
                   
                }//if
               
            }//if
            else
            {
                //check for a timeout
                if( CheckTimeout( &timeNow, &timeRX ) )
                    stateRX = ST_MSG_TIMEOUT;
                   
            }//else
               
        break;

case    ST_MSG_TIMEOUT:
            //we timed out waiting for a character; display error
            Serial.println( “Timeout waiting for character.” );  //send debug msg to serial monitor
           
            //probably not needed since we just timed out but flush the serial buffer anyway
            while( GlucoseSerial.available() )
                ch = GlucoseSerial.read();
               
            //then reset back to ENQ state
            timeMsg = timeNow;
            stateRX = ST_ENQ;
           
        break;
       
    }//switch
   
}//ReceiveStateMachine

bool GetSerialChar( char *pDest, unsigned long *pTimer )
{
    if( GlucoseSerial.available() )
    {
        //get the character   
        *pDest = GlucoseSerial.read();
       
        //and reset the character timeout
        *pTimer = millis();
       
        return true;

}//if
    else
        return false;
           
}//GetSerialChar

bool CheckTimeout( unsigned long *timeNow, unsigned long *timeStart )
{
    if( *timeNow - *timeStart >= CHAR_TIMEOUT )
        return true;
    else
        return false;   
       
}//CheckTimeout

void ServiceLED( void )
{
    if( !bLED )
        return;

if( (millis() - timeLED) >= LED_BLIP_TIME )
    {
        digitalWrite( pinLED, LOW );
        bLED = false;
       
    }//if
   
}//ServiceLED




It compiles for a 2560 but I have no idea if it works. It should send an ENQ every 5-seconds over a software serial port (pins 10 and 11) to the meter and, if it receives anything, should print the messages to the serial monitor. 

Each ENQ it should flash the built-in LED for 300mS.

If it's expecting a character it waits a maximum of 1-second before timing out.

This code is working great with but i want to get data when i need… like when i press a button it will return the data… I am trying to do this. cant figure out how to do this… can you please help me…

You can try this. It compiles but not sure if it works.

It expects a switch wired to pin 2. Normally-open, grounds the pin when closed.

The switch is checked every 50mS. A press should start a serial transaction that will update the glucose reading.

glucose_meter.ino (8.77 KB)