Closed vidavidorra closed 8 years ago
C++ solution in a function that takes the analog pin number as argument and returns the read value as integer.
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <stdint.h>
#include <string>
...
int readAnalogPin(uint8_t pin)
{
std::string filePath = "";
switch (pin) {
case 0:
filePath = "/sys/bus/iio/devices/iio:device1/in_voltage0_raw";
break;
case 1:
filePath = "/sys/bus/iio/devices/iio:device1/in_voltage1_raw";
break;
case 2:
filePath = "/sys/bus/iio/devices/iio:device1/in_voltage2_raw";
break;
case 3:
filePath = "/sys/bus/iio/devices/iio:device1/in_voltage3_raw";
break;
case 4:
filePath = "/sys/bus/iio/devices/iio:device1/in_voltage4_raw";
break;
case 5:
filePath = "/sys/bus/iio/devices/iio:device1/in_voltage5_raw";
break;
default:
std::cout << "ERROR: Unspecified analog pin number.";
return (-1);
break;
}
if (filePath != "") {
std::ifstream inFile(filePath.c_str());
if (inFile.is_open()) {
std::string line;
getline(inFile, line);
inFile.close();
int readVal = std::stoi (line ,nullptr, 10);
return (readVal);
} else {
std::cerr << "ERROR: Could not open file" << inFile << "\n";
return (-1);
}
}
return -1;
}
So we definately have a bug there I think introduced from subplatforms, I'm hunting now.
Note that what you're doing is a really bad idea because there's pinmuxing involved, doing so will not work in many configurations and is also very platform dependant. This is the fix, bug was introduced with firmata merge, I'll make sure nothing breaks with this and merge it later today.
diff --git a/src/aio/aio.c b/src/aio/aio.c
index 8ebf7c0..58a8883 100644
--- a/src/aio/aio.c
+++ b/src/aio/aio.c
@@ -122,14 +122,15 @@ mraa_aio_init(unsigned int aio)
}
}
+ dev->channel = board->pins[pin].aio.pinmap;
+ dev->value_bit = DEFAULT_BITS;
+
// Create ADC device connected to specified channel
mraa_aio_context dev = mraa_aio_init_internal(board->adv_func, aio);
if (dev == NULL) {
syslog(LOG_ERR, "aio: Insufficient memory for specified input channel %d", aio);
return NULL;
}
- dev->channel = board->pins[pin].aio.pinmap;
- dev->value_bit = DEFAULT_BITS;
if (IS_FUNC_DEFINED(dev, aio_init_pre)) {
mraa_result_t pre_ret = (dev->advance_func->aio_init_pre(aio));
Fixed properly :/ Not on form today
Since v0.9.6 the AIO reads the same value for all the analog pins off the Intel Edison Arduino board. This means that the value of A0 is returned when reading A1 for example.
At the moment we've found a temporary solution which avoids using the Aio read function. This method is basically accessing the kernel files directly using normal file I/O.
The file that needs to be read to get an analog value directly from the kernel is shown below.
/sys/bus/iio/devices/iio:device1/in_voltage0_raw
where thevoltage0
is the value of A0 andvoltage1
is A1, and so on. This works for both the C++ and javascript environment. Please note that this solution will always read an integer value. So to get a float, the read value needs to be divided by the maximum value (1024 for 10-bit ADC and 4096 for 12-bit ADC).Hope this helps!