enc03r: C port; FTI; C++ wraps C

The API for this driver has changed.  See docs/apichanges.md.

Signed-off-by: Jon Trulson <jtrulson@ics.com>
This commit is contained in:
Jon Trulson 2017-01-27 17:58:35 -07:00
parent f914159e21
commit 1bbb9386b7
15 changed files with 758 additions and 165 deletions

View File

@ -4,9 +4,16 @@ API Changes {#apichanges}
Here's a list of other API changes made to the library that break source/binary
compatibility between releases:
* **enc03r** This driver no longer supports the value() function. In
addition, an update() function has been added. This function must be
called prior to calling angularVelocity(). angularVelocity() no
longer accepts an argument. Additional functions have been added,
however they do not affect compatibility with previous versions.
* **ds18b20** The C++ interface init() function has been deprecated.
It is still present, but currently does nothing. It will be removed
in a future release.
* **grove<name>** Starting with UPM 1.0 the Grove libraries have been renamed
from *upm-grove<name>* to simply *upm-<name>*. Class names also match this new
format, with old classes marked as deprecated throughout the documentation.
@ -14,27 +21,35 @@ compatibility between releases:
groveelectromagnet, groveemg, grovegprs, grovegsr, grovelinefinder, grovemd,
grovemoisture, groveo2, grovescam, grovespeaker, groveultrasonic, grovevdiv,
grovewater, grovewfs.
* **grove** As of UPM 1.0 the Grove classes for sensors in the starter kit are
being separated into individual libraries. The old classes will be deprecated
over time and eventually removed. Corresponding libraries have the grove
prefix removed. Affected classes are GroveButton, GroveLed, GroveLight,
GroveRelay, GroveRotary, GroveSlide and GroveTemp.
* The **ublox6** driver has been replaced with a generic implementation called
nmea_gps as of UPM 1.0. This driver should handle all generic serial GPS
devices that output NMEA data going forward. This new driver has been tested
with ublox6, DFRobot VK2828U7 (ublox7) and ublox LEA-6H GPS devices.
* **grove** Binary compatibility was broken for the GroveTemp class as of UPM
v0.7.3. C++ code using this class has to be recompiled.
* There were frequent misspellings of the word *Celsius* in the UPM
code. In some cases, these were in method names, which will cause
some API compatibility issues. These have all been corrected for UPM
versions after v.0.7.2.
* Our **C++ header files** changed their extension from *.h* to *.hpp* in
version 0.7.0, Intel provided examples and code samples also reflect this
change but you will need to modify your `#include` directives in existing
code.
* **my9221**, **groveledbar** and **grovecircularled** are now all part of the
same library (my9221) and new functionality was added going to v.0.5.1.
* **stepmotor** driver API was changed significantly from v.0.4.1 to v.0.5.0.
* **eboled** library was greatly improved in version 0.4.0 and the `draw()`
function was removed in favor of a more complete GFX library implementation.

View File

@ -1,6 +1,6 @@
/*
* Author: Jon Trulson <jtrulson@ics.com>
* Copyright (c) 2014 Intel Corporation.
* Copyright (c) 2014-2017 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@ -36,44 +36,45 @@ bool shouldRun = true;
void sig_handler(int signo)
{
if (signo == SIGINT)
shouldRun = false;
if (signo == SIGINT)
shouldRun = false;
}
int main()
{
signal(SIGINT, sig_handler);
signal(SIGINT, sig_handler);
//! [Interesting]
// Instantiate a ENC03R on analog pin A0
upm::ENC03R *gyro = new upm::ENC03R(0);
// Instantiate a ENC03R on analog pin A0
upm::ENC03R *gyro = new upm::ENC03R(0);
// The first thing we need to do is calibrate the sensor.
cout << "Please place the sensor in a stable location, and do not" << endl;
cout << "move it while calibration takes place." << endl;
cout << "This may take a couple of minutes." << endl;
// The first thing we need to do is calibrate the sensor.
cout << "Please place the sensor in a stable location, and do not" << endl;
cout << "move it while calibration takes place." << endl;
cout << "This may take a couple of minutes." << endl;
gyro->calibrate(CALIBRATION_SAMPLES);
cout << "Calibration complete. Reference value: "
<< gyro->calibrationValue() << endl;
gyro->calibrate(CALIBRATION_SAMPLES);
cout << "Calibration complete. Reference value: "
<< gyro->calibrationValue() << endl;
// Read the input and print both the raw value and the angular velocity,
// waiting 0.1 seconds between readings
while (shouldRun)
// Read the input and print both the raw value and the angular velocity,
// waiting 0.1 seconds between readings
while (shouldRun)
{
unsigned int val = gyro->value();
double av = gyro->angularVelocity(val);
gyro->update();
cout << "Raw value: " << val << ", "
<< "angular velocity: " << av << " deg/s" << endl;
cout << "Angular velocity: "
<< gyro->angularVelocity()
<< " deg/s"
<< endl;
usleep(100000);
usleep(100000);
}
//! [Interesting]
cout << "Exiting" << endl;
cout << "Exiting" << endl;
delete gyro;
return 0;
delete gyro;
return 0;
}

View File

@ -147,6 +147,7 @@ add_example (speaker)
add_example (cjq4435)
add_example (hmc5883l)
add_example (wfs)
add_example (enc03r)
# Custom examples
add_custom_example (nmea_gps_i2c-example-c nmea_gps_i2c.c nmea_gps)

90
examples/c/enc03r.c Normal file
View File

@ -0,0 +1,90 @@
/*
* Author: Jon Trulson <jtrulson@ics.com>
* Copyright (c) 2014-2017 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <upm_utilities.h>
#include <upm_platform.h>
#include "enc03r.h"
bool shouldRun = true;
// The number of samples used for calibration
#if defined(UPM_PLATFORM_ZEPHYR)
# define CALIBRATION_SAMPLES 500
#else
# define CALIBRATION_SAMPLES 1000
#endif
void sig_handler(int signo)
{
if (signo == SIGINT)
shouldRun = false;
}
int main()
{
signal(SIGINT, sig_handler);
//! [Interesting]
// Instantiate a ENC03R on analog pin A0
enc03r_context sensor = enc03r_init(0, 5.0);
if (!sensor)
{
printf("%s: enc03r_init() failed\n", __FUNCTION__);
return 1;
}
// The first thing we need to do is calibrate the sensor.
printf("Please place the sensor in a stable location, and do not\n");
printf("move it while calibration takes place.\n");
printf("This may take a little time to complete.\n");
enc03r_calibrate(sensor, CALIBRATION_SAMPLES);
printf("Calibration complete. Reference value: %f\n\n",
enc03r_calibration_value(sensor));
// Read the input and print both the raw value and the angular velocity,
// waiting 0.1 seconds between readings
while (shouldRun)
{
enc03r_update(sensor);
printf("Angular velocity: %f deg/s\n",
enc03r_angular_velocity(sensor));
upm_delay_ms(100);
}
printf("Exiting\n");
enc03r_close(sensor);
//! [Interesting]
return 0;
}

View File

@ -22,7 +22,7 @@
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
//NOT TESTED!!!
public class ENC03RSample {
private static final long CALIBRATION_SAMPLES = 1000;
@ -42,12 +42,13 @@ public class ENC03RSample {
// Read the input and print both the raw value and the angular velocity,
// waiting 1 second between readings
while (true) {
long val = gyro.value();
double av = gyro.angularVelocity(val);
gyro.update();
System.out.println("Raw value: " + val + ", angular velocity: " + av + " deg/s");
System.out.println("Angular velocity: "
+ gyro.angularVelocity()
+ " deg/s");
Thread.sleep(1000);
Thread.sleep(100);
}
// ! [Interesting]
}

View File

@ -30,8 +30,8 @@ var myGyro = new analogGyro.ENC03R(0);
var CALIBRATION_SAMPLES = 1000;
console.log("Please place the sensor in a stable location,\n" +
"and do not move it while calibration takes place.\n" +
"This may take a couple of minutes.");
"and do not move it while calibration takes place.\n" +
"This may take a couple of minutes.");
myGyro.calibrate(CALIBRATION_SAMPLES);
console.log("Calibration complete. Reference value: " +
@ -41,23 +41,22 @@ console.log("Calibration complete. Reference value: " +
// waiting 0.1 seconds between readings
setInterval(function()
{
var gyroVal = myGyro.value();
var outputStr = "Raw value: " + gyroVal + ", " +
"angular velocity: " +
roundNum(myGyro.angularVelocity(gyroVal), 5) + " deg/s";
console.log(outputStr);
myGyro.update();
var outputStr = "Angular velocity: " +
roundNum(myGyro.angularVelocity(), 5) + " deg/s";
console.log(outputStr);
}, 100);
function roundNum(num, decimalPlaces)
{
var extraNum = (1 / (Math.pow(10, decimalPlaces) * 1000));
return (Math.round((num + extraNum) * (Math.pow(10, decimalPlaces))) /
var extraNum = (1 / (Math.pow(10, decimalPlaces) * 1000));
return (Math.round((num + extraNum) * (Math.pow(10, decimalPlaces))) /
Math.pow(10, decimalPlaces));
}
// Print message when exiting
process.on('SIGINT', function()
{
console.log("Exiting...");
process.exit(0);
console.log("Exiting...");
process.exit(0);
});

View File

@ -55,10 +55,9 @@ def main():
print("Reference value: ", myAnalogGyro.calibrationValue())
while(1):
gyroVal = myAnalogGyro.value();
outputStr = ("Raw value: {0}, "
"angular velocity: {1}"
" deg/s".format(gyroVal, myAnalogGyro.angularVelocity(gyroVal)))
myAnalogGyro.update();
outputStr = ("Angular velocity: {0}"
" deg/s".format(myAnalogGyro.angularVelocity()))
print(outputStr)
time.sleep(.1)

View File

@ -0,0 +1,42 @@
/*
* Author: Jon Trulson <jtrulson@ics.com>
* Copyright (c) 2017 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef UPM_GYROSCOPE_H_
#define UPM_GYROSCOPE_H_
#ifdef __cplusplus
extern "C" {
#endif
// Gyroscope function table
typedef struct _upm_gyroscope_ft {
upm_result_t (*upm_gyroscope_set_scale) (void* dev, float* scale);
upm_result_t (*upm_gyroscope_set_offset) (void* dev, float* offset);
upm_result_t (*upm_gyroscope_get_value) (void* dev, float* value);
} upm_gyroscope_ft;
#ifdef __cplusplus
}
#endif
#endif /* UPM_GYROSCOPE_H_ */

View File

@ -126,6 +126,7 @@ typedef struct _upm_sensor_ft* (*func_get_upm_sensor_ft)(upm_sensor_t sensor_typ
#include <fti/upm_rotaryencoder.h>
#include <fti/upm_pressure.h>
#include <fti/upm_compass.h>
#include <fti/upm_gyroscope.h>
#ifdef __cplusplus
}

View File

@ -1,5 +1,9 @@
set (libname "enc03r")
set (libdescription "Enc03r single axis analog gyro module")
set (module_src ${libname}.cxx)
set (module_hpp ${libname}.hpp)
upm_module_init()
upm_mixed_module_init (NAME enc03r
DESCRIPTION "Single-axis Analog Gyroscope"
C_HDR enc03r.h
C_SRC enc03r.c
CPP_HDR enc03r.hpp
CPP_SRC enc03r.cxx
FTI_SRC enc03r_fti.c
CPP_WRAPS_C
REQUIRES mraa)

158
src/enc03r/enc03r.c Normal file
View File

@ -0,0 +1,158 @@
/*
* Author: Jon Trulson <jtrulson@ics.com>
* Copyright (c) 2014-2017 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "enc03r.h"
enc03r_context enc03r_init(int pin, float aref)
{
// make sure MRAA is initialized
int mraa_rv;
if ((mraa_rv = mraa_init()) != MRAA_SUCCESS)
{
printf("%s: mraa_init() failed (%d).\n", __FUNCTION__, mraa_rv);
return NULL;
}
enc03r_context dev =
(enc03r_context)malloc(sizeof(struct _enc03r_context));
if (!dev)
return NULL;
// zero out context
memset((void *)dev, 0, sizeof(struct _enc03r_context));
dev->a_ref = aref;
if ( !(dev->aio = mraa_aio_init(pin)) )
{
printf("%s: mraa_aio_init() failed.\n", __FUNCTION__);
enc03r_close(dev);
return NULL;
}
dev->offset = 0.0;
dev->scale = 1.0;
dev->a_res = (float)(1 << mraa_aio_get_bit(dev->aio)) - 1.0;
dev->calibrationValue = 0.0;
return dev;
}
void enc03r_close(enc03r_context dev)
{
assert(dev != NULL);
if (dev->aio)
mraa_aio_close(dev->aio);
free(dev);
}
upm_result_t enc03r_update(enc03r_context dev)
{
assert(dev != NULL);
float val = (float)mraa_aio_read(dev->aio);
if (val < 0)
{
printf("%s: mraa_aio_read() failed\n", __FUNCTION__);
return UPM_ERROR_OPERATION_FAILED;
}
dev->normalized = val / dev->a_res;
// from seeed studio example
dev->angular_velocity =
((val - dev->calibrationValue) * (dev->a_ref * 1000.0)
/ dev->a_res / 0.67);
return UPM_SUCCESS;
}
upm_result_t enc03r_calibrate(const enc03r_context dev,
unsigned int samples)
{
assert(dev != NULL);
float total = 0.0;
for (int i=0; i<samples; i++)
{
int val = mraa_aio_read(dev->aio);
if (val < 0)
{
printf("%s: mraa_aio_read() failed\n", __FUNCTION__);
return UPM_ERROR_OPERATION_FAILED;
}
total += (float)val;
upm_delay_ms(2);
}
dev->calibrationValue = total / (float)samples;
return UPM_SUCCESS;
}
float enc03r_calibration_value(const enc03r_context dev)
{
assert(dev != NULL);
return dev->calibrationValue;
}
float enc03r_angular_velocity(const enc03r_context dev)
{
assert(dev != NULL);
return dev->angular_velocity * dev->scale + (dev->offset * dev->scale);
}
void enc03r_set_offset(const enc03r_context dev, float offset)
{
assert(dev != NULL);
dev->offset = offset;
}
void enc03r_set_scale(const enc03r_context dev, float scale)
{
assert(dev != NULL);
dev->scale = scale;
}
float enc03r_get_normalized(const enc03r_context dev)
{
assert(dev != NULL);
return dev->normalized;
}

View File

@ -1,6 +1,6 @@
/*
* Author: Jon Trulson <jtrulson@ics.com>
* Copyright (c) 2014 Intel Corporation.
* Copyright (c) 2014-2017 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@ -31,52 +31,49 @@
using namespace upm;
using namespace std;
ENC03R::ENC03R(int pin, float vref)
ENC03R::ENC03R(int pin, float aref) :
m_enc03r(enc03r_init(pin, aref))
{
if ( !(m_aio = mraa_aio_init(pin)) )
{
throw std::invalid_argument(std::string(__FUNCTION__) +
": mraa_aio_init() failed, invalid pin?");
return;
}
m_vref = vref;
m_calibrationValue = 0;
if (!m_enc03r)
throw std::runtime_error(string(__FUNCTION__)
+ ": enc03r_init() failed");
}
ENC03R::~ENC03R()
{
mraa_aio_close(m_aio);
}
unsigned int ENC03R::value()
{
int x = mraa_aio_read(m_aio);
if (x == -1) throw std::out_of_range(std::string(__FUNCTION__) +
": Failed to do an aio read.");
return (unsigned int) x;
enc03r_close(m_enc03r);
}
void ENC03R::calibrate(unsigned int samples)
{
int val;
float total = 0.0;
for (unsigned int i=0; i<samples; i++)
{
val = mraa_aio_read(m_aio);
if (val == -1) throw std::out_of_range(std::string(__FUNCTION__) +
": Failed to do an aio read.");
total += (float)val;
usleep(2000);
}
m_calibrationValue = total / (float)samples;
if (enc03r_calibrate(m_enc03r, samples))
throw std::runtime_error(string(__FUNCTION__)
+ ": enc03r_calibrate() failed");
}
double ENC03R::angularVelocity(unsigned int val)
void ENC03R::update()
{
// from seeed studio example
//return (((double)(val-m_calibrationValue)*(m_vref*1000.0))/1023.0/0.67);
return (((double)(val-m_calibrationValue)*(m_vref*1000.0))/685.41);
if (enc03r_update(m_enc03r))
throw std::runtime_error(string(__FUNCTION__)
+ ": enc03r_update() failed");
}
float ENC03R::angularVelocity()
{
return enc03r_angular_velocity(m_enc03r);
}
void ENC03R::setOffset(float offset)
{
enc03r_set_offset(m_enc03r, offset);
}
void ENC03R::setScale(float scale)
{
enc03r_set_scale(m_enc03r, scale);
}
float ENC03R::getNormalized()
{
return enc03r_get_normalized(m_enc03r);
}

159
src/enc03r/enc03r.h Normal file
View File

@ -0,0 +1,159 @@
/*
* Author: Jon Trulson <jtrulson@ics.com>
* Copyright (c) 2014-2017 Intel Corporation.
emacs . *
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#pragma once
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <mraa/aio.h>
#include <upm.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @file enc03r.h
* @library enc03r
* @brief Generic API for AT command based UART devices
*
*/
/**
* Device context
*/
typedef struct _enc03r_context {
mraa_aio_context aio;
// determined by calibrate();
float calibrationValue;
// our computed value
float angular_velocity;
// analog reference voltage
float a_ref;
// analog ADC resolution (max value)
float a_res;
// offset
float offset;
// scale
float scale;
// normalized ADC value
float normalized;
} *enc03r_context;
/**
* ENC03R sensor constructor
*
* @param pin Analog pin to use
* @param vref Reference voltage to use; default is 5.0 V
* @return Device context
*/
enc03r_context enc03r_init(int pin, float aref);
/**
* ENC03R destructor
*
* @param dev Device context
*/
void enc03r_close(enc03r_context dev);
/**
* Update the internal state with the current reading. This
* function must be called prior to calling
* enc03r_angular_velocity().
*
* @param dev Device context
* @return UPM result
*/
upm_result_t enc03r_update(enc03r_context dev);
/**
* Calibrates the sensor by determining an analog reading over many
* samples with no movement of the sensor. This must be done
* before attempting to use the sensor.
*
* @param dev Device context
* @param samples Number of samples to use for calibration
* @return UPM result
*/
upm_result_t enc03r_calibrate(const enc03r_context dev,
unsigned int samples);
/**
* Returns the currently stored calibration value
*
* @param dev Device context
* @return Current calibration value
*/
float enc03r_calibration_value(const enc03r_context dev);
/**
* Return the computed Angular Velocity in degrees per second.
* You must have called encr03r_update() prior to calling this
* function.
*
* @param dev Device context
* @return Computed angular velocity
*/
float enc03r_angular_velocity(const enc03r_context dev);
/**
* Set sensor offset. The offste is applied to the return value
* before scaling. Default is 0.
*
* @param dev Device context
* @param scale Scale to apply to value
*/
void enc03r_set_offset(const enc03r_context dev, float offset);
/**
* Set sensor scale. The return value is scaled by this value
* before the offset is applied. Default is 1.0.
*
* @param dev Device context
* @param scale Offset to apply to value
*/
void enc03r_set_scale(const enc03r_context dev, float scale);
/**
* Get a normalized ADC value from the sensor. The return value
* will be between 0.0 (indicating no voltage) and 1.0 indicating
* max voltage (aref). encr03r_update() must be called prior to
* calling this function.
*
* @param dev Device context
* @return The normalized reading from the ADC.
*/
float enc03r_get_normalized(const enc03r_context dev);
#ifdef __cplusplus
}
#endif

