Reading hex data from serial port of photon

photon
Tags: #<Tag:0x00007fe228d80010>

#1

hi,
I have connected distance sensor to serial1 of photon,
as per their documentation I should send hex command to sensor
and I will get hex data from the sensor in reply

Capture

I am trying the send the above command to sensor(table1)
and trying to get data (table2)

I wrote following sketch:

// Thishttps://build.particle.io/build/5d8506fc3be99d0021c72496#flash #include statement was automatically added by the Particle IDE.
#include <math.h>
#include "Serial2/Serial2.h"

const int powerUp1 = D0;
byte turn_on[] = { 0xAA, 0x00, 0x01, 0xBE, 0x00, 0x01, 0x00, 0x01 };//0xAA 0x00 0x01 0xBE 0x00 0x01 0x00 0x01 Checksum
byte turn_off[] = { 0xAA, 0x00, 0x01, 0xBE, 0x00, 0x01, 0x00, 0x00 };//0xAA 0x00 0x01 0xBE 0x00 0x01 0x00 0x00 Checksum
byte one_shot_slow[] = { 0xAA, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x01, 0x22 };
byte one_shot_fast[] = { 0xAA, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x02, 0x23 };

//checksum = address byte + register bytes + payload count bytes + all payload bytes,
void readDistance(){
    digitalWrite(powerUp1, HIGH);
    delay(1000);
    
    //OPEN
    Serial1.write(0x4F);
    delay(1000);
    String turn1 = Serial1.readString();
    Particle.publish("turn1", turn1, PRIVATE);
    
    while(true){
        //1shot slow
        Serial1.write(one_shot_slow, sizeof(one_shot_slow));
        delay(5000);//4 seconds for 1 shot slow
        int bytesAvailable = Serial1.available();
        for(int i=0;i<bytesAvailable;i++){
            byte response = Serial1.read();
            Particle.publish("response", String(response), PRIVATE);
        }
        delay(1000);
    }

    //CLOSE
    Serial1.write(0x43);
    delay(1000);
    String turn2 = Serial1.readString();
    Particle.publish("turn2", turn2, PRIVATE);
}

void setup() {
    pinMode(powerUp1, OUTPUT);
    digitalWrite(powerUp1, HIGH);
    
    Serial1.begin(19200, SERIAL_8N1);
}

void loop() {
    readDistance();
}

I am sending hex command using Serial1.write (is this correct way of doing it?)

how do I read data into hex format(table2) from serial1?
I am not sure my firmware code is correct as I am not getting expected result

help appreciated


#2

You are reading bytes they have no format other than binary.

Hex, oct or even dec are mere conventions to make these binary patterns better readable for humans. An electronic device is quite happy with binary and doesn’t even care how you type in a number in your code. After compilation that number (e.g. 88 or 0x58 or 0130 or 0b01011000 or even the letter ‘X’) are all the same thing for it.

Once you received the byte that is the hex or oct or dec or binary or ASCII value you need - any interpretation ontop of that is up to your needs.

If you want to visually read the data in hex representation you can translate the numeric value of your read byte like this

  uint8_t d = 88;
  uint8_t x = 0x58;
  uint8_t o = 0130;
  uint8_t b = 0b01011000;
  char    a = 'X';
  char    asText[64];
  snprintf(asText, sizeof(asText)
          , "All values as hex: 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x", d, x, o, b, a);
  Serial.println(asText);

(the 0x preceding the percent (%) signs are just static text to render the common 0x## representation)

But for your expected response length of 13 bytes you cannot use Particle.publish() for each individual byte as you will run into the rate limit after the first four bytes.
You also cannot transmit the checksum as in many cases it probably won’t fall into the allowed range of allowed characters.

BTW, I’m not sure what your command 0x4F is meant to return, but Serial1.readString() will stop reading as soon it finds a zero byte in the data stream - is this intended?


#3

hi ScruffR
thanks for reply.

I am quiet confused by your reply.
the table 6-20 shows the sensor will reply 8 bytes,
and the data received is in hex.

I wonder what change I should do in my code to get that response values.

kind regards


#4

When I count the bytes I do see 13 in 6-20 (if you had a link to the doc - or at least some indication what sensor this is - and not just a screenshot we could investigate what else the docs have to say)

0xAA 0x00 0x00 0x22 0x00 0x03 0xAA 0xBB 0xCC 0xDD 0x01 0x01 0x##

And as I said, hex is only the representation. The above would be exactly the same as

170 0 0 34 0 3 170 187 204 221 1 1 ##

in decimal.

On an oscillscope (ignoring the start, priority and stop bits) you’d see these binary patterns

1010 1010
0000 0000
0000 0000
0010 0010
0000 0000
0000 0011
1010 1010
1011 1011
1100 1100
1101 1101
0000 0001
0000 0001
#### ####

each set of four bits represents one hex digit

Something along this line

  uint8_t response[16];            // a buffer long enough for the expected responses
  Serial1.write(one_shot_slow, sizeof(one_shot_slow));
  Serial1.readBytes(response, 13); // 1-shot Auto Measure will return 13 bytes (will wait up to 1 second - default)

Update:
I found the doc and the info just bellow the table 6-20 even states this

So it talks about byte9 (counting from 0 means 10 bytes so far) plus signal quality (2 bytes). Adding the checksum that is expected at the end of each and every transmission for that sensor we do have 13 bytes.