It seems that there are debug/admin commands in the serial port.
Send: Start_measure_cmd
Parsed reply: Length=7509 ( =375.45mm )
Send: Get_info_from_last_measurement_cmd
reply: 49001e00030017fc4407c406b1054d078f00a608ef07000039ab2a473920564772b6fb46004d5c47d28ab848f6772543e48139437a470b43a0bc38435f8af043491d0000401d00005e1d0000721d00000000000000000000
parse reply:
parsed value 1=7497
parsed value 2=7488
parsed value 3=7518
parsed value 4=7538
Displayed value is an average of 4 measurement. Rest of the bytes in reply are unknown.
The link to the 'almost perfect' sensor is: http://208.73.204.85/item/50m-164ft-Laser-Distance-Measuring-Sensor-Range-Finder-Module-Low-cost-Diastimeter-Single-Continuous-Measurement/32792768667.html (http://208.73.204.85/item/50m-164ft-Laser-Distance-Measuring-Sensor-Range-Finder-Module-Low-cost-Diastimeter-Single-Continuous-Measurement/32792768667.html). I was not being secretive, just not sure what forum policy is on commercial links. There are many other makers of this type of laser sensor on Aliexpress. You can get complete tape measure units, kits, or just sensors.
To be clear, this sensor is 'almost perfect' for my particular application of package size measurement, YMMV. It will not be useful for robotics or drones, because it is slow- it takes 300 ms for a a measurement. However it is accurate and repeatable, as you would expect for the sensor at the heart of a laser tape measure. The 'almost' disclaimer is because of several factors:
1- connection, there is no simple header connector, you need to tack solder to the gold plated pads at the edge of the board. There are connectors but they are not documented and are very small.
2- It looks like each measurement must be triggered, there is no loop mode.
3- Not everyone will like the 3.3v serial interface. It works for me because I have lots of serial ports (xmega128A3U), and I can poll all 3 sensors simultaneously.
4- These come from China, with all the attendant communications, documentation, and delivery/customs issues. I am now waiting for 3 of these sensors that are stuck in customs at Fedex because of import problems (after paying $80 for air ship for $85 worth of sensors).
5- There is an audio beeper that sounds after each measurement. With a sensor for each axis (3), and multiple measurements for averaging/verification, this will sound like a field of crickets. Apparently there is no way to mute/disable it short of clipping it out. Query to maker so far unanswered (wish I spoke Cantonese...)
The interface needs 4 wires, 3.3V, Gnd, Tx, and Rx. Level is 3.3v for comms, at 19.2Kbps. Protocol is dead simple, send 'F', get a string like F: 0.767m, 0150[cr][lf]. Distance is in meters. Not sure what the other figure is, seems to vary even if distance is the same (undocumented, may be calculation time??). Easy to convert to inches: float inches=39.3701*atof(&rxbuf[3]);
I plan to ask Sparkfun if they would add this sensor to their roster, to make getting this sensor easier for everyone.
XX XX XX XX is hexadecimal float.
1089625758==0x40F25E9E==7.57405f==7.6m
And this is how I think crc is calculated:
+ couple commands to test with bluetooth(I don't have BT device)
/* BOSCH laser serial data crc value computing */
/* Program prints out crc value of byte array */
/* [0xC0][command][length][data][crc] */
//#include "stdafx.h"
#include "stdio.h"
#include "stdint.h"
#define POLYNOMIAL 166;
#define SEED 170;
//http://www.ti.com/lit/an/slua363/slua363.pdf
int calc_crc(int data_byte, int crc)
{
int bit_mask = 0, carry_check = 0, temp_data = 0;
temp_data = data_byte;
for (bit_mask = 0; bit_mask <= 7; bit_mask++)
{
data_byte = data_byte ^ crc;
crc = crc << 1;
temp_data = temp_data << 1;
carry_check = data_byte & 0x80;
if (carry_check)
{
crc = crc ^ POLYNOMIAL;
}
data_byte = temp_data;
}
return (crc);
}
int main()
{ //test arrays
//received data:
uint8_t data[] = { 0x00, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x08, 0xC1, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; //serial number received from device last byte 0xD4 removed(crc)
//commands:
//uint8_t data[] = { 0xC0, 0x55, 0x02, 0x01, 0x00 }; //crc should be 0x1A. PRL30C Set device as BT master
// these commands might work after device is set as BT master
//uint8_t data[] = { 0xC0, 0x51, 0x02, 0xFF, 0xFF }; //crc should be 0x9C. Get how many measurements in device memory
//uint8_t data[] = { 0xC0, 0x51, 0x02, 0x01, 0x01 }; //crc should be 0x18. Get measurement 1
//uint8_t data[] = { 0xC0, 0x51, 0x02, 0x01, 0x0A }; //crc should be 0x80. Get measurement 10
uint8_t crc = 0;
uint8_t newseed = SEED;
uint32_t bytearraysize = sizeof(data) ;
uint32_t bytepos = 0;
//calculate crc
do
{
newseed = calc_crc(data[bytepos++], newseed);
}while (bytepos < bytearraysize);
crc = newseed;
printf("crc: 0x%X ", crc);
getchar();
return 0;
}
Hi Dainius,
Answering your question:
"I am struggling to understand how to use particular command "0xC0, 0x40..........."
Reviewing my notes from 2023. See if you can figure out how to decode the measurements.
https://github.com/philipptrenz/BOSCH-GLM-rangefinder/blob/master/glm100c.py
cmds = {
'measure': b'\xC0\x40\x00\xEE',
'laser_on': b'\xC0\x41\x00\x96',
'laser_off': b'\xC0\x42\x00\x1E',
'backlight_on': b'\xC0\x47\x00\x20',
'backlight_off': b'\xC0\x48\x00\x62'
# distance to object from top of device
distance = int(struct.unpack("<L", data[2:6])[0])*0.05
#print(distance, 'mm')
return distance
distancia 40 cm
0xC0 0x40 0x00 0xEE = measure
C0 40 00 EE => 00 04 3C 1F 00 00 9E 7 Bytes
C0 40 00 EE => 00 04 49 1F 00 00 00
C0 40 00 EE => 00 04 41 1F 00 00 EE
C0 40 00 EE => 00 04 3C 1F 00 00 9E
C0 40 00 EE => 00 04 3E 1F 00 00 CC
C0 40 00 EE => 00 04 58 1F 00 00 80
C0 40 00 EE => 00 04 79 1F 00 00 8E
C0 40 00 EE => 00 04 75 1F 00 00 C4
C0 40 00 EE => 00 04 6C 1F 00 00 AA 0x1F6C = 8044 x 0.05 = 402,2 mm
C0 40 00 EE 00 04 61 1F 00 00 1A 1F61
C0 40 00 EE 00 04 66 1F 00 00 16
C0 40 00 EE 00 04 5B 1F 00 00 28
2.580 mm
C93E = 51518 x 0,05 = 2575,9 ou 51518/20
C0 40 00 EE => 00 04 3E C9 00 00 02
C0 40 00 EE => 00 04 45 C9 00 00 84 0xC945 = 51525 / 20 = 2576,25
C0 40 00 EE => 00 04 3C C9 00 00 50 0xC93C = 51516 / 20 =
C0 40 00 EE 00 04 3B C9 00 00 5C
0xC0 0x06 0X00 0X4A = Get Serial Number
C0 06 00 4A get serial number 3601K72EG0
00 1D 36 30 33 00 2F 11 03 00 00 00 01 00 00 01 00 00 33 36 30 31 4B 37 32 45 47 30 00 00 00 3E
C0 06 00 4A 00 1D 36 30 33 00 2F 11 03 00 00 00 01 00 00 01 00 00 33 36 30 31 4B 37 32 45 47 30 00 00 00 3E
C0 06 00 4A 00 1D 36 30 33 00 2F 11 03 00 00 00 01 00 00 01 00 00 33 36 30 31 4B 37 32 45 47 30 00 00 00 3E
C0 06 00 4A 00 1D 36 30 33 00 2F 11 03 00 00 00 01 00 00 01 00 00 33 36 30 31 4B 37 32 45 47 30 00 00 00 3E
C0 06 00 4A 00 1D 36 30 33 00 2F 11 03 00 00 00 01 00 00 01 00 00 33 36 30 31 4B 37 32 45 47 30 00 00 00 3E
ÀJ603/3601K72EG0>
0xC0 0x41 0X00 0X96 = Laser on
C0 41 00 96 00 00 82
C0 41 00 96 00 00 82
C0 41 00 96 00 00 82
C0 41 00 96 00 00 82
0xC0 0x42 0X00 0X1E = Laser OFF
C0 42 00 1E 00 00 82
C0 42 00 1E 00 00 82
C0 42 00 1E 00 00 82
C0 42 00 1E 00 00 82
0xC0 0x47 0X00 0X20 = Backlight ON
C0 47 00 20 00 00 82
C0 47 00 20 00 00 82
C0 47 00 20 00 00 82
C0 47 00 20 00 00 82
0xC0 0x48 0X00 0X62 = Backlight OFF
C0 48 00 62 00 00 82
C0 48 00 62 00 00 82
C0 48 00 62 00 00 82
C0 48 00 62 00 00 82
And using Arduino Code on Raspberry Pico: (attached file: GLM20_PICO2.INO)
byte byte1 = receivedBytes[8];
byte byte2 = receivedBytes[7];
byte byte3 = receivedBytes[6];
unsigned long valor = ((unsigned long)byte1 << 16) | ((unsigned long)byte2 << 8) | (unsigned long)byte3;
float valor_decimal = float(valor);
Serial.println((valor_decimal / 200), 2); // valor em cm
Serial.println();
10:42:51.410 -> Comando enviado
10:42:52.723 -> Received Serial Data is:
10:42:52.723 -> C0 40 0 EE 0 4 42 22 0 0 92 0
10:42:52.723 -> 43.85
10:42:52.723 ->
10:42:53.989 -> Comando enviado
10:42:55.301 -> Received Serial Data is:
10:42:55.301 -> C0 40 0 EE 0 4 6 2A 0 0 D2 0
10:42:55.301 -> 53.79
10:42:55.301 ->
23:30:54.043 -> Comando enviado
23:30:55.350 -> Received Serial Data is:
23:30:55.350 -> C0 40 0 EE 0 4 9B D2 0 0 B4 22
23:30:55.350 -> 269.58
23:30:55.350 ->
23:30:56.605 -> Comando enviado
23:30:57.908 -> Received Serial Data is:
23:30:57.908 -> C0 40 0 EE 0 4 9C D2 0 0 B8 22
23:30:57.908 -> 269.58