View File

@ -1,6 +1,6 @@
/*
* Author: Jon Trulson <jtrulson@ics.com>
* Copyright (c) 2014 Intel Corporation.
* Copyright (c) 2014-2017 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
@ -24,92 +24,116 @@
#pragma once
#include <string>
#include <mraa/aio.h>
#include "enc03r.h"
namespace upm {
/**
* @brief ENC03R Single Axis Gyro library
* @defgroup enc03r libupm-enc03r
* @ingroup seeed analog compass robok
*/
/**
* @library enc03r
* @sensor enc03r
* @comname ENC03R Single Axis Gyro
* @altname Grove Single Axis Analog Gyro
* @type compass
* @man seeed
* @con analog
* @kit robok
*
* @brief API for the ENC03R Single Axis Analog Gyro
*
* UPM module for the ENC03R single axis analog gyro.
* This gyroscope measures x-axis angular velocity, that is
* how fast the sensor is rotating around the x-axis.
* Calibration of the sensor is necessary for accurate readings.
*
* @image html enc03r.jpg
* @snippet enc03r.cxx Interesting
*/
class ENC03R {
public:
/**
* @brief ENC03R Single Axis Gyro library
* @defgroup enc03r libupm-enc03r
* @ingroup seeed analog compass robok
*/
/**
* ENC03R sensor constructor
* @library enc03r
* @sensor enc03r
* @comname ENC03R Single Axis Gyro
* @altname Grove Single Axis Analog Gyro
* @type compass
* @man seeed
* @con analog
* @kit robok
*
* @param pin Analog pin to use
* @param vref Reference voltage to use; default is 5.0 V
*/
ENC03R(int pin, float vref=5.0);
/**
* ENC03R destructor
*/
~ENC03R();
/**
* Calibrates the sensor by determining an analog reading over many
* samples with no movement of the sensor. This must be done
* before attempting to use the sensor.
* @brief API for the ENC03R Single Axis Analog Gyro
*
* @param samples Number of samples to use for calibration
*/
void calibrate(unsigned int samples);
/**
* Returns the raw value of the sensor
* UPM module for the ENC03R single axis analog gyro.
* This gyroscope measures x-axis angular velocity, that is
* how fast the sensor is rotating around the x-axis.
* Calibration of the sensor is necessary for accurate readings.
*
* @return Raw value of the sensor
* @image html enc03r.jpg
* @snippet enc03r.cxx Interesting
*/
unsigned int value();
class ENC03R {
public:
/**
* Returns the currently stored calibration value
*
* @return Current calibration value
*/
float calibrationValue() { return m_calibrationValue; };
/**
* ENC03R sensor constructor
*
* @param pin Analog pin to use
* @param vref Reference voltage to use; default is 5.0 V
*/
ENC03R(int pin, float aref=5.0);
/**
* Computes angular velocity based on the value and stored calibration
* reference.
*
* @param val Value to use to compute angular velocity
* @return Computed angular velocity
*/
double angularVelocity(unsigned int val);
/**
* ENC03R destructor
*/
~ENC03R();
private:
// determined by calibrate();
float m_calibrationValue;
/**
* Calibrates the sensor by determining an analog reading over many
* samples with no movement of the sensor. This must be done
* before attempting to use the sensor.
*
* @param samples Number of samples to use for calibration
*/
void calibrate(unsigned int samples);
// reference voltage
float m_vref;
mraa_aio_context m_aio;
};
/**
* Update the internal state with the current reading. This
* function must be called prior to calling
* angularVelocity().
*
* @param dev Device context
*/
void update();
/**
* Returns the currently stored calibration value
*
* @return Current calibration value
*/
float calibrationValue() { return enc03r_calibration_value(m_enc03r); };
/**
* Computes angular velocity based on the value and stored calibration
* reference.
*
* @param val Value to use to compute angular velocity
* @return Computed angular velocity
*/
float angularVelocity();
/**
* Set sensor offset. The offste is applied to the return value
* before scaling. Default is 0.
*
* @param scale Scale to apply to value
*/
void setOffset(float offset);
/**
* Set sensor scale. The return value is scaled by this value
* before the offset is applied. Default is 1.0.
*
* @param dev Device context
* @param scale Offset to apply to value
*/
void setScale(float scale);
/**
* Get a normalized ADC value from the sensor. The return
* value will be between 0.0 (indicating no voltage) and 1.0
* indicating max voltage (aref). update() must be called
* prior to calling this function.
*
* @return The normalized reading from the ADC.
*/
float getNormalized();
protected:
enc03r_context m_enc03r;
private:
};
}

