Merge branch 'master' into literate
* master: Crazyflies Updated servo examples to use a limit range of motion instead of full 180. Update digital read to parseInt buffer response. DigitalRead buffer data converted to string now. Debugging digitalPin read. Added servo example for Raspi. Add more supported devices to README Update to 0.6.1 Update digital pin close callback param. Fixes err param not being passed. Updated digital pin and added pwm raspi example. Conflicts: examples/servo.coffee
This commit is contained in:
commit
2c52db8086
10
README.md
10
README.md
|
@ -77,7 +77,9 @@ Cylon.js has a extensible system for connecting to hardware devices. The followi
|
||||||
|
|
||||||
- [Ardrone](http://ardrone2.parrot.com/) <==> [Adaptor/Drivers](https://github.com/hybridgroup/cylon-ardrone)
|
- [Ardrone](http://ardrone2.parrot.com/) <==> [Adaptor/Drivers](https://github.com/hybridgroup/cylon-ardrone)
|
||||||
- [Arduino](http://www.arduino.cc/) <==> [Adaptor](https://github.com/hybridgroup/cylon-firmata)
|
- [Arduino](http://www.arduino.cc/) <==> [Adaptor](https://github.com/hybridgroup/cylon-firmata)
|
||||||
|
- [Crazyflie](http://www.bitcraze.se/) <==> [Adaptor/Driver](https://github.com/hybridgroup/cylon-crazyflie)
|
||||||
- [Leap Motion](https://www.leapmotion.com/) <==> [Adaptor/Driver](https://github.com/hybridgroup/cylon-leapmotion)
|
- [Leap Motion](https://www.leapmotion.com/) <==> [Adaptor/Driver](https://github.com/hybridgroup/cylon-leapmotion)
|
||||||
|
- [Pebble](http://www.getpebble.com/) <==> [Adaptor/Driver](https://github.com/hybridgroup/cylon-pebble)
|
||||||
- [Raspberry Pi](http://www.raspberrypi.org/) <==> [Adaptor](https://github.com/hybridgroup/cylon-raspi)
|
- [Raspberry Pi](http://www.raspberrypi.org/) <==> [Adaptor](https://github.com/hybridgroup/cylon-raspi)
|
||||||
- [Salesforce](http://www.force.com/) <==> [Adaptor/Driver](https://github.com/hybridgroup/cylon-force)
|
- [Salesforce](http://www.force.com/) <==> [Adaptor/Driver](https://github.com/hybridgroup/cylon-force)
|
||||||
- [Sphero](http://www.gosphero.com/) <==> [Adaptor/Driver](https://github.com/hybridgroup/cylon-sphero)
|
- [Sphero](http://www.gosphero.com/) <==> [Adaptor/Driver](https://github.com/hybridgroup/cylon-sphero)
|
||||||
|
@ -86,11 +88,19 @@ Support for many devices that use General Purpose Input/Output (GPIO) have
|
||||||
a shared set of drivers provded using the cylon-gpio module:
|
a shared set of drivers provded using the cylon-gpio module:
|
||||||
|
|
||||||
- [GPIO](https://en.wikipedia.org/wiki/General_Purpose_Input/Output) <=> [Drivers](https://github.com/hybridgroup/cylon-gpio)
|
- [GPIO](https://en.wikipedia.org/wiki/General_Purpose_Input/Output) <=> [Drivers](https://github.com/hybridgroup/cylon-gpio)
|
||||||
|
- Analog Sensor
|
||||||
|
- Button
|
||||||
|
- LED
|
||||||
|
- Motor
|
||||||
|
- Maxbotix Ultrasonic Range Finder
|
||||||
|
- Servo
|
||||||
|
|
||||||
Support for devices that use Inter-Integrated Circuit (I2C) have a shared set of
|
Support for devices that use Inter-Integrated Circuit (I2C) have a shared set of
|
||||||
drivers provded using the cylon-i2c module:
|
drivers provded using the cylon-i2c module:
|
||||||
|
|
||||||
- [I2C](https://en.wikipedia.org/wiki/I%C2%B2C) <=> [Drivers](https://github.com/hybridgroup/cylon-i2c)
|
- [I2C](https://en.wikipedia.org/wiki/I%C2%B2C) <=> [Drivers](https://github.com/hybridgroup/cylon-i2c)
|
||||||
|
- BlinkM
|
||||||
|
- HMC6352 Digital Compass
|
||||||
|
|
||||||
More platforms and drivers are coming soon...
|
More platforms and drivers are coming soon...
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@
|
||||||
DigitalPin.prototype.close = function() {
|
DigitalPin.prototype.close = function() {
|
||||||
var _this = this;
|
var _this = this;
|
||||||
return FS.writeFile(this._unexportPath(), "" + this.pinNum, function(err) {
|
return FS.writeFile(this._unexportPath(), "" + this.pinNum, function(err) {
|
||||||
return _this._closeCallback();
|
return _this._closeCallback(err);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -77,13 +77,14 @@
|
||||||
this._setMode('w');
|
this._setMode('w');
|
||||||
}
|
}
|
||||||
this.status = value === 1 ? 'high' : 'low';
|
this.status = value === 1 ? 'high' : 'low';
|
||||||
return FS.writeFile(this._valuePath(), value, function(err) {
|
FS.writeFile(this._valuePath(), value, function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return _this.emit('error', "Error occurred while writing value " + value + " to pin " + _this.pinNum);
|
return _this.emit('error', "Error occurred while writing value " + value + " to pin " + _this.pinNum);
|
||||||
} else {
|
} else {
|
||||||
return _this.emit('digitalWrite', value);
|
return _this.emit('digitalWrite', value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return value;
|
||||||
};
|
};
|
||||||
|
|
||||||
DigitalPin.prototype.digitalRead = function(interval) {
|
DigitalPin.prototype.digitalRead = function(interval) {
|
||||||
|
@ -93,16 +94,17 @@
|
||||||
this._setMode('r');
|
this._setMode('r');
|
||||||
}
|
}
|
||||||
readData = null;
|
readData = null;
|
||||||
return setInterval(function() {
|
setInterval(function() {
|
||||||
return FS.readFile(_this._valuePath(), function(err, data) {
|
return FS.readFile(_this._valuePath(), function(err, data) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return _this.emit('error', "Error occurred while reading from pin " + _this.pinNum);
|
return _this.emit('error', "Error occurred while reading from pin " + _this.pinNum);
|
||||||
} else {
|
} else {
|
||||||
readData = data;
|
readData = parseInt(data.toString());
|
||||||
return _this.emit('digitalRead', data);
|
return _this.emit('digitalRead', readData);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, interval);
|
}, interval);
|
||||||
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
DigitalPin.prototype.setHigh = function() {
|
DigitalPin.prototype.setHigh = function() {
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
Cylon = require '..'
|
||||||
|
|
||||||
|
Cylon.robot
|
||||||
|
connection:
|
||||||
|
name: 'crazyflie', adaptor: 'crazyflie', port: "radio://1/10/250KPS"
|
||||||
|
|
||||||
|
device:
|
||||||
|
name: 'drone', driver: 'crazyflie'
|
||||||
|
|
||||||
|
work: (my) ->
|
||||||
|
#my.drone.setParam('flightmode.althold', true)
|
||||||
|
my.drone.on 'start', ->
|
||||||
|
my.drone.takeoff()
|
||||||
|
after 10.seconds(), ->
|
||||||
|
my.drone.land()
|
||||||
|
after 15.seconds(), ->
|
||||||
|
my.drone.stop()
|
||||||
|
|
||||||
|
.start()
|
|
@ -0,0 +1,20 @@
|
||||||
|
Cylon = require('..')
|
||||||
|
|
||||||
|
# Initialize the robot
|
||||||
|
Cylon.robot
|
||||||
|
connection:
|
||||||
|
name: 'raspi', adaptor: 'raspi', port: '/dev/ttyACM0'
|
||||||
|
|
||||||
|
device:
|
||||||
|
name: 'led', driver: 'led', pin: 11
|
||||||
|
|
||||||
|
work: (my) ->
|
||||||
|
# we do our thing here
|
||||||
|
brightness = 0
|
||||||
|
fade = 5
|
||||||
|
every 0.05.seconds(), ->
|
||||||
|
brightness += fade
|
||||||
|
my.led.brightness(brightness)
|
||||||
|
fade = -fade if (brightness is 0) or (brightness is 255)
|
||||||
|
|
||||||
|
.start()
|
|
@ -0,0 +1,22 @@
|
||||||
|
Cylon = require('..')
|
||||||
|
|
||||||
|
# Initialize the robot
|
||||||
|
Cylon.robot
|
||||||
|
connection:
|
||||||
|
name: 'raspi', adaptor: 'raspi', port: '/dev/ttyACM0'
|
||||||
|
|
||||||
|
device:
|
||||||
|
name: 'servo', driver: 'servo', pin: 11
|
||||||
|
|
||||||
|
work: (my) ->
|
||||||
|
# we do our thing here
|
||||||
|
work: (my) ->
|
||||||
|
angle = 30
|
||||||
|
increment = 40
|
||||||
|
every 1.seconds(), ->
|
||||||
|
angle += increment
|
||||||
|
my.servo.angle(angle)
|
||||||
|
console.log("Current Angle => #{ my.servo.currentAngle() }")
|
||||||
|
increment = -increment if (angle is 30) or (angle is 150)
|
||||||
|
|
||||||
|
.start()
|
|
@ -5,8 +5,8 @@ Cylon.robot
|
||||||
device: { name: 'servo', driver: 'servo', pin: 3 }
|
device: { name: 'servo', driver: 'servo', pin: 3 }
|
||||||
|
|
||||||
work: (my) ->
|
work: (my) ->
|
||||||
angle = 0
|
angle = 30
|
||||||
increment = 90
|
increment = 40
|
||||||
|
|
||||||
every 1.seconds(), ->
|
every 1.seconds(), ->
|
||||||
angle += increment
|
angle += increment
|
||||||
|
@ -14,6 +14,6 @@ Cylon.robot
|
||||||
|
|
||||||
Logger.info "Current Angle: #{my.servo.currentAngle()}"
|
Logger.info "Current Angle: #{my.servo.currentAngle()}"
|
||||||
|
|
||||||
increment = -increment if (angle is 0) or (angle is 180)
|
increment = -increment if (angle is 30) or (angle is 150)
|
||||||
|
|
||||||
.start()
|
.start()
|
||||||
|
|
|
@ -5,8 +5,8 @@ Cylon.robot({
|
||||||
device: { name: 'servo', driver: 'servo', pin: 3 },
|
device: { name: 'servo', driver: 'servo', pin: 3 },
|
||||||
|
|
||||||
work: function(my) {
|
work: function(my) {
|
||||||
var angle = 0;
|
var angle = 30;
|
||||||
var increment = 90;
|
var increment = 40;
|
||||||
|
|
||||||
every(1..seconds(), function() {
|
every(1..seconds(), function() {
|
||||||
angle += increment;
|
angle += increment;
|
||||||
|
@ -14,7 +14,7 @@ Cylon.robot({
|
||||||
|
|
||||||
Logger.info("Current Angle: " + (my.servo.currentAngle()));
|
Logger.info("Current Angle: " + (my.servo.currentAngle()));
|
||||||
|
|
||||||
if ((angle === 0) || (angle === 180)) { increment = -increment; }
|
if ((angle === 30) || (angle === 150)) { increment = -increment; }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
|
|
|
@ -27,19 +27,19 @@ We'll start defining the work for our robot next:
|
||||||
We'll define variables to hold our servo's angle, and the rate at which that
|
We'll define variables to hold our servo's angle, and the rate at which that
|
||||||
angle will change:
|
angle will change:
|
||||||
|
|
||||||
angle = 0
|
angle = 30
|
||||||
increment = 5
|
increment = 40
|
||||||
|
|
||||||
Every second, we'll increment the `angle`, set the servo to run at that angle,
|
Every second, we'll increment the `angle`, set the servo to run at that angle,
|
||||||
and log the angle we're running at to the console. We'll also make sure to
|
and log the angle we're running at to the console. We'll also make sure to
|
||||||
change the increment if the angle is at the upper/lower bounds of the values
|
change the increment if the angle is at the upper/lower bounds of the values
|
||||||
supported:
|
supported:
|
||||||
|
|
||||||
every 0.05.seconds(), ->
|
every 1.seconds(), ->
|
||||||
angle += increment
|
angle += increment
|
||||||
my.servo.angle(angle)
|
my.servo.angle(angle)
|
||||||
Logger.info "Current angle: #{my.servo.currentAngle() }"
|
Logger.info "Current angle: #{my.servo.currentAngle() }"
|
||||||
increment = -increment if (angle is 0) or (angle is 180)
|
increment = -increment if (angle is 30) or (angle is 150)
|
||||||
|
|
||||||
And with all that done, we can now start our robot:
|
And with all that done, we can now start our robot:
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "cylon",
|
"name": "cylon",
|
||||||
"version": "0.6.0",
|
"version": "0.6.1",
|
||||||
"main": "dist/cylon.js",
|
"main": "dist/cylon.js",
|
||||||
"description": "A JavaScript robotics framework using Node.js",
|
"description": "A JavaScript robotics framework using Node.js",
|
||||||
"homepage": "http://cylonjs.com",
|
"homepage": "http://cylonjs.com",
|
||||||
|
|
|
@ -34,29 +34,31 @@ namespace 'Cylon.IO', ->
|
||||||
@mode ?= mode
|
@mode ?= mode
|
||||||
|
|
||||||
# Check if the pin acceess file is already in the GPIO folder
|
# Check if the pin acceess file is already in the GPIO folder
|
||||||
FS.exists @_pinPath(), (exists) =>
|
FS.exists(@_pinPath(), (exists) =>
|
||||||
if exists then @_openPin() else @_createGPIOPin()
|
if exists then @_openPin() else @_createGPIOPin()
|
||||||
|
)
|
||||||
|
|
||||||
close: ->
|
close: ->
|
||||||
FS.writeFile @_unexportPath(), "#{ @pinNum }", (err) =>
|
FS.writeFile(@_unexportPath(), "#{ @pinNum }", (err) =>
|
||||||
@_closeCallback()
|
@_closeCallback(err)
|
||||||
|
)
|
||||||
|
|
||||||
closeSync: ->
|
closeSync: ->
|
||||||
FS.writeFileSync @_unexportPath(), "#{ @pinNum }"
|
FS.writeFileSync(@_unexportPath(), "#{ @pinNum }")
|
||||||
@_closeCallback false
|
@_closeCallback(false)
|
||||||
|
|
||||||
digitalWrite: (value) ->
|
digitalWrite: (value) ->
|
||||||
@_setMode('w') unless @mode is 'w'
|
@_setMode('w') unless @mode is 'w'
|
||||||
@status = if value is 1 then 'high' else 'low'
|
@status = if value is 1 then 'high' else 'low'
|
||||||
|
|
||||||
FS.writeFile @_valuePath(), value, (err) =>
|
FS.writeFile(@_valuePath(), value, (err) =>
|
||||||
if err
|
if err
|
||||||
@emit(
|
@emit('error', "Error occurred while writing value #{value} to pin #{@pinNum}")
|
||||||
'error',
|
|
||||||
"Error occurred while writing value #{value} to pin #{@pinNum}"
|
|
||||||
)
|
|
||||||
else
|
else
|
||||||
@emit 'digitalWrite', value
|
@emit('digitalWrite', value)
|
||||||
|
)
|
||||||
|
|
||||||
|
value
|
||||||
|
|
||||||
# Reads the pin input every interval amount of time:
|
# Reads the pin input every interval amount of time:
|
||||||
# params:
|
# params:
|
||||||
|
@ -65,14 +67,17 @@ namespace 'Cylon.IO', ->
|
||||||
@_setMode('r') unless @mode is 'r'
|
@_setMode('r') unless @mode is 'r'
|
||||||
readData = null
|
readData = null
|
||||||
|
|
||||||
setInterval =>
|
setInterval(() =>
|
||||||
FS.readFile @_valuePath(), (err, data) =>
|
FS.readFile(@_valuePath(), (err, data) =>
|
||||||
if err
|
if err
|
||||||
@emit 'error', "Error occurred while reading from pin #{ @pinNum }"
|
@emit('error', "Error occurred while reading from pin #{ @pinNum }")
|
||||||
else
|
else
|
||||||
readData = data
|
readData = parseInt(data.toString())
|
||||||
@emit 'digitalRead', data
|
@emit('digitalRead', readData)
|
||||||
, interval
|
)
|
||||||
|
, interval)
|
||||||
|
|
||||||
|
true
|
||||||
|
|
||||||
setHigh: ->
|
setHigh: ->
|
||||||
@digitalWrite 1
|
@digitalWrite 1
|
||||||
|
@ -85,35 +90,38 @@ namespace 'Cylon.IO', ->
|
||||||
|
|
||||||
# Creates the GPIO file to read/write from
|
# Creates the GPIO file to read/write from
|
||||||
_createGPIOPin: () ->
|
_createGPIOPin: () ->
|
||||||
FS.writeFile @_exportPath(), "#{ @pinNum }", (err) =>
|
FS.writeFile(@_exportPath(), "#{ @pinNum }", (err) =>
|
||||||
if err
|
if err
|
||||||
@emit 'error', 'Error while creating pin files'
|
@emit('error', 'Error while creating pin files')
|
||||||
else
|
else
|
||||||
@_openPin()
|
@_openPin()
|
||||||
|
)
|
||||||
|
|
||||||
_openPin: () ->
|
_openPin: () ->
|
||||||
@_setMode @mode, true
|
@_setMode(@mode, true)
|
||||||
@emit 'open'
|
@emit('open')
|
||||||
|
|
||||||
_closeCallback: (err) ->
|
_closeCallback: (err) ->
|
||||||
if err
|
if err
|
||||||
@emit 'error', 'Error while closing pin files'
|
@emit('error', 'Error while closing pin files')
|
||||||
else
|
else
|
||||||
@emit 'close', @pinNum
|
@emit('close', @pinNum)
|
||||||
|
|
||||||
# Sets the mode for the GPIO pin by writing the correct values to the pin reference files
|
# Sets the mode for the GPIO pin by writing the correct values to the pin reference files
|
||||||
_setMode: (mode, emitConnect = false) ->
|
_setMode: (mode, emitConnect = false) ->
|
||||||
@mode = mode
|
@mode = mode
|
||||||
if mode is 'w'
|
if mode is 'w'
|
||||||
FS.writeFile @_directionPath(), GPIO_DIRECTION_WRITE, (err) =>
|
FS.writeFile(@_directionPath(), GPIO_DIRECTION_WRITE, (err) =>
|
||||||
@_setModeCallback err, emitConnect
|
@_setModeCallback(err, emitConnect)
|
||||||
|
)
|
||||||
else if mode is 'r'
|
else if mode is 'r'
|
||||||
FS.writeFile @_directionPath(), GPIO_DIRECTION_READ, (err) =>
|
FS.writeFile(@_directionPath(), GPIO_DIRECTION_READ, (err) =>
|
||||||
@_setModeCallback err, emitConnect
|
@_setModeCallback(err, emitConnect)
|
||||||
|
)
|
||||||
|
|
||||||
_setModeCallback: (err, emitConnect) ->
|
_setModeCallback: (err, emitConnect) ->
|
||||||
if err
|
if err
|
||||||
@emit 'error', "Setting up pin direction failed"
|
@emit('error', "Setting up pin direction failed")
|
||||||
else
|
else
|
||||||
@ready = true
|
@ready = true
|
||||||
@emit('connect', @mode) if emitConnect
|
@emit('connect', @mode) if emitConnect
|
||||||
|
|
Loading…
Reference in New Issue