I've tried to create a generic library for Sensors and Devices:
http://zbotic.com/index.php/about/
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 __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):
#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"
// CONSTRUCTORS
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
// INITIALIZE
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);
}
// SETUP
void setup()
{
Serial.begin(9600);
Wire.begin();
initializeDevices();
}
// LOOP
void loop(){
readsensorValue(); // Get Sensor Readings
displaysensorValue(); // Display them
delay(500);
}
// READ SENSORS
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;
}