102
src/enc03r/enc03r_fti.c Normal file
View File

@ -0,0 +1,102 @@
/*
* Author: Jon Trulson <jtrulson@ics.com>
* Copyright (c) 2017 Intel Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "enc03r.h"
#include "upm_fti.h"
/**
* This file implements the Function Table Interface (FTI) for this sensor
*/
const char upm_enc03r_name[] = "ENC03R";
const char upm_enc03r_description[] = "Analog Single Axis Gyroscope";
const upm_protocol_t upm_enc03r_protocol[] = {UPM_ANALOG};
const upm_sensor_t upm_enc03r_category[] = {UPM_GYROSCOPE};
// forward declarations
const void* upm_enc03r_get_ft(upm_sensor_t sensor_type);
void* upm_enc03r_init_name();
void upm_enc03r_close(void *dev);
upm_result_t upm_enc03r_get_value(void *dev, float *value);
const upm_sensor_descriptor_t upm_enc03r_get_descriptor()
{
upm_sensor_descriptor_t usd;
usd.name = upm_enc03r_name;
usd.description = upm_enc03r_description;
usd.protocol_size = 1;
usd.protocol = upm_enc03r_protocol;
usd.category_size = 1;
usd.category = upm_enc03r_category;
return usd;
}
static const upm_sensor_ft ft =
{
.upm_sensor_init_name = &upm_enc03r_init_name,
.upm_sensor_close = &upm_enc03r_close,
};
static const upm_gyroscope_ft gft =
{
.upm_gyroscope_get_value = &upm_enc03r_get_value
};
const void* upm_enc03r_get_ft(upm_sensor_t sensor_type)
{
switch(sensor_type)
{
case UPM_SENSOR:
return &ft;
case UPM_GYROSCOPE:
return &gft;
default:
return NULL;
}
}
void* upm_enc03r_init_name()
{
return NULL;
}
void upm_enc03r_close(void *dev)
{
enc03r_close((enc03r_context)dev);
}
upm_result_t upm_enc03r_get_value(void *dev, float *value)
{
if (enc03r_update((enc03r_context)dev))
return UPM_ERROR_OPERATION_FAILED;
value[0] = enc03r_angular_velocity((enc03r_context)dev);
value[1] = 0.0;
value[2] = 0.0;
return UPM_SUCCESS;
}