Go Down

Topic: A new Generic Library for Sensors and Devices (Read 1 time) previous topic - next topic


I've tried to create a generic library for Sensors and Devices:


I'd like feedback on whether people think the design makes sense or suggestions for changes. Obviously feel free to use if you find it useful.  Most of the libraries are based on refactoring code on Arduino sites (with original authors in place) to make them more generic.

Device Library - v1.0
This is a set of Device libraries that all use the same standard interfaces such as begin() and read().  This makes it really easy to incorporate new devices into your sketches since they all work the same way.  This  currently has standard libraries for: distance sensor, proximity sensor, compass, color sensor, ambient volume sensor, IRRemote, GPS, and generic Analog sensor and generic Digital Sensor, and an LCD shield.  Note that the IRRemote Library is interrupt based rather than using a polling loop.

The Device Libraries all use the following standard interfaces

Constructor takes no parameters - simply Xyz();

Xyz.begin(int pin, DeviceType deviceType) - This is used for all initialization.  PIN is the first parameter for digital, analog, serial and interrupt sensor libraries.  This performs all initialization and returns an errorCode or ERROR_SUCCESS if successful.  Note that the "begin" function always uses a PIN  even for serial devices (use TX pin), likewise it uses the PIN for Interrupt functions, not the Interrupt number. 
The Device type is the second parameter and can be DIGITAL_SENSOR, ANALOG_ SENSOR, I2C_DEVICE, SERIAL_DEVICE, INTERRUPT_DEVICE, DIGITAL_OUT_DEVICE, PWM_DEVICE or OTHER_DEVICE. Additional initialization parameters are passed after Sensor Type for some of the sensors.

Xyz.read() - If the sensor has only one function, then Xyz.read() performs all work necessary to return the device's currrent value.  For example, read is used for the distance sensor and simply returns the distance.  No other calls are needed to do a read.

Xyz.readAbc()  -If the sensor has multiple functions, then Xyz.readAbc() returns the device's currrent value for one of it's multiple functions, for example GPS.readLatitude();
All libraries use the base library, Device.h

General rules for the libraries
Loops or delays are avoided in the libraries (only LCD and Temperature have delays)
They support UNO/compatible and Mega2560/compatible systems. 
They can use any supported hardware pins (UNO/compatible and Mega2560/compatible).
Consistent error codes are used (from ErrorCodes.h)
They use JavaDoc formatted comments

Library Names
All the interface names are generic and hide the specifics of the underlying hardware, however the actual library name to be included may have a suffix for the specific hardware type.  For example, the temperature sensor library is named TemperatureSensor_DH11.h since it supports the DH11 chip, but the classes and interfaces are generic: Temperature,temperature.begin(), temperature.readTemperature(), temperature.readHumidity(), etc.  This makes it easy to switch specific hardware types without needing to change any code.

Pin Assigments
The only time a pin (or any hardware specific item) is specified is in the Xyz.begin interface. 
All example code uses pin assignments from MyHardware.h and it is recommended that your code place all pin assignments in this file. This file contains all the pin assignments and hardware specific items you use and allows easier management of pin assignments.  This allows you to easilly move a project to a different hardware setup without any code changes, just changes to MyHardware.h.  By placing all the pin assignments in one file, it's easy to see if there are any conflicts and also easy to wire up your Arduino.
Pin names are formed as <Library>_<Instance>_PIN.  For example, DISTANCE_LEFT_PIN.  Instance is optional if only one sensor for that type is present
Error Codes
ErrorCodes.h contains all errorCodes
All interfaces set the errorCode variable in the object

Metric / Imperial
All libraries use Metric by default.  You can call Xyz.SetImperial() to have a device use Imperial units instead.

Here is a sample routine using the library (error handling removed):

Code: [Select]
#include "myhardware.h"
#include "Wire.h"
#include "Device.h"
#include "Servo.h"
#include "Ping.h"
#include "LiquidCrystalI2C.h"
#include "Compass_LSM303.h"
#include "Proximity.h"
#include "Sonar.h"
#include "irController.h"
#include "Temperature_DHT11.h"
#include "TinyGPS.h"
#include "GPS_MTK3329.h"

