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)
|
||||
- [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)
|
||||
- [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)
|
||||
- [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)
|
||||
|
@ -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:
|
||||
|
||||
- [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
|
||||
drivers provded using the cylon-i2c module:
|
||||
|
||||
- [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...
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
DigitalPin.prototype.close = function() {
|
||||
var _this = this;
|
||||
return FS.writeFile(this._unexportPath(), "" + this.pinNum, function(err) {
|
||||
return _this._closeCallback();
|
||||
return _this._closeCallback(err);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -77,13 +77,14 @@
|
|||
this._setMode('w');
|
||||
}
|
||||
this.status = value === 1 ? 'high' : 'low';
|
||||
return FS.writeFile(this._valuePath(), value, function(err) {
|
||||
FS.writeFile(this._valuePath(), value, function(err) {
|
||||
if (err) {
|
||||
return _this.emit('error', "Error occurred while writing value " + value + " to pin " + _this.pinNum);
|
||||
} else {
|
||||
return _this.emit('digitalWrite', value);
|
||||
}
|
||||
});
|
||||
return value;
|
||||
};
|
||||
|
||||
DigitalPin.prototype.digitalRead = function(interval) {
|
||||
|
@ -93,16 +94,17 @@
|
|||
this._setMode('r');
|
||||
}
|
||||
readData = null;
|
||||
return setInterval(function() {
|
||||
setInterval(function() {
|
||||
return FS.readFile(_this._valuePath(), function(err, data) {
|
||||
if (err) {
|
||||
return _this.emit('error', "Error occurred while reading from pin " + _this.pinNum);
|
||||
} else {
|
||||
readData = data;
|
||||
return _this.emit('digitalRead', data);
|
||||
readData = parseInt(data.toString());
|
||||
return _this.emit('digitalRead', readData);
|
||||
}
|
||||
});
|
||||
}, interval);
|
||||
return true;
|
||||
};
|
||||
|
||||
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 }
|
||||
|
||||
work: (my) ->
|
||||
angle = 0
|
||||
increment = 90
|
||||
angle = 30
|
||||
increment = 40
|
||||
|
||||
every 1.seconds(), ->
|
||||
angle += increment
|
||||
|
@ -14,6 +14,6 @@ Cylon.robot
|
|||
|
||||
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()
|
||||
|
|
|
@ -5,8 +5,8 @@ Cylon.robot({
|
|||
device: { name: 'servo', driver: 'servo', pin: 3 },
|
||||
|
||||
work: function(my) {
|
||||
var angle = 0;
|
||||
var increment = 90;
|
||||
var angle = 30;
|
||||
var increment = 40;
|
||||
|
||||
every(1..seconds(), function() {
|
||||
angle += increment;
|
||||
|
@ -14,7 +14,7 @@ Cylon.robot({
|
|||
|
||||
Logger.info("Current Angle: " + (my.servo.currentAngle()));
|
||||
|
||||
if ((angle === 0) || (angle === 180)) { increment = -increment; }
|
||||
if ((angle === 30) || (angle === 150)) { increment = -increment; }
|
||||
});
|
||||
}
|
||||
}).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
|
||||
angle will change:
|
||||
|
||||
angle = 0
|
||||
increment = 5
|
||||
angle = 30
|
||||
increment = 40
|
||||
|
||||
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
|
||||
change the increment if the angle is at the upper/lower bounds of the values
|
||||
supported:
|
||||
|
||||
every 0.05.seconds(), ->
|
||||
every 1.seconds(), ->
|
||||
angle += increment
|
||||
my.servo.angle(angle)
|
||||
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:
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "cylon",
|
||||
"version": "0.6.0",
|
||||
"version": "0.6.1",
|
||||
"main": "dist/cylon.js",
|
||||
"description": "A JavaScript robotics framework using Node.js",
|
||||
"homepage": "http://cylonjs.com",
|
||||
|
|
|
@ -34,29 +34,31 @@ namespace 'Cylon.IO', ->
|
|||
@mode ?= mode
|
||||
|
||||
# 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()
|
||||
)
|
||||
|
||||
close: ->
|
||||
FS.writeFile @_unexportPath(), "#{ @pinNum }", (err) =>
|
||||
@_closeCallback()
|
||||
FS.writeFile(@_unexportPath(), "#{ @pinNum }", (err) =>
|
||||
@_closeCallback(err)
|
||||
)
|
||||
|
||||
closeSync: ->
|
||||
FS.writeFileSync @_unexportPath(), "#{ @pinNum }"
|
||||
@_closeCallback false
|
||||
FS.writeFileSync(@_unexportPath(), "#{ @pinNum }")
|
||||
@_closeCallback(false)
|
||||
|
||||
digitalWrite: (value) ->
|
||||
@_setMode('w') unless @mode is 'w'
|
||||
@status = if value is 1 then 'high' else 'low'
|
||||
|
||||
FS.writeFile @_valuePath(), value, (err) =>
|
||||
FS.writeFile(@_valuePath(), value, (err) =>
|
||||
if err
|
||||
@emit(
|
||||
'error',
|
||||
"Error occurred while writing value #{value} to pin #{@pinNum}"
|
||||
)
|
||||
@emit('error', "Error occurred while writing value #{value} to pin #{@pinNum}")
|
||||
else
|
||||
@emit 'digitalWrite', value
|
||||
@emit('digitalWrite', value)
|
||||
)
|
||||
|
||||
value
|
||||
|
||||
# Reads the pin input every interval amount of time:
|
||||
# params:
|
||||
|
@ -65,14 +67,17 @@ namespace 'Cylon.IO', ->
|
|||
@_setMode('r') unless @mode is 'r'
|
||||
readData = null
|
||||
|
||||
setInterval =>
|
||||
FS.readFile @_valuePath(), (err, data) =>
|
||||
setInterval(() =>
|
||||
FS.readFile(@_valuePath(), (err, data) =>
|
||||
if err
|
||||
@emit 'error', "Error occurred while reading from pin #{ @pinNum }"
|
||||
@emit('error', "Error occurred while reading from pin #{ @pinNum }")
|
||||
else
|
||||
readData = data
|
||||
@emit 'digitalRead', data
|
||||
, interval
|
||||
readData = parseInt(data.toString())
|
||||
@emit('digitalRead', readData)
|
||||
)
|
||||
, interval)
|
||||
|
||||
true
|
||||
|
||||
setHigh: ->
|
||||
@digitalWrite 1
|
||||
|
@ -85,35 +90,38 @@ namespace 'Cylon.IO', ->
|
|||
|
||||
# Creates the GPIO file to read/write from
|
||||
_createGPIOPin: () ->
|
||||
FS.writeFile @_exportPath(), "#{ @pinNum }", (err) =>
|
||||
FS.writeFile(@_exportPath(), "#{ @pinNum }", (err) =>
|
||||
if err
|
||||
@emit 'error', 'Error while creating pin files'
|
||||
@emit('error', 'Error while creating pin files')
|
||||
else
|
||||
@_openPin()
|
||||
)
|
||||
|
||||
_openPin: () ->
|
||||
@_setMode @mode, true
|
||||
@emit 'open'
|
||||
@_setMode(@mode, true)
|
||||
@emit('open')
|
||||
|
||||
_closeCallback: (err) ->
|
||||
if err
|
||||
@emit 'error', 'Error while closing pin files'
|
||||
@emit('error', 'Error while closing pin files')
|
||||
else
|
||||
@emit 'close', @pinNum
|
||||
@emit('close', @pinNum)
|
||||
|
||||
# Sets the mode for the GPIO pin by writing the correct values to the pin reference files
|
||||
_setMode: (mode, emitConnect = false) ->
|
||||
@mode = mode
|
||||
if mode is 'w'
|
||||
FS.writeFile @_directionPath(), GPIO_DIRECTION_WRITE, (err) =>
|
||||
@_setModeCallback err, emitConnect
|
||||
FS.writeFile(@_directionPath(), GPIO_DIRECTION_WRITE, (err) =>
|
||||
@_setModeCallback(err, emitConnect)
|
||||
)
|
||||
else if mode is 'r'
|
||||
FS.writeFile @_directionPath(), GPIO_DIRECTION_READ, (err) =>
|
||||
@_setModeCallback err, emitConnect
|
||||
FS.writeFile(@_directionPath(), GPIO_DIRECTION_READ, (err) =>
|
||||
@_setModeCallback(err, emitConnect)
|
||||
)
|
||||
|
||||
_setModeCallback: (err, emitConnect) ->
|
||||
if err
|
||||
@emit 'error', "Setting up pin direction failed"
|
||||
@emit('error', "Setting up pin direction failed")
|
||||
else
|
||||
@ready = true
|
||||
@emit('connect', @mode) if emitConnect
|
||||
|
|
Loading…
Reference in New Issue