Closed xbolshe closed 8 years ago
2.Look at https://communities.intel.com/thread/94135 It seems MRAA does not control pull-up resistors while using ADC convertor. And there is a voltage on an analog pin, when there is no external connection.
Here is a related part of Gen2 circuit diagram:
And simplified picture:
And PIN configuration:
Now have: Direction = Output Value = 1 (VCC voltage to resistor)
Shall be: Direction = Input Value = Any
And code with bug:
mraa_result_t mraa_setup_mux_mapped(mraa_pin_t meta) { int mi;
for (mi = 0; mi < meta.mux_total; mi++) {
mraa_gpio_context mux_i;
mux_i = mraa_gpio_init_raw(meta.mux[mi].pin);
if (mux_i == NULL) {
return MRAA_ERROR_INVALID_HANDLE;
}
// this function will sometimes fail, however this is not critical as
// long as the write succeeds - Test case galileo gen2 pin2
mraa_gpio_dir(mux_i, MRAA_GPIO_OUT);
mraa_gpio_owner(mux_i, 0);
if (mraa_gpio_write(mux_i, meta.mux[mi].value) != MRAA_SUCCESS) {
mraa_gpio_close(mux_i);
return MRAA_ERROR_INVALID_RESOURCE;
}
mraa_gpio_close(mux_i);
}
return MRAA_SUCCESS;
}
Seems need to add pull-up resistor control for ADC conversion in MRAA API.
Just to make sure (because as @arfoll mentioned this part of the functionality should be quite well-tested) - what exactly is the problem here from the user standpoint, sort of "so what if we don't control these"?
Problem: ADC performs a measurement of unexpected signal (when an additional resistor is connected to the GND or VCC, or an analog pin is connected to the GND or VCC via digital outputs of A0,A1,A2,...). An unexpected signal may be changed from time to time and randomly.
My perspective of the problem as a user of the Galileo Gen 2 is that the A0 can not be used to read input of sensors.
As an example I have an TMP36 wired to A0 and another wired to A1. Reading the values using python and MRAA I get different readings.
I use this program here: https://github.com/joemcmanus/analog/blob/master/analog.py
TMP36 on A0:
| Raw MRAA Reading | 1384 | | MRAA Voltage Calc | 1.6899 |
TMP on A1: | Raw MRAA Reading | 584 | | MRAA Voltage Calc | 0.7131 |
The voltage on A0 is just wrong...
Cheers, -Joe
In the problem case of @joemcmanus the following PIN configuration is applied while reading A0:
GPIOs 48-63, i2c/0-0027, pcal9555a, can sleep: gpio-48 (sysfs ) in hi gpio-49 (sysfs ) out hi gpio-50 (sysfs ) in lo gpio-51 (sysfs ) in lo
gpio-49 enables a pull-up resistor to VCC.
And A1 works correctly because of A1.mux_total = 0
It's weird because I've tried with the muxes, using mux_total=1, clean reboots and after initialising i2c (which will flip the muxes), and A0 & A1 are fairly stable. A1 is usually a little on the low side but I can't see anything much different to usual. I'm happy to take the change to set mux_total=1 since that seems to be what "should" be done and doesn't seem to harm anything but it doesn't imho fix any issues of galileo gen2 ADC being a little 'dodgy'. in testing (admitedly ages ago) we tried mraa against arduino on gen2 (totally different implementations) and found ADC results matched.
My testing is on the Intel Galileo Gen 2 using the IoTDevKit image iot-devkit-201510010757-mmcblkp0-galileo.direct . I have tested this on two different Galileo Gen 2's reading using MRAA and reading from the file system /sys/bus/iio/devices/iio:device0/in_voltage0_raw .
Full thread on the intel community https://communities.intel.com/thread/94135 .
@arfoll I have checked circuit diagrams and found that:
I may expect that after booting many boards have a stable and repeatable state of GPIOs. That is why in many situations there is no problem. But if in some cases GPIOs are changes before operations (because of new firmware, some programs, etc.), MRAA processing is unexpected. And need to perform a full initialisation of GPIOs before operations.
So, a current MRAA version does not perform a full initialisation of GPIOs as needed for Galileo Gen2 board.
Why does intel_edison_fab_c.c have pullup_map[] in mraa_intel_edison_aio_init_pre as well as mraa_gpio_dir(pullup_pin, MRAA_GPIO_IN) while Gen2 has not ?
Just need to repeat the idea in intel_edison_fab_c.c regarding pullup_map[] for Gen2.
Also there is a problem with:
A4:
b->pins[18].aio.mux_total = 3;
b->pins[18].aio.mux[0].pin = 60;
b->pins[18].aio.mux[0].value = 1;
b->pins[18].aio.mux[1].pin = 78;
b->pins[18].aio.mux[1].value = 0;
b->pins[18].aio.mux[2].pin = 57;
b->pins[18].aio.mux[2].value = 0;
A5:
b->pins[19].aio.mux_total = 3;
b->pins[19].aio.mux[0].pin = 60;
b->pins[19].aio.mux[0].value = 1;
b->pins[19].aio.mux[1].pin = 79;
b->pins[19].aio.mux[1].value = 0;
b->pins[19].aio.mux[2].pin = 59;
b->pins[19].aio.mux[2].value = 1;
Why is a different value used for pin 59 and 57 ?
BR, xbolshe
It is possible that enabled and uncontrolled pull-up/pull-down resistors block I2C bus on A4/A5. That causes that there is a problem with GPIO control of many pins.
Some pictures how to reproduce an I2C time-out issue with an external wire: Same situation is present with internal pull-up/down resistors.
Here is my proposal to fix: https://github.com/intel-iot-devkit/mraa/pull/459
BR, xbolshe
The fix was commited with 3397c95c0a15fa42d15ed0b7a4b04ff0f6d17276 and 95c259f6b2420f04078ea83ec5c9a9a9e52f3a77, closing this one.
Let's see https://github.com/intel-iot-devkit/mraa/blob/master/src/x86/intel_galileo_rev_g.c
// ANALOG strncpy(b->pins[14].name, "A0", 8); b->pins[14].aio.pinmap = 0; b->pins[14].aio.mux_total = 1; b->pins[14].aio.mux[0].pin = 49; b->pins[14].aio.mux[0].value = 1;
I'm not sure about bugs, but have questions:
BR, xbolshe