LiquidCrystal lcd;          // LCD Display
Compass      compass;       // Compass
Proximity    obstacleLeft;  // Proximity sensor
Device       sound;         // Ambient Sound sensor
Device       motion;        // Motion Detector
Sonar        sonar;         // Distance Sensor
IRController irController;  // IR Remote Control reader - Interrupt Based
Temperature  temperature;   // Temperature Sensor
GPS          gps;           // GPS

void initializeDevices() {
int result;

  result = lcd.begin(LCD_I2C_ADDR, 20, 4);
  result = compass.begin( -549, -364, -250, 335, 547, 817 );   // You MUST run calibrate to get calibration values for minx, miny, minz, maxx, maxy, maxz
  result = gps.begin(1, SERIAL_DEVICE);
  result = sound.begin(SOUND_PIN, ANALOG_SENSOR);
  result = motion.begin(MOTION_PIN, DIGITAL_SENSOR);
  result = temperature.begin(TEMPERATURE_PIN, OTHER_DEVICE);
  result = irController.begin(IR_PIN, OTHER_DEVICE);
  result = sonar.begin(SONAR_PIN, OTHER_DEVICE,SONAR_SERVO_PIN, 3, 90);
  result = obstacleLeft.begin(SONAR_LEFT_PIN, DIGITAL_SENSOR);

void setup()

void loop(){
  readsensorValue();    // Get Sensor Readings
  displaysensorValue(); // Display them

void readsensorValue(){
  int val;

  sensorValue[DAT_COMPASS] = compass.read();
  sensorValue[DAT_LAT]     = gps.readLatitude();
  sensorValue[DAT_LON]     = gps.readLongitude();
  sensorValue[DAT_VLM]     = sound.read();
  sensorValue[DAT_FRONT]   = sonar.read();
  sensorValue[DAT_LEFT]    = obstacleLeft.read();
  sensorValue[DAT_TEMP]    = temperature.readTemperature();
  sensorValue[DAT_HUM]     = temperature.readHumidity();
  sensorValue[DAT_MOVE]    = motion.read();
  val               = irController.read();
  if (val >0) sensorValue[DAT_IR] = val;


Apr 16, 2012, 11:51 am Last Edit: Apr 16, 2012, 12:36 pm by brunialti Reason: 1
I like this approach.
May I suggest a more restrictive name convenction for the device .h?

Something looking as following:

For instance the two includes
#include "TinyGPS.h"
#include "GPS_MTK3329.h"

could be:
#include "GPS_TinyGPS.h"
#include "GPS_MTK3329.h"

#include "Proximity.h"

could be changed in:
#include "Distance_xxx.h"

where xx is the device commercial code?


That is definitely what I had in mind.  The first part would be the generic sensor type, followed by specific HW.  It's actually a bit hard to find the hardware specifics for some of these devices, but I'll try to clean that up.   After your post, I was thinking about the GPS and I actually think the code will work for any GPS since they all seem to be Serial and use the same standard NMEA command set.  So I think the libraries will be:





Distance_??? - need to research the chipset, but all the online ones seem to work the same as the Parallax Ping sensor

Temperature_DHT11_DHT22 - changing this to work with either DHT11 or DHT22 chipset


If you have a family of chipset supported i suggest Temperature_DHTX.
Tell me if you need some other sensor lib. I have quite a lot.


That would be great if you could provide more sensor libs.  I can then "genericize" them.


Apr 17, 2012, 08:45 pm Last Edit: Apr 17, 2012, 08:48 pm by brunialti Reason: 1
look at the following list.
Of course rfid e printer should'nt be abstracted due to the complex syntax, same as keytab and lcds
Abaout lcds ... too much syntax to be usefull to abstract... there are very good libs that make lcd abstraction on omogeneous syntax scope.


my only suggestion is that if this is aimed at beginners..  then the documentation.. including SAMPEL CODE on ow each function is ued is crucial.. 

it already has good explanation of def.. just no example of the actual method/function in use.

Go Up