A non-platform-specific embedded C++ framework for using seeed's Grove modules. Specifc platforms are supported on seperate branches!
- Overview
- Framework Documentation
- Usage
- Supported Platforms
- Adding Platforms
- Authors
The idea behind this is to provide an embedded C++ framework for using Grove Modules without targeting specific hardware. This is done by keeping the master branch of this repo as general-purpose as possible - without using any platform specific fucntionality. Of course the problem with this is that platform specific functionality is required to talk to hardware. The solution is to modularise all the platform specific functionality in wrapper functions (Found in GroveCommon) that the different classes call upon.
The GroveCommon wrapper functions don't have an implementation on the master branch and instead have an #error macro telling you to implement the functionality for your platform. Note: it's important that you implement these wrapper functions as they're expected - see the documentation/comments for details on this.
Then for a specific platform, you make a platform/* branch and add your platform-specific implementation. For examples of this, see 5. Supported Platforms.
The API is currently documented using Doxygen. All the comments are doxygen compatible and I've tried to be as thorough as possible, but I'll give a brief overview of it here for ease-of-use sake.
The framework splits Grove modules in their general types: Sensors, Actuators, Display, Communication and Other.
An Abstract Base Class is written for each type, these ABCs each contain a GrovePinout
object that defines it's pin logic. For the master branch, this class simply has a variable for pin1 and pin2 of the Grove Modules.
Individual modules then inherit from one of these ABCs, depending upon their type and provide their implementation for the ABC's virtual functions. In it's constructor it just needs to create an instance of it's parent ABC.
To see module functionality, just look at the Abstract Base Classes (ABC's) since each module is requried to implement these.
Module | Constructor |
---|---|
Actuators | GroveActuator(int pin) |
Grove Button | GroveButton(int pin) |
Grove Buzzer | GroveBuzzer(int pin) |
Grove LED | GroveLED(int pin) |
Sensors | GroveSensor(int pin) |
Grove Temperature/Grove Temperature V1.2 | GroveTemperature(int pin) |
Grove Touch | GroveTouch(int pin) |
Grove Light | GroveLight(int pin) |
Grove Rotary Angle | GroveRotaryAngle(int pin) |
Grove Sound | GroveSound(int pin) |
Communication | GroveCommunication(int pin1_rx, int pin2_tx) |
Grove GPS | GroveGPS(int rx, int tx) |
This is obviously going to depend on your platform.
See specific-branch README's for usage on specific platforms (5. Supported Platforms)
If your platform isn't supported, see 6. Adding Platform Support.
The general-usage stuff (found in GroveCommon) can be called by calling the namespace first: GroveCommon::*
, where the * is the variable/function you want to call. Generally you won't need to do this aside from using the MAX_BUFF
variable and ReturnCode
enum.
The individual modules can be called by first declaring an object of your target module. To see the available modules, see Framework Documentation/Supported Grove Modules. The functions each module can perform can be viewed in the ABC classes (see Framework Documentation for details).
#include "GroveDrivers.h"
#define PIN1 1
GroveButton button(PIN1);
int main()
{
while (1)
{
printf("%i", (int)button.read()); //prints 1 if the button is pressed, else 0
}
}
See branch: platform/mbit's README.md.
I've tried to modularise the changes needed to add a platform as much as possible. See the other branches for examples of how to do this.
(Generally) There are two files that will need changing:
This is the most important. It's got several functions that act as wrapper for platform-specific functionality. It's important you implement these functions as they're expected to be implemented.
Feel free to add functionality to this file if required
This reads 1 byte from an analog pin. The pin read from is the pin
parameter passed to it. This can stay unused if it's not necessary.
This writes 1 byte to an analog pin. The pin written to is the pin
parameter passed to it. The value written to the pin is the value
parameter. The pin
can stay unused if it's not necessary.
This reads 1 byte from a digital pin. The pin read from is the pin
parameter passed to it. This can stay unused if it's not necessary.
This writes 1 byte to a digital pin. The pin written to is the pin
parameter passed to it. The value written to the pin is the value
parameter. The pin
can stay unused if it's not necessary.
This reads 1 byte via UART serial. The pin read from is the rx_pin
parameter passed to it. This can stay unused if it's not necessary.
This writes 1 byte via UART serial. The pin written to is the tx_pin
parameter passed to it. The value written to the pin is the value
parameter. The tx_pin
can stay unused if it's not necessary.
- Alexander Collins (alexander-collins@outlook.com)