Laser distance sensor (M88B4)

Hello all of you,
So I have been trying to get an output from the M88B4 laser distance sensor by connecting it to my ESP32. I made sure that the sensor was working by connecting it to my PC with a USB-TTL converter and using their premade software and no problems. I have studied the manual I posted below and I have searched the internet for anything to do with laser sensors from JRT and how to make them work with a microcontroller. My schematic looks like this:


The webservice that I used to make the schematic didn't have a ESP32 or the Laser sensor (understandably) so Im not using the depicted UNO but a ESP32 (so using D4 and D2 as my RX1 and TX1 and D18 as digital pin) and also the small breadboard is supposed to be the laser sensor (With connections VCC GND TX PWREN RX). I use an external power source of 3.3V so the laser sensor receives enough current, the RX and TX pins of ESP32 and Laser are cross connected and I put a 15k Ohm pull up resistor in between (Don't need a logic level shifter since ESP32 runs on 3.3V as well). The PWREN pin is connected to the D18 because as far as I understand the manual I have to give a logical HIGH on that pin to startup the serial connection. The ESP32 is connected and powered by my PC and is supposed to give the Serial output. When I build the circuit and run the code I can see that the laser is on and it beeps once (same as when I connected it to my USB port with the TTL adapter, so it's getting the necessary current I think) but the serial outputs nothing. The code that I am using is very minimal:

#include <HardwareSerial.h>
#define PWREN_PIN 18

//UART1
HardwareSerial SerialPort(1);

byte startmsg[] = {0x55};
byte shotmsg[] = {0xAA, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x01, 0x21};// one shot auto distance measure
byte incomingByte;

/*
On SerialPort (UART1)
                      ESP32
    PWREN <-----------> D18
    RX  <-15K Ohm->  (D2) TX1
    TX  <-15K Ohm->  (D4) RX1
    VCC  
    GND

*/

void setup() {
  pinMode(PWREN_PIN, OUTPUT);
  delay(100);
  Serial.begin(19200);
  SerialPort.begin(19200,SERIAL_8N1,4,2);
  digitalWrite(PWREN_PIN, HIGH);
  delay(100);
  SerialPort.write(startmsg, sizeof(startmsg));
  delay(100);
}

void loop() {
 SerialPort.write(shotmsg, sizeof(shotmsg));
  delay(1000);

   
   for (int i = 0; i <18; i++) { 
      if (SerialPort.available() > 0){ 
        int incomingByte = SerialPort.read();
        Serial.print(incomingByte, HEX);
        Serial.print(' ');
      }
   Serial.println();     
   delay(500);
   }
}

I am not sure if connecting the PWREN pin to a digital pin and giving a logical HIGH is even the right thing to do since the manual is a bit hard to understand (I tried the code with and without doing that and neither worked). If all is working I think I should get the adress printed out due to sending this byte {0x55} (I am not sure but the manual says so) and also I should get singular measurements printed out every second in the loop. None of this is happening (the if SerialPort.available loop never gets activated so there is no data coming in) and I don't know what else to try.
Any help would be massively appreciated, thanks.

Since I am a new user I apparently can't upload my pdf manual so I will post pictures of the relevant parts of the manual:






you are using ESP32 pin2 which may cause problems - see esp32-pinout-reference-gpios
i tend to use Serial1 on pins 16 and 17, e.g.

// ESP32  Serial1 test - for loopback test connect pins 16 and 17

#define RXD1 16
#define TXD1 17

void setup() {
  // initialize both serial ports:
  Serial.begin(115200);
  Serial1.begin(115200, SERIAL_8N1, RXD1, TXD1);
  Serial.println();
  Serial.println("\n\nESP32 serial1  test Rx pin 16 Tx pin 17");
  Serial.write("   for loopback test connect pin 16 to pin 17\n");
}

void loop() {
  // read from port 1, send to port 0:
  if (Serial1.available()) {
    int inByte = Serial1.read();
    Serial.write(inByte);
  }

  // read from port 0, send to port 1:
  if (Serial.available()) {
    int inByte = Serial.read();
    //Serial.write(inByte);
    Serial1.write(inByte);
  }
}

connect pin 16 to 17 to form a loopback test - text entered on serial monitor is echoed back to the display

Edit: if I change the above program to use pins 2 and 4

#define RXD1 2
#define TXD1 4

and connect pins 2 to 4 the loopback fails - no echo

Unfortunately thats not it, I have used that same setup (same code and wiring of RX/TX pins) for the UART for a different sensor before (and tested it just now again) and it works. I get the bytes of data from that different sensor so I definitely know that the wiring for the TX and RX is ok and works. Just to be sure I did the loopback test and both configurations worked and also with my code and the same problem, still no serial output. Also when I try to Serialprint the serial.read() after the autobaudrate call (which is where it should give out the adress of the sensor) in HEX format I get "FFFFFFFF".
I think the problem is with the "PWREN" pin and getting the laser sensor out of power down mode.
For context, when I used the software that they sent me I hook up the USB-TTL converter and the sensor the same way (RX and TX cross connect, VCC to 3.3V, GND to GND and PWREN to RTS) exept for the PWREN (here PWREN is connected to RTS). Then in the software after finding the Laser sensor you have to check a box that says "RTS " which turns the "power off" according to the prompt. After that I uncheck that box again and it says "power on" and is then usable for measurements. In the manual that process is described this way: "In initial state, Slave module (laser rangefinder) is in power down mode before Master pull up the PWREN pin. After PWREN goes high, and if nRST pin. Used please also remember to de-assert the nRST ping by pull it up."
So what I am doing with my Dig Pin 18 is setting that PWREN to high like they said but I have no idea what is up with that nRST they are talking about and why the PWREN pin is connected to the RTS pin on the TTL-USB converter (and what that even does) when I use the premade program. Even after a decent bit of research I still don't have a clue how this RTS pad functions and how I could implement that in my circuit (if I even need to).
Sorry for typing this much but I am trying to explain it all as detailed as I can to make finding the problem easier.

I have since found out that the PWREN Pin is not as stated in the manual default on LOW but it is on HIGH. So I changed my startup sequence by setting the Dig Pin 18 first to LOW then after a delay to HIGH and I was able to reproduce what happened when I checked and unchecked the RTS box in the premade software. The Laser is powered off and after a delay powered on again. From this point you are able to send commands (like measure) in the premade software. My problem now is that the sensor doesn't seem to receive my bytes of information I am trying to send it (for example Laser on). My wiring is still the same but my code now looks like this:

#define PWREN_PIN 18
#define RX2 16
#define TX2 17

#include <HardwareSerial.h>

HardwareSerial SerialPort(2);

byte startmsg[] = {0x55};
byte lon[] = {0xAA, 0x00, 0x01, 0xBE, 0x00, 0x01, 0x00, 0x01, 0xC1};// Laser on
byte shotmsg[] = {0xAA, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x21};
byte incomingByte;
byte testByte;

void setup() {
  delay(2000);
  pinMode(PWREN_PIN, OUTPUT);
  digitalWrite(PWREN_PIN, LOW);
  delay(3000);
  digitalWrite(PWREN_PIN, HIGH);
  delay(500);
  Serial.begin(19200);
  SerialPort.begin(19200,SERIAL_8N1,RX2,TX2);

  delay(100);
  SerialPort.write(lon, sizeof(lon));
  delay(100);


}

void loop() {
}

This should in theory turn the laser on but my byte isn't transmitted to the sensor for some reason. Again any help is appreciated.

Now that I can upload stuff here is the full manual:
M8XX Laser Distance Sensor USER MANUAL.pdf (2.7 MB)

Ok so I found out what caused the problem and got it to work so I am gonna post it here for anyone in the future struggling with this sensor.
The wiring of the RX, TX, VCC and GND I did was correct (if you run this on a 3.3V microcontroller you don't even need the 10K pull-up resistors for RX and TX) but the wiring of the PWREN Pin works the way I did it but doesn't have to be done that way. You can program it like I did and set the Dig Pin connected to PWREN to LOW and after a delay to HIGH (like the manual suggests) before starting the serial connection and it will work but you don't even need to do that. As done by another user it is enough to connect the PWREN Pin to the 3.3V+ of your power source (or Arduino [The ESP32 outputs enough current to run the sensor but I am not sure if that is really recommended]) and then connect it to the GND (it is suggested with a 10 uF capacitor in between). This way the PWREN pin gets a permanent HIGH from startup and it also works. The problem I had was that these pins here don't work:


The upper column of pins doesn't have RX, TX or PWREN it seems so you have to use the lower column of pins and also importantly don't connect anything to the upper column or you will run into problems (like I did). I used a sensor that was already connected to a PCB on the upper column of pins which is why it didn't work. Weirdly enough when I used the lower column of pins to connect it to my PC with the USB TTL converter it worked flawlessly which is why I didn't suspect something being connected to the upper column of pins to be an issue.
For completion sake and anyone trying to connect this sensor I will post the code and wiring schematic below.

Wiring:


Code:

#define RX 16
#define TX 17

#include <HardwareSerial.h>
HardwareSerial SERIAL_S(1);

#include <M88B4.h>

/*
On SERIAL_2 (UART2)
   M88B4       ESP32 
   
    RX    (D17) TX2
    TX    (D16) RX2
    VCC <-----> 3.3V
    PWREN <---> 3.3V
(10uF capacitor between PWREN and GND)
    GND <-----> GND          

*/



void setup() {
  //Pullup RX and TX pins to remove any noise
  gpio_pullup_en(GPIO_NUM_16);
  gpio_pullup_en(GPIO_NUM_17);

  Serial.begin(115200);

  delay(500);

  initSensor();
  delay(3000);


}

void loop() {

SERIAL_S.write(shotauto, sizeof(shotauto));
      delay(500);  
      if(SERIAL_S.available() > 0){ // Check if there is input from RX-TX communication     
          Serial.print(F("\nDistance : "));
          SERIAL_S.readBytes(incomingByte, 13);
          for(int i = 0; i < 13; i++) {
            if(incomingByte[i] < 10)  Serial.print("0"); 
            Serial.print(incomingByte[i], HEX); 
            Serial.print(" ");
          }
          Serial.println();
      }
      else {
          Serial.print("no data received");
      }

delay(2000);
}

Library file:
M88B4.h (2.6 KB)

So thats it. The only weird thing I have found is that the first byte sequence I Serial.write on the sensor always returns no data but every Serial.write after that works just fine. No clue why maybe someone has an idea but it's not that big of a deal to me at the time being so I am just glad I got it to work.

2 Likes

Thank you so much for all the effort you've put in. I'm also working with the JRT U81B laser and Arduino. It's only been three days, and I've encountered many problems. After seeing your work, I've decided to try with ESP32. I hope you're still around because I might need some help.

If I need assistance, I'll write from this post. (By the way, this is my first post on this forum. I'm not exactly sure how things work here.) Hopefully, you can help. Thanks again for all the effort you've put in.

Hey,
Yeah no problem if you run into any issues that you can't fix with what I have wrote here or you find on the internet just ask in this thread and I'll try to help.

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