Serial Read Issue Nano

Hello

I am using two ways to communicate to a current loop driver board. I have a nano with its rx and tx connected to the driver board and as another test I have a FDTI FT232RL to the same points. All the instructions except one work on the nano and all work on the FDTI.

I am sending simple hex commands with a baud rate of 4800 and 8bit even stop bit 1. Same settings for both boards.

For the FDTI I am using docklight to send the commands and on the nano I am sending it from a arduino sketch.

This is the command
F1 16 B0

For the response
FDTI: F1 16 B0 D1 E1 E0 E5 E1 E9 E6 E0 E0 E1 E8 E4 E0 E0 E0 E3 A0 3F 3F DF

However with the nano it differs

3F 3F 3F 3F FF 3F 3F FF F1 FF 8B B0 FF FF FF BF E1 FF FF E0 FF FF 79

The funny part is that there are some of the correct HEX values in the mess of other HEX

Any suggestions for the reason for the difference?

8bit even stop bit 1

You're sending what?

Where's the code?

void setup() {
  byte i;
 pinMode(LED, OUTPUT);
 Serial.begin(4800,SERIAL_8E1);

byte getTransaction(Stream &serial, byte pumpNozzle)
{
  byte bytes[3];

  bytes[0] = pumpNozzle;
  bytes[1] = 0x16;
  bytes[2] = 0xB0;

  for (int i=0; i<=sizeof(bytes); i++){
    serial.write(bytes[i]);
  }

//While loop to ensure the buffer has the correct number of bytes

    for (int i=0; i<=64; i++){
      character = serial.read();

      mySerial.write(character);
      content[i] = character;
    }    

  return content[24];
};
      character = serial.read();

      mySerial.write(character);

Can you post a picture of your mySerial?

What is serial an instance of?

Sorry I have an instance of software serial running to monitor the response. I output the results with a 9600 baud this is how I got the output on the screen.

I have an instance of software serial running to monitor the response.

From your mySerial? Just what the heck IS a mySerial?

I output the results with a 9600 baud this is how I got the output on the screen.

Using serial? I would expect you to have to use Serial.

    for (int i=0; i<=64; i++){
      character = serial.read();
Why would you assume that there are 64 characters that are available to read?

Serial.read() returns -1 when there is no data. With “believable” manipulation, that would give you your string of 0x3F characters…

Here is the full script

#include "Arduino.h"
#include "HardwareSerial.h"
#include "SoftwareSerial.h"

#define RFCHANNEL        0       // Let's use channel 0
#define SYNCWORD1        0xB5    // Synchronization word, high byte
#define SYNCWORD0        0x47    // Synchronization word, low byte
#define SOURCE_ADDR      5       // Device address
#define LED              13


//CCPACKET packet;

long previousMillis = 0;
long interval = 120;  
byte previousState = 0xFB;  
byte pumpNumber = 0xF1;
const byte rxPin = 11;
const byte txPin = 12;

byte NORESP = 0xE0;
byte ERR = 0xE0;
byte OFF = 0xE1;
byte CALL = 0xE2;
byte PUMPBUSY = 0xE3;
byte FIN = 0xE4;
byte ALONE = 0xE5;
byte LEAK = 0xE6;
byte PERR = 0xE7;
byte AUND = 0xE8;
byte PAUSE = 0xE9;

SoftwareSerial mySerial (rxPin, txPin);

void setup() {
  // put your setup code here, to run once:
  byte i;
 pinMode(LED, OUTPUT);
 //digitalWrite(LED, HIGH);
 Serial.begin(4800,SERIAL_8E1);
 //Serial.begin(9600);
 mySerial.begin(9600);
//mySerial.print("Start");
//panstamp.radio.setChannel(RFCHANNEL);
//  panstamp.radio.setSyncWord(SYNCWORD1, SYNCWORD0);
//  panstamp.radio.setDevAddress(SOURCE_ADDR);
//  panstamp.radio.setCCregs();
//  panstamp.setHighTxPower();

//  packet.length = 10;
  
//  for(i=0 ; i<packet.length ; i++)
//    packet.data[i] = i;
 
}

void loop() {
  delay(80);
  // put your main code here, to run repeatedly:
  //sendString("Check Packet");
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis; 

      byte nozzleResult = getNozzleStatus(Serial,pumpNumber);
//mySerial.println(nozzleResult);
      if(nozzleResult == ERR || nozzleResult == OFF
        || nozzleResult == CALL || nozzleResult == PUMPBUSY
        || nozzleResult == FIN || nozzleResult == ALONE
        || nozzleResult == LEAK || nozzleResult == PERR
        || nozzleResult == AUND || nozzleResult == PAUSE)
      {
           setNozzleCall(Serial,nozzleResult,previousState);
          previousState = nozzleResult;
             //sendString(nozzleResult);
      }
     
         
      
  }
}

void sendString(String str)
{
//  CCPACKET packet;
//  int i = 0;
//
//  // Copy string into packet  
//  while ((str[i] != 0) && (i < CCPACKET_DATA_LEN))
//    packet.data[i] = str.charAt(i);
//    
//  // Set packet length
//  packet.length = i;
//
//  // Transmit packet
// panstamp.radio.sendData(packet);
}






void setNozzleCall(Stream &serial, byte pumpNozzleStatus, byte pumpPreviousNozzleStatus)
{   
    if((pumpPreviousNozzleStatus == NORESP || pumpPreviousNozzleStatus == OFF || pumpPreviousNozzleStatus == CALL) && (pumpNozzleStatus == CALL))
    {
        byte authResult = setAuth(serial,pumpNumber);
        mySerial.println("call");
        //mySerial.println(authResult);
    }
    else if((pumpPreviousNozzleStatus == NORESP || pumpPreviousNozzleStatus == CALL) && (pumpNozzleStatus == PUMPBUSY))
    {
        //mySerial.println("pumping");
    }
    else if((pumpPreviousNozzleStatus == NORESP || pumpPreviousNozzleStatus == PUMPBUSY) && (pumpNozzleStatus == PUMPBUSY))
    {
        //mySerial.println("pumping");
    }
    else if((pumpPreviousNozzleStatus == NORESP || pumpPreviousNozzleStatus == PUMPBUSY) && (pumpNozzleStatus == FIN))
    {
        getTransaction(serial,pumpNumber);
        //mySerial.println("transaction complete");
    }
    else if((pumpPreviousNozzleStatus == NORESP || pumpPreviousNozzleStatus == FIN) && (pumpNozzleStatus == FIN))
    {
        getTransaction(serial,pumpNumber);
        //mySerial.println("transaction complete");
    }
    else if((pumpPreviousNozzleStatus == NORESP || pumpPreviousNozzleStatus == FIN) && (pumpNozzleStatus == OFF))
    {
        //mySerial.println("transaction finalised");
    }
}

byte getNozzleStatus(Stream &serial, byte pumpNozzle)
{
  byte bytes[3];
  
  bytes[0] = pumpNozzle;
  bytes[1] = 0x10;
  bytes[2] = 0xB0;

  byte instructionResult = SendInstruction(serial, bytes);

  return instructionResult;  
};

byte getTransaction(Stream &serial, byte pumpNozzle)
{
  byte bytes[3];
  //mySerial.println("test");
  bytes[0] = pumpNozzle;
  bytes[1] = 0x16;
  bytes[2] = 0xB0;

  for (int i=0; i<=sizeof(bytes); i++){
    serial.write(bytes[i]);
  }

  int serialState = 0;
  byte content[4];
  char character;
  long interval = 160; 
 unsigned long currentMillis = millis();
 long previousMillis = millis();

//mySerial.println(serial.available());
 while ( !(serial.available() <= 19) && serialState != 1) {
  currentMillis = millis();
   if(currentMillis - previousMillis > interval){
        serialState = 1;
   }
 }
 //mySerial.println("test");
 //timeout = 0;

  //while (serial.available()) {
    for (int i=0; i<=23; i++){
      character = serial.read();

      mySerial.write(character);
      content[i] = character;
    }    
  //}
  return content[24];
};

byte setAuth(Stream &serial, byte pumpNozzle)
{
    byte bytes[3];
  
    bytes[0] = pumpNozzle;
    bytes[1] = 0x11;
    bytes[2] = 0xB0;
  
    byte instructionResult = SendInstruction(serial, bytes);

    return instructionResult;  
};

byte SendInstruction(Stream &serial,byte command[3])
{
  for (int i=0; i<=sizeof(command); i++){
    serial.write(command[i]);
  }
  return ReadResult(serial);
};

byte ReadResult(Stream &serial)
{
  int serialState = 0;
  byte content[4];
  char character;
  long interval = 80; 
 unsigned long currentMillis = millis();
 long previousMillis = millis();

 while ( !(serial.available() < 4) && serialState != 1) {
  currentMillis = millis();
   if(currentMillis - previousMillis > interval){
        serialState = 1;
   }
 }
 
 //timeout = 0;

  while (serial.available()) {
    for (int i=0; i<=3; i++){
      character = serial.read();
      content[i] = character;
    }    
  }

  return content[3];
};
 unsigned long currentMillis = millis();
 long previousMillis = millis();

Why is currentMillis unsigned, while previousMillis is signed? Why does previousMillis get populated AFTER currentMillis?

 while ( !(serial.available() <= 19) && serialState != 1) {

What’s with the convoluted logic? Why not say:

   while(serial.available() > 20 && serialState != 1)

Why does this code stop when there are 20 bytes left in the buffer?

PaulS:

 unsigned long currentMillis = millis();

long previousMillis = millis();



Why is currentMillis unsigned, while previousMillis is signed? Why does previousMillis get populated AFTER currentMillis?



while ( !(serial.available() <= 19) && serialState != 1) {



What's with the convoluted logic? Why not say:


while(serial.available() > 20 && serialState != 1)



Why does this code stop when there are 20 bytes left in the buffer?

I apologies for the lack of consistency in the code I will change these values. I am expecting 20 hex values back in the buffer. Do you think this will cause extra values to be added in between the real return values?

I am expecting 20 hex values back in the buffer.

What does this mean? It appears that you don't understand that there is an input buffer and an output buffer, and that they are completely independent.

Do you think this will cause extra values to be added in between the real return values?

Leaving data in the input buffer has nothing to do with the output buffer.

PaulS:
What does this mean? It appears that you don’t understand that there is an input buffer and an output buffer, and that they are completely independent.
Leaving data in the input buffer has nothing to do with the output buffer.

I am a newbie so please excuse me if I dont explain well.

I think you might have answered the question. I have been thinking that I am able to serial read then serial write that same hex value that I have read from the input buffer to software serial so i can monitor what is being written into the input buffer on my console.

for (int i=0; i<=19; i++){
character = Serial.read();
softwareserial.write(character);
}

Can one not do the above or is the output not going to be the same as what is read?

Can one not do the above

Yes, one can.

is the output not going to be the same as what is read?

That depends on the type of character. If it is a char, byte, or uint8_t, the output will be exactly the same as the input.

PaulS:
Yes, one can.
That depends on the type of character. If it is a char, byte, or uint8_t, the output will be exactly the same as the input.

Okay thanks.
What I have done to resolve my issue is this

while (Serial.available()) {
byte serialVal = Serial.read();

byte acceptedBytes[12] = { 0xF1,0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xA0};

for (int p=0; p<=12; p++){

if(bytes[p] == serialVal ){
//use the accepted hex value
}
}
}

This cleans out any unwanted hex values that seem to be in the input buffer

 for (int p=0; p<=12; p++){

Oops.

In your byte getTransaction(Stream &serial, byte pumpNozzle) function you define :

byte content[4];

but at the end :

return content[24];

... far away from the end of array!

Chers, Ale.

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data.

...R

Hello

Thanks for the help.

I have added a schmitt chip in to get rid of any unwanted bytes.
The FDTI chip has this built into it.

I will run a tests and post the results