Reading analog voltage with ADC and attenuation

  • Hi all,

    I am playing with a rangefinder ultrasonic sensor (MB7360 from Maxbotix) and I have some question regarding the way to correctly read the sensor values.

    The sensor operates at voltage between 2.7V and 5.5V, so I hooked it up on the 3.3V pin of the expansion board.

    I am using the sensor's analog voltage output to read the distance measured by the sensor. In the spec-sheet it is mentioned that

    • the output is referenced to the sensor ground and Vcc (which is 3.3V, right?)
    • the scale factor is Vcc / 5120 per 1 mm
    • using a 10 bits ADC, we just need to multiply the voltage read by 5 to obtain the distance

    Since the maximum voltage output is 3.3V, I used an attenuation of 11 dB and I am using this piece of code to get the distance:

    from machine import ADC
    # setting up the Analog/Digital Converter with 10 bits
    adc = ADC(bits=10)
    # create an analog pin on P20 for the ultrasonic sensor
    apin ='P20', attn=ADC.ATTN_11DB)
    # get distance
    dist = apin() * 5

    With that code, the readings are not accurate, so I was wondering if I need to scale the distance to take into account the attenuation? (sorry if it's a stupid question, this is new to me)

    Many thanks for your help/comments/suggestions!



    PS: the sensor has also other outputs such as a Pulse Width output and a serial output (RS232 format), but the former seems to be difficult to measure using a LoPy (correct me if I am wrong, maybe I missed something while searching in the forum) and I don't have a RS232 <-> TTL converter with me for the later(plus I'd like to avoid using additional boards).

  • @robert-hh
    Thanks for all the clarifications! I'll switch to an ADC of 12 bits and give it a try.

  • @jojo The internal range of the ADC is 0-1V. The attentiation of 11dB gives the range of 0-3.3V, which is what you need for our sensor, running at an Vcc of 3.3V. So you do not need a factor of x of range scaling, but you might need it for calibration.
    I never used the ADC in a range other than 12 bits. It might be that in lower than 12 bits mode you have to shift right the returned value by 1 or 2 bits. I have to try. So if the value you get is off by a factor of 4, that this may be the reason.

  • @robert-hh
    Thanks for the quick reply! :)

    I should have said that when I use:

    dist = apin() * 5

    it is already a shortcut for

    dist = apin() * 5120 / 1024

    where 5120 is the sensor range and 1024 is the range of the ADC using 10 bits. I was wondering if because there is an attenuation, I also have to scale the value of apin() by a factor x:

    dist = apin() * 5 * x

    Also, thanks for the suggestions. I should have mentioned that the piece of code is just a simplified exemple. In my code I also take multiple readings and then use the median (I'm not too found of the mean due to the huge variability). I agree that using a RS232 <-> TTL converter is probably the best option.

  • @jojo With an attn of 11db, the range of the ADC is 0-3.3V. You used 10 bits, so 1024 is equivalent to about 5 meters. I would assume then that the distance in meters you should get is:

    ADC_RANGE = const(1024)
    sensor_range = 5.0
    dist = apin * sensor_range/ ADC_RANGE

    If you use bits=12, then ADC_RANGE has to be set to 4096. You might need to adapt sensor_range for calibration. And be warned, the ADC of ESP is not very good. It is nonlinear and noisy. It might be advisable instead of a single value to take the average of several values.
    Anyhow, from that data sheet it looks as anyhow using the serial output is the most precise option.

Log in to reply

Looks like your connection to Pycom Forum was lost, please wait while we try to reconnect.