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:
Andrew Stewart 2013-11-28 12:07:51 -08:00
commit 2c52db8086
10 changed files with 125 additions and 44 deletions

View File

@ -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...

12
dist/digital-pin.js vendored
View File

@ -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() {

19
examples/crazyflie.coffee Normal file
View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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();

View File

@ -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:

View File

@ -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",

View File

@ -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