Maxbotix sensor and TTL serial


#1

Hi guys,

I’m doing a project with water level measured by an ultrasonic sensor.
I have one live in the field, using an analog output, but wanted to get a version going with serial data from the sensor.

I got this one:
MB7389 HRXL-MaxSonar-WRMT

I intended to get the one that does RS232, but accidentally ordered the one that uses TTL data.
Is it possible to use this?

Can anyone point me in the right direction toward some sample code that I can start with to get it working? Project is on an Electron.

Thanks,
J


#2

If you want to connect your sensor to a Particle device you actually want a TTL version.


#3

OK, Great!

Any ideas for some sample code or a library that can help me get started?

thx,
J


#4

How about this?

found via Google “MB7389 HRXL-MaxSonar-WRMT arduino” :wink:

But the easiest sketch would look like this

void setup() {
  Serial.begin(115200);
  Serial1.begin(9600);
}
void loop() {
  while(Serial1.available())
    Serial.write(Serial1.read());
}

This will forward the incoming data via USB Serial to your computer to catch with any serial terminal program.


#5

Thanks @ScruffR, I’ll see if I can get going with that!
I saw the Arduino code, but I haven’t been too successful adapting Arduino code to the Particle in the past. Even just writing the serial to a terminal might just be enough to get things going.
J


#6

With 0.6.2 Arduino compatibility/portability has been much improved (where it’s not directly HW dependent). Just add #include <Arduino.h>.

But with a mere RX/TX communication there should not be any problem with any version.


#7

Hi All,

I’ve got a problem that has developed with an electron that is in a remote location, and I’m trying to diagnose the issue. It has a maxbotix sensor that gives me a distance reading, and for part of the day it is giving very erratic readings, and the other half of the day it is quite steady.

I want to change the way I’m getting the data from the sensor, from the analog output (which is affected by the input voltage to the sensor) to the serial output. It already has a connection from the RX pin on the electron to the Tx pin on the sensor which I tested before deployment with a super simple sketch (thanks @ScruffR!) :

void setup() {
Serial.begin(115200);
Serial1.begin(9600);
}
void loop() {
while(Serial1.available())
Serial.write(Serial1.read());
}

Since I can’t connect via USB (I won’t be able to make a trip out there for weeks) - I want to make a firmware version to send a publish with the received serial data. The Serial data is ASCII capital “R”, followed by maximum 4 ASCII (numerical) character digits.

Can someone point me to an example that will help me get the serial data into a variable and publish the result? I’ve gone thru @rickkas7’s serial tutorial, but am still not clear how to read the incoming data and get it into a variable that I can use in a publish event. Maxbotix gives some code examples, but I can’t find any for the serial output (probably why I used the analog method!). I’m sure I could bumble thru it if I could physically get to the unit and use the USB serial, but without that access, I need more help!

Would very much appreciate some guidance or someone to point me in the right direction.

Thanks,
J


#8

Could it be that at these times the sun is directly shining on the sensor?
On my car the parking sensors cry havoc when the sun shines on them directly for a few hours.

A simple way to wait for a serial transmission starting with R would be to

  • use Serial1.peek() to check for R as next character
    • if it isn’t, just consume that byte via Serial1.read()
    • if it is, just wait for Serial1.available() >= 5
  • once Serial1.available() >= 5 read into a char[6]
  • parse (e.g. someInt = atoi(&buf[1]) or sscanf(buf, "R%d", &someInt))

#9

Thanks,

I wish it was that, at least I’d understand it.

It did exactly the same thing the past two days, both started at 0020 local time, and the first day lasted 12 hours, the second on lasted 13 hours. It doesn’t seem to have occurred this morning.

I’ll try to get some working serial code into it later today to see if that helps the stability of the data, and to compare that to the analog measurement. I’m testing a new model at home that has a temperature sensor in the enclosure, and I’m seeing a pretty significant correlation between enclosure temp and distance reading errors, so I’m going to have to install an external temp sensor to compensate the ultrasonic readings - the enclosure gets much hotter than the air that I’m ranging in, so the sensor thinks it needs to adjust for a different speed of sound than is actually present. The analog sensing is also based on the sensor input voltage, which I’ve hoped has been steady but I haven’t measured - it comes from a 3.3v reg on the board the electron is on.

J


#10

Does this look like a good way to get my Serial Data? It seems to work, but I want to make sure Im doing it right.
Am I using serial.readBytes correctly?

while(Serial1.available()) {
            checkForR = Serial1.peek();
            if (checkForR == 'R') {
                if (Serial1.available() >= 5) {
                    Serial1.readBytes(buf,6);
                    distanceToWaterMM = atoi(&buf[1]);
                    return(distanceToWaterMM);
                }
            }
            else {
                Serial1.read();
            }

#11

I think this should work and while there are alternative ways to do it, if this is the way that’s best comprehensible to you, then that’s the way you should do it.

One thing I’d suggest tho’ is to add some timeout for the while(), just in case you don’t get a valid transmission - e.g. you get the R but then the wire drops out and you never get all the required bytes. Then you should probably flush the buffer and issue some warning.


#12

Cool, thanks.
something like this:

if (waitFor(Serial1.available() >= 5), 10000) {
   //get my serial data
}
else {
   //flush buffer and log timeout message
}

#13

Or like this

  char buf[7];
  static uint32_t msTimeout = 0;              // timestamp of recently found R
                                              // persists between calls of function
  while(Serial1.available()) {
    if ('R' == Serial1.peek()) {
      if (!msTimeout) msTimeout = millis();   // when new R found - store timestamp
      if (Serial1.available() >= 5) {         // already received a complete packet?
        memset(buf, 0x00, sizeof(buf));       // ensure properly terminated string
        Serial1.readBytes(buf, 6);            // read the packet
        distanceToWaterMM = atoi(&buf[1]);    // convert string following the R to integer
        msTimeout = 0;                        // prepare for next incoming R
        return(distanceToWaterMM);
      }
      else if(millis() - msTimeout > 1000) {  // current R is outdated
        Serial1.read();                       // flush R and move on
        msTimeout = 0;                        // prepare for next incoming R   
      }
    }
    else {
      Serial1.read();                        // flush "orphaned" bytes
    }
  }

#14

Cool, I like it. Good to see how someone who understands all this stuff does it!
J