GPIO Analog Data

edited May 2018 in C++

Hi,

I am trying to read analog data from an external sensor but I am having trouble getting valid values.

I have connected a MPXV5050DP Differential Pressure Sensor (Datasheet) to Analog Pin 0 of a MetaWearRG Board. The sensor is also connected to an external power source that provides a supply voltage of 5V. I have also connected a Voltmeter to the sensor and I know for sure that the output of the sensor is approximately 230 mV. I have also verified the output using an Arduino UNO. However, when I use the C++ API to perform an analog read from the MetaWear board the data I receive seem to be random values. For example, when I do consecutive analog reads the voltage that the API reads can vary from 800 mV to 1500 mV.

I am using the standard code described in the latest C++ Documentation which is:

auto abs_ref_signal = mbl_mw_gpio_get_analog_input_data_signal(board, 0, MBL_MW_GPIO_ANALOG_READ_MODE_ABS_REF);
    mbl_mw_datasignal_subscribe(abs_ref_signal, nullptr, [](void* context, const MblMwData* data) {
        // Cast value to uint32_t*
        printf("Analog Input Voltage = %d mV\n", *((uint32_t*) data->value));
    });
for(int i = 0; i < 20; ++i) mbl_mw_datasignal_read(abs_ref_signal);

I have tried setting a pullup/pulldown pin (although I am not familiar with the concept) and setting a delay of 10/20 milliseconds but this doesn't work either.
Is there something wrong with my board? Is there a different way I can try to read the correct values?

By the way, I am using Ubuntu 16.0.4 and my BlueZ version is 5.42.

Comments

  • The GPIO pins are only rated for 3V; I would not recommend using that pressure sensor as it's max output voltage is 5V, or you will need to add additional circuitry to protect against overvoltage.

    Please provide a circuit diagram of your current setup. The root cause of your issue is probably with the circuit.

  • Hi Eric.

    I understand that this sensor can have an output voltage greater than 3V but I will find a way to restrain the output voltage. However, for the moment the output voltage of the sensor is not greater than 500 mV so there shouldn't be any problem.

    Circuit Diagram

    Here is a diagram of my circuit. As you can see it is really simple and straightforward.

  • Hi @Manos.

    Is that the complete wiring diagram? If so, you should attach the ground from the power source to one of the MetaWear ground connections as well. You can route the wire from the ground connection at the pressure sensor -- this is preferable from a performance perspective.

    As you have it wired now, there is no common reference point (typically ground) between the sensor and the MetaWear.

    As Eric mentioned, you will want to limit the voltage delivered to the MetaWear, as it will be easily damaged by voltage exceeding ratings. You could do this with a voltage divider, a current limiting resistor and zener, etc. If there is a 3.0/3.3V version of the sensor that would be even better.

  • edited May 2018

    Hi @Matt

    Yes that was the complete wiring diagram and the problem was the one you described. I have updated the circuit and now it works correctly. I am not familiar with circuits and that was clearly my mistake. Thank you for your response, your post was really helpful. I am attaching a diagram of my current circuit in case someone else needs it in the future.
    As far as the voltage is concerned I know that the board can be damaged and that's why I make sure that with the current usage of the sensor the voltage is never greater than 500 mV. For the moment our system is still being developed that's why I am not concerned about the output of the pressure sensor. We will see in the near future whether we use a different sensor or simply limit the output voltage of the current one. However, thank you for your concern.

    Now regarding the C++ API. Is there a way to stream analog data? I've noticed that when using mbl_mw_datasignal_read your API writes a certain value to a GATT characteristic and then there is a GATT notification that it processes. However, this can take some time. Can I stream data like the accelerometer? I've seen in the documentation that a Timer can be used and read analog data every time the timer ticks but if I understand correctly this is "master" side. I was wondering if it is possible to be achieved through the MetaWearRG board and have it send GPIO adc data periodically (like the accelerometer).

  • @Manos said:
    Now regarding the C++ API. Is there a way to stream analog data? I've noticed that when using mbl_mw_datasignal_read your API writes a certain value to a GATT characteristic and then there is a GATT notification that it processes. However, this can take some time. Can I stream data like the accelerometer? I've seen in the documentation that a Timer can be used and read analog data every time the timer ticks but if I understand correctly this is "master" side. I was wondering if it is possible to be achieved through the MetaWearRG board and have it send GPIO adc data periodically (like the accelerometer).

    https://mbientlab.com/cppdocs/0/timer.html#task-scheduling

  • edited May 2018

    Hi Eric.

    I am trying to use the Timer as you suggested. I am using the standard code that you provide in the C++ documentation (the link you gave me). My problem is that when creating a timer, it is always a NULL one. This means that inside the function timer_created the MblMwTimer* timer argument is always nullptr and that leads to a Segmentation Fault. I cannot understand why this happens. I have verified that the MblMwMetaWearBoard* argument that i give to timer_setup is not nullptr.

    One thing I should note is that I changed the following line of code from

    auto adc_signal= mbl_mw_gpio_get_analog_input_data_signal(board, 0, MBL_MW_GPIO_ANALOG_READ_MODE_ADC);

    to

    auto adc_signal= mbl_mw_gpio_get_analog_input_data_signal(owner, 0, MBL_MW_GPIO_ANALOG_READ_MODE_ADC);
    

    I believe that this is the correct way beacuase otherwise it won't compile.

  • Reset the board then try again. It sounds like there are already exiting timers present on the board that were never removed.

  • @Eric said:
    Reset the board then try again. It sounds like there are already exiting timers present on the board that were never removed.

    Do you mean call mbl_mw_metawearboard_tear_down?

    I've seen that the iOS (Swift) API provides a way to reset the board. Is there something similar for the C++ API?

  • edited June 2018

    No, i mean exactly as stated, though in this instance, mbl_mw_metawearboard_tear_down will also work.

    Yes, mbl_mw_debug_reset

  • @Eric said:
    No, i mean exactly as stated, though in this instance, mbl_mw_metawearboard_tear_down will also work.

    Yes, mbl_mw_debug_reset

    Thank you Eric I will try this out.
    As you may know there is no documentation about mbl_mw_debug_ and even a search of "reset" on the C++ API overview does not show anything up so I couldn't know about it.

This discussion has been closed.