first commit
This commit is contained in:
commit
a5a0434432
1126 changed files with 439481 additions and 0 deletions
15
Software/NodeJS/.gitignore
vendored
Normal file
15
Software/NodeJS/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
raw
|
||||
node_modules
|
||||
.log
|
||||
.idea
|
||||
.swp
|
||||
.*.swp
|
||||
._*
|
||||
.DS_Store
|
||||
.git
|
||||
.hg
|
||||
.lock-wscript
|
||||
.svn
|
||||
.wafpickle-*
|
||||
CVS
|
||||
npm-debug.log
|
||||
7
Software/NodeJS/CONTRIBUTING.md
Normal file
7
Software/NodeJS/CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
## How to contribute to GrovePi for Node.js
|
||||
|
||||
* Before you open a ticket or send a pull request, [search](https://github.com/DexterInd/GrovePi/issues) for previous discussions about the same feature or issue. Add to the earlier ticket if you find one.
|
||||
|
||||
* Use the coding style suggested by [npmjs](https://docs.npmjs.com/misc/coding-style).
|
||||
|
||||
* Be creative :-)
|
||||
24
Software/NodeJS/LICENSE
Normal file
24
Software/NodeJS/LICENSE
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
## License
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
|
||||
Copyright (C) 2017 Dexter Industries
|
||||
|
||||
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.
|
||||
154
Software/NodeJS/README.md
Normal file
154
Software/NodeJS/README.md
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
GrovePi for Node.js
|
||||
=======
|
||||
|
||||
GrovePi is an open source platform for connecting Grove Sensors to the Raspberry Pi.
|
||||
|
||||
## Quick start
|
||||
|
||||
Before to start you should install Node.js on your RaspberryPi and clone the repo on your local environment.
|
||||
Be sure to have npm installed and then you can proceed installing the package.
|
||||
To install node.js you can do the following:
|
||||
|
||||
```bash
|
||||
curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash -
|
||||
sudo apt-get install nodejs
|
||||
cd $HOME && mkdir .node_modules_global
|
||||
npm config set prefix $HOME/.node_modules_global
|
||||
```
|
||||
|
||||
#### Installing Package from NPM Repository
|
||||
|
||||
Go inside your Node.js application folder and type
|
||||
```bash
|
||||
$ npm install node-grovepi
|
||||
```
|
||||
|
||||
#### Installing Package by Linking the Project In This Repo
|
||||
|
||||
`cd` to `libs` directory in this folder and type
|
||||
```bash
|
||||
npm install
|
||||
npm link
|
||||
```
|
||||
|
||||
Now, inside your own app (which can be anywhere in `$HOME`) you need to run
|
||||
```
|
||||
npm link node-grovepi
|
||||
```
|
||||
once in order to link your project to the library that's in this repository (`libs`) folder.
|
||||
|
||||
#### Using the Library
|
||||
|
||||
Now you can include the module inside your application:
|
||||
```javascript
|
||||
var GrovePi = require('node-grovepi').GrovePi
|
||||
```
|
||||
|
||||
At this point you may need to include the GrovePi base classes:
|
||||
```javascript
|
||||
var Commands = GrovePi.commands
|
||||
var Board = GrovePi.board
|
||||
```
|
||||
|
||||
If the sensor/component you need to use already has the classes then you can include them:
|
||||
```javascript
|
||||
var AccelerationI2cSensor = GrovePi.sensors.AccelerationI2C
|
||||
var UltrasonicDigitalSensor = GrovePi.sensors.UltrasonicDigital
|
||||
var AirQualityAnalogSensor = GrovePi.sensors.AirQualityAnalog
|
||||
var DHTDigitalSensor = GrovePi.sensors.DHTDigital
|
||||
var LightAnalogSensor = GrovePi.sensors.LightAnalog
|
||||
var DigitalButtonSensor = GrovePi.sensors.DigitalButton
|
||||
var LoudnessAnalogSensor = GrovePi.sensors.LoudnessAnalog
|
||||
var RotaryAngleAnalogSensor = GrovePi.sensors.RotaryAnalog
|
||||
```
|
||||
|
||||
Now you can instantiate the GrovePi and your sensors/components, for example:
|
||||
```javascript
|
||||
var board = new Board({
|
||||
debug: true,
|
||||
onError: function(err) {
|
||||
console.log('Something wrong just happened')
|
||||
console.log(err)
|
||||
},
|
||||
onInit: function(res) {
|
||||
if (res) {
|
||||
console.log('GrovePi Version :: ' + board.version())
|
||||
|
||||
var lightSensor = new LightAnalogSensor(2)
|
||||
console.log('Light Analog Sensor (start watch)')
|
||||
lightSensor.on('change', function(res) {
|
||||
console.log('Light onChange value=' + res)
|
||||
})
|
||||
lightSensor.watch()
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
If there is no class for your sensors or components then you can write your own functions for them:
|
||||
_Note: every custom function must be called only after the Board init._
|
||||
```javascript
|
||||
function customAccelerationReading() {
|
||||
var write = board.writeBytes(Commands.acc_xyz.concat([Commands.unused, Commands.unused, Commands.unused]))
|
||||
if (write) {
|
||||
board.wait(100)
|
||||
board.readByte()
|
||||
var bytes = board.readBytes()
|
||||
if (bytes instanceof Buffer) {
|
||||
var x = bytes[1] > 32 ? -(bytes[1]-224) : bytes[1]
|
||||
var y = bytes[2] > 32 ? -(bytes[2]-224) : bytes[2]
|
||||
var z = bytes[3] > 32 ? -(bytes[3]-224) : bytes[3]
|
||||
return [x, y, z]
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
When you are ready to go you should call the init method
|
||||
```javascript
|
||||
board.init()
|
||||
```
|
||||
|
||||
Each sensor/component has at least 3 methods to get access to the data:
|
||||
- **read()** - Read data from the sensor/component
|
||||
- **stream(delay, callback)** - Start a stream with the sensor/component, each N milliseconds (delay) sends data to the callback. You can use stopStream() to close the connection.
|
||||
- **watch(delay)** - Start a polling routine which will fire a "change" event only when there are new data coming from the sensor/component. The internal timer will use the given delay value or 100 milliseconds as default. You can use stopWatch() to stop the polling.
|
||||
|
||||
And 1 method to write data:
|
||||
- **write(value)** - Write a value on the sensor/component
|
||||
|
||||
Some sensors expose additional methods
|
||||
- *DigitalButton* sensor exposes a **down** event which has a single argument on the callback. This argument will have the value **singlepress* or **longpress**, depending on how long the user has been pressing the button.
|
||||
- *RotaryAngleAnalogSensor* overrides the **read** method to provide noise-less output, since there are cases in which the sensor may incorrectly report that its value has changed. The sensor will return a value from 0 to 100. User also needs to call the **start** method for this sensor.
|
||||
- *LoudnessAnalogSensor* provides a **readAvgMax** method which will return average and maximum values coming from the sensor for a period of time. This period restarts every time you call the **readAvgMax** method, so it is supposed that the method is called repeatedly in a timely manner (e.g. with a **setInterval** callback). User has to call the **start** method for the monitoring to begin.
|
||||
|
||||
You'll find more complex examples in the "basicTest.js" file under the "tests" folder of the repository.
|
||||
|
||||
## License
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
|
||||
Copyright (C) 2017 Dexter Industries
|
||||
|
||||
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.
|
||||
99
Software/NodeJS/libs/commands.js
Normal file
99
Software/NodeJS/libs/commands.js
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
module.exports = {
|
||||
//Command Format
|
||||
// digitalRead() command format header
|
||||
dRead : [1]
|
||||
// digitalWrite() command format header
|
||||
, dWrite : [2]
|
||||
// analogRead() command format header
|
||||
, aRead : [3]
|
||||
// analogWrite() command format header
|
||||
, aWrite : [4]
|
||||
// pinMode() command format header
|
||||
, pMode : [5]
|
||||
// Ultrasonic read
|
||||
, uRead : [7]
|
||||
// Get firmware version
|
||||
, version : [8]
|
||||
// Accelerometer (+/- 1.5g) read
|
||||
, acc_xyz : [20]
|
||||
// RTC get time
|
||||
, rtc_getTime : [30]
|
||||
// DHT Pro sensor temperature
|
||||
, dht_temp : [40]
|
||||
|
||||
// Grove LED Bar commands
|
||||
// Initialise
|
||||
, ledBarInit : [50]
|
||||
// Set orientation
|
||||
, ledBarOrient : [51]
|
||||
// Set level
|
||||
, ledBarLevel : [52]
|
||||
// Set single LED
|
||||
, ledBarSetOne : [53]
|
||||
// Toggle single LED
|
||||
, ledBarToggleOne : [54]
|
||||
// Set all LEDs
|
||||
, ledBarSet : [55]
|
||||
// Get current state
|
||||
, ledBarGet : [56]
|
||||
|
||||
// Grove 4 Digit Display commands
|
||||
// Initialise
|
||||
, fourDigitInit : [70]
|
||||
// Set brightness, not visible until next cmd
|
||||
, fourDigitBrightness : [71]
|
||||
// Set numeric value without leading zeros
|
||||
, fourDigitValue : [72]
|
||||
// Set numeric value with leading zeros
|
||||
, fourDigitValueZeros : [73]
|
||||
// Set individual digit
|
||||
, fourDigitIndividualDigit : [74]
|
||||
// Set individual leds of a segment
|
||||
, fourDigitIndividualLeds : [75]
|
||||
// Set left and right values with colon
|
||||
, fourDigitScore : [76]
|
||||
// Analog read for n seconds
|
||||
, fourDigitAnalogRead : [77]
|
||||
// Entire display on
|
||||
, fourDigitAllOn : [78]
|
||||
// Entire display off
|
||||
, fourDigitAllOff : [79]
|
||||
|
||||
// Grove Chainable RGB LED commands
|
||||
// Store color for later use
|
||||
, storeColor : [90]
|
||||
// Initialise
|
||||
, chainableRgbLedInit : [91]
|
||||
// Initialise and test with a simple color
|
||||
, chainableRgbLedTest : [92]
|
||||
// Set one or more leds to the stored color by pattern
|
||||
, chainableRgbLedSetPattern : [93]
|
||||
// Set one or more leds to the stored color by modulo
|
||||
, chainableRgbLedSetModulo : [94]
|
||||
// Sets leds similar to a bar graph, reversible
|
||||
, chainableRgbLedSetLevel : [95]
|
||||
|
||||
// Grove IR sensor
|
||||
// Read the button from IR sensor
|
||||
, irRead : [21]
|
||||
// Set pin for the IR reciever
|
||||
, irRecvPin : [22]
|
||||
|
||||
// Grove Dust sensor
|
||||
, dustSensorRead : [10]
|
||||
, dustSensorEn : [14]
|
||||
, dustSensorDis : [15]
|
||||
|
||||
// Encoder
|
||||
, encoderRead : [11]
|
||||
, encoderEn : [16]
|
||||
, encoderDis : [17]
|
||||
|
||||
// Grove Flow sensor
|
||||
, flowRead : [12]
|
||||
, flowEn : [18]
|
||||
, flowDis : [13]
|
||||
|
||||
// This allows us to be more specific about which commands contain unused bytes
|
||||
, unused : 0
|
||||
};
|
||||
192
Software/NodeJS/libs/grovepi.js
Normal file
192
Software/NodeJS/libs/grovepi.js
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
// Modules
|
||||
var i2c = require('i2c-bus')
|
||||
var async = require('async')
|
||||
var log = require('npmlog')
|
||||
var sleep = require('sleep')
|
||||
var fs = require('fs')
|
||||
var commands = require('./commands')
|
||||
|
||||
var I2CCMD = 1
|
||||
var debugMode = false
|
||||
var i2c0Path = '/dev/i2c-0'
|
||||
var i2c1Path = '/dev/i2c-1'
|
||||
var bus
|
||||
var busNumber
|
||||
|
||||
var initWait = 1 // in seconds
|
||||
|
||||
var isInit = false
|
||||
var isHalt = false
|
||||
var isBusy = false
|
||||
|
||||
var ADDRESS = 0x04
|
||||
|
||||
var onError, onInit
|
||||
|
||||
function GrovePi(opts) {
|
||||
this.BYTESLEN = 4
|
||||
this.INPUT = 'input'
|
||||
this.OUTPUT = 'output'
|
||||
|
||||
if (typeof opts == 'undefined')
|
||||
opts = {}
|
||||
|
||||
if (typeof opts.debug != 'undefined')
|
||||
this.debugMode = opts.debug
|
||||
else
|
||||
this.debugMode = debugMode
|
||||
|
||||
// TODO: Dispatch an error event instead
|
||||
if (typeof opts.onError == 'function')
|
||||
onError = opts.onError
|
||||
|
||||
// TODO: Dispatch a init event instead
|
||||
if (typeof opts.onInit == 'function')
|
||||
onInit = opts.onInit
|
||||
|
||||
if (fs.existsSync(i2c0Path)) {
|
||||
isHalt = false
|
||||
busNumber = 0
|
||||
} else if (fs.existsSync(i2c1Path)) {
|
||||
isHalt = false
|
||||
busNumber = 1
|
||||
} else {
|
||||
var err = new Error('GrovePI could not determine your i2c device')
|
||||
isHalt = true
|
||||
if (typeof onError == 'function')
|
||||
onError(err)
|
||||
this.debug(err)
|
||||
}
|
||||
}
|
||||
|
||||
GrovePi.prototype.init = function() {
|
||||
if (!isHalt) {
|
||||
bus = i2c.openSync(busNumber)
|
||||
|
||||
if (!isInit) {
|
||||
this.debug('GrovePi is initing')
|
||||
sleep.sleep(initWait)
|
||||
isInit = true
|
||||
|
||||
if (typeof onInit == 'function')
|
||||
onInit(true)
|
||||
} else {
|
||||
var err = new Error('GrovePI is already initialized')
|
||||
if (typeof onInit == 'function')
|
||||
onInit(false)
|
||||
onError(err)
|
||||
}
|
||||
} else {
|
||||
var err = new Error('GrovePI cannot be initialized')
|
||||
if (typeof onInit == 'function')
|
||||
onInit(false)
|
||||
onError(err)
|
||||
}
|
||||
}
|
||||
GrovePi.prototype.close = function() {
|
||||
if (typeof bus != 'undefined') {
|
||||
this.debug('GrovePi is closing')
|
||||
bus.closeSync()
|
||||
} else {
|
||||
this.debug('The device is not defined')
|
||||
}
|
||||
}
|
||||
GrovePi.prototype.run = function(tasks) {
|
||||
this.debug('GrovePi is about to execute ' + tasks.length + ' tasks')
|
||||
async.waterfall(tasks)
|
||||
}
|
||||
GrovePi.prototype.checkStatus = function() {
|
||||
if (!isInit || isHalt){
|
||||
if (!isHalt) {
|
||||
this.debug('GrovePi needs to be initialized.')
|
||||
} else {
|
||||
this.debug('GrovePi is not operative because halted')
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
GrovePi.prototype.readByte = function() {
|
||||
var isOperative = this.checkStatus()
|
||||
if (!isOperative)
|
||||
return false
|
||||
|
||||
var length = 1
|
||||
var buffer = new Buffer.alloc(length)
|
||||
var ret = bus.i2cReadSync(ADDRESS, length, buffer)
|
||||
return ret > 0 ? buffer : false
|
||||
}
|
||||
GrovePi.prototype.readBytes = function(length) {
|
||||
if (typeof length == 'undefined')
|
||||
length = this.BYTESLEN
|
||||
|
||||
var isOperative = this.checkStatus()
|
||||
if (!isOperative)
|
||||
return false
|
||||
|
||||
var buffer = new Buffer.alloc(length)
|
||||
var ret = false
|
||||
try {
|
||||
var val = bus.i2cReadSync(ADDRESS, length, buffer)
|
||||
ret = val > 0 ? buffer : false
|
||||
} catch (err) {
|
||||
ret = false
|
||||
} finally {
|
||||
return ret
|
||||
}
|
||||
}
|
||||
GrovePi.prototype.writeBytes = function(bytes) {
|
||||
var isOperative = this.checkStatus()
|
||||
if (!isOperative)
|
||||
return false
|
||||
|
||||
var buffer = new Buffer.from(bytes)
|
||||
var ret = false
|
||||
try {
|
||||
var val = bus.i2cWriteSync(ADDRESS, buffer.length, buffer)
|
||||
ret = val > 0 ? true : false
|
||||
} catch (err) {
|
||||
ret = false
|
||||
} finally {
|
||||
return ret
|
||||
}
|
||||
}
|
||||
GrovePi.prototype.pinMode = function(pin, mode) {
|
||||
var isOperative = this.checkStatus()
|
||||
if (!isOperative)
|
||||
return false
|
||||
|
||||
if (mode == this.OUTPUT) {
|
||||
return this.writeBytes(commands.pMode.concat([pin, 1, commands.unused]))
|
||||
} else if (mode == this.INPUT) {
|
||||
return this.writeBytes(commands.pMode.concat([pin, 0, commands.unused]))
|
||||
} else {
|
||||
this.debug('Unknown pin mode')
|
||||
}
|
||||
}
|
||||
GrovePi.prototype.debug = function(msg) {
|
||||
if (this.debugMode)
|
||||
log.info('GrovePi.board', msg)
|
||||
}
|
||||
GrovePi.prototype.wait = function(ms) {
|
||||
sleep.usleep(1000 * ms)
|
||||
}
|
||||
|
||||
// GrovePi functions
|
||||
GrovePi.prototype.version = function() {
|
||||
var write = this.writeBytes(commands.version.concat([commands.unused, commands.unused, commands.unused]))
|
||||
if (write) {
|
||||
this.wait(100)
|
||||
this.readByte()
|
||||
var bytes = this.readBytes()
|
||||
if (typeof bytes == 'object')
|
||||
return (bytes[1] + '.' + bytes[2] + '.' + bytes[3])
|
||||
else
|
||||
return false
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// export the class
|
||||
module.exports = GrovePi
|
||||
32
Software/NodeJS/libs/index.js
Normal file
32
Software/NodeJS/libs/index.js
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
module.exports.GrovePi = {
|
||||
commands: require('./commands')
|
||||
, board: require('./grovepi')
|
||||
, sensors: {
|
||||
base: {
|
||||
Sensor: require('./sensors/base/sensor')
|
||||
, Analog: require('./sensors/base/analogSensor')
|
||||
, Digital: require('./sensors/base/digitalSensor')
|
||||
, I2C: require('./sensors/base/i2cSensor')
|
||||
}
|
||||
, DigitalInput: require('./sensors/genericDigitalInputSensor')
|
||||
, DigitalOutput: require('./sensors/genericDigitalOutputSensor')
|
||||
, AccelerationI2C: require('./sensors/accelerationI2cSensor')
|
||||
, AirQualityAnalog: require('./sensors/airQualityAnalogSensor')
|
||||
, ChainableRGBLedDigital: require('./sensors/chainableRGBLedDigitalSensor')
|
||||
, DHTDigital: require('./sensors/DHTDigitalSensor')
|
||||
, FourDigitDigital: require('./sensors/fourDigitDigitalSensor')
|
||||
, LedBarDigital: require('./sensors/ledBarDigitalSensor')
|
||||
, LightAnalog: require('./sensors/lightAnalogSensor')
|
||||
, RTCI2C: require('./sensors/rtcI2cSensor')
|
||||
, TemperatureAnalog: require('./sensors/temperatureAnalogSensor')
|
||||
, UltrasonicDigital: require('./sensors/ultrasonicDigitalSensor')
|
||||
, IRReceiver: require('./sensors/IRReceiverSensor')
|
||||
, SPDTRelay: require('./sensors/SPDTRelay')
|
||||
, dustDigital: require('./sensors/dustDigitalSensor')
|
||||
, encoderDigital: require('./sensors/encoderDigitalSensor')
|
||||
, waterFlowDigital: require('./sensors/waterFlowDigitalSensor')
|
||||
, DigitalButton: require('./sensors/digitalButton')
|
||||
, LoudnessAnalog: require('./sensors/loudnessAnalogSensor')
|
||||
, RotaryAnalog: require('./sensors/rotaryAngleAnalogSensor')
|
||||
}
|
||||
}
|
||||
27
Software/NodeJS/libs/package.json
Normal file
27
Software/NodeJS/libs/package.json
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"name": "node-grovepi",
|
||||
"version": "2.2.0",
|
||||
"description": "GrovePi library for Node.js",
|
||||
"keywords": ["grovepi", "robot", "gpio", "i2c"],
|
||||
"dependencies": {
|
||||
"async": "1.*",
|
||||
"i2c-bus": "1.*",
|
||||
"npmlog": "2.*",
|
||||
"sleep": "3.*",
|
||||
"mathjs": "3.17.*"
|
||||
},
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/marcellobarile/GrovePi.git"
|
||||
},
|
||||
"author": "Marcello Barile <marcello.barile@gmail.com> (http://www.barile.eu)",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/marcellobarile/GrovePi/issues"
|
||||
},
|
||||
"homepage": "https://github.com/marcellobarile/GrovePi"
|
||||
}
|
||||
92
Software/NodeJS/libs/sensors/DHTDigitalSensor.js
Normal file
92
Software/NodeJS/libs/sensors/DHTDigitalSensor.js
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
var DigitalSensor = require('./base/digitalSensor')
|
||||
var commands = require('../commands')
|
||||
|
||||
function DHTDigitalSensor(pin, moduleType, scale) {
|
||||
DigitalSensor.apply(this, Array.prototype.slice.call(arguments))
|
||||
this.moduleType = moduleType
|
||||
this.scale = scale
|
||||
}
|
||||
function convertCtoF(temp) {
|
||||
return temp * 9 / 5 + 32
|
||||
}
|
||||
function convertFtoC(temp) {
|
||||
return (temp - 32) * 5 / 9
|
||||
}
|
||||
function getHeatIndex(temp, hum, scale) {
|
||||
// http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml
|
||||
var needsConversion = typeof scale == 'undefined' || scale == DHTDigitalSensor.CELSIUS
|
||||
|
||||
temp = needsConversion ? convertCtoF(temp) : temp
|
||||
|
||||
// Steadman's result
|
||||
var heatIndex = 0.5 * (temp + 61 + (temp - 68) * 1.2 + hum * 0.094)
|
||||
|
||||
// regression equation of Rothfusz is appropriate
|
||||
if (temp >= 80) {
|
||||
var heatIndexBase = (-42.379 +
|
||||
2.04901523 * temp +
|
||||
10.14333127 * hum +
|
||||
-0.22475541 * temp * hum +
|
||||
-0.00683783 * temp * temp +
|
||||
-0.05481717 * hum * hum +
|
||||
0.00122874 * temp * temp * hum +
|
||||
0.00085282 * temp * hum * hum +
|
||||
-0.00000199 * temp * temp * hum * hum )
|
||||
// adjustment
|
||||
if (hum < 13 && temp <= 112) {
|
||||
heatIndex = heatIndexBase - (13 - hum) / 4 * Math.sqrt((17 - Math.abs(temp - 95)) / 17)
|
||||
} else if (hum > 85 && temp <= 87) {
|
||||
heatIndex = heatIndexBase + ((hum - 85) / 10) * ((87 - temp) / 5)
|
||||
} else {
|
||||
heatIndex = heatIndexBase
|
||||
}
|
||||
}
|
||||
|
||||
return needsConversion ? convertFtoC(heatIndex) : heatIndex
|
||||
}
|
||||
|
||||
DHTDigitalSensor.prototype = new DigitalSensor()
|
||||
DHTDigitalSensor.VERSION = {
|
||||
'DHT11' : 0
|
||||
, 'DHT22' : 1
|
||||
, 'DHT21' : 2
|
||||
, 'AM2301': 3
|
||||
}
|
||||
DHTDigitalSensor.CELSIUS = 'c'
|
||||
DHTDigitalSensor.FAHRENHEIT = 'f'
|
||||
|
||||
DHTDigitalSensor.prototype.read = function() {
|
||||
var write = this.board.writeBytes(commands.dht_temp.concat([this.pin, this.moduleType, commands.unused]))
|
||||
if (write) {
|
||||
this.board.wait(500)
|
||||
this.board.readByte()
|
||||
this.board.wait(200)
|
||||
var bytes = this.board.readBytes(9)
|
||||
if (bytes instanceof Buffer) {
|
||||
var hex
|
||||
var tempBytes = bytes.slice(1, 5).reverse()
|
||||
var humBytes = bytes.slice(5, 9).reverse()
|
||||
|
||||
hex = '0x' + tempBytes.toString('hex')
|
||||
var temp = (hex & 0x7fffff | 0x800000) * 1.0 / Math.pow(2, 23) * Math.pow(2, ((hex >> 23 & 0xff) - 127))
|
||||
temp = +(Number(parseFloat(temp - 0.5).toFixed(2)))
|
||||
if (this.scale == DHTDigitalSensor.FAHRENHEIT) {
|
||||
temp = convertCtoF(temp)
|
||||
}
|
||||
|
||||
hex = '0x' + humBytes.toString('hex')
|
||||
var hum = (hex & 0x7fffff | 0x800000) * 1.0 / Math.pow(2, 23) * Math.pow(2, ((hex >> 23 & 0xff) - 127))
|
||||
hum = +(Number(parseFloat(hum - 2).toFixed(2)))
|
||||
|
||||
var heatIndex = +(Number(parseFloat(getHeatIndex(temp, hum, this.scale)).toFixed(2)))
|
||||
// From: https://github.com/adafruit/DHT-sensor-library/blob/master/DHT.cpp
|
||||
|
||||
return [temp, hum, heatIndex]
|
||||
} else
|
||||
return false
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = DHTDigitalSensor
|
||||
33
Software/NodeJS/libs/sensors/IRReceiverSensor.js
Normal file
33
Software/NodeJS/libs/sensors/IRReceiverSensor.js
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
var util = require('util')
|
||||
var Sensor = require('./base/sensor')
|
||||
var commands = require('../commands')
|
||||
|
||||
function IRReceiverSensor(pin) {
|
||||
Sensor.apply(this, Array.prototype.slice.call(arguments))
|
||||
this.pin = pin + 1
|
||||
}
|
||||
util.inherits(IRReceiverSensor, Sensor);
|
||||
IRReceiverSensor.prototype = new IRReceiverSensor()
|
||||
|
||||
IRReceiverSensor.prototype.read = function() {
|
||||
this.write(commands.unused)
|
||||
var writeRet = this.board.writeBytes(commands.irRead.concat([commands.unused, commands.unused, commands.unused]))
|
||||
if (writeRet) {
|
||||
this.board.wait(100)
|
||||
this.board.readByte()
|
||||
var bytes = this.board.readBytes(22)
|
||||
if (bytes instanceof Buffer && bytes[1] != 255) {
|
||||
bytes.slice(0,1)
|
||||
return bytes
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
IRReceiverSensor.prototype.write = function(value) {
|
||||
return this.board.writeBytes(commands.irRecvPin.concat([this.pin, value, commands.unused]))
|
||||
}
|
||||
|
||||
module.exports = IRReceiverSensor
|
||||
29
Software/NodeJS/libs/sensors/SPDTRelay.js
Normal file
29
Software/NodeJS/libs/sensors/SPDTRelay.js
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
var DigitalSensor = require('./base/digitalSensor'),
|
||||
commands = require('../commands')
|
||||
|
||||
function SPDTRelay(pin) {
|
||||
DigitalSensor.apply(this, Array.prototype.slice.call(arguments))
|
||||
}
|
||||
SPDTRelay.prototype = new DigitalSensor()
|
||||
|
||||
SPDTRelay.prototype.on = function () {
|
||||
this.board.pinMode(this.board.OUTPUT)
|
||||
var write = this.board.writeBytes(commands.dWrite.concat([this.pin, 1, commands.unused]))
|
||||
if (write) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
SPDTRelay.prototype.off = function () {
|
||||
this.board.pinMode(this.board.OUTPUT)
|
||||
var write = this.board.writeBytes(commands.dWrite.concat([this.pin, 0, commands.unused]))
|
||||
if (write) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = SPDTRelay
|
||||
29
Software/NodeJS/libs/sensors/accelerationI2cSensor.js
Normal file
29
Software/NodeJS/libs/sensors/accelerationI2cSensor.js
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
var util = require('util')
|
||||
var I2cSensor = require('./base/i2cSensor')
|
||||
var commands = require('../commands')
|
||||
|
||||
function AccelerationI2cSensor() {
|
||||
I2cSensor.apply(this, Array.prototype.slice.call(arguments))
|
||||
}
|
||||
AccelerationI2cSensor.prototype = new I2cSensor()
|
||||
|
||||
AccelerationI2cSensor.prototype.read = function() {
|
||||
var write = this.board.writeBytes(commands.acc_xyz.concat([commands.unused, commands.unused, commands.unused]))
|
||||
if (write) {
|
||||
this.board.wait(100)
|
||||
this.board.readByte()
|
||||
var bytes = this.board.readBytes()
|
||||
if (bytes instanceof Buffer) {
|
||||
var x = bytes[1] > 32 ? -(bytes[1]-224) : bytes[1]
|
||||
var y = bytes[2] > 32 ? -(bytes[2]-224) : bytes[2]
|
||||
var z = bytes[3] > 32 ? -(bytes[3]-224) : bytes[3]
|
||||
return [x, y, z]
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AccelerationI2cSensor
|
||||
14
Software/NodeJS/libs/sensors/airQualityAnalogSensor.js
Normal file
14
Software/NodeJS/libs/sensors/airQualityAnalogSensor.js
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
var AnalogSensor = require('./base/analogSensor')
|
||||
var commands = require('../commands')
|
||||
|
||||
function AirQualityAnalogSensor(pin) {
|
||||
AnalogSensor.apply(this, Array.prototype.slice.call(arguments))
|
||||
}
|
||||
AirQualityAnalogSensor.prototype = new AnalogSensor()
|
||||
|
||||
AirQualityAnalogSensor.prototype.read = function() {
|
||||
var res = AnalogSensor.prototype.read.call(this)
|
||||
return parseInt(res)
|
||||
}
|
||||
|
||||
module.exports = AirQualityAnalogSensor
|
||||
33
Software/NodeJS/libs/sensors/base/analogSensor.js
Normal file
33
Software/NodeJS/libs/sensors/base/analogSensor.js
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
var util = require('util')
|
||||
var Sensor = require('./sensor')
|
||||
var commands = require('../../commands')
|
||||
|
||||
function AnalogSensor(pin) {
|
||||
Sensor.apply(this, Array.prototype.slice.call(arguments))
|
||||
this.pin = pin
|
||||
}
|
||||
util.inherits(AnalogSensor, Sensor)
|
||||
AnalogSensor.prototype = new AnalogSensor()
|
||||
|
||||
AnalogSensor.prototype.read = function(length) {
|
||||
if (typeof length == 'undefined')
|
||||
length = this.board.BYTESLEN
|
||||
|
||||
var writeRet = this.board.writeBytes(commands.aRead.concat([this.pin, commands.unused, commands.unused]))
|
||||
if (writeRet) {
|
||||
this.board.readByte()
|
||||
var bytes = this.board.readBytes(length)
|
||||
if (bytes instanceof Buffer) {
|
||||
return bytes[1] * 256 + bytes[2]
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
AnalogSensor.prototype.write = function(value) {
|
||||
return this.board.writeBytes(commands.aWrite.concat([this.pin, value, commands.unused]))
|
||||
}
|
||||
|
||||
module.exports = AnalogSensor
|
||||
25
Software/NodeJS/libs/sensors/base/digitalSensor.js
Normal file
25
Software/NodeJS/libs/sensors/base/digitalSensor.js
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
var util = require('util')
|
||||
var Sensor = require('./sensor')
|
||||
var commands = require('../../commands')
|
||||
|
||||
function DigitalSensor(pin) {
|
||||
Sensor.apply(this, Array.prototype.slice.call(arguments))
|
||||
this.pin = pin
|
||||
}
|
||||
util.inherits(DigitalSensor, Sensor)
|
||||
DigitalSensor.prototype = new DigitalSensor()
|
||||
|
||||
DigitalSensor.prototype.read = function() {
|
||||
var writeRet = this.board.writeBytes(commands.dRead.concat([this.pin, commands.unused, commands.unused]))
|
||||
if (writeRet) {
|
||||
this.board.wait(100)
|
||||
return this.board.readBytes(2)[1]
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
DigitalSensor.prototype.write = function(value) {
|
||||
return this.board.writeBytes(commands.dWrite.concat([this.pin, value, commands.unused]))
|
||||
}
|
||||
|
||||
module.exports = DigitalSensor
|
||||
11
Software/NodeJS/libs/sensors/base/i2cSensor.js
Normal file
11
Software/NodeJS/libs/sensors/base/i2cSensor.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
var util = require('util')
|
||||
var Sensor = require('./sensor')
|
||||
var commands = require('../../commands')
|
||||
|
||||
function I2cSensor() {
|
||||
Sensor.apply(this, Array.prototype.slice.call(arguments))
|
||||
}
|
||||
util.inherits(I2cSensor, Sensor)
|
||||
I2cSensor.prototype = new I2cSensor()
|
||||
|
||||
module.exports = I2cSensor
|
||||
67
Software/NodeJS/libs/sensors/base/sensor.js
Normal file
67
Software/NodeJS/libs/sensors/base/sensor.js
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
var util = require('util')
|
||||
var EventEmitter = require('events').EventEmitter
|
||||
var Board = require('../../grovepi')
|
||||
|
||||
var isEqual = function(a, b) {
|
||||
if (typeof a == 'object') {
|
||||
for (var i in a) {
|
||||
if (a[i] !== b[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
return a === b
|
||||
}
|
||||
}
|
||||
|
||||
function Sensor() {
|
||||
this.board = new Board()
|
||||
this.lastValue = 0
|
||||
this.currentValue = 0
|
||||
this.streamInterval = this.watchInterval = undefined
|
||||
this.watchDelay = 100
|
||||
}
|
||||
|
||||
util.inherits(Sensor, EventEmitter)
|
||||
|
||||
Sensor.prototype.read = function() {}
|
||||
Sensor.prototype.write = function() {}
|
||||
Sensor.prototype.stream = function(delay, cb) {
|
||||
var self = this
|
||||
delay = typeof delay == 'undefined' ? self.watchDelay : delay
|
||||
|
||||
self.stopStream()
|
||||
self.streamInterval = setInterval(function onStreamInterval() {
|
||||
var res = self.read()
|
||||
cb(res)
|
||||
}, delay)
|
||||
}
|
||||
Sensor.prototype.stopStream = function() {
|
||||
var self = this
|
||||
if (typeof self.streamInterval != 'undefined')
|
||||
clearInterval(self.streamInterval)
|
||||
}
|
||||
|
||||
Sensor.prototype.watch = function(delay) {
|
||||
var self = this
|
||||
delay = typeof delay == 'undefined' ? self.watchDelay : delay
|
||||
|
||||
self.stopWatch()
|
||||
self.watchInterval = setInterval(function onInterval() {
|
||||
var res = self.read()
|
||||
|
||||
self.lastValue = self.currentValue
|
||||
self.currentValue = res
|
||||
|
||||
if (!isEqual(self.currentValue, self.lastValue))
|
||||
self.emit('change', self.currentValue)
|
||||
}, delay)
|
||||
}
|
||||
Sensor.prototype.stopWatch = function() {
|
||||
var self = this
|
||||
if (typeof self.watchInterval != 'undefined')
|
||||
clearInterval(self.watchInterval)
|
||||
}
|
||||
|
||||
module.exports = Sensor
|
||||
52
Software/NodeJS/libs/sensors/chainableRGBLedDigitalSensor.js
Normal file
52
Software/NodeJS/libs/sensors/chainableRGBLedDigitalSensor.js
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
var DigitalSensor = require('./base/digitalSensor')
|
||||
var commands = require('../commands')
|
||||
|
||||
function ChainableRGBLedDigitalSensor(pin, numLeds) {
|
||||
DigitalSensor.apply(this, Array.prototype.slice.call(arguments))
|
||||
this.numLeds
|
||||
}
|
||||
ChainableRGBLedDigitalSensor.prototype = new DigitalSensor()
|
||||
|
||||
ChainableRGBLedDigitalSensor.prototype.init = function() {
|
||||
this.board.pinMode(this.board.OUTPUT)
|
||||
var write = this.board.writeBytes(commands.chainableRgbLedInit.concat([this.pin, this.numLeds, commands.unused]))
|
||||
if (write) {
|
||||
this.board.wait(500)
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
ChainableRGBLedDigitalSensor.prototype.setPattern = function(pattern, whichLed) {
|
||||
this.board.pinMode(this.board.OUTPUT)
|
||||
var write = this.board.writeBytes(commands.chainableRgbLedSetPattern.concat([this.pin, pattern, whichLed]))
|
||||
if (write) {
|
||||
this.board.wait(500)
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
ChainableRGBLedDigitalSensor.prototype.setModulo = function(offset, divisor) {
|
||||
this.board.pinMode(this.board.OUTPUT)
|
||||
var write = this.board.writeBytes(commands.chainableRgbLedSetModulo.concat([this.pin, offset, divisor]))
|
||||
if (write) {
|
||||
this.board.wait(500)
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
ChainableRGBLedDigitalSensor.prototype.setLevel = function(level, reverse) {
|
||||
this.board.pinMode(this.board.OUTPUT)
|
||||
var write = this.board.writeBytes(commands.chainableRgbLedSetLevel.concat([this.pin, level, reverse]))
|
||||
if (write) {
|
||||
this.board.wait(500)
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports = ChainableRGBLedDigitalSensor
|
||||
46
Software/NodeJS/libs/sensors/digitalButton.js
Normal file
46
Software/NodeJS/libs/sensors/digitalButton.js
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
var DigitalInput = require('./base/digitalSensor')
|
||||
|
||||
const buttonMode = {
|
||||
UP: 0,
|
||||
DOWN: 1
|
||||
}
|
||||
|
||||
var mode = buttonMode.UP //not pressed
|
||||
|
||||
var pressedDateTime
|
||||
var currentDateTime
|
||||
var milliseconds
|
||||
|
||||
//digital button, can throw singlepress and longpress events
|
||||
function DigitalButton(pin, longPressDelay) {
|
||||
DigitalInput.apply(this, Array.prototype.slice.call(arguments))
|
||||
this.longPressDelay = longPressDelay || 1100
|
||||
this.on('change', function (res) {
|
||||
//user presses the button for the first time
|
||||
if (res == 1 && mode === buttonMode.UP) {
|
||||
pressedDateTime = new Date()
|
||||
mode = buttonMode.DOWN
|
||||
return
|
||||
}
|
||||
//user continues to press the button
|
||||
else if (res == 1 && mode === buttonMode.DOWN) {
|
||||
//do nothing
|
||||
return
|
||||
} else { //res == 0 so user has lifted her finger
|
||||
currentDateTime = new Date()
|
||||
milliseconds = currentDateTime.getTime() - pressedDateTime.getTime()
|
||||
//if less than longPressDelay milliseconds
|
||||
if (milliseconds <= this.longPressDelay) {
|
||||
this.emit('down', 'singlepress')
|
||||
} else {
|
||||
this.emit('down', 'longpress')
|
||||
}
|
||||
//reset the mode
|
||||
mode = buttonMode.UP
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
DigitalButton.prototype = new DigitalInput()
|
||||
|
||||
module.exports = DigitalButton
|
||||
85
Software/NodeJS/libs/sensors/dustDigitalSensor.js
Normal file
85
Software/NodeJS/libs/sensors/dustDigitalSensor.js
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
// TODO: call disable function on exit
|
||||
var DigitalSensor = require('./base/digitalSensor')
|
||||
var commands = require('../commands')
|
||||
var helpers = require('./helpers')
|
||||
|
||||
function DustDigitalSensor(pin) {
|
||||
DigitalSensor.apply(this, Array.prototype.slice.call(arguments))
|
||||
this.results = new Array()
|
||||
}
|
||||
DustDigitalSensor.prototype = new DigitalSensor()
|
||||
|
||||
DustDigitalSensor.prototype.read = function () {
|
||||
var write = this.board.writeBytes(commands.dustSensorRead.concat([this.pin, commands.unused, commands.unused]))
|
||||
if (write) {
|
||||
this.board.wait(200)
|
||||
var bytes = this.board.readBytes()
|
||||
//console.log(bytes[0] + ' ' + bytes[1] + ' ' + bytes[2] + ' ' + bytes[3])
|
||||
if (bytes instanceof Buffer && bytes[0] != 0)
|
||||
return [bytes[0], (bytes[3] * 256 * 256 + bytes[2] * 256 + bytes[1])]
|
||||
else
|
||||
return false
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
DustDigitalSensor.prototype.enable = function () {
|
||||
var write = this.board.writeBytes(commands.dustSensorEn.concat([commands.unused, commands.unused, commands.unused]))
|
||||
if (write) {
|
||||
this.board.wait(200)
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
DustDigitalSensor.prototype.disable = function () {
|
||||
var write = this.board.writeBytes(commands.dustSensorDis.concat([commands.unused, commands.unused, commands.unused]))
|
||||
if (write) {
|
||||
this.board.wait(200)
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
DustDigitalSensor.prototype.start = function () {
|
||||
if (!this.enable())
|
||||
throw new Error('cannot enable dust sensor')
|
||||
this.enable()
|
||||
setInterval(loop.bind(this), 30 * 1000) //every 30 seconds
|
||||
}
|
||||
|
||||
DustDigitalSensor.prototype.stop = function () {
|
||||
this.disable()
|
||||
clearInterval(loop)
|
||||
}
|
||||
|
||||
function loop() {
|
||||
let currentResult = this.read()
|
||||
this.results.push(currentResult[1])
|
||||
}
|
||||
|
||||
DustDigitalSensor.prototype.readAvgMax = function () {
|
||||
|
||||
if (this.results.length === 0) return {
|
||||
avg: helpers.NOT_AVAILABLE,
|
||||
max: helpers.NOT_AVAILABLE
|
||||
};
|
||||
|
||||
let sum = this.results.reduce((acc, cur) => acc + cur, 0)
|
||||
let avg = sum / this.results.length
|
||||
|
||||
let max = this.results.reduce(function (a, b) {
|
||||
return Math.max(a, b)
|
||||
});
|
||||
|
||||
//reset the array
|
||||
this.results = new Array()
|
||||
|
||||
return {
|
||||
avg: helpers.round(avg, 2),
|
||||
max: helpers.round(max, 2)
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = DustDigitalSensor
|
||||
43
Software/NodeJS/libs/sensors/encoderDigitalSensor.js
Normal file
43
Software/NodeJS/libs/sensors/encoderDigitalSensor.js
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
// TODO: call disable function on exit
|
||||
var DigitalSensor = require('./base/digitalSensor')
|
||||
var commands = require('../commands')
|
||||
|
||||
function EncoderDigitalSensor(pin) {
|
||||
DigitalSensor.apply(this, Array.prototype.slice.call(arguments))
|
||||
}
|
||||
EncoderDigitalSensor.prototype = new DigitalSensor()
|
||||
|
||||
EncoderDigitalSensor.prototype.read = function() {
|
||||
var write = this.board.writeBytes(commands.encoderRead.concat([this.pin, commands.unused, commands.unused]))
|
||||
if (write) {
|
||||
this.board.wait(200)
|
||||
this.board.readByte()
|
||||
var bytes = this.board.readBytes()
|
||||
if (bytes instanceof Buffer && bytes[1] != 255)
|
||||
return [bytes[1], bytes[2]]
|
||||
else
|
||||
return false
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
EncoderDigitalSensor.prototype.enable = function() {
|
||||
var write = this.board.writeBytes(commands.encoderEn.concat([commands.unused, commands.unused, commands.unused]))
|
||||
if (write) {
|
||||
this.board.wait(200)
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
EncoderDigitalSensor.prototype.disable = function() {
|
||||
var write = this.board.writeBytes(commands.encoderDis.concat([commands.unused, commands.unused, commands.unused]))
|
||||
if (write) {
|
||||
this.board.wait(200)
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = EncoderDigitalSensor
|
||||
97
Software/NodeJS/libs/sensors/fourDigitDigitalSensor.js
Normal file
97
Software/NodeJS/libs/sensors/fourDigitDigitalSensor.js
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
var DigitalSensor = require('./base/digitalSensor')
|
||||
var commands = require('../commands')
|
||||
|
||||
function FourDigitDigitalSensor(pin) {
|
||||
DigitalSensor.apply(this, Array.prototype.slice.call(arguments))
|
||||
}
|
||||
FourDigitDigitalSensor.prototype = new DigitalSensor()
|
||||
|
||||
FourDigitDigitalSensor.prototype.init = function() {
|
||||
this.board.pinMode(this.board.OUTPUT)
|
||||
return this.board.writeBytes(commands.fourDigitInit.concat([this.pin, commands.unused, commands.unused]))
|
||||
}
|
||||
FourDigitDigitalSensor.prototype.setNumber = function(value, useLeadingZero) {
|
||||
this.board.pinMode(this.board.OUTPUT)
|
||||
var byte1 = value & 255
|
||||
var byte2 = value >> 8
|
||||
var command = useLeadingZero ? commands.fourDigitValue : commands.fourDigitValueZeros
|
||||
var write = this.board.writeBytes(command.concat([this.pin, byte1, byte2]))
|
||||
if (write) {
|
||||
this.board.wait(500)
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
FourDigitDigitalSensor.prototype.setBrightness = function(brightness) {
|
||||
this.board.pinMode(this.board.OUTPUT)
|
||||
var write = this.board.writeBytes(commands.fourDigitBrightness.concat([this.pin, brightness, commands.unused]))
|
||||
if (write) {
|
||||
this.board.wait(500)
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
FourDigitDigitalSensor.prototype.setDigit = function(segment, value) {
|
||||
this.board.pinMode(this.board.OUTPUT)
|
||||
var write = this.board.writeBytes(commands.fourDigitIndividualDigit.concat([this.pin, segment, value]))
|
||||
if (write) {
|
||||
this.board.wait(500)
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
FourDigitDigitalSensor.prototype.setSegment = function(segment, leds) {
|
||||
this.board.pinMode(this.board.OUTPUT)
|
||||
var write = this.board.writeBytes(commands.fourDigitIndividualLeds.concat([this.pin, segment, leds]))
|
||||
if (write) {
|
||||
this.board.wait(500)
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
FourDigitDigitalSensor.prototype.setScore = function(left, right) {
|
||||
this.board.pinMode(this.board.OUTPUT)
|
||||
var write = this.board.writeBytes(commands.fourDigitScore.concat([this.pin, left, right]))
|
||||
if (write) {
|
||||
this.board.wait(500)
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
FourDigitDigitalSensor.prototype.monitor = function(analog, duration) {
|
||||
this.board.pinMode(this.board.OUTPUT)
|
||||
var write = this.board.writeBytes(commands.fourDigitAnalogRead.concat([this.pin, analog, duration]))
|
||||
if (write) {
|
||||
this.board.wait(duration/1000 + 500) // TODO: This should be tested
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
FourDigitDigitalSensor.prototype.on = function() {
|
||||
this.board.pinMode(this.board.OUTPUT)
|
||||
var write = this.board.writeBytes(commands.fourDigitAllOn.concat([this.pin, commands.unused, commands.unused]))
|
||||
if (write) {
|
||||
this.board.wait(500)
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
FourDigitDigitalSensor.prototype.off = function() {
|
||||
this.board.pinMode(this.board.OUTPUT)
|
||||
var write = this.board.writeBytes(commands.fourDigitAllOff.concat([this.pin, commands.unused, commands.unused]))
|
||||
if (write) {
|
||||
this.board.wait(500)
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = FourDigitDigitalSensor
|
||||
14
Software/NodeJS/libs/sensors/genericDigitalInputSensor.js
Normal file
14
Software/NodeJS/libs/sensors/genericDigitalInputSensor.js
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
// Thanks to Craig Watkins for the contribution
|
||||
var DigitalSensor = require('./base/digitalSensor')
|
||||
var commands = require('../commands')
|
||||
|
||||
function GenericDigitalInputSensor(pin) {
|
||||
DigitalSensor.apply(this, Array.prototype.slice.call(arguments))
|
||||
}
|
||||
GenericDigitalInputSensor.prototype = new DigitalSensor()
|
||||
|
||||
GenericDigitalInputSensor.prototype.read = function() {
|
||||
return DigitalSensor.prototype.read.call(this)
|
||||
}
|
||||
|
||||
module.exports = GenericDigitalInputSensor
|
||||
30
Software/NodeJS/libs/sensors/genericDigitalOutputSensor.js
Normal file
30
Software/NodeJS/libs/sensors/genericDigitalOutputSensor.js
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
// Thanks to Craig Watkins for the contribution
|
||||
var DigitalSensor = require('./base/digitalSensor')
|
||||
var commands = require('../commands')
|
||||
|
||||
function GenericDigitalOutputSensor(pin) {
|
||||
DigitalSensor.apply(this, Array.prototype.slice.call(arguments))
|
||||
}
|
||||
GenericDigitalOutputSensor.prototype = new DigitalSensor()
|
||||
|
||||
GenericDigitalOutputSensor.prototype.turnOn = function() {
|
||||
this.board.pinMode(this.board.OUTPUT)
|
||||
var write = this.board.writeBytes(commands.dWrite.concat([this.pin, 1, commands.unused]))
|
||||
if (write) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
GenericDigitalOutputSensor.prototype.turnOff = function() {
|
||||
this.board.pinMode(this.board.OUTPUT)
|
||||
var write = this.board.writeBytes(commands.dWrite.concat([this.pin, 0, commands.unused]))
|
||||
if (write) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GenericDigitalOutputSensor
|
||||
16
Software/NodeJS/libs/sensors/helpers.js
Normal file
16
Software/NodeJS/libs/sensors/helpers.js
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
function round(number, precision) {
|
||||
if (isNaN(number)) return NOT_AVAILABLE
|
||||
if (precision == undefined || isNaN(precision))
|
||||
precision = 2
|
||||
var factor = Math.pow(10, precision)
|
||||
var tempNumber = number * factor
|
||||
var roundedTempNumber = Math.round(tempNumber)
|
||||
return roundedTempNumber / factor
|
||||
}
|
||||
|
||||
const NOT_AVAILABLE = 'N/A'
|
||||
|
||||
module.exports = {
|
||||
round,
|
||||
NOT_AVAILABLE
|
||||
}
|
||||
56
Software/NodeJS/libs/sensors/ledBarDigitalSensor.js
Normal file
56
Software/NodeJS/libs/sensors/ledBarDigitalSensor.js
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
var DigitalSensor = require('./base/digitalSensor')
|
||||
var commands = require('../commands')
|
||||
|
||||
function LedBarDigitalSensor(pin, orientation) {
|
||||
DigitalSensor.apply(this, Array.prototype.slice.call(arguments))
|
||||
this.orientation = orientation
|
||||
this.level = 0
|
||||
}
|
||||
LedBarDigitalSensor.prototype = new DigitalSensor()
|
||||
|
||||
LedBarDigitalSensor.prototype.init = function() {
|
||||
return this.setOrientation(this.orientation)
|
||||
}
|
||||
LedBarDigitalSensor.prototype.setOrientation = function(orientation) {
|
||||
this.board.pinMode(this.board.OUTPUT)
|
||||
this.orientation = orientation
|
||||
return this.board.writeBytes(commands.ledBarInit.concat([this.pin, this.orientation, commands.unused]))
|
||||
}
|
||||
LedBarDigitalSensor.prototype.setLevel = function(level) {
|
||||
this.board.pinMode(this.board.OUTPUT)
|
||||
this.level = level
|
||||
return this.board.writeBytes(commands.ledBarLevel.concat([this.pin, this.level, commands.unused]))
|
||||
}
|
||||
LedBarDigitalSensor.prototype.setLed = function(led, state) {
|
||||
this.board.pinMode(this.board.OUTPUT)
|
||||
return this.board.writeBytes(commands.ledBarSetOne.concat([this.pin, led, state]))
|
||||
}
|
||||
LedBarDigitalSensor.prototype.toggleLed = function(led) {
|
||||
this.board.pinMode(this.board.OUTPUT)
|
||||
return this.board.writeBytes(commands.ledBarToggleOne.concat([this.pin, led, commands.unused]))
|
||||
}
|
||||
LedBarDigitalSensor.prototype.setBits = function(led, state) {
|
||||
this.board.pinMode(this.board.OUTPUT)
|
||||
var byte1 = state & 255
|
||||
var byte2 = state >> 8
|
||||
return this.board.writeBytes(commands.ledBarSet.concat([this.pin, byte1, byte2]))
|
||||
}
|
||||
LedBarDigitalSensor.prototype.getBits = function() {
|
||||
this.board.pinMode(this.board.OUTPUT)
|
||||
var byte1 = state & 255
|
||||
var byte2 = state >> 8
|
||||
var write = this.board.writeBytes(commands.ledBarGet.concat([this.pin, commands.unused, commands.unused]))
|
||||
if (write) {
|
||||
this.board.wait(200)
|
||||
this.board.readByte()
|
||||
var bytes = this.board.readBytes()
|
||||
if (bytes instanceof Buffer)
|
||||
return (bytes[1] ^ (bytes[2] << 8))
|
||||
else
|
||||
return false
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = LedBarDigitalSensor
|
||||
16
Software/NodeJS/libs/sensors/lightAnalogSensor.js
Normal file
16
Software/NodeJS/libs/sensors/lightAnalogSensor.js
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
var AnalogSensor = require('./base/analogSensor')
|
||||
var commands = require('../commands')
|
||||
|
||||
function LightAnalogSensor(pin) {
|
||||
AnalogSensor.apply(this, Array.prototype.slice.call(arguments))
|
||||
}
|
||||
LightAnalogSensor.prototype = new AnalogSensor()
|
||||
|
||||
LightAnalogSensor.prototype.read = function() {
|
||||
var res = AnalogSensor.prototype.read.call(this)
|
||||
var number = parseInt(res)
|
||||
var resistance = number <= 0 ? 0 : +(Number(parseFloat((1023 - number) * 10 / number)).toFixed(2))
|
||||
return resistance
|
||||
}
|
||||
|
||||
module.exports = LightAnalogSensor
|
||||
48
Software/NodeJS/libs/sensors/loudnessAnalogSensor.js
Normal file
48
Software/NodeJS/libs/sensors/loudnessAnalogSensor.js
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
var AnalogSensor = require('./base/analogSensor')
|
||||
|
||||
//same class can be used for the sound sensor
|
||||
function LoudnessAnalogSensor(pin, samplespersecond) {
|
||||
AnalogSensor.apply(this, Array.prototype.slice.call(arguments))
|
||||
this.samplespersecond = samplespersecond || 5
|
||||
this.results = new Array()
|
||||
}
|
||||
LoudnessAnalogSensor.prototype = new AnalogSensor()
|
||||
|
||||
//returns loudness average and max for values taken since the last time it was called
|
||||
LoudnessAnalogSensor.prototype.readAvgMax = function () {
|
||||
if (this.results.length == 0)
|
||||
throw new Error('no results. Did you call start()?')
|
||||
|
||||
//reduce values to get the sum
|
||||
let sum = this.results.reduce((acc, cur) => acc + cur, 0)
|
||||
let avg = sum / this.results.length
|
||||
|
||||
//reduce the values to get the max
|
||||
let max = this.results.reduce(function (a, b) {
|
||||
return Math.max(a, b)
|
||||
})
|
||||
|
||||
//reset the array - clear its elements
|
||||
this.results = new Array()
|
||||
|
||||
return {
|
||||
avg,
|
||||
max
|
||||
}
|
||||
}
|
||||
|
||||
LoudnessAnalogSensor.prototype.start = function () {
|
||||
loop.bind(this)() //so we can use 'this' inside the loop method
|
||||
setInterval(loop.bind(this), 1000 / this.samplespersecond)
|
||||
}
|
||||
|
||||
LoudnessAnalogSensor.prototype.stop = function () {
|
||||
clearInterval(loop)
|
||||
}
|
||||
|
||||
function loop() {
|
||||
let currentResult = this.read()
|
||||
this.results.push(currentResult)
|
||||
}
|
||||
|
||||
module.exports = LoudnessAnalogSensor
|
||||
74
Software/NodeJS/libs/sensors/rotaryAngleAnalogSensor.js
Normal file
74
Software/NodeJS/libs/sensors/rotaryAngleAnalogSensor.js
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
var AnalogSensor = require('./base/analogSensor')
|
||||
var helpers = require('./helpers')
|
||||
const FULL_ANGLE = 300
|
||||
|
||||
//RotaryAngleSensor
|
||||
//returns a value from 0 to 100
|
||||
//implemented a basic noise filtering algorithm, as in our experiments
|
||||
//the rotary sensor was throwing random values at random times
|
||||
function RotaryAngleAnalogSensor(pin, watchDelay, samplesize) {
|
||||
AnalogSensor.apply(this, Array.prototype.slice.call(arguments))
|
||||
this.watchDelay = watchDelay || 10
|
||||
this.samplesize = samplesize || 40
|
||||
//watchDelay * samplesize equals the miliseconds interval that the sensor will report data
|
||||
}
|
||||
RotaryAngleAnalogSensor.prototype = new AnalogSensor()
|
||||
|
||||
RotaryAngleAnalogSensor.prototype.read = function () {
|
||||
let value = AnalogSensor.prototype.read.call(this)
|
||||
|
||||
let degrees = convertDHTToDegrees(value)
|
||||
|
||||
//Calculate result (0 to 100) from degrees(0 to 300)
|
||||
let result = Math.floor(degrees / FULL_ANGLE * 100)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
const convertDHTToDegrees = function (value) {
|
||||
//http://wiki.seeed.cc/Grove-Rotary_Angle_Sensor/
|
||||
let adc_ref = 5
|
||||
let grove_vcc = 5
|
||||
|
||||
let voltage = helpers.round((value) * adc_ref / 1023, 2)
|
||||
|
||||
//Calculate rotation in degrees(0 to 300)
|
||||
return helpers.round((voltage * FULL_ANGLE) / grove_vcc, 2)
|
||||
}
|
||||
|
||||
RotaryAngleAnalogSensor.prototype.start = function () {
|
||||
setInterval(loop.bind(this), this.watchDelay)
|
||||
}
|
||||
|
||||
RotaryAngleAnalogSensor.prototype.stop = function () {
|
||||
clearInterval(loop)
|
||||
}
|
||||
|
||||
//new array initialized to zero
|
||||
let temp = Array.apply(null, Array(101)).map(Number.prototype.valueOf, 0) //0..100
|
||||
let timesRun = 0
|
||||
|
||||
let previousData = null
|
||||
|
||||
function loop() {
|
||||
const reading = this.read()
|
||||
if (reading < 0 || reading > 100) throw new Error('improper reading')
|
||||
|
||||
temp[reading]++
|
||||
if (++timesRun === this.samplesize) {
|
||||
//find the index of the biggest integer
|
||||
const result = temp.indexOf(Math.max(...temp))
|
||||
timesRun = 0
|
||||
//reset the array
|
||||
temp = Array.apply(null, Array(101)).map(Number.prototype.valueOf, 0)
|
||||
|
||||
//compare current data to previous data
|
||||
if (previousData === null || Math.abs(result - previousData) != 0) {
|
||||
//there is a new value
|
||||
this.emit('data', result)
|
||||
previousData = result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = RotaryAngleAnalogSensor
|
||||
20
Software/NodeJS/libs/sensors/rtcI2cSensor.js
Normal file
20
Software/NodeJS/libs/sensors/rtcI2cSensor.js
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
var I2cSensor = require('./base/i2cSensor')
|
||||
var commands = require('../commands')
|
||||
|
||||
function RtcI2cSensor() {
|
||||
I2cSensor.apply(this, Array.prototype.slice.call(arguments))
|
||||
}
|
||||
RtcI2cSensor.prototype = new I2cSensor()
|
||||
|
||||
RtcI2cSensor.prototype.read = function() {
|
||||
var write = this.board.writeBytes(commands.rtc_getTime.concat([commands.unused, commands.unused, commands.unused]))
|
||||
if (write) {
|
||||
this.board.wait(100)
|
||||
this.board.readByte()
|
||||
return this.board.readBytes()
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = RtcI2cSensor
|
||||
15
Software/NodeJS/libs/sensors/temperatureAnalogSensor.js
Normal file
15
Software/NodeJS/libs/sensors/temperatureAnalogSensor.js
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
var AnalogSensor = require('./base/analogSensor')
|
||||
var commands = require('../commands')
|
||||
|
||||
function TemperatureAnalogSensor(pin) {
|
||||
AnalogSensor.apply(this, Array.prototype.slice.call(arguments))
|
||||
}
|
||||
TemperatureAnalogSensor.prototype = new AnalogSensor()
|
||||
|
||||
TemperatureAnalogSensor.prototype.read = function() {
|
||||
var res = AnalogSensor.prototype.read.call(this)
|
||||
var resistance = (1023-res) * 10000 / res
|
||||
return (1 / (Math.log(resistance / 10000) / 3975 + 1 / 298.15) - 273.15)
|
||||
}
|
||||
|
||||
module.exports = TemperatureAnalogSensor
|
||||
24
Software/NodeJS/libs/sensors/ultrasonicDigitalSensor.js
Normal file
24
Software/NodeJS/libs/sensors/ultrasonicDigitalSensor.js
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
var DigitalSensor = require('./base/digitalSensor')
|
||||
var commands = require('../commands')
|
||||
|
||||
function UltrasonicDigitalSensor(pin) {
|
||||
DigitalSensor.apply(this, Array.prototype.slice.call(arguments))
|
||||
}
|
||||
UltrasonicDigitalSensor.prototype = new DigitalSensor()
|
||||
|
||||
UltrasonicDigitalSensor.prototype.read = function() {
|
||||
var write = this.board.writeBytes(commands.uRead.concat([this.pin, commands.unused, commands.unused]))
|
||||
if (write) {
|
||||
this.board.wait(200)
|
||||
this.board.readByte()
|
||||
var bytes = this.board.readBytes()
|
||||
if (bytes instanceof Buffer)
|
||||
return (bytes[1] * 256 + bytes[2])
|
||||
else
|
||||
return false
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = UltrasonicDigitalSensor
|
||||
43
Software/NodeJS/libs/sensors/waterFlowDigitalSensor.js
Normal file
43
Software/NodeJS/libs/sensors/waterFlowDigitalSensor.js
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
// TODO: call disable function on exit
|
||||
var DigitalSensor = require('./base/digitalSensor')
|
||||
var commands = require('../commands')
|
||||
|
||||
function WaterFlowDigitalSensor(pin) {
|
||||
DigitalSensor.apply(this, Array.prototype.slice.call(arguments))
|
||||
}
|
||||
WaterFlowDigitalSensor.prototype = new DigitalSensor()
|
||||
|
||||
WaterFlowDigitalSensor.prototype.read = function() {
|
||||
var write = this.board.writeBytes(commands.flowRead.concat([this.pin, commands.unused, commands.unused]))
|
||||
if (write) {
|
||||
this.board.wait(200)
|
||||
this.board.readByte()
|
||||
var bytes = this.board.readBytes()
|
||||
if (bytes instanceof Buffer && bytes[1] != 255)
|
||||
return [bytes[1], (bytes[3] * 256 + bytes[2])]
|
||||
else
|
||||
return false
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
WaterFlowDigitalSensor.prototype.enable = function() {
|
||||
var write = this.board.writeBytes(commands.flowEn.concat([commands.unused, commands.unused, commands.unused]))
|
||||
if (write) {
|
||||
this.board.wait(200)
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
WaterFlowDigitalSensor.prototype.disable = function() {
|
||||
var write = this.board.writeBytes(commands.flowDis.concat([commands.unused, commands.unused, commands.unused]))
|
||||
if (write) {
|
||||
this.board.wait(200)
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = WaterFlowDigitalSensor
|
||||
203
Software/NodeJS/tests/basicTest.js
Normal file
203
Software/NodeJS/tests/basicTest.js
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
var GrovePi = require('../libs').GrovePi
|
||||
var Commands = GrovePi.commands
|
||||
var Board = GrovePi.board
|
||||
var AccelerationI2cSensor = GrovePi.sensors.AccelerationI2C
|
||||
var UltrasonicDigitalSensor = GrovePi.sensors.UltrasonicDigital
|
||||
var AirQualityAnalogSensor = GrovePi.sensors.AirQualityAnalog
|
||||
var DHTDigitalSensor = GrovePi.sensors.DHTDigital
|
||||
var LightAnalogSensor = GrovePi.sensors.LightAnalog
|
||||
var DigitalButtonSensor = GrovePi.sensors.DigitalButton
|
||||
var LoudnessAnalogSensor = GrovePi.sensors.LoudnessAnalog
|
||||
var RotaryAngleAnalogSensor = GrovePi.sensors.RotaryAnalog
|
||||
var DustDigitalSensor = GrovePi.sensors.dustDigital
|
||||
|
||||
var board
|
||||
|
||||
|
||||
var testOptions = {
|
||||
acceleration: false,
|
||||
ultrasonic: false,
|
||||
airQuality: false,
|
||||
dhtDigital: false,
|
||||
lightAnalog: false,
|
||||
digitalButton: true,
|
||||
loudnessAnalog: false,
|
||||
rotaryAngle: true,
|
||||
dust: true,
|
||||
customAccelerationReading: false
|
||||
}
|
||||
|
||||
function start() {
|
||||
console.log('starting')
|
||||
|
||||
board = new Board({
|
||||
debug: true,
|
||||
onError: function (err) {
|
||||
console.log('TEST ERROR')
|
||||
console.log(err)
|
||||
},
|
||||
onInit: function (res) {
|
||||
if (res) {
|
||||
|
||||
console.log('GrovePi Version :: ' + board.version())
|
||||
|
||||
if (testOptions.acceleration) {
|
||||
var accSensor = new AccelerationI2cSensor()
|
||||
// I2C sensor doesn't need to specify a port
|
||||
// Acc. XYZ
|
||||
console.log('Acceleration I2C Sensor (single read) :: ' + accSensor.read())
|
||||
console.log('Acceleration I2C Sensor (start stream - 1sec delay)')
|
||||
accSensor.stream(1000, function (res) {
|
||||
console.log('Acceleration stream value=' + res)
|
||||
})
|
||||
console.log('Acceleration I2C Sensor (start watch)')
|
||||
accSensor.on('change', function (res) {
|
||||
console.log('Acceleration onChange value=' + res)
|
||||
})
|
||||
accSensor.watch()
|
||||
}
|
||||
|
||||
if (testOptions.ultrasonic) {
|
||||
var ultrasonicSensor = new UltrasonicDigitalSensor(3)
|
||||
// Digital Port 3
|
||||
// Ultrasonic Ranger
|
||||
console.log('Ultrasonic Ranger Digital Sensor (start watch)')
|
||||
ultrasonicSensor.on('change', function (res) {
|
||||
console.log('Ultrasonic Ranger onChange value=' + res)
|
||||
})
|
||||
ultrasonicSensor.watch()
|
||||
}
|
||||
|
||||
if (testOptions.airQuality) {
|
||||
var airQualitySensor = new AirQualityAnalogSensor(1)
|
||||
// Analog Port 1
|
||||
// Air Quality Sensor
|
||||
console.log('AirQuality Analog Sensor (start watch)')
|
||||
airQualitySensor.on('change', function (res) {
|
||||
console.log('AirQuality onChange value=' + res)
|
||||
})
|
||||
airQualitySensor.watch()
|
||||
}
|
||||
|
||||
if (testOptions.dhtDigital) {
|
||||
var dhtSensor = new DHTDigitalSensor(3, DHTDigitalSensor.VERSION.DHT22, DHTDigitalSensor.CELSIUS)
|
||||
// Digital Port 3
|
||||
// DHT Sensor
|
||||
console.log('DHT Digital Sensor (start watch)')
|
||||
dhtSensor.on('change', function (res) {
|
||||
console.log('DHT onChange value=' + res)
|
||||
})
|
||||
dhtSensor.watch(500) // milliseconds
|
||||
}
|
||||
|
||||
if (testOptions.lightAnalog) {
|
||||
var lightSensor = new LightAnalogSensor(3)
|
||||
// Analog Port 3
|
||||
// Light Sensor
|
||||
console.log('Light Analog Sensor (start watch)')
|
||||
lightSensor.on('change', function (res) {
|
||||
console.log('Light onChange value=' + res)
|
||||
})
|
||||
lightSensor.watch()
|
||||
}
|
||||
|
||||
if (testOptions.loudnessAnalog) {
|
||||
var loudnessSensor = new LoudnessAnalogSensor(2)
|
||||
//Analog Port 2
|
||||
// Loudness Sensor
|
||||
console.log('Loudness Analog Sensor (start monitoring - reporting results every 10s)')
|
||||
loudnessSensor.start()
|
||||
setInterval(loudnessSensorGetAvgMax, 10000, loudnessSensor)
|
||||
}
|
||||
|
||||
if (testOptions.digitalButton) {
|
||||
var buttonSensor = new DigitalButtonSensor(4)
|
||||
//Digital Port 4
|
||||
// Button sensor
|
||||
console.log('Digital Button Sensor (start watch)')
|
||||
buttonSensor.on('down', function (res) {
|
||||
//res will be either singlepress or longpress
|
||||
console.log('Button onDown, data=' + res)
|
||||
})
|
||||
buttonSensor.watch()
|
||||
}
|
||||
|
||||
if (testOptions.rotaryAngle) {
|
||||
var rotaryAngleSensor = new RotaryAngleAnalogSensor(1)
|
||||
//Analog Port 1
|
||||
// Rotary Angle Sensor
|
||||
console.log('Rotary Angle Sensor (start watch)')
|
||||
rotaryAngleSensor.start()
|
||||
rotaryAngleSensor.on('data', function (res) {
|
||||
console.log('Rotary onData value=' + res)
|
||||
})
|
||||
}
|
||||
|
||||
if (testOptions.dust) {
|
||||
var dustSensor = new DustDigitalSensor(2)
|
||||
//digital port 2
|
||||
// Dust Digital Sensor
|
||||
console.log('Dust Digital Sensor (start monitoring - reporting results every 30s)')
|
||||
//we must get results every 30 seconds
|
||||
dustSensor.start()
|
||||
setInterval(dustSensorGetAvgMax, 30 * 1000, dustSensor)
|
||||
}
|
||||
|
||||
if (testOptions.customAccelerationReading) {
|
||||
// Custom external reading
|
||||
console.log('Custom external reading')
|
||||
console.log('customAccelerationReading()::' + customAccelerationReading())
|
||||
}
|
||||
} else {
|
||||
console.log('TEST CANNOT START')
|
||||
}
|
||||
}
|
||||
})
|
||||
board.init()
|
||||
}
|
||||
|
||||
function loudnessSensorGetAvgMax(loudnessSensor) {
|
||||
var res = loudnessSensor.readAvgMax()
|
||||
console.log('Loudness avg value=' + res.avg + ' and max value=' + res.max)
|
||||
}
|
||||
|
||||
function dustSensorGetAvgMax(dustSensor) {
|
||||
var res = dustSensor.readAvgMax()
|
||||
//avg and max will be the same in this test
|
||||
//since we're gathering them over 30 seconds
|
||||
//but that's the same pediod this loop runs
|
||||
console.log('Dust avg value=' + res.avg + ' and max value=' + res.max)
|
||||
}
|
||||
|
||||
function customAccelerationReading() {
|
||||
var write = board.writeBytes(Commands.acc_xyz.concat([Commands.unused, Commands.unused, Commands.unused]))
|
||||
if (write) {
|
||||
board.wait(100)
|
||||
board.readByte()
|
||||
var bytes = board.readBytes()
|
||||
if (bytes instanceof Buffer) {
|
||||
var x = bytes[1] > 32 ? -(bytes[1] - 224) : bytes[1]
|
||||
var y = bytes[2] > 32 ? -(bytes[2] - 224) : bytes[2]
|
||||
var z = bytes[3] > 32 ? -(bytes[3] - 224) : bytes[3]
|
||||
return [x, y, z]
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
function onExit(err) {
|
||||
console.log('ending')
|
||||
board.close()
|
||||
process.removeAllListeners()
|
||||
process.exit()
|
||||
if (typeof err != 'undefined')
|
||||
console.log(err)
|
||||
}
|
||||
|
||||
// starts the test
|
||||
start()
|
||||
// catches ctrl+c event
|
||||
process.on('SIGINT', onExit)
|
||||
62
Software/NodeJS/tests/led_blink.js
Normal file
62
Software/NodeJS/tests/led_blink.js
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
var GrovePi = require('../libs').GrovePi
|
||||
|
||||
// put led in port D3
|
||||
var led = new GrovePi.sensors.DigitalOutput(3);
|
||||
|
||||
// status will tell us if the led is on or off
|
||||
var status = 0;
|
||||
|
||||
var board;
|
||||
|
||||
function toggle() {
|
||||
|
||||
if (status == 0){
|
||||
console.log("toggle off");
|
||||
led.turnOff();
|
||||
status = 1;
|
||||
}
|
||||
else {
|
||||
console.log("toggle on");
|
||||
led.turnOn();
|
||||
status = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function start() {
|
||||
console.log('starting')
|
||||
|
||||
board = new GrovePi.board({
|
||||
debug: true,
|
||||
onError: function(err) {
|
||||
console.log('TEST ERROR')
|
||||
},
|
||||
|
||||
onInit: function(res) {
|
||||
console.log("OnInit");
|
||||
if (res) {
|
||||
// call toggle every second
|
||||
setInterval(toggle, 1000)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
board.init();
|
||||
} // end start()
|
||||
|
||||
|
||||
// called on Ctrl-C.
|
||||
// close the board and clean up
|
||||
function onExit(err) {
|
||||
console.log('ending')
|
||||
board.close()
|
||||
process.removeAllListeners()
|
||||
process.exit()
|
||||
if (typeof err != 'undefined')
|
||||
console.log(err)
|
||||
}
|
||||
|
||||
// starts the test
|
||||
start()
|
||||
// catches ctrl+c event
|
||||
process.on('SIGINT', onExit)
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue