In this blog post, we will explore the ways of interfacing a temperature sensor using both mraa and upm.
The Grove temperature sensor that we are going to use is a class of transducer know as the thermistor. It is called so because it's resistance (the 'istor') part is controlled by the thermal energy ('therm' part) applied on the sensor. We are going to use the Grove temperature sensor.
We have already learned from the previous blog post that with ADC, we can measure the change in the resistance of a device connected to the analog input of Edison/Galileo.
Connect the temperature sensor to analog port 0. Note that in the circuit fritzing diagram, the Grove temperature sensor depicted is older one but the one used in this tutorial is same as in the link above however, this has no impact on the circuit connection.
The resistance offered by the thermistor varies linearly with applied/ambient thermal energy. From the wiki page of the Grove temperature module, by following the example, we can learn how the measured resistance value relates to the ambient temperature. Using the equations listed in the above link. Usually, these equations will be listed in the manufacturer's datasheet.
Using these equations, we will now implement a mraa based implementation that will read the resistance using ADC and applies the required transformation on the read value to print the temperature in degree Celsius on the console.
As usual, we start by creating context for analog IO, called “adc_pin” and the context is initialized:
Then the value is read using this context and then, transformation is done on this raw value in accordance to the equation and then the value is printed.
Note that we are adding the math lib (via -lm) for using the log() function
Even though we will be using C++ from now on, I will limit to the language’s usage only to instantiate and use of the sensor object under consideration and rest of the things in the code will largely be in ‘C’ style.
The Grove temperature sensor that we are going to use is a class of transducer know as the thermistor. It is called so because it's resistance (the 'istor') part is controlled by the thermal energy ('therm' part) applied on the sensor. We are going to use the Grove temperature sensor.
We have already learned from the previous blog post that with ADC, we can measure the change in the resistance of a device connected to the analog input of Edison/Galileo.
Hardware connection:
Connect the temperature sensor to analog port 0. Note that in the circuit fritzing diagram, the Grove temperature sensor depicted is older one but the one used in this tutorial is same as in the link above however, this has no impact on the circuit connection.
Using mraa to read the temperature
The resistance offered by the thermistor varies linearly with applied/ambient thermal energy. From the wiki page of the Grove temperature module, by following the example, we can learn how the measured resistance value relates to the ambient temperature. Using the equations listed in the above link. Usually, these equations will be listed in the manufacturer's datasheet.
Using these equations, we will now implement a mraa based implementation that will read the resistance using ADC and applies the required transformation on the read value to print the temperature in degree Celsius on the console.
#include <stdio.h> #include <mraa.h> #include <math.h> // for the log function const int B = 4275; // B value for thermistor const int R0 = 100; // R0 is 100k ohms #define TEMP_ADC_PIN 0 // ADC pin is 0 int main(void) { mraa_aio_context adcPin; // used as AIO context float adcValue; // ADC value read into this variable float R, temperature; // Used in calculations /* Step1: Initialize the mraa */ mraa_init(); /* Step2: Initlaize the ADC pin */ adcPin = mraa_aio_init(TEMP_ADC_PIN); /* Step3: Read the ADC value */ adcValue = mraa_aio_read(adcPin); /* Step4: Apply the transformation */ R = 1023.0/((float)adcValue)-1.0; // Promote to float R = 100000.0*R; temperature = 1.0/(log(R/100000.0)/B+1/298.15)-273.15; /* Step5: Print the temperature */ printf ("The temperature is %0.2f degree Celcius\n", temperature); return 0; }
As usual, we start by creating context for analog IO, called “adc_pin” and the context is initialized:
/* Step1: Initialize the mraa */ mraa_init(); /* Step2: Initlaize the ADC pin */ adcPin = mraa_aio_init(TEMP_ADC_PIN);
Then the value is read using this context and then, transformation is done on this raw value in accordance to the equation and then the value is printed.
adcValue = mraa_aio_read(adcPin);
R = 1023.0/((float)adcValue)-1.0; R = 100000.0*R; temperature = 1.0/(log(R/100000.0)/B+1/298.15)-273.15; printf ("The temperature is %0.2f degree Celcius\n", temperature);
Trying it out:
Run the following command from within your Edison console to download and compile the source code:curl https://raw.githubusercontent.com/navin-bhaskar/C-CPP-on-Intel-Edison-Galileo/master/part5-temperature/temp_mraa.c > temp_mraa.c gcc -o temp temp_mraa.c -lmraa -lm
Run the code by typing
./temp
You should see the temperature printed on your console
Using the upm library
Now we will use the upm library to interface the Grove temperature sensor module with the Edison/Galileo. upm is a C++ library that kind of abstracts all the lower level details and presents a clean and consistent APIs across a class of sensors. For example, in case of temperature sensor, you can find consistent APIs for different temperature sensor (sometimes with some difference in the way they behave) and the methods provided by upm library for a particular sensor will take care of details such as the physical interface used and the way the sensor is to be operated on.Even though we will be using C++ from now on, I will limit to the language’s usage only to instantiate and use of the sensor object under consideration and rest of the things in the code will largely be in ‘C’ style.
#include <stdio.h> // for printf() /* Step1: Bring in the upm */ #include <upm/grove.h> #define TEMP_ADC_PIN 0 // ADC pin is 0 int main(void) { int temperature; /* Step2: Instantiate an instance of Grove temperature sensor */ upm::GroveTemp *temp = new upm::GroveTemp(TEMP_ADC_PIN); /* Step3: Record the temperature and print */ temperature = temp->value(); printf ("The temperature is %d degree Celcius\n", temperature); return 0; }
#include <upm/grove.h> #define TEMP_ADC_PIN 0 // ADC pin is 0 upm::GroveTemp *temp = new upm::GroveTemp(TEMP_ADC_PIN);
temperature = temp->value(); printf ("The temperature is %d degree Celcius\n", temperature);
Trying it out:
Fetch the source from github:
curl https://raw.githubusercontent.com/navin-bhaskar/C-CPP-on-Intel-Edison-Galileo/master/part5-temperature/temp_upm.cpp > temp_upm.cpp
we would be using the ‘g++’ compiler which is GNU’s C++ compiler to generate the executable out of the downloaded source file
g++ temp_upm.cpp -o temp_upm -lupm-grove
Note that we are adding the "upm-grove" lib in the command line. "upm-grove" is where the upm objects for Grove kit is defined.
Run the executable using following command to see the temperature value printed on your console:
./temp_upm
You should see the temperature being printed out
No comments:
Post a Comment