20 |
21 | https://github.com/shokai/node-ble-firmata
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/History.txt:
--------------------------------------------------------------------------------
1 | === 0.2.1 2015-12-09
2 |
3 | * update for blendmicro v0.4.0
4 |
5 | === 0.2.0 2015-10-24
6 |
7 | * bugfixed reconnection #2
8 |
9 | === 0.1.4 2015-07-29
10 |
11 | * update blendmicro npm to support OSX Yosemite
12 | * ignore compiled js from git repos
13 | * ignore src/ and samples/ to push npmjs.com
14 |
15 | === 0.1.3 2014-12-24
16 |
17 | * add method "sendI2CConfig" and "sendI2CWriteRequest"
18 | thank you for contributing @noopkat
19 |
20 | === 0.1.2 2014-06-15
21 |
22 | * fix dependencies
23 |
24 | === 0.1.1 2014-06-14
25 |
26 | * add property BLEFirmata#reconnect to control auto-reconnect #3
27 |
28 | === 0.1.0 2014-06-14
29 |
30 | * re-connect on BLE closed #2
31 | * fix samples
32 |
33 | === 0.0.2 2014-06-14
34 |
35 | * fix samples
36 | * fix firmware for BLE Shield
37 |
38 | === 0.0.1 2014-06-13
39 |
40 | * first release
41 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2014 Sho Hashimoto
2 |
3 | MIT License
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining
6 | a copy of this software and associated documentation files (the
7 | "Software"), to deal in the Software without restriction, including
8 | without limitation the rights to use, copy, modify, merge, publish,
9 | distribute, sublicense, and/or sell copies of the Software, and to
10 | permit persons to whom the Software is furnished to do so, subject to
11 | the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be
14 | included in all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/samples/sysex/SysexLedBlinkFirmata/SysexLedBlinkFirmata.ino:
--------------------------------------------------------------------------------
1 | #define BLE_NAME "BlendMicro"
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include "BLEFirmata.h"
8 | #include
9 |
10 | void setup()
11 | {
12 | BleFirmata.setFirmwareVersion(FIRMATA_MAJOR_VERSION, FIRMATA_MINOR_VERSION);
13 | BleFirmata.attach(START_SYSEX, sysexCallback);
14 |
15 | ble_set_name(BLE_NAME);
16 | ble_begin();
17 | }
18 |
19 | void loop()
20 | {
21 | ble_do_events();
22 |
23 | while(BleFirmata.available()) {
24 | BleFirmata.processInput();
25 | }
26 | }
27 |
28 | void sysexCallback(byte command, byte argc, byte*argv)
29 | {
30 | switch(command){
31 | case 0x01: // LED Blink Command
32 | if(argc < 3) break;
33 | byte blink_pin;
34 | byte blink_count;
35 | int delayTime;
36 | blink_pin = argv[0];
37 | blink_count = argv[1];
38 | delayTime = argv[2] * 100;
39 |
40 | pinMode(blink_pin, OUTPUT);
41 | byte i;
42 | for(i = 0; i < blink_count; i++){
43 | digitalWrite(blink_pin, true);
44 | delay(delayTime);
45 | digitalWrite(blink_pin, false);
46 | delay(delayTime);
47 | }
48 | BleFirmata.sendSysex(command, argc, argv); // callback
49 | break;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ble-firmata",
3 | "private": false,
4 | "version": "0.2.1",
5 | "description": "BlendMicro & Arduino BLE-Shield Firmata implementation for Node.js",
6 | "main": "lib/ble-firmata.js",
7 | "scripts": {
8 | "test": "grunt test",
9 | "build": "grunt build",
10 | "watch": "grunt"
11 | },
12 | "devDependencies": {
13 | "coffee-errors": "*",
14 | "coffee-script": "*",
15 | "async": "*",
16 | "mocha": "*",
17 | "grunt": "*",
18 | "grunt-cli": "*",
19 | "grunt-simple-mocha": "*",
20 | "grunt-notify": "*",
21 | "grunt-contrib-coffee": "*",
22 | "grunt-coffeelint": "*",
23 | "grunt-contrib-watch": "*",
24 | "socket.io": "*"
25 | },
26 | "keywords": [
27 | "arduino",
28 | "blendmicro",
29 | "BLE",
30 | "bluetooth",
31 | "firmata"
32 | ],
33 | "author": "Sho Hashimoto ",
34 | "license": "MIT",
35 | "dependencies": {
36 | "blendmicro": ">=0.4.0",
37 | "debug": "*",
38 | "eventemitter2": "*"
39 | },
40 | "directories": {
41 | "test": "tests"
42 | },
43 | "repository": {
44 | "type": "git",
45 | "url": "git://github.com/shokai/node-ble-firmata.git"
46 | },
47 | "bugs": {
48 | "url": "https://github.com/shokai/node-ble-firmata/issues"
49 | },
50 | "homepage": "https://github.com/shokai/node-ble-firmata"
51 | }
52 |
--------------------------------------------------------------------------------
/Gruntfile.coffee:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | module.exports = (grunt) ->
4 |
5 | require 'coffee-errors'
6 |
7 | grunt.loadNpmTasks 'grunt-contrib-coffee'
8 | grunt.loadNpmTasks 'grunt-contrib-watch'
9 | grunt.loadNpmTasks 'grunt-coffeelint'
10 | grunt.loadNpmTasks 'grunt-simple-mocha'
11 | grunt.loadNpmTasks 'grunt-notify'
12 |
13 | grunt.registerTask 'build', [ 'coffeelint', 'coffee' ]
14 | grunt.registerTask 'test', [ 'build', 'simplemocha' ]
15 | grunt.registerTask 'default', [ 'build', 'watch' ]
16 |
17 | grunt.initConfig
18 |
19 | coffeelint:
20 | options:
21 | max_line_length:
22 | value: 119
23 | indentation:
24 | value: 2
25 | newlines_after_classes:
26 | level: 'error'
27 | no_empty_param_list:
28 | level: 'error'
29 | no_unnecessary_fat_arrows:
30 | level: 'ignore'
31 | dist:
32 | files: [
33 | { expand: yes, cwd: 'src/', src: [ '**/*.coffee' ] }
34 | { expand: yes, cwd: 'tests/', src: [ '**/*.coffee' ] }
35 | ]
36 |
37 | coffee:
38 | dist:
39 | files: [{
40 | expand: yes
41 | cwd: 'src/'
42 | src: [ '**/*.coffee' ]
43 | dest: 'lib/'
44 | ext: '.js'
45 | }]
46 |
47 | simplemocha:
48 | options:
49 | ui: 'bdd'
50 | reporter: 'spec'
51 | compilers: 'coffee:coffee-script'
52 | ignoreLeaks: no
53 | dist:
54 | src: [ 'tests/test_*.coffee' ]
55 |
56 | watch:
57 | options:
58 | interrupt: yes
59 | dist:
60 | files: [ 'src/**/*.coffee' ]
61 | tasks: [ 'build' ]
62 |
--------------------------------------------------------------------------------
/samples/server/server.js:
--------------------------------------------------------------------------------
1 | var http = require('http');
2 | var fs = require('fs');
3 | var url = require('url');
4 |
5 | var app_handler = function(req, res) {
6 | var path, _url;
7 | _url = url.parse(decodeURI(req.url), true);
8 | path = _url.pathname === '/' ? '/index.html' : _url.pathname;
9 | console.log(req.method + " - " + path);
10 | fs.readFile(__dirname + path, function(err, data) {
11 | if (err) {
12 | res.writeHead(500);
13 | res.end('error load file');
14 | }
15 | res.writeHead(200);
16 | res.end(data);
17 | });
18 | };
19 |
20 | var app = http.createServer(app_handler);
21 | var io = require('socket.io').listen(app);
22 |
23 | // var BLEFirmata = require('ble-firmata');
24 | var BLEFirmata = require('../../');
25 | arduino = new BLEFirmata().connect();
26 |
27 | arduino.on('connect', function(){
28 | console.log('arduino connect!');
29 | io.sockets.emit('bleState', arduino.state);
30 | });
31 |
32 | arduino.on('disconnect', function(){
33 | console.log('arduino disconnect!');
34 | io.sockets.emit('bleState', arduino.state);
35 | });
36 |
37 | // emit sensor-value to HTML-side
38 | arduino.on('analogChange', function(e){
39 | if(e.pin != 0) return;
40 | console.log(e);
41 | io.sockets.emit('analogRead', e.value);
42 | });
43 |
44 | io.sockets.on('connection', function(socket) {
45 |
46 | socket.emit('bleState', arduino.state);
47 | socket.emit('analogRead', arduino.analogRead(0));
48 |
49 | // on click button on HTML-side, change LED
50 | socket.on('digitalWrite', function(stat) {
51 | console.log("pin13:"+stat);
52 | arduino.digitalWrite(13, stat);
53 | });
54 |
55 | });
56 |
57 | var port = process.argv[2]-0 || 3000;
58 | app.listen(port);
59 | console.log("server start - port:" + port);
60 | console.log(" => http://localhost:"+port)
61 |
--------------------------------------------------------------------------------
/tests/test_ble.coffee:
--------------------------------------------------------------------------------
1 | process.env.NODE_ENV = 'test'
2 |
3 | path = require 'path'
4 | assert = require 'assert'
5 | async = require 'async'
6 |
7 | BLEFirmata = require path.resolve()
8 |
9 | describe 'instance of BLEFirmata', ->
10 |
11 | arduino = new BLEFirmata()
12 |
13 | it 'should have method "connect"', ->
14 | assert.equal typeof arduino['connect'], 'function'
15 |
16 |
17 | it 'should have method "close"', ->
18 | assert.equal typeof arduino['close'], 'function'
19 |
20 |
21 | it 'should have method "isOpen"', ->
22 | assert.equal typeof arduino['isOpen'], 'function'
23 |
24 |
25 | it 'should emit "connect" event', (done) ->
26 | @timeout 10000
27 | arduino.connect()
28 | arduino.on 'connect', ->
29 | assert.equal arduino.isOpen(), true
30 | done()
31 | assert.equal arduino.isOpen(), false
32 |
33 |
34 | it 'should have property "boardVersion"', ->
35 | assert.ok arduino.boardVersion.match(/^\d+\.\d+$/)
36 |
37 |
38 | it 'should have method "pinMode"', ->
39 | assert.equal typeof arduino['pinMode'], 'function'
40 |
41 |
42 | it 'should have method "digitalWrite"', ->
43 | assert.equal typeof arduino['digitalWrite'], 'function'
44 |
45 | describe 'method "digitalWrite"', ->
46 |
47 | it 'output digital', ->
48 | for i in [0..13]
49 | arduino.digitalWrite(i, true)
50 | arduino.digitalWrite(i, false)
51 |
52 |
53 | it 'should have method "analogWrite"', ->
54 | assert.equal typeof arduino['analogWrite'], 'function'
55 |
56 | describe 'method "analogWrite"', ->
57 |
58 | it 'output analog', ->
59 | for i in [0..13]
60 | out = Math.random()*256
61 | arduino.analogWrite(i, out)
62 | arduino.analogWrite(i, out)
63 |
64 |
65 | it 'should have method "servoWrite"', ->
66 | assert.equal typeof arduino['servoWrite'], 'function'
67 |
68 | describe 'method "servoWrite"', ->
69 |
70 | it 'output servo angle', ->
71 | for i in [0..13]
72 | out = Math.random()*180
73 | arduino.servoWrite(i, out)
74 | arduino.servoWrite(i, out)
75 |
76 |
77 | it 'should have method "digitalRead"', ->
78 | assert.equal typeof arduino['digitalRead'], 'function'
79 |
80 | describe 'method "digitalRead"', ->
81 |
82 | it 'should return value true or false', ->
83 | for i in [0..13]
84 | stat = arduino.digitalRead(i)
85 | assert.ok ((stat is true) or (stat is false))
86 |
87 |
88 | it 'should have method "analogRead"', ->
89 | assert.equal typeof arduino['analogRead'], 'function'
90 |
91 | describe 'method "analogRead"', ->
92 |
93 | it 'should return value 0~1023', ->
94 | for i in [0..5]
95 | val = arduino.analogRead(i)
96 | assert.ok (0 <= val and val < 1024)
97 |
98 |
99 | it 'should have method "sysex"', ->
100 | assert.equal typeof arduino['sysex'], 'function'
101 |
102 | describe 'method "sysex"', ->
103 |
104 | it 'should send sysex command', (done) ->
105 | arduino.on 'sysex', (e) ->
106 | assert e.command, 0x01
107 | assert e.data, [0x01, 0, 3, 0, 2]
108 | done()
109 | arduino.sysex 0x01, [13,3,2]
110 |
111 | it 'should have method "sendI2CConfig"', ->
112 | assert.equal typeof arduino['sendI2CConfig'], 'function'
113 |
114 | describe 'method "sendI2CConfig"', ->
115 |
116 | it 'should send I2C config command', ->
117 | arduino.sendI2CConfig
118 |
119 | it 'should have method "sendI2CWriteRequest"', ->
120 | assert.equal typeof arduino['sendI2CWriteRequest'], 'function'
121 |
122 | describe 'method "sendI2CWriteRequest"', ->
123 |
124 | it 'should send I2C write request command', ->
125 | arduino.sendI2CWriteRequest 0x3D, [13,3,2]
126 |
127 | describe 'method "close"', ->
128 |
129 | it 'should close BLE connection', (done) ->
130 | arduino.close ->
131 | done()
132 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | BLE Firmata
2 | ===========
3 | Arduino [Firmata](http://firmata.org) implementation on BLE (Bluetooth Low Energy) and Node.js.
4 |
5 | [](https://travis-ci.org/shokai/node-ble-firmata)
6 |
7 | - Firmata is a protocol to controll Arduino from software on PC.
8 | - You can embed Arduino code into Node.js application.
9 | - supports [BlendMicro](http://redbearlab.squarespace.com/blendmicro/).
10 | - also should works on [BLE Shield](http://redbearlab.squarespace.com/bleshield/), but I dont't have it.
11 |
12 |
13 | sites
14 |
15 | - https://github.com/shokai/node-ble-firmata
16 | - https://npmjs.org/package/ble-firmata
17 |
18 |
19 | Install
20 | -------
21 |
22 | % npm install ble-firmata
23 |
24 |
25 | Requirements
26 | ------------
27 |
28 | - [BlendMicro](http://redbearlab.squarespace.com/blendmicro)
29 | - you have to check pin function. pin 4/6/7 are reserved for BLE controll.
30 | - Install [patched Standard Firmata v2.3](./firmware/BLEFirmataSketch/BLEFirmataSketch.ino) to BlendMicro
31 | - fix `#define BLE_NAME "BlendMicro"` if you need.
32 | - [download zip](https://github.com/shokai/node-ble-firmata/archive/master.zip)
33 |
34 |
35 | Usage
36 | -----
37 |
38 | ### Samples
39 |
40 | - https://github.com/shokai/ble-arduino-firmata/tree/master/samples
41 |
42 |
43 | ### Setup
44 |
45 | Connect
46 | ```javascript
47 | var BLEFirmata = require('ble-firmata');
48 | var arduino = new BLEFirmata();
49 |
50 | // search device with BLE peripheral name
51 | arduino.connect("BlendMicro");
52 |
53 | // search with default name "BlendMicro"
54 | arduino.connect();
55 |
56 | arduino.on('connect', function(){
57 |
58 | console.log("board version"+arduino.boardVersion);
59 | // your-code-here
60 |
61 | });
62 | ```
63 |
64 | Reset
65 | ```javascript
66 | arduino.reset(callback);
67 | ```
68 |
69 | Close
70 | ```javascript
71 | arduino.close(callback);
72 | ```
73 |
74 |
75 | ### I/O
76 |
77 | Digital Write
78 | ```javascript
79 | arduino.digitalWrite(13, true, callback);
80 | arduino.digitalWrite(13, false, callback);
81 | ```
82 |
83 | Digital Read
84 | ```javascript
85 | arduino.pinMode(1, BLEFirmata.INPUT);
86 | console.log( arduino.digitalRead(1) ); // => true/false
87 | ```
88 |
89 | Digital Read (event)
90 | ```javascript
91 | arduino.pinMode(1, BLEFirmata.INPUT);
92 |
93 | arduino.on('digitalChange', function(e){
94 | console.log("pin" + e.pin + " : " + e.old_value + " -> " + e.value);
95 | });
96 | ```
97 |
98 | Analog Write (PWM)
99 | ```
100 | setInterval(function(){
101 | var an = Math.random()*255; // 0 ~ 255
102 | arduino.analogWrite(9, an, callback);
103 | }, 100);
104 | ```
105 |
106 | Analog Read
107 | ```javascript
108 | console.log( arduino.analogRead(0) ); // => 0 ~ 1023
109 | ```
110 |
111 | Analog Read (event)
112 | ```javascript
113 | arduino.on('analogChange', function(e){
114 | console.log("pin" + e.pin + " : " + e.old_value + " -> " + e.value);
115 | });
116 | ```
117 |
118 | Servo Motor
119 | ```javascript
120 | setInterval(function(){
121 | var angle = Math.random()*180; // 0 ~ 180
122 | arduino.servoWrite(11, angle, callback);
123 | }, 1000);
124 | ```
125 |
126 | ### Sysex
127 |
128 | - http://firmata.org/wiki/V2.1ProtocolDetails#Sysex_Message_Format
129 | - https://github.com/shokai/ble-arduino-firmata/tree/master/samples/sysex
130 |
131 | Send
132 | ```javascript
133 | arduino.sysex(0x01, [13, 5, 2], callback); // command, data_array, callback
134 | ```
135 |
136 | Register Sysex Event
137 | ```javascript
138 | arduino.on('sysex', function(e){
139 | console.log("command : " + e.command);
140 | console.log(e.data);
141 | });
142 | ```
143 |
144 | Debug
145 | -----
146 |
147 | set `DEBUG` env var
148 |
149 | % DEBUG=ble-firmata node samples/analog_write.js
150 | % DEBUG=*ble* node samples/analog_write.js
151 |
152 | Test
153 | ----
154 |
155 | ### Install SysexLedBlinkFirmata into Arduino
156 |
157 | * https://github.com/shokai/node-ble-firmata/blob/master/samples/sysex/BLEFirmataWithLedBlink/BLEFirmataWithLedBlink.ino
158 |
159 |
160 | ### Run Test
161 |
162 | % npm install
163 | % npm test
164 |
165 |
166 | Contributing
167 | ------------
168 | 1. Fork it
169 | 2. Create your feature branch (`git checkout -b my-new-feature`)
170 | 3. Commit your changes (`git commit -am 'Add some feature'`)
171 | 4. Push to the branch (`git push origin my-new-feature`)
172 | 5. Create new Pull Request
173 |
--------------------------------------------------------------------------------
/firmware/BLEFirmataSketch/BLEFirmata.h:
--------------------------------------------------------------------------------
1 | /*
2 | Firmata.h - Firmata library
3 | Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.
4 |
5 | This library is free software; you can redistribute it and/or
6 | modify it under the terms of the GNU Lesser General Public
7 | License as published by the Free Software Foundation; either
8 | version 2.1 of the License, or (at your option) any later version.
9 |
10 | See file LICENSE.txt for further informations on licensing terms.
11 | */
12 |
13 | #ifndef BleFirmata_h
14 | #define BleFirmata_h
15 |
16 | #include "Boards.h" /* Hardware Abstraction Layer + Wiring/Arduino */
17 |
18 | /* Version numbers for the protocol. The protocol is still changing, so these
19 | * version numbers are important. This number can be queried so that host
20 | * software can test whether it will be compatible with the currently
21 | * installed firmware. */
22 | #define FIRMATA_MAJOR_VERSION 2 // for non-compatible changes
23 | #define FIRMATA_MINOR_VERSION 3 // for backwards compatible changes
24 | #define FIRMATA_BUGFIX_VERSION 1 // for bugfix releases
25 |
26 | #define MAX_DATA_BYTES 32 // max number of data bytes in non-Sysex messages
27 |
28 | // message command bytes (128-255/0x80-0xFF)
29 | #define DIGITAL_MESSAGE 0x90 // send data for a digital pin
30 | #define ANALOG_MESSAGE 0xE0 // send data for an analog pin (or PWM)
31 | #define REPORT_ANALOG 0xC0 // enable analog input by pin #
32 | #define REPORT_DIGITAL 0xD0 // enable digital input by port pair
33 | //
34 | #define SET_PIN_MODE 0xF4 // set a pin to INPUT/OUTPUT/PWM/etc
35 | //
36 | #define REPORT_VERSION 0xF9 // report protocol version
37 | #define SYSTEM_RESET 0xFF // reset from MIDI
38 | //
39 | #define START_SYSEX 0xF0 // start a MIDI Sysex message
40 | #define END_SYSEX 0xF7 // end a MIDI Sysex message
41 |
42 | // extended command set using sysex (0-127/0x00-0x7F)
43 | /* 0x00-0x0F reserved for user-defined commands */
44 | #define SERVO_CONFIG 0x70 // set max angle, minPulse, maxPulse, freq
45 | #define STRING_DATA 0x71 // a string message with 14-bits per char
46 | #define SHIFT_DATA 0x75 // a bitstream to/from a shift register
47 | #define I2C_REQUEST 0x76 // send an I2C read/write request
48 | #define I2C_REPLY 0x77 // a reply to an I2C read request
49 | #define I2C_CONFIG 0x78 // config I2C settings such as delay times and power pins
50 | #define EXTENDED_ANALOG 0x6F // analog write (PWM, Servo, etc) to any pin
51 | #define PIN_STATE_QUERY 0x6D // ask for a pin's current mode and value
52 | #define PIN_STATE_RESPONSE 0x6E // reply with pin's current mode and value
53 | #define CAPABILITY_QUERY 0x6B // ask for supported modes and resolution of all pins
54 | #define CAPABILITY_RESPONSE 0x6C // reply with supported modes and resolution
55 | #define ANALOG_MAPPING_QUERY 0x69 // ask for mapping of analog to pin numbers
56 | #define ANALOG_MAPPING_RESPONSE 0x6A // reply with mapping info
57 | #define REPORT_FIRMWARE 0x79 // report name and version of the firmware
58 | #define SAMPLING_INTERVAL 0x7A // set the poll rate of the main loop
59 | #define SYSEX_NON_REALTIME 0x7E // MIDI Reserved for non-realtime messages
60 | #define SYSEX_REALTIME 0x7F // MIDI Reserved for realtime messages
61 | // these are DEPRECATED to make the naming more consistent
62 | #define FIRMATA_STRING 0x71 // same as STRING_DATA
63 | #define SYSEX_I2C_REQUEST 0x76 // same as I2C_REQUEST
64 | #define SYSEX_I2C_REPLY 0x77 // same as I2C_REPLY
65 | #define SYSEX_SAMPLING_INTERVAL 0x7A // same as SAMPLING_INTERVAL
66 |
67 | // pin modes
68 | //#define INPUT 0x00 // defined in wiring.h
69 | //#define OUTPUT 0x01 // defined in wiring.h
70 | #define ANALOG 0x02 // analog pin in analogInput mode
71 | #define PWM 0x03 // digital pin in PWM output mode
72 | #define SERVO 0x04 // digital pin in Servo output mode
73 | #define SHIFT 0x05 // shiftIn/shiftOut mode
74 | #define I2C 0x06 // pin included in I2C setup
75 | #define TOTAL_PIN_MODES 7
76 |
77 | extern "C" {
78 | // callback function types
79 | typedef void (*callbackFunction)(byte, int);
80 | typedef void (*systemResetCallbackFunction)(void);
81 | typedef void (*stringCallbackFunction)(char*);
82 | typedef void (*sysexCallbackFunction)(byte command, byte argc, byte*argv);
83 | }
84 |
85 |
86 | // TODO make it a subclass of a generic Serial/Stream base class
87 | class BleFirmataClass
88 | {
89 | public:
90 | BleFirmataClass(Stream &s);
91 | /* Arduino constructors */
92 | void begin();
93 | void begin(long);
94 | void begin(Stream &s);
95 | /* querying functions */
96 | void printVersion(void);
97 | void blinkVersion(void);
98 | void printFirmwareVersion(void);
99 | //void setFirmwareVersion(byte major, byte minor); // see macro below
100 | void setFirmwareNameAndVersion(const char *name, byte major, byte minor);
101 | /* serial receive handling */
102 | int available(void);
103 | void processInput(void);
104 | /* serial send handling */
105 | void sendAnalog(byte pin, int value);
106 | void sendDigital(byte pin, int value); // TODO implement this
107 | void sendDigitalPort(byte portNumber, int portData);
108 | void sendString(const char* string);
109 | void sendString(byte command, const char* string);
110 | void sendSysex(byte command, byte bytec, byte* bytev);
111 | /* attach & detach callback functions to messages */
112 | void attach(byte command, callbackFunction newFunction);
113 | void attach(byte command, systemResetCallbackFunction newFunction);
114 | void attach(byte command, stringCallbackFunction newFunction);
115 | void attach(byte command, sysexCallbackFunction newFunction);
116 | void detach(byte command);
117 |
118 | private:
119 | Stream &BleFirmataSerial;
120 | /* firmware name and version */
121 | byte firmwareVersionCount;
122 | byte *firmwareVersionVector;
123 | /* input message handling */
124 | byte waitForData; // this flag says the next serial input will be data
125 | byte executeMultiByteCommand; // execute this after getting multi-byte data
126 | byte multiByteChannel; // channel data for multiByteCommands
127 | byte storedInputData[MAX_DATA_BYTES]; // multi-byte data
128 | /* sysex */
129 | boolean parsingSysex;
130 | int sysexBytesRead;
131 | /* callback functions */
132 | callbackFunction currentAnalogCallback;
133 | callbackFunction currentDigitalCallback;
134 | callbackFunction currentReportAnalogCallback;
135 | callbackFunction currentReportDigitalCallback;
136 | callbackFunction currentPinModeCallback;
137 | systemResetCallbackFunction currentSystemResetCallback;
138 | stringCallbackFunction currentStringCallback;
139 | sysexCallbackFunction currentSysexCallback;
140 |
141 | /* private methods ------------------------------ */
142 | void processSysexMessage(void);
143 | void systemReset(void);
144 | void pin13strobe(int count, int onInterval, int offInterval);
145 | void sendValueAsTwo7bitBytes(int value);
146 | void startSysex(void);
147 | void endSysex(void);
148 | };
149 |
150 | extern BleFirmataClass BleFirmata;
151 |
152 | /*==============================================================================
153 | * MACROS
154 | *============================================================================*/
155 |
156 | /* shortcut for setFirmwareNameAndVersion() that uses __FILE__ to set the
157 | * firmware name. It needs to be a macro so that __FILE__ is included in the
158 | * firmware source file rather than the library source file.
159 | */
160 | #define setFirmwareVersion(x, y) setFirmwareNameAndVersion(__FILE__, x, y)
161 |
162 | #endif /* Firmata_h */
163 |
164 |
--------------------------------------------------------------------------------
/samples/sysex/SysexLedBlinkFirmata/BLEFirmata.h:
--------------------------------------------------------------------------------
1 | /*
2 | Firmata.h - Firmata library
3 | Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.
4 |
5 | This library is free software; you can redistribute it and/or
6 | modify it under the terms of the GNU Lesser General Public
7 | License as published by the Free Software Foundation; either
8 | version 2.1 of the License, or (at your option) any later version.
9 |
10 | See file LICENSE.txt for further informations on licensing terms.
11 | */
12 |
13 | #ifndef BleFirmata_h
14 | #define BleFirmata_h
15 |
16 | #include "Boards.h" /* Hardware Abstraction Layer + Wiring/Arduino */
17 |
18 | /* Version numbers for the protocol. The protocol is still changing, so these
19 | * version numbers are important. This number can be queried so that host
20 | * software can test whether it will be compatible with the currently
21 | * installed firmware. */
22 | #define FIRMATA_MAJOR_VERSION 2 // for non-compatible changes
23 | #define FIRMATA_MINOR_VERSION 3 // for backwards compatible changes
24 | #define FIRMATA_BUGFIX_VERSION 1 // for bugfix releases
25 |
26 | #define MAX_DATA_BYTES 32 // max number of data bytes in non-Sysex messages
27 |
28 | // message command bytes (128-255/0x80-0xFF)
29 | #define DIGITAL_MESSAGE 0x90 // send data for a digital pin
30 | #define ANALOG_MESSAGE 0xE0 // send data for an analog pin (or PWM)
31 | #define REPORT_ANALOG 0xC0 // enable analog input by pin #
32 | #define REPORT_DIGITAL 0xD0 // enable digital input by port pair
33 | //
34 | #define SET_PIN_MODE 0xF4 // set a pin to INPUT/OUTPUT/PWM/etc
35 | //
36 | #define REPORT_VERSION 0xF9 // report protocol version
37 | #define SYSTEM_RESET 0xFF // reset from MIDI
38 | //
39 | #define START_SYSEX 0xF0 // start a MIDI Sysex message
40 | #define END_SYSEX 0xF7 // end a MIDI Sysex message
41 |
42 | // extended command set using sysex (0-127/0x00-0x7F)
43 | /* 0x00-0x0F reserved for user-defined commands */
44 | #define SERVO_CONFIG 0x70 // set max angle, minPulse, maxPulse, freq
45 | #define STRING_DATA 0x71 // a string message with 14-bits per char
46 | #define SHIFT_DATA 0x75 // a bitstream to/from a shift register
47 | #define I2C_REQUEST 0x76 // send an I2C read/write request
48 | #define I2C_REPLY 0x77 // a reply to an I2C read request
49 | #define I2C_CONFIG 0x78 // config I2C settings such as delay times and power pins
50 | #define EXTENDED_ANALOG 0x6F // analog write (PWM, Servo, etc) to any pin
51 | #define PIN_STATE_QUERY 0x6D // ask for a pin's current mode and value
52 | #define PIN_STATE_RESPONSE 0x6E // reply with pin's current mode and value
53 | #define CAPABILITY_QUERY 0x6B // ask for supported modes and resolution of all pins
54 | #define CAPABILITY_RESPONSE 0x6C // reply with supported modes and resolution
55 | #define ANALOG_MAPPING_QUERY 0x69 // ask for mapping of analog to pin numbers
56 | #define ANALOG_MAPPING_RESPONSE 0x6A // reply with mapping info
57 | #define REPORT_FIRMWARE 0x79 // report name and version of the firmware
58 | #define SAMPLING_INTERVAL 0x7A // set the poll rate of the main loop
59 | #define SYSEX_NON_REALTIME 0x7E // MIDI Reserved for non-realtime messages
60 | #define SYSEX_REALTIME 0x7F // MIDI Reserved for realtime messages
61 | // these are DEPRECATED to make the naming more consistent
62 | #define FIRMATA_STRING 0x71 // same as STRING_DATA
63 | #define SYSEX_I2C_REQUEST 0x76 // same as I2C_REQUEST
64 | #define SYSEX_I2C_REPLY 0x77 // same as I2C_REPLY
65 | #define SYSEX_SAMPLING_INTERVAL 0x7A // same as SAMPLING_INTERVAL
66 |
67 | // pin modes
68 | //#define INPUT 0x00 // defined in wiring.h
69 | //#define OUTPUT 0x01 // defined in wiring.h
70 | #define ANALOG 0x02 // analog pin in analogInput mode
71 | #define PWM 0x03 // digital pin in PWM output mode
72 | #define SERVO 0x04 // digital pin in Servo output mode
73 | #define SHIFT 0x05 // shiftIn/shiftOut mode
74 | #define I2C 0x06 // pin included in I2C setup
75 | #define TOTAL_PIN_MODES 7
76 |
77 | extern "C" {
78 | // callback function types
79 | typedef void (*callbackFunction)(byte, int);
80 | typedef void (*systemResetCallbackFunction)(void);
81 | typedef void (*stringCallbackFunction)(char*);
82 | typedef void (*sysexCallbackFunction)(byte command, byte argc, byte*argv);
83 | }
84 |
85 |
86 | // TODO make it a subclass of a generic Serial/Stream base class
87 | class BleFirmataClass
88 | {
89 | public:
90 | BleFirmataClass(Stream &s);
91 | /* Arduino constructors */
92 | void begin();
93 | void begin(long);
94 | void begin(Stream &s);
95 | /* querying functions */
96 | void printVersion(void);
97 | void blinkVersion(void);
98 | void printFirmwareVersion(void);
99 | //void setFirmwareVersion(byte major, byte minor); // see macro below
100 | void setFirmwareNameAndVersion(const char *name, byte major, byte minor);
101 | /* serial receive handling */
102 | int available(void);
103 | void processInput(void);
104 | /* serial send handling */
105 | void sendAnalog(byte pin, int value);
106 | void sendDigital(byte pin, int value); // TODO implement this
107 | void sendDigitalPort(byte portNumber, int portData);
108 | void sendString(const char* string);
109 | void sendString(byte command, const char* string);
110 | void sendSysex(byte command, byte bytec, byte* bytev);
111 | /* attach & detach callback functions to messages */
112 | void attach(byte command, callbackFunction newFunction);
113 | void attach(byte command, systemResetCallbackFunction newFunction);
114 | void attach(byte command, stringCallbackFunction newFunction);
115 | void attach(byte command, sysexCallbackFunction newFunction);
116 | void detach(byte command);
117 |
118 | private:
119 | Stream &BleFirmataSerial;
120 | /* firmware name and version */
121 | byte firmwareVersionCount;
122 | byte *firmwareVersionVector;
123 | /* input message handling */
124 | byte waitForData; // this flag says the next serial input will be data
125 | byte executeMultiByteCommand; // execute this after getting multi-byte data
126 | byte multiByteChannel; // channel data for multiByteCommands
127 | byte storedInputData[MAX_DATA_BYTES]; // multi-byte data
128 | /* sysex */
129 | boolean parsingSysex;
130 | int sysexBytesRead;
131 | /* callback functions */
132 | callbackFunction currentAnalogCallback;
133 | callbackFunction currentDigitalCallback;
134 | callbackFunction currentReportAnalogCallback;
135 | callbackFunction currentReportDigitalCallback;
136 | callbackFunction currentPinModeCallback;
137 | systemResetCallbackFunction currentSystemResetCallback;
138 | stringCallbackFunction currentStringCallback;
139 | sysexCallbackFunction currentSysexCallback;
140 |
141 | /* private methods ------------------------------ */
142 | void processSysexMessage(void);
143 | void systemReset(void);
144 | void pin13strobe(int count, int onInterval, int offInterval);
145 | void sendValueAsTwo7bitBytes(int value);
146 | void startSysex(void);
147 | void endSysex(void);
148 | };
149 |
150 | extern BleFirmataClass BleFirmata;
151 |
152 | /*==============================================================================
153 | * MACROS
154 | *============================================================================*/
155 |
156 | /* shortcut for setFirmwareNameAndVersion() that uses __FILE__ to set the
157 | * firmware name. It needs to be a macro so that __FILE__ is included in the
158 | * firmware source file rather than the library source file.
159 | */
160 | #define setFirmwareVersion(x, y) setFirmwareNameAndVersion(__FILE__, x, y)
161 |
162 | #endif /* Firmata_h */
163 |
164 |
--------------------------------------------------------------------------------
/samples/sysex/BLEFirmataWithLedBlink/BLEFirmata.h:
--------------------------------------------------------------------------------
1 | /*
2 | Firmata.h - Firmata library
3 | Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.
4 |
5 | This library is free software; you can redistribute it and/or
6 | modify it under the terms of the GNU Lesser General Public
7 | License as published by the Free Software Foundation; either
8 | version 2.1 of the License, or (at your option) any later version.
9 |
10 | See file LICENSE.txt for further informations on licensing terms.
11 | */
12 |
13 | #ifndef BleFirmata_h
14 | #define BleFirmata_h
15 |
16 | #include "Boards.h" /* Hardware Abstraction Layer + Wiring/Arduino */
17 |
18 | /* Version numbers for the protocol. The protocol is still changing, so these
19 | * version numbers are important. This number can be queried so that host
20 | * software can test whether it will be compatible with the currently
21 | * installed firmware. */
22 | #define FIRMATA_MAJOR_VERSION 2 // for non-compatible changes
23 | #define FIRMATA_MINOR_VERSION 3 // for backwards compatible changes
24 | #define FIRMATA_BUGFIX_VERSION 1 // for bugfix releases
25 |
26 | #define MAX_DATA_BYTES 32 // max number of data bytes in non-Sysex messages
27 |
28 | // message command bytes (128-255/0x80-0xFF)
29 | #define DIGITAL_MESSAGE 0x90 // send data for a digital pin
30 | #define ANALOG_MESSAGE 0xE0 // send data for an analog pin (or PWM)
31 | #define REPORT_ANALOG 0xC0 // enable analog input by pin #
32 | #define REPORT_DIGITAL 0xD0 // enable digital input by port pair
33 | //
34 | #define SET_PIN_MODE 0xF4 // set a pin to INPUT/OUTPUT/PWM/etc
35 | //
36 | #define REPORT_VERSION 0xF9 // report protocol version
37 | #define SYSTEM_RESET 0xFF // reset from MIDI
38 | //
39 | #define START_SYSEX 0xF0 // start a MIDI Sysex message
40 | #define END_SYSEX 0xF7 // end a MIDI Sysex message
41 |
42 | // extended command set using sysex (0-127/0x00-0x7F)
43 | /* 0x00-0x0F reserved for user-defined commands */
44 | #define SERVO_CONFIG 0x70 // set max angle, minPulse, maxPulse, freq
45 | #define STRING_DATA 0x71 // a string message with 14-bits per char
46 | #define SHIFT_DATA 0x75 // a bitstream to/from a shift register
47 | #define I2C_REQUEST 0x76 // send an I2C read/write request
48 | #define I2C_REPLY 0x77 // a reply to an I2C read request
49 | #define I2C_CONFIG 0x78 // config I2C settings such as delay times and power pins
50 | #define EXTENDED_ANALOG 0x6F // analog write (PWM, Servo, etc) to any pin
51 | #define PIN_STATE_QUERY 0x6D // ask for a pin's current mode and value
52 | #define PIN_STATE_RESPONSE 0x6E // reply with pin's current mode and value
53 | #define CAPABILITY_QUERY 0x6B // ask for supported modes and resolution of all pins
54 | #define CAPABILITY_RESPONSE 0x6C // reply with supported modes and resolution
55 | #define ANALOG_MAPPING_QUERY 0x69 // ask for mapping of analog to pin numbers
56 | #define ANALOG_MAPPING_RESPONSE 0x6A // reply with mapping info
57 | #define REPORT_FIRMWARE 0x79 // report name and version of the firmware
58 | #define SAMPLING_INTERVAL 0x7A // set the poll rate of the main loop
59 | #define SYSEX_NON_REALTIME 0x7E // MIDI Reserved for non-realtime messages
60 | #define SYSEX_REALTIME 0x7F // MIDI Reserved for realtime messages
61 | // these are DEPRECATED to make the naming more consistent
62 | #define FIRMATA_STRING 0x71 // same as STRING_DATA
63 | #define SYSEX_I2C_REQUEST 0x76 // same as I2C_REQUEST
64 | #define SYSEX_I2C_REPLY 0x77 // same as I2C_REPLY
65 | #define SYSEX_SAMPLING_INTERVAL 0x7A // same as SAMPLING_INTERVAL
66 |
67 | // pin modes
68 | //#define INPUT 0x00 // defined in wiring.h
69 | //#define OUTPUT 0x01 // defined in wiring.h
70 | #define ANALOG 0x02 // analog pin in analogInput mode
71 | #define PWM 0x03 // digital pin in PWM output mode
72 | #define SERVO 0x04 // digital pin in Servo output mode
73 | #define SHIFT 0x05 // shiftIn/shiftOut mode
74 | #define I2C 0x06 // pin included in I2C setup
75 | #define TOTAL_PIN_MODES 7
76 |
77 | extern "C" {
78 | // callback function types
79 | typedef void (*callbackFunction)(byte, int);
80 | typedef void (*systemResetCallbackFunction)(void);
81 | typedef void (*stringCallbackFunction)(char*);
82 | typedef void (*sysexCallbackFunction)(byte command, byte argc, byte*argv);
83 | }
84 |
85 |
86 | // TODO make it a subclass of a generic Serial/Stream base class
87 | class BleFirmataClass
88 | {
89 | public:
90 | BleFirmataClass(Stream &s);
91 | /* Arduino constructors */
92 | void begin();
93 | void begin(long);
94 | void begin(Stream &s);
95 | /* querying functions */
96 | void printVersion(void);
97 | void blinkVersion(void);
98 | void printFirmwareVersion(void);
99 | //void setFirmwareVersion(byte major, byte minor); // see macro below
100 | void setFirmwareNameAndVersion(const char *name, byte major, byte minor);
101 | /* serial receive handling */
102 | int available(void);
103 | void processInput(void);
104 | /* serial send handling */
105 | void sendAnalog(byte pin, int value);
106 | void sendDigital(byte pin, int value); // TODO implement this
107 | void sendDigitalPort(byte portNumber, int portData);
108 | void sendString(const char* string);
109 | void sendString(byte command, const char* string);
110 | void sendSysex(byte command, byte bytec, byte* bytev);
111 | /* attach & detach callback functions to messages */
112 | void attach(byte command, callbackFunction newFunction);
113 | void attach(byte command, systemResetCallbackFunction newFunction);
114 | void attach(byte command, stringCallbackFunction newFunction);
115 | void attach(byte command, sysexCallbackFunction newFunction);
116 | void detach(byte command);
117 |
118 | private:
119 | Stream &BleFirmataSerial;
120 | /* firmware name and version */
121 | byte firmwareVersionCount;
122 | byte *firmwareVersionVector;
123 | /* input message handling */
124 | byte waitForData; // this flag says the next serial input will be data
125 | byte executeMultiByteCommand; // execute this after getting multi-byte data
126 | byte multiByteChannel; // channel data for multiByteCommands
127 | byte storedInputData[MAX_DATA_BYTES]; // multi-byte data
128 | /* sysex */
129 | boolean parsingSysex;
130 | int sysexBytesRead;
131 | /* callback functions */
132 | callbackFunction currentAnalogCallback;
133 | callbackFunction currentDigitalCallback;
134 | callbackFunction currentReportAnalogCallback;
135 | callbackFunction currentReportDigitalCallback;
136 | callbackFunction currentPinModeCallback;
137 | systemResetCallbackFunction currentSystemResetCallback;
138 | stringCallbackFunction currentStringCallback;
139 | sysexCallbackFunction currentSysexCallback;
140 |
141 | /* private methods ------------------------------ */
142 | void processSysexMessage(void);
143 | void systemReset(void);
144 | void pin13strobe(int count, int onInterval, int offInterval);
145 | void sendValueAsTwo7bitBytes(int value);
146 | void startSysex(void);
147 | void endSysex(void);
148 | };
149 |
150 | extern BleFirmataClass BleFirmata;
151 |
152 | /*==============================================================================
153 | * MACROS
154 | *============================================================================*/
155 |
156 | /* shortcut for setFirmwareNameAndVersion() that uses __FILE__ to set the
157 | * firmware name. It needs to be a macro so that __FILE__ is included in the
158 | * firmware source file rather than the library source file.
159 | */
160 | #define setFirmwareVersion(x, y) setFirmwareNameAndVersion(__FILE__, x, y)
161 |
162 | #endif /* Firmata_h */
163 |
164 |
--------------------------------------------------------------------------------
/src/ble-firmata.coffee:
--------------------------------------------------------------------------------
1 | events = require 'eventemitter2'
2 | BlendMicro = require 'blendmicro'
3 |
4 | debug = require('debug')('ble-firmata')
5 |
6 | exports = module.exports = class BLEFirmata extends events.EventEmitter2
7 |
8 | @INPUT = 0
9 | @OUTPUT = 1
10 | @ANALOG = 2
11 | @PWM = 3
12 | @SERVO = 4
13 | @SHIFT = 5
14 | @I2C = 6
15 | @LOW = 0
16 | @HIGH = 1
17 |
18 | @MAX_DATA_BYTES = 32
19 | @DIGITAL_MESSAGE = 0x90 # send data for a digital port
20 | @ANALOG_MESSAGE = 0xE0 # send data for an analog pin (or PWM)
21 | @REPORT_ANALOG = 0xC0 # enable analog input by pin
22 | @REPORT_DIGITAL = 0xD0 # enable digital input by port
23 | @SET_PIN_MODE = 0xF4 # set a pin to INPUT/OUTPUT/PWM/etc
24 | @REPORT_VERSION = 0xF9 # report firmware version
25 | @SYSTEM_RESET = 0xFF # reset from MIDI
26 | @START_SYSEX = 0xF0 # start a MIDI SysEx message
27 | @END_SYSEX = 0xF7 # end a MIDI SysEx message
28 |
29 | @I2C_REQUEST = 0x76
30 | @I2C_REPLY = 0x77
31 | @I2C_CONFIG = 0x78
32 |
33 | @I2C_MODES = {
34 | WRITE: 0x00,
35 | READ: 1,
36 | CONTINUOUS_READ: 2,
37 | STOP_READING: 3
38 | }
39 |
40 | constructor: ->
41 | @ble = null
42 | @state = 'close'
43 | @wait_for_data = 0
44 | @execute_multi_byte_command = 0
45 | @multi_byte_channel = 0
46 | @stored_input_data = []
47 | @parsing_sysex = false
48 | @sysex_bytes_read = 0
49 | @digital_output_data = [0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0]
50 | @digital_input_data = [0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0]
51 | @analog_input_data = [0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0]
52 | @boardVersion = null
53 |
54 | @__defineGetter__ "reconnect", =>
55 | return @ble?.reconnect
56 |
57 | @__defineSetter__ "reconnect", (enable) =>
58 | @ble?.reconnect = enable
59 |
60 | @on 'boardReady', ->
61 | debug "boardReady \"#{@peripheralName}\""
62 | io_init_wait = 100
63 | debug "wait #{io_init_wait}(msec)"
64 | setTimeout =>
65 | for i in [0...6]
66 | @write [(BLEFirmata.REPORT_ANALOG | i), 1]
67 | for i in [0...2]
68 | @write [(BLEFirmata.REPORT_DIGITAL | i), 1]
69 | debug 'init IO ports'
70 | @emit 'connect'
71 | , io_init_wait
72 |
73 | connect: (@peripheralName = "BlendMicro") ->
74 | return if @state isnt "close"
75 |
76 | debug "connect(#{@peripheralName})"
77 | if @ble is null
78 | @ble = new BlendMicro @peripheralName
79 | else
80 | @ble.open @peripheralName
81 |
82 | @ble.on 'open', =>
83 | debug 'BLE open'
84 | timer_report_version = setInterval =>
85 | debug 'request REPORT_VERSION'
86 | @force_write [BLEFirmata.REPORT_VERSION]
87 | , 1000
88 |
89 | @once 'boardVersion', (version) =>
90 | clearInterval timer_report_version
91 | @state = 'open'
92 | @emit 'boardReady'
93 |
94 | @ble.on 'data', (data) =>
95 | for byte in data
96 | @process_input byte
97 |
98 | @ble.once 'close', =>
99 | @state = 'close'
100 | clearInterval timer_report_version
101 | debug 'BLE close'
102 | @emit 'disconnect'
103 |
104 | return @
105 |
106 | isOpen: ->
107 | return @state is 'open'
108 |
109 | close: (callback) ->
110 | debug 'close'
111 | @state = 'close'
112 | @ble.removeAllListeners()
113 | @ble.close callback
114 |
115 | reset: (callback) ->
116 | @write [BLEFirmata.SYSTEM_RESET], callback
117 |
118 | write: (bytes, callback) ->
119 | return if @state isnt 'open'
120 | @force_write bytes, callback
121 |
122 | force_write: (bytes, callback) ->
123 | try
124 | unless @ble.state is 'open'
125 | return
126 | @ble.write bytes, callback
127 | catch err
128 | @ble.close
129 |
130 | sysex: (command, data=[], callback) ->
131 | ## http://firmata.org/wiki/V2.1ProtocolDetails#Sysex_Message_Format
132 | data = data.map (i) -> i & 0b1111111 # 7bit
133 | write_data = [BLEFirmata.START_SYSEX, command].concat data, [BLEFirmata.END_SYSEX]
134 | @write write_data, callback
135 |
136 | sendI2CConfig: (delay=0, callback) ->
137 | data = [delay, delay >>> 8]
138 | data = data.map (i) -> i & 0b11111111 # 7bit
139 | write_data = [BLEFirmata.START_SYSEX, BLEFirmata.I2C_CONFIG].concat data, [BLEFirmata.END_SYSEX]
140 | @write write_data, callback
141 |
142 | sendI2CWriteRequest: (slaveAddress, bytes, callback) ->
143 | data = [slaveAddress, BLEFirmata.I2C_MODES.WRITE << 3]
144 | bytes.map (i) ->
145 | data.push i, i >>> 7
146 | @sysex BLEFirmata.I2C_REQUEST, data, callback
147 |
148 | pinMode: (pin, mode, callback) ->
149 | switch mode
150 | when true
151 | mode = BLEFirmata.OUTPUT
152 | when false
153 | mode = BLEFirmata.INPUT
154 | @write [BLEFirmata.SET_PIN_MODE, pin, mode], callback
155 |
156 | digitalWrite: (pin, value, callback) ->
157 | @pinMode pin, BLEFirmata.OUTPUT
158 | port_num = (pin >>> 3) & 0x0F
159 | if value is 0 or value is false
160 | @digital_output_data[port_num] &= ~(1 << (pin & 0x07))
161 | else
162 | @digital_output_data[port_num] |= (1 << (pin & 0x07))
163 | @write [ (BLEFirmata.DIGITAL_MESSAGE | port_num),
164 | (@digital_output_data[port_num] & 0x7F),
165 | (@digital_output_data[port_num] >>> 7) ],
166 | callback
167 |
168 | analogWrite: (pin, value, callback) ->
169 | value = Math.floor value
170 | @pinMode pin, BLEFirmata.PWM
171 | @write [ (BLEFirmata.ANALOG_MESSAGE | (pin & 0x0F)),
172 | (value & 0x7F),
173 | (value >>> 7) ],
174 | callback
175 |
176 | servoWrite: (pin, angle, callback) ->
177 | @pinMode pin, BLEFirmata.SERVO
178 | @write [ (BLEFirmata.ANALOG_MESSAGE | (pin & 0x0F)),
179 | (angle & 0x7F),
180 | (angle >>> 7) ],
181 | callback
182 |
183 | digitalRead: (pin) ->
184 | return ((@digital_input_data[pin >>> 3] >>> (pin & 0x07)) & 0x01) > 0
185 |
186 | analogRead: (pin) ->
187 | return @analog_input_data[pin]
188 |
189 | process_input: (input_data) ->
190 | if @parsing_sysex
191 | if input_data is BLEFirmata.END_SYSEX
192 | @parsing_sysex = false
193 | sysex_command = @stored_input_data[0]
194 | sysex_data = @stored_input_data[1...@sysex_bytes_read]
195 | @emit 'sysex', {command: sysex_command, data: sysex_data}
196 | else
197 | @stored_input_data[@sysex_bytes_read] = input_data
198 | @sysex_bytes_read += 1
199 | else if @wait_for_data > 0 and input_data < 128
200 | @wait_for_data -= 1
201 | @stored_input_data[@wait_for_data] = input_data
202 | if @execute_multi_byte_command isnt 0 and @wait_for_data is 0
203 | switch @execute_multi_byte_command
204 | when BLEFirmata.DIGITAL_MESSAGE
205 | input_data = (@stored_input_data[0] << 7) + @stored_input_data[1]
206 | diff = @digital_input_data[@multi_byte_channel] ^ input_data
207 | @digital_input_data[@multi_byte_channel] = input_data
208 | if @listeners('digitalChange').length > 0
209 | for i in [0..13]
210 | if ((0x01 << i) & diff) > 0
211 | stat = (input_data&diff) > 0
212 | @emit 'digitalChange',
213 | {pin: i+@multi_byte_channel*8, value: stat, old_value: !stat}
214 | when BLEFirmata.ANALOG_MESSAGE
215 | analog_value = (@stored_input_data[0] << 7) + @stored_input_data[1]
216 | old_analog_value = @analogRead(@multi_byte_channel)
217 | @analog_input_data[@multi_byte_channel] = analog_value
218 | if old_analog_value != analog_value
219 | @emit 'analogChange', {
220 | pin: @multi_byte_channel,
221 | value: analog_value,
222 | old_value: old_analog_value
223 | }
224 | when BLEFirmata.REPORT_VERSION
225 | @boardVersion = "#{@stored_input_data[1]}.#{@stored_input_data[0]}"
226 | @emit 'boardVersion', @boardVersion
227 | else
228 | if input_data < 0xF0
229 | command = input_data & 0xF0
230 | @multi_byte_channel = input_data & 0x0F
231 | else
232 | command = input_data
233 | if command is BLEFirmata.START_SYSEX
234 | @parsing_sysex = true
235 | @sysex_bytes_read = 0
236 | else if command is BLEFirmata.DIGITAL_MESSAGE or
237 | command is BLEFirmata.ANALOG_MESSAGE or
238 | command is BLEFirmata.REPORT_VERSION
239 | @wait_for_data = 2
240 | @execute_multi_byte_command = command
241 |
--------------------------------------------------------------------------------
/firmware/BLEFirmataSketch/BLEFirmata.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | Firmata.cpp - Firmata library
3 | Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.
4 |
5 | This library is free software; you can redistribute it and/or
6 | modify it under the terms of the GNU Lesser General Public
7 | License as published by the Free Software Foundation; either
8 | version 2.1 of the License, or (at your option) any later version.
9 |
10 | See file LICENSE.txt for further informations on licensing terms.
11 | */
12 |
13 | //******************************************************************************
14 | //* Includes
15 | //******************************************************************************
16 |
17 | #include "BLEFirmata.h"
18 | #include "HardwareSerial.h"
19 | #include "RBL_nRF8001.h"
20 |
21 | extern "C" {
22 | #include
23 | #include
24 | }
25 |
26 | //******************************************************************************
27 | //* Support Functions
28 | //******************************************************************************
29 |
30 | void BleFirmataClass::sendValueAsTwo7bitBytes(int value)
31 | {
32 | ble_write(value & B01111111); // LSB
33 | ble_write(value >> 7 & B01111111); // MSB
34 | }
35 |
36 | void BleFirmataClass::startSysex(void)
37 | {
38 | ble_write(START_SYSEX);
39 | }
40 |
41 | void BleFirmataClass::endSysex(void)
42 | {
43 | ble_write(END_SYSEX);
44 | }
45 |
46 | //******************************************************************************
47 | //* Constructors
48 | //******************************************************************************
49 |
50 | BleFirmataClass::BleFirmataClass(Stream &s) : BleFirmataSerial(s)
51 | {
52 | firmwareVersionCount = 0;
53 | systemReset();
54 | }
55 |
56 | //******************************************************************************
57 | //* Public Methods
58 | //******************************************************************************
59 |
60 | /* begin method for overriding default serial bitrate */
61 | void BleFirmataClass::begin(void)
62 | {
63 | begin(57600);
64 | }
65 |
66 | /* begin method for overriding default serial bitrate */
67 | void BleFirmataClass::begin(long speed)
68 | {
69 | // Serial.begin(speed);
70 | BleFirmataSerial = Serial;
71 | blinkVersion();
72 | printVersion();
73 | printFirmwareVersion();
74 | }
75 |
76 | void BleFirmataClass::begin(Stream &s)
77 | {
78 | BleFirmataSerial = s;
79 | systemReset();
80 | printVersion();
81 | printFirmwareVersion();
82 | }
83 |
84 | // output the protocol version message to the serial port
85 | void BleFirmataClass::printVersion(void) {
86 | ble_write(REPORT_VERSION);
87 | ble_write(FIRMATA_MAJOR_VERSION);
88 | ble_write(FIRMATA_MINOR_VERSION);
89 | }
90 |
91 | void BleFirmataClass::blinkVersion(void)
92 | {
93 | // flash the pin with the protocol version
94 | pinMode(VERSION_BLINK_PIN,OUTPUT);
95 | pin13strobe(FIRMATA_MAJOR_VERSION, 40, 210);
96 | delay(250);
97 | pin13strobe(FIRMATA_MINOR_VERSION, 40, 210);
98 | delay(125);
99 | }
100 |
101 | void BleFirmataClass::printFirmwareVersion(void)
102 | {
103 | byte i;
104 |
105 | if(firmwareVersionCount) { // make sure that the name has been set before reporting
106 | startSysex();
107 | ble_write(REPORT_FIRMWARE);
108 | ble_write(firmwareVersionVector[0]); // major version number
109 | ble_write(firmwareVersionVector[1]); // minor version number
110 | for(i=2; i 0) && (inputData < 128) ) {
198 | waitForData--;
199 | storedInputData[waitForData] = inputData;
200 | if( (waitForData==0) && executeMultiByteCommand ) { // got the whole message
201 | switch(executeMultiByteCommand) {
202 | case ANALOG_MESSAGE:
203 | if(currentAnalogCallback) {
204 | (*currentAnalogCallback)(multiByteChannel,
205 | (storedInputData[0] << 7)
206 | + storedInputData[1]);
207 | }
208 | break;
209 | case DIGITAL_MESSAGE:
210 | if(currentDigitalCallback) {
211 | (*currentDigitalCallback)(multiByteChannel,
212 | (storedInputData[0] << 7)
213 | + storedInputData[1]);
214 | }
215 | break;
216 | case SET_PIN_MODE:
217 | if(currentPinModeCallback)
218 | (*currentPinModeCallback)(storedInputData[1], storedInputData[0]);
219 | break;
220 | case REPORT_ANALOG:
221 | if(currentReportAnalogCallback)
222 | (*currentReportAnalogCallback)(multiByteChannel,storedInputData[0]);
223 | break;
224 | case REPORT_DIGITAL:
225 | if(currentReportDigitalCallback)
226 | (*currentReportDigitalCallback)(multiByteChannel,storedInputData[0]);
227 | break;
228 | }
229 | executeMultiByteCommand = 0;
230 | }
231 | } else {
232 | // remove channel info from command byte if less than 0xF0
233 | if(inputData < 0xF0) {
234 | command = inputData & 0xF0;
235 | multiByteChannel = inputData & 0x0F;
236 | } else {
237 | command = inputData;
238 | // commands in the 0xF* range don't use channel data
239 | }
240 | switch (command) {
241 | case ANALOG_MESSAGE:
242 | case DIGITAL_MESSAGE:
243 | case SET_PIN_MODE:
244 | waitForData = 2; // two data bytes needed
245 | executeMultiByteCommand = command;
246 | break;
247 | case REPORT_ANALOG:
248 | case REPORT_DIGITAL:
249 | waitForData = 1; // two data bytes needed
250 | executeMultiByteCommand = command;
251 | break;
252 | case START_SYSEX:
253 | parsingSysex = true;
254 | sysexBytesRead = 0;
255 | break;
256 | case SYSTEM_RESET:
257 | systemReset();
258 | break;
259 | case REPORT_VERSION:
260 | BleFirmata.printVersion();
261 | break;
262 | }
263 | }
264 | }
265 |
266 | //------------------------------------------------------------------------------
267 | // Serial Send Handling
268 |
269 | // send an analog message
270 | void BleFirmataClass::sendAnalog(byte pin, int value)
271 | {
272 | // pin can only be 0-15, so chop higher bits
273 | ble_write(ANALOG_MESSAGE | (pin & 0xF));
274 | sendValueAsTwo7bitBytes(value);
275 | }
276 |
277 | // send a single digital pin in a digital message
278 | void BleFirmataClass::sendDigital(byte pin, int value)
279 | {
280 | /* TODO add single pin digital messages to the protocol, this needs to
281 | * track the last digital data sent so that it can be sure to change just
282 | * one bit in the packet. This is complicated by the fact that the
283 | * numbering of the pins will probably differ on Arduino, Wiring, and
284 | * other boards. The DIGITAL_MESSAGE sends 14 bits at a time, but it is
285 | * probably easier to send 8 bit ports for any board with more than 14
286 | * digital pins.
287 | */
288 |
289 | // TODO: the digital message should not be sent on the serial port every
290 | // time sendDigital() is called. Instead, it should add it to an int
291 | // which will be sent on a schedule. If a pin changes more than once
292 | // before the digital message is sent on the serial port, it should send a
293 | // digital message for each change.
294 |
295 | // if(value == 0)
296 | // sendDigitalPortPair();
297 | }
298 |
299 |
300 | // send 14-bits in a single digital message (protocol v1)
301 | // send an 8-bit port in a single digital message (protocol v2)
302 | void BleFirmataClass::sendDigitalPort(byte portNumber, int portData)
303 | {
304 | ble_write(DIGITAL_MESSAGE | (portNumber & 0xF));
305 | ble_write((byte)portData % 128); // Tx bits 0-6
306 | ble_write(portData >> 7); // Tx bits 7-13
307 | }
308 |
309 |
310 | void BleFirmataClass::sendSysex(byte command, byte bytec, byte* bytev)
311 | {
312 | byte i;
313 | startSysex();
314 | ble_write(command);
315 | for(i=0; i
23 | #include
24 | }
25 |
26 | //******************************************************************************
27 | //* Support Functions
28 | //******************************************************************************
29 |
30 | void BleFirmataClass::sendValueAsTwo7bitBytes(int value)
31 | {
32 | ble_write(value & B01111111); // LSB
33 | ble_write(value >> 7 & B01111111); // MSB
34 | }
35 |
36 | void BleFirmataClass::startSysex(void)
37 | {
38 | ble_write(START_SYSEX);
39 | }
40 |
41 | void BleFirmataClass::endSysex(void)
42 | {
43 | ble_write(END_SYSEX);
44 | }
45 |
46 | //******************************************************************************
47 | //* Constructors
48 | //******************************************************************************
49 |
50 | BleFirmataClass::BleFirmataClass(Stream &s) : BleFirmataSerial(s)
51 | {
52 | firmwareVersionCount = 0;
53 | systemReset();
54 | }
55 |
56 | //******************************************************************************
57 | //* Public Methods
58 | //******************************************************************************
59 |
60 | /* begin method for overriding default serial bitrate */
61 | void BleFirmataClass::begin(void)
62 | {
63 | begin(57600);
64 | }
65 |
66 | /* begin method for overriding default serial bitrate */
67 | void BleFirmataClass::begin(long speed)
68 | {
69 | // Serial.begin(speed);
70 | BleFirmataSerial = Serial;
71 | blinkVersion();
72 | printVersion();
73 | printFirmwareVersion();
74 | }
75 |
76 | void BleFirmataClass::begin(Stream &s)
77 | {
78 | BleFirmataSerial = s;
79 | systemReset();
80 | printVersion();
81 | printFirmwareVersion();
82 | }
83 |
84 | // output the protocol version message to the serial port
85 | void BleFirmataClass::printVersion(void) {
86 | ble_write(REPORT_VERSION);
87 | ble_write(FIRMATA_MAJOR_VERSION);
88 | ble_write(FIRMATA_MINOR_VERSION);
89 | }
90 |
91 | void BleFirmataClass::blinkVersion(void)
92 | {
93 | // flash the pin with the protocol version
94 | pinMode(VERSION_BLINK_PIN,OUTPUT);
95 | pin13strobe(FIRMATA_MAJOR_VERSION, 40, 210);
96 | delay(250);
97 | pin13strobe(FIRMATA_MINOR_VERSION, 40, 210);
98 | delay(125);
99 | }
100 |
101 | void BleFirmataClass::printFirmwareVersion(void)
102 | {
103 | byte i;
104 |
105 | if(firmwareVersionCount) { // make sure that the name has been set before reporting
106 | startSysex();
107 | ble_write(REPORT_FIRMWARE);
108 | ble_write(firmwareVersionVector[0]); // major version number
109 | ble_write(firmwareVersionVector[1]); // minor version number
110 | for(i=2; i 0) && (inputData < 128) ) {
198 | waitForData--;
199 | storedInputData[waitForData] = inputData;
200 | if( (waitForData==0) && executeMultiByteCommand ) { // got the whole message
201 | switch(executeMultiByteCommand) {
202 | case ANALOG_MESSAGE:
203 | if(currentAnalogCallback) {
204 | (*currentAnalogCallback)(multiByteChannel,
205 | (storedInputData[0] << 7)
206 | + storedInputData[1]);
207 | }
208 | break;
209 | case DIGITAL_MESSAGE:
210 | if(currentDigitalCallback) {
211 | (*currentDigitalCallback)(multiByteChannel,
212 | (storedInputData[0] << 7)
213 | + storedInputData[1]);
214 | }
215 | break;
216 | case SET_PIN_MODE:
217 | if(currentPinModeCallback)
218 | (*currentPinModeCallback)(storedInputData[1], storedInputData[0]);
219 | break;
220 | case REPORT_ANALOG:
221 | if(currentReportAnalogCallback)
222 | (*currentReportAnalogCallback)(multiByteChannel,storedInputData[0]);
223 | break;
224 | case REPORT_DIGITAL:
225 | if(currentReportDigitalCallback)
226 | (*currentReportDigitalCallback)(multiByteChannel,storedInputData[0]);
227 | break;
228 | }
229 | executeMultiByteCommand = 0;
230 | }
231 | } else {
232 | // remove channel info from command byte if less than 0xF0
233 | if(inputData < 0xF0) {
234 | command = inputData & 0xF0;
235 | multiByteChannel = inputData & 0x0F;
236 | } else {
237 | command = inputData;
238 | // commands in the 0xF* range don't use channel data
239 | }
240 | switch (command) {
241 | case ANALOG_MESSAGE:
242 | case DIGITAL_MESSAGE:
243 | case SET_PIN_MODE:
244 | waitForData = 2; // two data bytes needed
245 | executeMultiByteCommand = command;
246 | break;
247 | case REPORT_ANALOG:
248 | case REPORT_DIGITAL:
249 | waitForData = 1; // two data bytes needed
250 | executeMultiByteCommand = command;
251 | break;
252 | case START_SYSEX:
253 | parsingSysex = true;
254 | sysexBytesRead = 0;
255 | break;
256 | case SYSTEM_RESET:
257 | systemReset();
258 | break;
259 | case REPORT_VERSION:
260 | BleFirmata.printVersion();
261 | break;
262 | }
263 | }
264 | }
265 |
266 | //------------------------------------------------------------------------------
267 | // Serial Send Handling
268 |
269 | // send an analog message
270 | void BleFirmataClass::sendAnalog(byte pin, int value)
271 | {
272 | // pin can only be 0-15, so chop higher bits
273 | ble_write(ANALOG_MESSAGE | (pin & 0xF));
274 | sendValueAsTwo7bitBytes(value);
275 | }
276 |
277 | // send a single digital pin in a digital message
278 | void BleFirmataClass::sendDigital(byte pin, int value)
279 | {
280 | /* TODO add single pin digital messages to the protocol, this needs to
281 | * track the last digital data sent so that it can be sure to change just
282 | * one bit in the packet. This is complicated by the fact that the
283 | * numbering of the pins will probably differ on Arduino, Wiring, and
284 | * other boards. The DIGITAL_MESSAGE sends 14 bits at a time, but it is
285 | * probably easier to send 8 bit ports for any board with more than 14
286 | * digital pins.
287 | */
288 |
289 | // TODO: the digital message should not be sent on the serial port every
290 | // time sendDigital() is called. Instead, it should add it to an int
291 | // which will be sent on a schedule. If a pin changes more than once
292 | // before the digital message is sent on the serial port, it should send a
293 | // digital message for each change.
294 |
295 | // if(value == 0)
296 | // sendDigitalPortPair();
297 | }
298 |
299 |
300 | // send 14-bits in a single digital message (protocol v1)
301 | // send an 8-bit port in a single digital message (protocol v2)
302 | void BleFirmataClass::sendDigitalPort(byte portNumber, int portData)
303 | {
304 | ble_write(DIGITAL_MESSAGE | (portNumber & 0xF));
305 | ble_write((byte)portData % 128); // Tx bits 0-6
306 | ble_write(portData >> 7); // Tx bits 7-13
307 | }
308 |
309 |
310 | void BleFirmataClass::sendSysex(byte command, byte bytec, byte* bytev)
311 | {
312 | byte i;
313 | startSysex();
314 | ble_write(command);
315 | for(i=0; i
23 | #include
24 | }
25 |
26 | //******************************************************************************
27 | //* Support Functions
28 | //******************************************************************************
29 |
30 | void BleFirmataClass::sendValueAsTwo7bitBytes(int value)
31 | {
32 | ble_write(value & B01111111); // LSB
33 | ble_write(value >> 7 & B01111111); // MSB
34 | }
35 |
36 | void BleFirmataClass::startSysex(void)
37 | {
38 | ble_write(START_SYSEX);
39 | }
40 |
41 | void BleFirmataClass::endSysex(void)
42 | {
43 | ble_write(END_SYSEX);
44 | }
45 |
46 | //******************************************************************************
47 | //* Constructors
48 | //******************************************************************************
49 |
50 | BleFirmataClass::BleFirmataClass(Stream &s) : BleFirmataSerial(s)
51 | {
52 | firmwareVersionCount = 0;
53 | systemReset();
54 | }
55 |
56 | //******************************************************************************
57 | //* Public Methods
58 | //******************************************************************************
59 |
60 | /* begin method for overriding default serial bitrate */
61 | void BleFirmataClass::begin(void)
62 | {
63 | begin(57600);
64 | }
65 |
66 | /* begin method for overriding default serial bitrate */
67 | void BleFirmataClass::begin(long speed)
68 | {
69 | // Serial.begin(speed);
70 | BleFirmataSerial = Serial;
71 | blinkVersion();
72 | printVersion();
73 | printFirmwareVersion();
74 | }
75 |
76 | void BleFirmataClass::begin(Stream &s)
77 | {
78 | BleFirmataSerial = s;
79 | systemReset();
80 | printVersion();
81 | printFirmwareVersion();
82 | }
83 |
84 | // output the protocol version message to the serial port
85 | void BleFirmataClass::printVersion(void) {
86 | ble_write(REPORT_VERSION);
87 | ble_write(FIRMATA_MAJOR_VERSION);
88 | ble_write(FIRMATA_MINOR_VERSION);
89 | }
90 |
91 | void BleFirmataClass::blinkVersion(void)
92 | {
93 | // flash the pin with the protocol version
94 | pinMode(VERSION_BLINK_PIN,OUTPUT);
95 | pin13strobe(FIRMATA_MAJOR_VERSION, 40, 210);
96 | delay(250);
97 | pin13strobe(FIRMATA_MINOR_VERSION, 40, 210);
98 | delay(125);
99 | }
100 |
101 | void BleFirmataClass::printFirmwareVersion(void)
102 | {
103 | byte i;
104 |
105 | if(firmwareVersionCount) { // make sure that the name has been set before reporting
106 | startSysex();
107 | ble_write(REPORT_FIRMWARE);
108 | ble_write(firmwareVersionVector[0]); // major version number
109 | ble_write(firmwareVersionVector[1]); // minor version number
110 | for(i=2; i 0) && (inputData < 128) ) {
198 | waitForData--;
199 | storedInputData[waitForData] = inputData;
200 | if( (waitForData==0) && executeMultiByteCommand ) { // got the whole message
201 | switch(executeMultiByteCommand) {
202 | case ANALOG_MESSAGE:
203 | if(currentAnalogCallback) {
204 | (*currentAnalogCallback)(multiByteChannel,
205 | (storedInputData[0] << 7)
206 | + storedInputData[1]);
207 | }
208 | break;
209 | case DIGITAL_MESSAGE:
210 | if(currentDigitalCallback) {
211 | (*currentDigitalCallback)(multiByteChannel,
212 | (storedInputData[0] << 7)
213 | + storedInputData[1]);
214 | }
215 | break;
216 | case SET_PIN_MODE:
217 | if(currentPinModeCallback)
218 | (*currentPinModeCallback)(storedInputData[1], storedInputData[0]);
219 | break;
220 | case REPORT_ANALOG:
221 | if(currentReportAnalogCallback)
222 | (*currentReportAnalogCallback)(multiByteChannel,storedInputData[0]);
223 | break;
224 | case REPORT_DIGITAL:
225 | if(currentReportDigitalCallback)
226 | (*currentReportDigitalCallback)(multiByteChannel,storedInputData[0]);
227 | break;
228 | }
229 | executeMultiByteCommand = 0;
230 | }
231 | } else {
232 | // remove channel info from command byte if less than 0xF0
233 | if(inputData < 0xF0) {
234 | command = inputData & 0xF0;
235 | multiByteChannel = inputData & 0x0F;
236 | } else {
237 | command = inputData;
238 | // commands in the 0xF* range don't use channel data
239 | }
240 | switch (command) {
241 | case ANALOG_MESSAGE:
242 | case DIGITAL_MESSAGE:
243 | case SET_PIN_MODE:
244 | waitForData = 2; // two data bytes needed
245 | executeMultiByteCommand = command;
246 | break;
247 | case REPORT_ANALOG:
248 | case REPORT_DIGITAL:
249 | waitForData = 1; // two data bytes needed
250 | executeMultiByteCommand = command;
251 | break;
252 | case START_SYSEX:
253 | parsingSysex = true;
254 | sysexBytesRead = 0;
255 | break;
256 | case SYSTEM_RESET:
257 | systemReset();
258 | break;
259 | case REPORT_VERSION:
260 | BleFirmata.printVersion();
261 | break;
262 | }
263 | }
264 | }
265 |
266 | //------------------------------------------------------------------------------
267 | // Serial Send Handling
268 |
269 | // send an analog message
270 | void BleFirmataClass::sendAnalog(byte pin, int value)
271 | {
272 | // pin can only be 0-15, so chop higher bits
273 | ble_write(ANALOG_MESSAGE | (pin & 0xF));
274 | sendValueAsTwo7bitBytes(value);
275 | }
276 |
277 | // send a single digital pin in a digital message
278 | void BleFirmataClass::sendDigital(byte pin, int value)
279 | {
280 | /* TODO add single pin digital messages to the protocol, this needs to
281 | * track the last digital data sent so that it can be sure to change just
282 | * one bit in the packet. This is complicated by the fact that the
283 | * numbering of the pins will probably differ on Arduino, Wiring, and
284 | * other boards. The DIGITAL_MESSAGE sends 14 bits at a time, but it is
285 | * probably easier to send 8 bit ports for any board with more than 14
286 | * digital pins.
287 | */
288 |
289 | // TODO: the digital message should not be sent on the serial port every
290 | // time sendDigital() is called. Instead, it should add it to an int
291 | // which will be sent on a schedule. If a pin changes more than once
292 | // before the digital message is sent on the serial port, it should send a
293 | // digital message for each change.
294 |
295 | // if(value == 0)
296 | // sendDigitalPortPair();
297 | }
298 |
299 |
300 | // send 14-bits in a single digital message (protocol v1)
301 | // send an 8-bit port in a single digital message (protocol v2)
302 | void BleFirmataClass::sendDigitalPort(byte portNumber, int portData)
303 | {
304 | ble_write(DIGITAL_MESSAGE | (portNumber & 0xF));
305 | ble_write((byte)portData % 128); // Tx bits 0-6
306 | ble_write(portData >> 7); // Tx bits 7-13
307 | }
308 |
309 |
310 | void BleFirmataClass::sendSysex(byte command, byte bytec, byte* bytev)
311 | {
312 | byte i;
313 | startSysex();
314 | ble_write(command);
315 | for(i=0; i
7 |
8 | #if defined(ARDUINO) && ARDUINO >= 100
9 | #include "Arduino.h" // for digitalRead, digitalWrite, etc
10 | #else
11 | #include "WProgram.h"
12 | #endif
13 |
14 | // Normally Servo.h must be included before Firmata.h (which then includes
15 | // this file). If Servo.h wasn't included, this allows the code to still
16 | // compile, but without support for any Servos. Hopefully that's what the
17 | // user intended by not including Servo.h
18 | #ifndef MAX_SERVOS
19 | #define MAX_SERVOS 0
20 | #endif
21 |
22 | /*
23 | Firmata Hardware Abstraction Layer
24 |
25 | Firmata is built on top of the hardware abstraction functions of Arduino,
26 | specifically digitalWrite, digitalRead, analogWrite, analogRead, and
27 | pinMode. While these functions offer simple integer pin numbers, Firmata
28 | needs more information than is provided by Arduino. This file provides
29 | all other hardware specific details. To make Firmata support a new board,
30 | only this file should require editing.
31 |
32 | The key concept is every "pin" implemented by Firmata may be mapped to
33 | any pin as implemented by Arduino. Usually a simple 1-to-1 mapping is
34 | best, but such mapping should not be assumed. This hardware abstraction
35 | layer allows Firmata to implement any number of pins which map onto the
36 | Arduino implemented pins in almost any arbitrary way.
37 |
38 |
39 | General Constants:
40 |
41 | These constants provide basic information Firmata requires.
42 |
43 | TOTAL_PINS: The total number of pins Firmata implemented by Firmata.
44 | Usually this will match the number of pins the Arduino functions
45 | implement, including any pins pins capable of analog or digital.
46 | However, Firmata may implement any number of pins. For example,
47 | on Arduino Mini with 8 analog inputs, 6 of these may be used
48 | for digital functions, and 2 are analog only. On such boards,
49 | Firmata can implement more pins than Arduino's pinMode()
50 | function, in order to accommodate those special pins. The
51 | Firmata protocol supports a maximum of 128 pins, so this
52 | constant must not exceed 128.
53 |
54 | TOTAL_ANALOG_PINS: The total number of analog input pins implemented.
55 | The Firmata protocol allows up to 16 analog inputs, accessed
56 | using offsets 0 to 15. Because Firmata presents the analog
57 | inputs using different offsets than the actual pin numbers
58 | (a legacy of Arduino's analogRead function, and the way the
59 | analog input capable pins are physically labeled on all
60 | Arduino boards), the total number of analog input signals
61 | must be specified. 16 is the maximum.
62 |
63 | VERSION_BLINK_PIN: When Firmata starts up, it will blink the version
64 | number. This constant is the Arduino pin number where a
65 | LED is connected.
66 |
67 |
68 | Pin Mapping Macros:
69 |
70 | These macros provide the mapping between pins as implemented by
71 | Firmata protocol and the actual pin numbers used by the Arduino
72 | functions. Even though such mappings are often simple, pin
73 | numbers received by Firmata protocol should always be used as
74 | input to these macros, and the result of the macro should be
75 | used with with any Arduino function.
76 |
77 | When Firmata is extended to support a new pin mode or feature,
78 | a pair of macros should be added and used for all hardware
79 | access. For simple 1:1 mapping, these macros add no actual
80 | overhead, yet their consistent use allows source code which
81 | uses them consistently to be easily adapted to all other boards
82 | with different requirements.
83 |
84 | IS_PIN_XXXX(pin): The IS_PIN macros resolve to true or non-zero
85 | if a pin as implemented by Firmata corresponds to a pin
86 | that actually implements the named feature.
87 |
88 | PIN_TO_XXXX(pin): The PIN_TO macros translate pin numbers as
89 | implemented by Firmata to the pin numbers needed as inputs
90 | to the Arduino functions. The corresponding IS_PIN macro
91 | should always be tested before using a PIN_TO macro, so
92 | these macros only need to handle valid Firmata pin
93 | numbers for the named feature.
94 |
95 |
96 | Port Access Inline Funtions:
97 |
98 | For efficiency, Firmata protocol provides access to digital
99 | input and output pins grouped by 8 bit ports. When these
100 | groups of 8 correspond to actual 8 bit ports as implemented
101 | by the hardware, these inline functions can provide high
102 | speed direct port access. Otherwise, a default implementation
103 | using 8 calls to digitalWrite or digitalRead is used.
104 |
105 | When porting Firmata to a new board, it is recommended to
106 | use the default functions first and focus only on the constants
107 | and macros above. When those are working, if optimized port
108 | access is desired, these inline functions may be extended.
109 | The recommended approach defines a symbol indicating which
110 | optimization to use, and then conditional complication is
111 | used within these functions.
112 |
113 | readPort(port, bitmask): Read an 8 bit port, returning the value.
114 | port: The port number, Firmata pins port*8 to port*8+7
115 | bitmask: The actual pins to read, indicated by 1 bits.
116 |
117 | writePort(port, value, bitmask): Write an 8 bit port.
118 | port: The port number, Firmata pins port*8 to port*8+7
119 | value: The 8 bit value to write
120 | bitmask: The actual pins to write, indicated by 1 bits.
121 | */
122 |
123 | /*==============================================================================
124 | * Board Specific Configuration
125 | *============================================================================*/
126 |
127 | #ifndef digitalPinHasPWM
128 | #define digitalPinHasPWM(p) IS_PIN_DIGITAL(p)
129 | #endif
130 |
131 | // Arduino Duemilanove, Diecimila, and NG
132 | #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
133 | #if defined(NUM_ANALOG_INPUTS) && NUM_ANALOG_INPUTS == 6
134 | #define TOTAL_ANALOG_PINS 6
135 | #define TOTAL_PINS 20 // 14 digital + 6 analog
136 | #else
137 | #define TOTAL_ANALOG_PINS 8
138 | #define TOTAL_PINS 22 // 14 digital + 8 analog
139 | #endif
140 | #define VERSION_BLINK_PIN 13
141 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19)
142 | #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS)
143 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
144 | #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS)
145 | #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19)
146 | #define PIN_TO_DIGITAL(p) (p)
147 | #define PIN_TO_ANALOG(p) ((p) - 14)
148 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
149 | #define PIN_TO_SERVO(p) ((p) - 2)
150 | #define ARDUINO_PINOUT_OPTIMIZE 1
151 |
152 |
153 | // Wiring (and board)
154 | #elif defined(WIRING)
155 | #define VERSION_BLINK_PIN WLED
156 | #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
157 | #define IS_PIN_ANALOG(p) ((p) >= FIRST_ANALOG_PIN && (p) < (FIRST_ANALOG_PIN+TOTAL_ANALOG_PINS))
158 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
159 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
160 | #define IS_PIN_I2C(p) ((p) == SDA || (p) == SCL)
161 | #define PIN_TO_DIGITAL(p) (p)
162 | #define PIN_TO_ANALOG(p) ((p) - FIRST_ANALOG_PIN)
163 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
164 | #define PIN_TO_SERVO(p) (p)
165 |
166 |
167 | // old Arduinos
168 | #elif defined(__AVR_ATmega8__)
169 | #define TOTAL_ANALOG_PINS 6
170 | #define TOTAL_PINS 20 // 14 digital + 6 analog
171 | #define VERSION_BLINK_PIN 13
172 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19)
173 | #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 19)
174 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
175 | #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS)
176 | #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19)
177 | #define PIN_TO_DIGITAL(p) (p)
178 | #define PIN_TO_ANALOG(p) ((p) - 14)
179 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
180 | #define PIN_TO_SERVO(p) ((p) - 2)
181 | #define ARDUINO_PINOUT_OPTIMIZE 1
182 |
183 |
184 | // Arduino Mega
185 | #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
186 | #define TOTAL_ANALOG_PINS 16
187 | #define TOTAL_PINS 70 // 54 digital + 16 analog
188 | #define VERSION_BLINK_PIN 13
189 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
190 | #define IS_PIN_ANALOG(p) ((p) >= 54 && (p) < TOTAL_PINS)
191 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
192 | #define IS_PIN_SERVO(p) ((p) >= 2 && (p) - 2 < MAX_SERVOS)
193 | #define IS_PIN_I2C(p) ((p) == 20 || (p) == 21)
194 | #define PIN_TO_DIGITAL(p) (p)
195 | #define PIN_TO_ANALOG(p) ((p) - 54)
196 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
197 | #define PIN_TO_SERVO(p) ((p) - 2)
198 |
199 |
200 | // Teensy 1.0
201 | #elif defined(__AVR_AT90USB162__)
202 | #define TOTAL_ANALOG_PINS 0
203 | #define TOTAL_PINS 21 // 21 digital + no analog
204 | #define VERSION_BLINK_PIN 6
205 | #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
206 | #define IS_PIN_ANALOG(p) (0)
207 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
208 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
209 | #define IS_PIN_I2C(p) (0)
210 | #define PIN_TO_DIGITAL(p) (p)
211 | #define PIN_TO_ANALOG(p) (0)
212 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
213 | #define PIN_TO_SERVO(p) (p)
214 |
215 |
216 | // Teensy 2.0
217 | #elif defined(__AVR_ATmega32U4__)
218 | #define TOTAL_ANALOG_PINS 12
219 | #define TOTAL_PINS 25 // 11 digital + 12 analog
220 | #define VERSION_BLINK_PIN 11
221 | #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
222 | #define IS_PIN_ANALOG(p) ((p) >= 11 && (p) <= 22)
223 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
224 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
225 | #define IS_PIN_I2C(p) ((p) == 5 || (p) == 6)
226 | #define PIN_TO_DIGITAL(p) (p)
227 | #define PIN_TO_ANALOG(p) (((p)<22)?21-(p):11)
228 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
229 | #define PIN_TO_SERVO(p) (p)
230 |
231 |
232 | // Teensy++ 1.0 and 2.0
233 | #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
234 | #define TOTAL_ANALOG_PINS 8
235 | #define TOTAL_PINS 46 // 38 digital + 8 analog
236 | #define VERSION_BLINK_PIN 6
237 | #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
238 | #define IS_PIN_ANALOG(p) ((p) >= 38 && (p) < TOTAL_PINS)
239 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
240 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
241 | #define IS_PIN_I2C(p) ((p) == 0 || (p) == 1)
242 | #define PIN_TO_DIGITAL(p) (p)
243 | #define PIN_TO_ANALOG(p) ((p) - 38)
244 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
245 | #define PIN_TO_SERVO(p) (p)
246 |
247 |
248 | // Sanguino
249 | #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
250 | #define TOTAL_ANALOG_PINS 8
251 | #define TOTAL_PINS 32 // 24 digital + 8 analog
252 | #define VERSION_BLINK_PIN 0
253 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
254 | #define IS_PIN_ANALOG(p) ((p) >= 24 && (p) < TOTAL_PINS)
255 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
256 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
257 | #define IS_PIN_I2C(p) ((p) == 16 || (p) == 17)
258 | #define PIN_TO_DIGITAL(p) (p)
259 | #define PIN_TO_ANALOG(p) ((p) - 24)
260 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
261 | #define PIN_TO_SERVO(p) ((p) - 2)
262 |
263 |
264 | // Illuminato
265 | #elif defined(__AVR_ATmega645__)
266 | #define TOTAL_ANALOG_PINS 6
267 | #define TOTAL_PINS 42 // 36 digital + 6 analog
268 | #define VERSION_BLINK_PIN 13
269 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
270 | #define IS_PIN_ANALOG(p) ((p) >= 36 && (p) < TOTAL_PINS)
271 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
272 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
273 | #define IS_PIN_I2C(p) ((p) == 4 || (p) == 5)
274 | #define PIN_TO_DIGITAL(p) (p)
275 | #define PIN_TO_ANALOG(p) ((p) - 36)
276 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
277 | #define PIN_TO_SERVO(p) ((p) - 2)
278 |
279 |
280 | // Arduino DUE
281 | #elif defined(__SAM3X8E__)
282 | #define TOTAL_ANALOG_PINS 12
283 | #define TOTAL_PINS 66 // 54 digital + 12 analog
284 | #define VERSION_BLINK_PIN 13
285 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
286 | #define IS_PIN_ANALOG(p) ((p) >= 54 && (p) < TOTAL_PINS)
287 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
288 | #define IS_PIN_SERVO(p) ((p) >= 2 && (p) - 2 < MAX_SERVOS)
289 | #define IS_PIN_I2C(p) ((p) == 20 || (p) == 21) // 70 71
290 | #define PIN_TO_DIGITAL(p) (p)
291 | #define PIN_TO_ANALOG(p) ((p) - 54)
292 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
293 | #define PIN_TO_SERVO(p) ((p) - 2)
294 |
295 |
296 | // anything else
297 | #else
298 | #error "Please edit Boards.h with a hardware abstraction for this board"
299 | #endif
300 |
301 |
302 | /*==============================================================================
303 | * readPort() - Read an 8 bit port
304 | *============================================================================*/
305 |
306 | static inline unsigned char readPort(byte, byte) __attribute__((always_inline, unused));
307 | static inline unsigned char readPort(byte port, byte bitmask)
308 | {
309 | #if defined(ARDUINO_PINOUT_OPTIMIZE)
310 | if (port == 0) return (PIND & 0xFC) & bitmask; // ignore Rx/Tx 0/1
311 | if (port == 1) return ((PINB & 0x3F) | ((PINC & 0x03) << 6)) & bitmask;
312 | if (port == 2) return ((PINC & 0x3C) >> 2) & bitmask;
313 | return 0;
314 | #else
315 | unsigned char out=0, pin=port*8;
316 | if (IS_PIN_DIGITAL(pin+0) && (bitmask & 0x01) && digitalRead(PIN_TO_DIGITAL(pin+0))) out |= 0x01;
317 | if (IS_PIN_DIGITAL(pin+1) && (bitmask & 0x02) && digitalRead(PIN_TO_DIGITAL(pin+1))) out |= 0x02;
318 | if (IS_PIN_DIGITAL(pin+2) && (bitmask & 0x04) && digitalRead(PIN_TO_DIGITAL(pin+2))) out |= 0x04;
319 | if (IS_PIN_DIGITAL(pin+3) && (bitmask & 0x08) && digitalRead(PIN_TO_DIGITAL(pin+3))) out |= 0x08;
320 | if (IS_PIN_DIGITAL(pin+4) && (bitmask & 0x10) && digitalRead(PIN_TO_DIGITAL(pin+4))) out |= 0x10;
321 | if (IS_PIN_DIGITAL(pin+5) && (bitmask & 0x20) && digitalRead(PIN_TO_DIGITAL(pin+5))) out |= 0x20;
322 | if (IS_PIN_DIGITAL(pin+6) && (bitmask & 0x40) && digitalRead(PIN_TO_DIGITAL(pin+6))) out |= 0x40;
323 | if (IS_PIN_DIGITAL(pin+7) && (bitmask & 0x80) && digitalRead(PIN_TO_DIGITAL(pin+7))) out |= 0x80;
324 | return out;
325 | #endif
326 | }
327 |
328 | /*==============================================================================
329 | * writePort() - Write an 8 bit port, only touch pins specified by a bitmask
330 | *============================================================================*/
331 |
332 | static inline unsigned char writePort(byte, byte, byte) __attribute__((always_inline, unused));
333 | static inline unsigned char writePort(byte port, byte value, byte bitmask)
334 | {
335 | #if defined(ARDUINO_PINOUT_OPTIMIZE)
336 | if (port == 0) {
337 | bitmask = bitmask & 0xFC; // do not touch Tx & Rx pins
338 | byte valD = value & bitmask;
339 | byte maskD = ~bitmask;
340 | cli();
341 | PORTD = (PORTD & maskD) | valD;
342 | sei();
343 | } else if (port == 1) {
344 | byte valB = (value & bitmask) & 0x3F;
345 | byte valC = (value & bitmask) >> 6;
346 | byte maskB = ~(bitmask & 0x3F);
347 | byte maskC = ~((bitmask & 0xC0) >> 6);
348 | cli();
349 | PORTB = (PORTB & maskB) | valB;
350 | PORTC = (PORTC & maskC) | valC;
351 | sei();
352 | } else if (port == 2) {
353 | bitmask = bitmask & 0x0F;
354 | byte valC = (value & bitmask) << 2;
355 | byte maskC = ~(bitmask << 2);
356 | cli();
357 | PORTC = (PORTC & maskC) | valC;
358 | sei();
359 | }
360 | #else
361 | byte pin=port*8;
362 | if ((bitmask & 0x01)) digitalWrite(PIN_TO_DIGITAL(pin+0), (value & 0x01));
363 | if ((bitmask & 0x02)) digitalWrite(PIN_TO_DIGITAL(pin+1), (value & 0x02));
364 | if ((bitmask & 0x04)) digitalWrite(PIN_TO_DIGITAL(pin+2), (value & 0x04));
365 | if ((bitmask & 0x08)) digitalWrite(PIN_TO_DIGITAL(pin+3), (value & 0x08));
366 | if ((bitmask & 0x10)) digitalWrite(PIN_TO_DIGITAL(pin+4), (value & 0x10));
367 | if ((bitmask & 0x20)) digitalWrite(PIN_TO_DIGITAL(pin+5), (value & 0x20));
368 | if ((bitmask & 0x40)) digitalWrite(PIN_TO_DIGITAL(pin+6), (value & 0x40));
369 | if ((bitmask & 0x80)) digitalWrite(PIN_TO_DIGITAL(pin+7), (value & 0x80));
370 | #endif
371 | }
372 |
373 |
374 |
375 |
376 | #ifndef TOTAL_PORTS
377 | #define TOTAL_PORTS ((TOTAL_PINS + 7) / 8)
378 | #endif
379 |
380 |
381 | #endif /* Firmata_Boards_h */
382 |
383 |
--------------------------------------------------------------------------------
/samples/sysex/BLEFirmataWithLedBlink/Boards.h:
--------------------------------------------------------------------------------
1 | /* Boards.h - Hardware Abstraction Layer for Firmata library */
2 |
3 | #ifndef Firmata_Boards_h
4 | #define Firmata_Boards_h
5 |
6 | #include
7 |
8 | #if defined(ARDUINO) && ARDUINO >= 100
9 | #include "Arduino.h" // for digitalRead, digitalWrite, etc
10 | #else
11 | #include "WProgram.h"
12 | #endif
13 |
14 | // Normally Servo.h must be included before Firmata.h (which then includes
15 | // this file). If Servo.h wasn't included, this allows the code to still
16 | // compile, but without support for any Servos. Hopefully that's what the
17 | // user intended by not including Servo.h
18 | #ifndef MAX_SERVOS
19 | #define MAX_SERVOS 0
20 | #endif
21 |
22 | /*
23 | Firmata Hardware Abstraction Layer
24 |
25 | Firmata is built on top of the hardware abstraction functions of Arduino,
26 | specifically digitalWrite, digitalRead, analogWrite, analogRead, and
27 | pinMode. While these functions offer simple integer pin numbers, Firmata
28 | needs more information than is provided by Arduino. This file provides
29 | all other hardware specific details. To make Firmata support a new board,
30 | only this file should require editing.
31 |
32 | The key concept is every "pin" implemented by Firmata may be mapped to
33 | any pin as implemented by Arduino. Usually a simple 1-to-1 mapping is
34 | best, but such mapping should not be assumed. This hardware abstraction
35 | layer allows Firmata to implement any number of pins which map onto the
36 | Arduino implemented pins in almost any arbitrary way.
37 |
38 |
39 | General Constants:
40 |
41 | These constants provide basic information Firmata requires.
42 |
43 | TOTAL_PINS: The total number of pins Firmata implemented by Firmata.
44 | Usually this will match the number of pins the Arduino functions
45 | implement, including any pins pins capable of analog or digital.
46 | However, Firmata may implement any number of pins. For example,
47 | on Arduino Mini with 8 analog inputs, 6 of these may be used
48 | for digital functions, and 2 are analog only. On such boards,
49 | Firmata can implement more pins than Arduino's pinMode()
50 | function, in order to accommodate those special pins. The
51 | Firmata protocol supports a maximum of 128 pins, so this
52 | constant must not exceed 128.
53 |
54 | TOTAL_ANALOG_PINS: The total number of analog input pins implemented.
55 | The Firmata protocol allows up to 16 analog inputs, accessed
56 | using offsets 0 to 15. Because Firmata presents the analog
57 | inputs using different offsets than the actual pin numbers
58 | (a legacy of Arduino's analogRead function, and the way the
59 | analog input capable pins are physically labeled on all
60 | Arduino boards), the total number of analog input signals
61 | must be specified. 16 is the maximum.
62 |
63 | VERSION_BLINK_PIN: When Firmata starts up, it will blink the version
64 | number. This constant is the Arduino pin number where a
65 | LED is connected.
66 |
67 |
68 | Pin Mapping Macros:
69 |
70 | These macros provide the mapping between pins as implemented by
71 | Firmata protocol and the actual pin numbers used by the Arduino
72 | functions. Even though such mappings are often simple, pin
73 | numbers received by Firmata protocol should always be used as
74 | input to these macros, and the result of the macro should be
75 | used with with any Arduino function.
76 |
77 | When Firmata is extended to support a new pin mode or feature,
78 | a pair of macros should be added and used for all hardware
79 | access. For simple 1:1 mapping, these macros add no actual
80 | overhead, yet their consistent use allows source code which
81 | uses them consistently to be easily adapted to all other boards
82 | with different requirements.
83 |
84 | IS_PIN_XXXX(pin): The IS_PIN macros resolve to true or non-zero
85 | if a pin as implemented by Firmata corresponds to a pin
86 | that actually implements the named feature.
87 |
88 | PIN_TO_XXXX(pin): The PIN_TO macros translate pin numbers as
89 | implemented by Firmata to the pin numbers needed as inputs
90 | to the Arduino functions. The corresponding IS_PIN macro
91 | should always be tested before using a PIN_TO macro, so
92 | these macros only need to handle valid Firmata pin
93 | numbers for the named feature.
94 |
95 |
96 | Port Access Inline Funtions:
97 |
98 | For efficiency, Firmata protocol provides access to digital
99 | input and output pins grouped by 8 bit ports. When these
100 | groups of 8 correspond to actual 8 bit ports as implemented
101 | by the hardware, these inline functions can provide high
102 | speed direct port access. Otherwise, a default implementation
103 | using 8 calls to digitalWrite or digitalRead is used.
104 |
105 | When porting Firmata to a new board, it is recommended to
106 | use the default functions first and focus only on the constants
107 | and macros above. When those are working, if optimized port
108 | access is desired, these inline functions may be extended.
109 | The recommended approach defines a symbol indicating which
110 | optimization to use, and then conditional complication is
111 | used within these functions.
112 |
113 | readPort(port, bitmask): Read an 8 bit port, returning the value.
114 | port: The port number, Firmata pins port*8 to port*8+7
115 | bitmask: The actual pins to read, indicated by 1 bits.
116 |
117 | writePort(port, value, bitmask): Write an 8 bit port.
118 | port: The port number, Firmata pins port*8 to port*8+7
119 | value: The 8 bit value to write
120 | bitmask: The actual pins to write, indicated by 1 bits.
121 | */
122 |
123 | /*==============================================================================
124 | * Board Specific Configuration
125 | *============================================================================*/
126 |
127 | #ifndef digitalPinHasPWM
128 | #define digitalPinHasPWM(p) IS_PIN_DIGITAL(p)
129 | #endif
130 |
131 | // Arduino Duemilanove, Diecimila, and NG
132 | #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__)
133 | #if defined(NUM_ANALOG_INPUTS) && NUM_ANALOG_INPUTS == 6
134 | #define TOTAL_ANALOG_PINS 6
135 | #define TOTAL_PINS 20 // 14 digital + 6 analog
136 | #else
137 | #define TOTAL_ANALOG_PINS 8
138 | #define TOTAL_PINS 22 // 14 digital + 8 analog
139 | #endif
140 | #define VERSION_BLINK_PIN 13
141 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19)
142 | #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) < 14 + TOTAL_ANALOG_PINS)
143 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
144 | #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS)
145 | #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19)
146 | #define PIN_TO_DIGITAL(p) (p)
147 | #define PIN_TO_ANALOG(p) ((p) - 14)
148 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
149 | #define PIN_TO_SERVO(p) ((p) - 2)
150 | #define ARDUINO_PINOUT_OPTIMIZE 1
151 |
152 |
153 | // Wiring (and board)
154 | #elif defined(WIRING)
155 | #define VERSION_BLINK_PIN WLED
156 | #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
157 | #define IS_PIN_ANALOG(p) ((p) >= FIRST_ANALOG_PIN && (p) < (FIRST_ANALOG_PIN+TOTAL_ANALOG_PINS))
158 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
159 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
160 | #define IS_PIN_I2C(p) ((p) == SDA || (p) == SCL)
161 | #define PIN_TO_DIGITAL(p) (p)
162 | #define PIN_TO_ANALOG(p) ((p) - FIRST_ANALOG_PIN)
163 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
164 | #define PIN_TO_SERVO(p) (p)
165 |
166 |
167 | // old Arduinos
168 | #elif defined(__AVR_ATmega8__)
169 | #define TOTAL_ANALOG_PINS 6
170 | #define TOTAL_PINS 20 // 14 digital + 6 analog
171 | #define VERSION_BLINK_PIN 13
172 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 19)
173 | #define IS_PIN_ANALOG(p) ((p) >= 14 && (p) <= 19)
174 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
175 | #define IS_PIN_SERVO(p) (IS_PIN_DIGITAL(p) && (p) - 2 < MAX_SERVOS)
176 | #define IS_PIN_I2C(p) ((p) == 18 || (p) == 19)
177 | #define PIN_TO_DIGITAL(p) (p)
178 | #define PIN_TO_ANALOG(p) ((p) - 14)
179 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
180 | #define PIN_TO_SERVO(p) ((p) - 2)
181 | #define ARDUINO_PINOUT_OPTIMIZE 1
182 |
183 |
184 | // Arduino Mega
185 | #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
186 | #define TOTAL_ANALOG_PINS 16
187 | #define TOTAL_PINS 70 // 54 digital + 16 analog
188 | #define VERSION_BLINK_PIN 13
189 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
190 | #define IS_PIN_ANALOG(p) ((p) >= 54 && (p) < TOTAL_PINS)
191 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
192 | #define IS_PIN_SERVO(p) ((p) >= 2 && (p) - 2 < MAX_SERVOS)
193 | #define IS_PIN_I2C(p) ((p) == 20 || (p) == 21)
194 | #define PIN_TO_DIGITAL(p) (p)
195 | #define PIN_TO_ANALOG(p) ((p) - 54)
196 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
197 | #define PIN_TO_SERVO(p) ((p) - 2)
198 |
199 |
200 | // Teensy 1.0
201 | #elif defined(__AVR_AT90USB162__)
202 | #define TOTAL_ANALOG_PINS 0
203 | #define TOTAL_PINS 21 // 21 digital + no analog
204 | #define VERSION_BLINK_PIN 6
205 | #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
206 | #define IS_PIN_ANALOG(p) (0)
207 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
208 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
209 | #define IS_PIN_I2C(p) (0)
210 | #define PIN_TO_DIGITAL(p) (p)
211 | #define PIN_TO_ANALOG(p) (0)
212 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
213 | #define PIN_TO_SERVO(p) (p)
214 |
215 |
216 | // Teensy 2.0
217 | #elif defined(__AVR_ATmega32U4__)
218 | #define TOTAL_ANALOG_PINS 12
219 | #define TOTAL_PINS 25 // 11 digital + 12 analog
220 | #define VERSION_BLINK_PIN 11
221 | #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
222 | #define IS_PIN_ANALOG(p) ((p) >= 11 && (p) <= 22)
223 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
224 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
225 | #define IS_PIN_I2C(p) ((p) == 5 || (p) == 6)
226 | #define PIN_TO_DIGITAL(p) (p)
227 | #define PIN_TO_ANALOG(p) (((p)<22)?21-(p):11)
228 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
229 | #define PIN_TO_SERVO(p) (p)
230 |
231 |
232 | // Teensy++ 1.0 and 2.0
233 | #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
234 | #define TOTAL_ANALOG_PINS 8
235 | #define TOTAL_PINS 46 // 38 digital + 8 analog
236 | #define VERSION_BLINK_PIN 6
237 | #define IS_PIN_DIGITAL(p) ((p) >= 0 && (p) < TOTAL_PINS)
238 | #define IS_PIN_ANALOG(p) ((p) >= 38 && (p) < TOTAL_PINS)
239 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
240 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
241 | #define IS_PIN_I2C(p) ((p) == 0 || (p) == 1)
242 | #define PIN_TO_DIGITAL(p) (p)
243 | #define PIN_TO_ANALOG(p) ((p) - 38)
244 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
245 | #define PIN_TO_SERVO(p) (p)
246 |
247 |
248 | // Sanguino
249 | #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
250 | #define TOTAL_ANALOG_PINS 8
251 | #define TOTAL_PINS 32 // 24 digital + 8 analog
252 | #define VERSION_BLINK_PIN 0
253 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
254 | #define IS_PIN_ANALOG(p) ((p) >= 24 && (p) < TOTAL_PINS)
255 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
256 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
257 | #define IS_PIN_I2C(p) ((p) == 16 || (p) == 17)
258 | #define PIN_TO_DIGITAL(p) (p)
259 | #define PIN_TO_ANALOG(p) ((p) - 24)
260 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
261 | #define PIN_TO_SERVO(p) ((p) - 2)
262 |
263 |
264 | // Illuminato
265 | #elif defined(__AVR_ATmega645__)
266 | #define TOTAL_ANALOG_PINS 6
267 | #define TOTAL_PINS 42 // 36 digital + 6 analog
268 | #define VERSION_BLINK_PIN 13
269 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
270 | #define IS_PIN_ANALOG(p) ((p) >= 36 && (p) < TOTAL_PINS)
271 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
272 | #define IS_PIN_SERVO(p) ((p) >= 0 && (p) < MAX_SERVOS)
273 | #define IS_PIN_I2C(p) ((p) == 4 || (p) == 5)
274 | #define PIN_TO_DIGITAL(p) (p)
275 | #define PIN_TO_ANALOG(p) ((p) - 36)
276 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
277 | #define PIN_TO_SERVO(p) ((p) - 2)
278 |
279 |
280 | // Arduino DUE
281 | #elif defined(__SAM3X8E__)
282 | #define TOTAL_ANALOG_PINS 12
283 | #define TOTAL_PINS 66 // 54 digital + 12 analog
284 | #define VERSION_BLINK_PIN 13
285 | #define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) < TOTAL_PINS)
286 | #define IS_PIN_ANALOG(p) ((p) >= 54 && (p) < TOTAL_PINS)
287 | #define IS_PIN_PWM(p) digitalPinHasPWM(p)
288 | #define IS_PIN_SERVO(p) ((p) >= 2 && (p) - 2 < MAX_SERVOS)
289 | #define IS_PIN_I2C(p) ((p) == 20 || (p) == 21) // 70 71
290 | #define PIN_TO_DIGITAL(p) (p)
291 | #define PIN_TO_ANALOG(p) ((p) - 54)
292 | #define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
293 | #define PIN_TO_SERVO(p) ((p) - 2)
294 |
295 |
296 | // anything else
297 | #else
298 | #error "Please edit Boards.h with a hardware abstraction for this board"
299 | #endif
300 |
301 |
302 | /*==============================================================================
303 | * readPort() - Read an 8 bit port
304 | *============================================================================*/
305 |
306 | static inline unsigned char readPort(byte, byte) __attribute__((always_inline, unused));
307 | static inline unsigned char readPort(byte port, byte bitmask)
308 | {
309 | #if defined(ARDUINO_PINOUT_OPTIMIZE)
310 | if (port == 0) return (PIND & 0xFC) & bitmask; // ignore Rx/Tx 0/1
311 | if (port == 1) return ((PINB & 0x3F) | ((PINC & 0x03) << 6)) & bitmask;
312 | if (port == 2) return ((PINC & 0x3C) >> 2) & bitmask;
313 | return 0;
314 | #else
315 | unsigned char out=0, pin=port*8;
316 | if (IS_PIN_DIGITAL(pin+0) && (bitmask & 0x01) && digitalRead(PIN_TO_DIGITAL(pin+0))) out |= 0x01;
317 | if (IS_PIN_DIGITAL(pin+1) && (bitmask & 0x02) && digitalRead(PIN_TO_DIGITAL(pin+1))) out |= 0x02;
318 | if (IS_PIN_DIGITAL(pin+2) && (bitmask & 0x04) && digitalRead(PIN_TO_DIGITAL(pin+2))) out |= 0x04;
319 | if (IS_PIN_DIGITAL(pin+3) && (bitmask & 0x08) && digitalRead(PIN_TO_DIGITAL(pin+3))) out |= 0x08;
320 | if (IS_PIN_DIGITAL(pin+4) && (bitmask & 0x10) && digitalRead(PIN_TO_DIGITAL(pin+4))) out |= 0x10;
321 | if (IS_PIN_DIGITAL(pin+5) && (bitmask & 0x20) && digitalRead(PIN_TO_DIGITAL(pin+5))) out |= 0x20;
322 | if (IS_PIN_DIGITAL(pin+6) && (bitmask & 0x40) && digitalRead(PIN_TO_DIGITAL(pin+6))) out |= 0x40;
323 | if (IS_PIN_DIGITAL(pin+7) && (bitmask & 0x80) && digitalRead(PIN_TO_DIGITAL(pin+7))) out |= 0x80;
324 | return out;
325 | #endif
326 | }
327 |
328 | /*==============================================================================
329 | * writePort() - Write an 8 bit port, only touch pins specified by a bitmask
330 | *============================================================================*/
331 |
332 | static inline unsigned char writePort(byte, byte, byte) __attribute__((always_inline, unused));
333 | static inline unsigned char writePort(byte port, byte value, byte bitmask)
334 | {
335 | #if defined(ARDUINO_PINOUT_OPTIMIZE)
336 | if (port == 0) {
337 | bitmask = bitmask & 0xFC; // do not touch Tx & Rx pins
338 | byte valD = value & bitmask;
339 | byte maskD = ~bitmask;
340 | cli();
341 | PORTD = (PORTD & maskD) | valD;
342 | sei();
343 | } else if (port == 1) {
344 | byte valB = (value & bitmask) & 0x3F;
345 | byte valC = (value & bitmask) >> 6;
346 | byte maskB = ~(bitmask & 0x3F);
347 | byte maskC = ~((bitmask & 0xC0) >> 6);
348 | cli();
349 | PORTB = (PORTB & maskB) | valB;
350 | PORTC = (PORTC & maskC) | valC;
351 | sei();
352 | } else if (port == 2) {
353 | bitmask = bitmask & 0x0F;
354 | byte valC = (value & bitmask) << 2;
355 | byte maskC = ~(bitmask << 2);
356 | cli();
357 | PORTC = (PORTC & maskC) | valC;
358 | sei();
359 | }
360 | #else
361 | byte pin=port*8;
362 | if ((bitmask & 0x01)) digitalWrite(PIN_TO_DIGITAL(pin+0), (value & 0x01));
363 | if ((bitmask & 0x02)) digitalWrite(PIN_TO_DIGITAL(pin+1), (value & 0x02));
364 | if ((bitmask & 0x04)) digitalWrite(PIN_TO_DIGITAL(pin+2), (value & 0x04));
365 | if ((bitmask & 0x08)) digitalWrite(PIN_TO_DIGITAL(pin+3), (value & 0x08));
366 | if ((bitmask & 0x10)) digitalWrite(PIN_TO_DIGITAL(pin+4), (value & 0x10));
367 | if ((bitmask & 0x20)) digitalWrite(PIN_TO_DIGITAL(pin+5), (value & 0x20));
368 | if ((bitmask & 0x40)) digitalWrite(PIN_TO_DIGITAL(pin+6), (value & 0x40));
369 | if ((bitmask & 0x80)) digitalWrite(PIN_TO_DIGITAL(pin+7), (value & 0x80));
370 | #endif
371 | }
372 |
373 |
374 |
375 |
376 | #ifndef TOTAL_PORTS
377 | #define TOTAL_PORTS ((TOTAL_PINS + 7) / 8)
378 | #endif
379 |
380 |
381 | #endif /* Firmata_Boards_h */
382 |
383 |
--------------------------------------------------------------------------------
/firmware/BLEFirmataSketch/BLEFirmataSketch.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * BLEFirmataSketch
3 | *
4 | * This sketch is for the BLE Arduino App
5 | * It is a modified version of the Standard Firmata
6 | * sketch by adding support for BLE.
7 | *
8 | */
9 |
10 | #define BLE_NAME "BlendMicro"
11 |
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include "BLEFirmata.h"
17 | #include
18 |
19 | /*
20 | * Firmata is a generic protocol for communicating with microcontrollers
21 | * from software on a host computer. It is intended to work with
22 | * any host computer software package.
23 | *
24 | * To download a host software package, please clink on the following link
25 | * to open the download page in your default browser.
26 | *
27 | * http://firmata.org/wiki/Download
28 | */
29 |
30 | /*
31 | Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.
32 | Copyright (C) 2010-2011 Paul Stoffregen. All rights reserved.
33 | Copyright (C) 2009 Shigeru Kobayashi. All rights reserved.
34 | Copyright (C) 2009-2011 Jeff Hoefs. All rights reserved.
35 |
36 | This library is free software; you can redistribute it and/or
37 | modify it under the terms of the GNU Lesser General Public
38 | License as published by the Free Software Foundation; either
39 | version 2.1 of the License, or (at your option) any later version.
40 |
41 | See file LICENSE.txt for further informations on licensing terms.
42 |
43 | formatted using the GNU C formatting and indenting
44 | */
45 |
46 | /*
47 | * TODO: use Program Control to load stored profiles from EEPROM
48 | */
49 |
50 | // move the following defines to Firmata.h?
51 | #define I2C_WRITE B00000000
52 | #define I2C_READ B00001000
53 | #define I2C_READ_CONTINUOUSLY B00010000
54 | #define I2C_STOP_READING B00011000
55 | #define I2C_READ_WRITE_MODE_MASK B00011000
56 | #define I2C_10BIT_ADDRESS_MODE_MASK B00100000
57 |
58 | #define MAX_QUERIES 8
59 | #define MINIMUM_SAMPLING_INTERVAL 10
60 |
61 | #define REGISTER_NOT_SPECIFIED -1
62 |
63 | /*==============================================================================
64 | * GLOBAL VARIABLES
65 | *============================================================================*/
66 |
67 | /* analog inputs */
68 | int analogInputsToReport = 0; // bitwise array to store pin reporting
69 |
70 | /* digital input ports */
71 | byte reportPINs[TOTAL_PORTS]; // 1 = report this port, 0 = silence
72 | byte previousPINs[TOTAL_PORTS]; // previous 8 bits sent
73 |
74 | /* pins configuration */
75 | byte pinConfig[TOTAL_PINS]; // configuration of every pin
76 | byte portConfigInputs[TOTAL_PORTS]; // each bit: 1 = pin in INPUT, 0 = anything else
77 | int pinState[TOTAL_PINS]; // any value that has been written
78 |
79 | /* timer variables */
80 | unsigned long currentMillis; // store the current value from millis()
81 | unsigned long previousMillis; // for comparison with currentMillis
82 | int samplingInterval = 38; // how often to run the main loop (in ms)
83 |
84 | /* i2c data */
85 | struct i2c_device_info {
86 | byte addr;
87 | byte reg;
88 | byte bytes;
89 | };
90 |
91 | /* for i2c read continuous more */
92 | i2c_device_info query[MAX_QUERIES];
93 |
94 | byte i2cRxData[32];
95 | boolean isI2CEnabled = false;
96 | signed char queryIndex = -1;
97 | unsigned int i2cReadDelayTime = 0; // default delay time between i2c read request and Wire.requestFrom()
98 |
99 | Servo servos[MAX_SERVOS];
100 | /*==============================================================================
101 | * FUNCTIONS
102 | *============================================================================*/
103 |
104 | void readAndReportData(byte address, int theRegister, byte numBytes) {
105 | // allow I2C requests that don't require a register read
106 | // for example, some devices using an interrupt pin to signify new data available
107 | // do not always require the register read so upon interrupt you call Wire.requestFrom()
108 | if (theRegister != REGISTER_NOT_SPECIFIED) {
109 | Wire.beginTransmission(address);
110 | #if ARDUINO >= 100
111 | Wire.write((byte)theRegister);
112 | #else
113 | Wire.send((byte)theRegister);
114 | #endif
115 | Wire.endTransmission();
116 | delayMicroseconds(i2cReadDelayTime); // delay is necessary for some devices such as WiiNunchuck
117 | } else {
118 | theRegister = 0; // fill the register with a dummy value
119 | }
120 |
121 | Wire.requestFrom(address, numBytes); // all bytes are returned in requestFrom
122 |
123 | // check to be sure correct number of bytes were returned by slave
124 | if(numBytes == Wire.available()) {
125 | i2cRxData[0] = address;
126 | i2cRxData[1] = theRegister;
127 | for (int i = 0; i < numBytes; i++) {
128 | #if ARDUINO >= 100
129 | i2cRxData[2 + i] = Wire.read();
130 | #else
131 | i2cRxData[2 + i] = Wire.receive();
132 | #endif
133 | }
134 | }
135 | else {
136 | if(numBytes > Wire.available()) {
137 | BleFirmata.sendString("I2C Read Error: Too many bytes received");
138 | } else {
139 | BleFirmata.sendString("I2C Read Error: Too few bytes received");
140 | }
141 | }
142 |
143 | // send slave address, register and received bytes
144 | BleFirmata.sendSysex(SYSEX_I2C_REPLY, numBytes + 2, i2cRxData);
145 | }
146 |
147 | void outputPort(byte portNumber, byte portValue, byte forceSend)
148 | {
149 | // pins not configured as INPUT are cleared to zeros
150 | portValue = portValue & portConfigInputs[portNumber];
151 |
152 | // only send if the value is different than previously sent
153 | if(forceSend || previousPINs[portNumber] != portValue) {
154 | BleFirmata.sendDigitalPort(portNumber, portValue);
155 | previousPINs[portNumber] = portValue;
156 | }
157 | }
158 |
159 | /* -----------------------------------------------------------------------------
160 | * check all the active digital inputs for change of state, then add any events
161 | * to the Serial output queue using Serial.print() */
162 | void checkDigitalInputs(void)
163 | {
164 | /* Using non-looping code allows constants to be given to readPort().
165 | * The compiler will apply substantial optimizations if the inputs
166 | * to readPort() are compile-time constants. */
167 | if (TOTAL_PORTS > 0 && reportPINs[0]) outputPort(0, readPort(0, portConfigInputs[0]), false);
168 | if (TOTAL_PORTS > 1 && reportPINs[1]) outputPort(1, readPort(1, portConfigInputs[1]), false);
169 | if (TOTAL_PORTS > 2 && reportPINs[2]) outputPort(2, readPort(2, portConfigInputs[2]), false);
170 | if (TOTAL_PORTS > 3 && reportPINs[3]) outputPort(3, readPort(3, portConfigInputs[3]), false);
171 | if (TOTAL_PORTS > 4 && reportPINs[4]) outputPort(4, readPort(4, portConfigInputs[4]), false);
172 | if (TOTAL_PORTS > 5 && reportPINs[5]) outputPort(5, readPort(5, portConfigInputs[5]), false);
173 | if (TOTAL_PORTS > 6 && reportPINs[6]) outputPort(6, readPort(6, portConfigInputs[6]), false);
174 | if (TOTAL_PORTS > 7 && reportPINs[7]) outputPort(7, readPort(7, portConfigInputs[7]), false);
175 | if (TOTAL_PORTS > 8 && reportPINs[8]) outputPort(8, readPort(8, portConfigInputs[8]), false);
176 | if (TOTAL_PORTS > 9 && reportPINs[9]) outputPort(9, readPort(9, portConfigInputs[9]), false);
177 | if (TOTAL_PORTS > 10 && reportPINs[10]) outputPort(10, readPort(10, portConfigInputs[10]), false);
178 | if (TOTAL_PORTS > 11 && reportPINs[11]) outputPort(11, readPort(11, portConfigInputs[11]), false);
179 | if (TOTAL_PORTS > 12 && reportPINs[12]) outputPort(12, readPort(12, portConfigInputs[12]), false);
180 | if (TOTAL_PORTS > 13 && reportPINs[13]) outputPort(13, readPort(13, portConfigInputs[13]), false);
181 | if (TOTAL_PORTS > 14 && reportPINs[14]) outputPort(14, readPort(14, portConfigInputs[14]), false);
182 | if (TOTAL_PORTS > 15 && reportPINs[15]) outputPort(15, readPort(15, portConfigInputs[15]), false);
183 | }
184 |
185 | // -----------------------------------------------------------------------------
186 | /* sets the pin mode to the correct state and sets the relevant bits in the
187 | * two bit-arrays that track Digital I/O and PWM status
188 | */
189 | void setPinModeCallback(byte pin, int mode)
190 | {
191 | if (pinConfig[pin] == I2C && isI2CEnabled && mode != I2C) {
192 | // disable i2c so pins can be used for other functions
193 | // the following if statements should reconfigure the pins properly
194 | disableI2CPins();
195 | }
196 | if (IS_PIN_SERVO(pin) && mode != SERVO && servos[PIN_TO_SERVO(pin)].attached()) {
197 | servos[PIN_TO_SERVO(pin)].detach();
198 | }
199 | if (IS_PIN_ANALOG(pin)) {
200 | reportAnalogCallback(PIN_TO_ANALOG(pin), mode == ANALOG ? 1 : 0); // turn on/off reporting
201 | }
202 | if (IS_PIN_DIGITAL(pin)) {
203 | if (mode == INPUT) {
204 | portConfigInputs[pin/8] |= (1 << (pin & 7));
205 | } else {
206 | portConfigInputs[pin/8] &= ~(1 << (pin & 7));
207 | }
208 | }
209 | pinState[pin] = 0;
210 | switch(mode) {
211 | case ANALOG:
212 | if (IS_PIN_ANALOG(pin)) {
213 | if (IS_PIN_DIGITAL(pin)) {
214 | pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
215 | digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
216 | }
217 | pinConfig[pin] = ANALOG;
218 | }
219 | break;
220 | case INPUT:
221 | if (IS_PIN_DIGITAL(pin)) {
222 | pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
223 |
224 | // Select your internal pull-up here
225 | digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
226 | //digitalWrite(PIN_TO_DIGITAL(pin), HIGH); // enable internal pull-ups if you have only a wire to test
227 | pinConfig[pin] = INPUT;
228 |
229 | // hack it only
230 | reportPINs[pin/8] |= (1 << (pin & 7));
231 | }
232 | break;
233 | case OUTPUT:
234 | if (IS_PIN_DIGITAL(pin)) {
235 | digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable PWM
236 | pinMode(PIN_TO_DIGITAL(pin), OUTPUT);
237 | pinConfig[pin] = OUTPUT;
238 | }
239 | break;
240 | case PWM:
241 | if (IS_PIN_PWM(pin)) {
242 | pinMode(PIN_TO_PWM(pin), OUTPUT);
243 | analogWrite(PIN_TO_PWM(pin), 0);
244 | pinConfig[pin] = PWM;
245 | }
246 | break;
247 | case SERVO:
248 | if (IS_PIN_SERVO(pin)) {
249 | pinConfig[pin] = SERVO;
250 | if (!servos[PIN_TO_SERVO(pin)].attached()) {
251 | servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin));
252 | }
253 | }
254 | break;
255 | case I2C:
256 | if (IS_PIN_I2C(pin)) {
257 | // mark the pin as i2c
258 | // the user must call I2C_CONFIG to enable I2C for a device
259 | pinConfig[pin] = I2C;
260 | }
261 | break;
262 | default:
263 | BleFirmata.sendString("Unknown pin mode"); // TODO: put error msgs in EEPROM
264 | }
265 | // TODO: save status to EEPROM here, if changed
266 | }
267 |
268 | void analogWriteCallback(byte pin, int value)
269 | {
270 | if (pin < TOTAL_PINS) {
271 | switch(pinConfig[pin]) {
272 | case SERVO:
273 | if (IS_PIN_SERVO(pin))
274 | servos[PIN_TO_SERVO(pin)].write(value);
275 | pinState[pin] = value;
276 | break;
277 | case PWM:
278 | if (IS_PIN_PWM(pin))
279 | analogWrite(PIN_TO_PWM(pin), value);
280 | pinState[pin] = value;
281 | break;
282 | }
283 | }
284 | }
285 |
286 | void digitalWriteCallback(byte port, int value)
287 | {
288 | byte pin, lastPin, mask=1, pinWriteMask=0;
289 |
290 | if (port < TOTAL_PORTS) {
291 | // create a mask of the pins on this port that are writable.
292 | lastPin = port*8+8;
293 | if (lastPin > TOTAL_PINS) lastPin = TOTAL_PINS;
294 | for (pin=port*8; pin < lastPin; pin++) {
295 | // do not disturb non-digital pins (eg, Rx & Tx)
296 | if (IS_PIN_DIGITAL(pin)) {
297 | // only write to OUTPUT and INPUT (enables pullup)
298 | // do not touch pins in PWM, ANALOG, SERVO or other modes
299 | if (pinConfig[pin] == OUTPUT || pinConfig[pin] == INPUT) {
300 | pinWriteMask |= mask;
301 | pinState[pin] = ((byte)value & mask) ? 1 : 0;
302 | }
303 | }
304 | mask = mask << 1;
305 | }
306 | writePort(port, (byte)value, pinWriteMask);
307 | }
308 | }
309 |
310 |
311 | // -----------------------------------------------------------------------------
312 | /* sets bits in a bit array (int) to toggle the reporting of the analogIns
313 | */
314 | //void FirmataClass::setAnalogPinReporting(byte pin, byte state) {
315 | //}
316 | void reportAnalogCallback(byte analogPin, int value)
317 | {
318 | if (analogPin < TOTAL_ANALOG_PINS) {
319 | if(value == 0) {
320 | analogInputsToReport = analogInputsToReport &~ (1 << analogPin);
321 | } else {
322 | analogInputsToReport = analogInputsToReport | (1 << analogPin);
323 | }
324 | }
325 | // TODO: save status to EEPROM here, if changed
326 | }
327 |
328 | void reportDigitalCallback(byte port, int value)
329 | {
330 | if (port < TOTAL_PORTS) {
331 | reportPINs[port] = (byte)value;
332 | }
333 | // do not disable analog reporting on these 8 pins, to allow some
334 | // pins used for digital, others analog. Instead, allow both types
335 | // of reporting to be enabled, but check if the pin is configured
336 | // as analog when sampling the analog inputs. Likewise, while
337 | // scanning digital pins, portConfigInputs will mask off values from any
338 | // pins configured as analog
339 | }
340 |
341 | /*==============================================================================
342 | * SYSEX-BASED commands
343 | *============================================================================*/
344 |
345 | void sysexCallback(byte command, byte argc, byte *argv)
346 | {
347 | byte mode;
348 | byte slaveAddress;
349 | byte slaveRegister;
350 | byte data;
351 | unsigned int delayTime;
352 |
353 | switch(command) {
354 | case I2C_REQUEST:
355 | mode = argv[1] & I2C_READ_WRITE_MODE_MASK;
356 | if (argv[1] & I2C_10BIT_ADDRESS_MODE_MASK) {
357 | BleFirmata.sendString("10-bit addressing mode is not yet supported");
358 | return;
359 | }
360 | else {
361 | slaveAddress = argv[0];
362 | }
363 |
364 | switch(mode) {
365 | case I2C_WRITE:
366 | Wire.beginTransmission(slaveAddress);
367 | for (byte i = 2; i < argc; i += 2) {
368 | data = argv[i] + (argv[i + 1] << 7);
369 | #if ARDUINO >= 100
370 | Wire.write(data);
371 | #else
372 | Wire.send(data);
373 | #endif
374 | }
375 | Wire.endTransmission();
376 | delayMicroseconds(70);
377 | break;
378 | case I2C_READ:
379 | if (argc == 6) {
380 | // a slave register is specified
381 | slaveRegister = argv[2] + (argv[3] << 7);
382 | data = argv[4] + (argv[5] << 7); // bytes to read
383 | readAndReportData(slaveAddress, (int)slaveRegister, data);
384 | }
385 | else {
386 | // a slave register is NOT specified
387 | data = argv[2] + (argv[3] << 7); // bytes to read
388 | readAndReportData(slaveAddress, (int)REGISTER_NOT_SPECIFIED, data);
389 | }
390 | break;
391 | case I2C_READ_CONTINUOUSLY:
392 | if ((queryIndex + 1) >= MAX_QUERIES) {
393 | // too many queries, just ignore
394 | BleFirmata.sendString("too many queries");
395 | break;
396 | }
397 | queryIndex++;
398 | query[queryIndex].addr = slaveAddress;
399 | query[queryIndex].reg = argv[2] + (argv[3] << 7);
400 | query[queryIndex].bytes = argv[4] + (argv[5] << 7);
401 | break;
402 | case I2C_STOP_READING:
403 | byte queryIndexToSkip;
404 | // if read continuous mode is enabled for only 1 i2c device, disable
405 | // read continuous reporting for that device
406 | if (queryIndex <= 0) {
407 | queryIndex = -1;
408 | } else {
409 | // if read continuous mode is enabled for multiple devices,
410 | // determine which device to stop reading and remove it's data from
411 | // the array, shifiting other array data to fill the space
412 | for (byte i = 0; i < queryIndex + 1; i++) {
413 | if (query[i].addr = slaveAddress) {
414 | queryIndexToSkip = i;
415 | break;
416 | }
417 | }
418 |
419 | for (byte i = queryIndexToSkip; i 0) {
437 | i2cReadDelayTime = delayTime;
438 | }
439 |
440 | if (!isI2CEnabled) {
441 | enableI2CPins();
442 | }
443 |
444 | break;
445 | case SERVO_CONFIG:
446 | if(argc > 4) {
447 | // these vars are here for clarity, they'll optimized away by the compiler
448 | byte pin = argv[0];
449 | int minPulse = argv[1] + (argv[2] << 7);
450 | int maxPulse = argv[3] + (argv[4] << 7);
451 |
452 | if (IS_PIN_SERVO(pin)) {
453 | if (servos[PIN_TO_SERVO(pin)].attached())
454 | servos[PIN_TO_SERVO(pin)].detach();
455 | servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin), minPulse, maxPulse);
456 | setPinModeCallback(pin, SERVO);
457 | }
458 | }
459 | break;
460 | case SAMPLING_INTERVAL:
461 | if (argc > 1) {
462 | samplingInterval = argv[0] + (argv[1] << 7);
463 | if (samplingInterval < MINIMUM_SAMPLING_INTERVAL) {
464 | samplingInterval = MINIMUM_SAMPLING_INTERVAL;
465 | }
466 | } else {
467 | //Firmata.sendString("Not enough data");
468 | }
469 | break;
470 | case EXTENDED_ANALOG:
471 | if (argc > 1) {
472 | int val = argv[1];
473 | if (argc > 2) val |= (argv[2] << 7);
474 | if (argc > 3) val |= (argv[3] << 14);
475 | analogWriteCallback(argv[0], val);
476 | }
477 | break;
478 | case CAPABILITY_QUERY:
479 | ble_write(START_SYSEX);
480 | ble_write(CAPABILITY_RESPONSE);
481 | for (byte pin=0; pin < TOTAL_PINS; pin++) {
482 | if (IS_PIN_DIGITAL(pin)) {
483 | ble_write((byte)INPUT);
484 | ble_write(1);
485 | ble_write((byte)OUTPUT);
486 | ble_write(1);
487 | }
488 | if (IS_PIN_ANALOG(pin)) {
489 | ble_write(ANALOG);
490 | ble_write(10);
491 | }
492 | if (IS_PIN_PWM(pin)) {
493 | ble_write(PWM);
494 | ble_write(8);
495 | }
496 | if (IS_PIN_SERVO(pin)) {
497 | ble_write(SERVO);
498 | ble_write(14);
499 | }
500 | if (IS_PIN_I2C(pin)) {
501 | ble_write(I2C);
502 | ble_write(1); // to do: determine appropriate value
503 | }
504 | ble_write(127);
505 | }
506 | ble_write(END_SYSEX);
507 | break;
508 | case PIN_STATE_QUERY:
509 | if (argc > 0) {
510 | byte pin=argv[0];
511 | ble_write(START_SYSEX);
512 | ble_write(PIN_STATE_RESPONSE);
513 | ble_write(pin);
514 | if (pin < TOTAL_PINS) {
515 | ble_write((byte)pinConfig[pin]);
516 | ble_write((byte)pinState[pin] & 0x7F);
517 | if (pinState[pin] & 0xFF80) ble_write((byte)(pinState[pin] >> 7) & 0x7F);
518 | if (pinState[pin] & 0xC000) ble_write((byte)(pinState[pin] >> 14) & 0x7F);
519 | }
520 | ble_write(END_SYSEX);
521 | }
522 | break;
523 | case ANALOG_MAPPING_QUERY:
524 | ble_write(START_SYSEX);
525 | ble_write(ANALOG_MAPPING_RESPONSE);
526 | for (byte pin=0; pin < TOTAL_PINS; pin++) {
527 | ble_write(IS_PIN_ANALOG(pin) ? PIN_TO_ANALOG(pin) : 127);
528 | }
529 | ble_write(END_SYSEX);
530 | break;
531 | }
532 | }
533 |
534 | void enableI2CPins()
535 | {
536 | byte i;
537 | // is there a faster way to do this? would probaby require importing
538 | // Arduino.h to get SCL and SDA pins
539 | for (i=0; i < TOTAL_PINS; i++) {
540 | if(IS_PIN_I2C(i)) {
541 | // mark pins as i2c so they are ignore in non i2c data requests
542 | setPinModeCallback(i, I2C);
543 | }
544 | }
545 |
546 | isI2CEnabled = true;
547 |
548 | // is there enough time before the first I2C request to call this here?
549 | Wire.begin();
550 | }
551 |
552 | /* disable the i2c pins so they can be used for other functions */
553 | void disableI2CPins() {
554 | isI2CEnabled = false;
555 | // disable read continuous mode for all devices
556 | queryIndex = -1;
557 | // uncomment the following if or when the end() method is added to Wire library
558 | // Wire.end();
559 | }
560 |
561 | /*==============================================================================
562 | * SETUP()
563 | *============================================================================*/
564 |
565 | void systemResetCallback()
566 | {
567 | // initialize a defalt state
568 | // TODO: option to load config from EEPROM instead of default
569 | if (isI2CEnabled) {
570 | disableI2CPins();
571 | }
572 | for (byte i=0; i < TOTAL_PORTS; i++) {
573 | reportPINs[i] = false; // by default, reporting off
574 | portConfigInputs[i] = 0; // until activated
575 | previousPINs[i] = 0;
576 | }
577 | // pins with analog capability default to analog input
578 | // otherwise, pins default to digital output
579 | for (byte i=0; i < TOTAL_PINS; i++) {
580 |
581 | #if defined(BLEND_MICRO)
582 | // skip pin 4, 6, 7 for BlendMicro BLE controll
583 | if ((i == 4) || (i == 6) || (i == 7))
584 | continue;
585 | #else
586 | // skip pin 8, 9 for BLE Shield
587 | if ((i == 8) || (i == 9))
588 | continue;
589 | #endif
590 |
591 | // skip SPI pins
592 | if ( (i==MOSI) || (i==MISO) || (i==SCK) || (i==SS) )
593 | continue;
594 |
595 | // Default all to digital pins
596 | if (IS_PIN_ANALOG(i)) {
597 | // turns off pullup, configures everything
598 | setPinModeCallback(i, ANALOG);
599 | } else {
600 | // sets the output to 0, configures portConfigInputs
601 | //setPinModeCallback(i, OUTPUT);
602 | }
603 | }
604 | // by default, do not report any analog inputs
605 | analogInputsToReport = 0;
606 |
607 | /* send digital inputs to set the initial state on the host computer,
608 | * since once in the loop(), this firmware will only send on change */
609 | /*
610 | TODO: this can never execute, since no pins default to digital input
611 | but it will be needed when/if we support EEPROM stored config
612 | for (byte i=0; i < TOTAL_PORTS; i++) {
613 | outputPort(i, readPort(i, portConfigInputs[i]), true);
614 | }
615 | */
616 | }
617 |
618 | void setup()
619 | {
620 | BleFirmata.setFirmwareVersion(FIRMATA_MAJOR_VERSION, FIRMATA_MINOR_VERSION);
621 |
622 | BleFirmata.attach(ANALOG_MESSAGE, analogWriteCallback);
623 | BleFirmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);
624 | BleFirmata.attach(REPORT_ANALOG, reportAnalogCallback);
625 | BleFirmata.attach(REPORT_DIGITAL, reportDigitalCallback);
626 | BleFirmata.attach(SET_PIN_MODE, setPinModeCallback);
627 | BleFirmata.attach(START_SYSEX, sysexCallback);
628 | BleFirmata.attach(SYSTEM_RESET, systemResetCallback);
629 |
630 | // BleFirmata.begin(57600);
631 | systemResetCallback(); // reset to default config
632 |
633 | // Enable serial debug
634 | Serial.begin(57600);
635 |
636 | // Default pins set to 9 and 8 for REQN and RDYN
637 | // Set your REQN and RDYN here before ble_begin() if you need
638 | //ble_set_pins(3, 2);
639 |
640 | // Set your BLE Shield name here, max. length 10
641 | ble_set_name(BLE_NAME);
642 |
643 | // Init. BLE and start BLE library.
644 | ble_begin();
645 | }
646 |
647 | /*==============================================================================
648 | * LOOP()
649 | *============================================================================*/
650 | void loop()
651 | {
652 | byte pin, analogPin;
653 |
654 | /* DIGITALREAD - as fast as possible, check for changes and output them to the
655 | * FTDI buffer using Serial.print() */
656 | checkDigitalInputs();
657 |
658 | /* SERIALREAD - processing incoming messagse as soon as possible, while still
659 | * checking digital inputs. */
660 | while(BleFirmata.available())
661 | BleFirmata.processInput();
662 |
663 | /* SEND FTDI WRITE BUFFER - make sure that the FTDI buffer doesn't go over
664 | * 60 bytes. use a timer to sending an event character every 4 ms to
665 | * trigger the buffer to dump. */
666 |
667 | currentMillis = millis();
668 | if (currentMillis - previousMillis > samplingInterval) {
669 | previousMillis += samplingInterval;
670 | /* ANALOGREAD - do all analogReads() at the configured sampling interval */
671 | for(pin=0; pin -1) {
684 | for (byte i = 0; i < queryIndex + 1; i++) {
685 | readAndReportData(query[i].addr, query[i].reg, query[i].bytes);
686 | }
687 | }
688 | }
689 |
690 | if (!ble_connected())
691 | systemResetCallback();
692 |
693 | ble_do_events();
694 | }
695 |
696 |
--------------------------------------------------------------------------------
/samples/sysex/BLEFirmataWithLedBlink/LICENSE.txt:
--------------------------------------------------------------------------------
1 |
2 | GNU LESSER GENERAL PUBLIC LICENSE
3 | Version 2.1, February 1999
4 |
5 | Copyright (C) 1991, 1999 Free Software Foundation, Inc.
6 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
7 | Everyone is permitted to copy and distribute verbatim copies
8 | of this license document, but changing it is not allowed.
9 |
10 | [This is the first released version of the Lesser GPL. It also counts
11 | as the successor of the GNU Library Public License, version 2, hence
12 | the version number 2.1.]
13 |
14 | Preamble
15 |
16 | The licenses for most software are designed to take away your
17 | freedom to share and change it. By contrast, the GNU General Public
18 | Licenses are intended to guarantee your freedom to share and change
19 | free software--to make sure the software is free for all its users.
20 |
21 | This license, the Lesser General Public License, applies to some
22 | specially designated software packages--typically libraries--of the
23 | Free Software Foundation and other authors who decide to use it. You
24 | can use it too, but we suggest you first think carefully about whether
25 | this license or the ordinary General Public License is the better
26 | strategy to use in any particular case, based on the explanations below.
27 |
28 | When we speak of free software, we are referring to freedom of use,
29 | not price. Our General Public Licenses are designed to make sure that
30 | you have the freedom to distribute copies of free software (and charge
31 | for this service if you wish); that you receive source code or can get
32 | it if you want it; that you can change the software and use pieces of
33 | it in new free programs; and that you are informed that you can do
34 | these things.
35 |
36 | To protect your rights, we need to make restrictions that forbid
37 | distributors to deny you these rights or to ask you to surrender these
38 | rights. These restrictions translate to certain responsibilities for
39 | you if you distribute copies of the library or if you modify it.
40 |
41 | For example, if you distribute copies of the library, whether gratis
42 | or for a fee, you must give the recipients all the rights that we gave
43 | you. You must make sure that they, too, receive or can get the source
44 | code. If you link other code with the library, you must provide
45 | complete object files to the recipients, so that they can relink them
46 | with the library after making changes to the library and recompiling
47 | it. And you must show them these terms so they know their rights.
48 |
49 | We protect your rights with a two-step method: (1) we copyright the
50 | library, and (2) we offer you this license, which gives you legal
51 | permission to copy, distribute and/or modify the library.
52 |
53 | To protect each distributor, we want to make it very clear that
54 | there is no warranty for the free library. Also, if the library is
55 | modified by someone else and passed on, the recipients should know
56 | that what they have is not the original version, so that the original
57 | author's reputation will not be affected by problems that might be
58 | introduced by others.
59 |
60 | Finally, software patents pose a constant threat to the existence of
61 | any free program. We wish to make sure that a company cannot
62 | effectively restrict the users of a free program by obtaining a
63 | restrictive license from a patent holder. Therefore, we insist that
64 | any patent license obtained for a version of the library must be
65 | consistent with the full freedom of use specified in this license.
66 |
67 | Most GNU software, including some libraries, is covered by the
68 | ordinary GNU General Public License. This license, the GNU Lesser
69 | General Public License, applies to certain designated libraries, and
70 | is quite different from the ordinary General Public License. We use
71 | this license for certain libraries in order to permit linking those
72 | libraries into non-free programs.
73 |
74 | When a program is linked with a library, whether statically or using
75 | a shared library, the combination of the two is legally speaking a
76 | combined work, a derivative of the original library. The ordinary
77 | General Public License therefore permits such linking only if the
78 | entire combination fits its criteria of freedom. The Lesser General
79 | Public License permits more lax criteria for linking other code with
80 | the library.
81 |
82 | We call this license the "Lesser" General Public License because it
83 | does Less to protect the user's freedom than the ordinary General
84 | Public License. It also provides other free software developers Less
85 | of an advantage over competing non-free programs. These disadvantages
86 | are the reason we use the ordinary General Public License for many
87 | libraries. However, the Lesser license provides advantages in certain
88 | special circumstances.
89 |
90 | For example, on rare occasions, there may be a special need to
91 | encourage the widest possible use of a certain library, so that it becomes
92 | a de-facto standard. To achieve this, non-free programs must be
93 | allowed to use the library. A more frequent case is that a free
94 | library does the same job as widely used non-free libraries. In this
95 | case, there is little to gain by limiting the free library to free
96 | software only, so we use the Lesser General Public License.
97 |
98 | In other cases, permission to use a particular library in non-free
99 | programs enables a greater number of people to use a large body of
100 | free software. For example, permission to use the GNU C Library in
101 | non-free programs enables many more people to use the whole GNU
102 | operating system, as well as its variant, the GNU/Linux operating
103 | system.
104 |
105 | Although the Lesser General Public License is Less protective of the
106 | users' freedom, it does ensure that the user of a program that is
107 | linked with the Library has the freedom and the wherewithal to run
108 | that program using a modified version of the Library.
109 |
110 | The precise terms and conditions for copying, distribution and
111 | modification follow. Pay close attention to the difference between a
112 | "work based on the library" and a "work that uses the library". The
113 | former contains code derived from the library, whereas the latter must
114 | be combined with the library in order to run.
115 |
116 | GNU LESSER GENERAL PUBLIC LICENSE
117 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
118 |
119 | 0. This License Agreement applies to any software library or other
120 | program which contains a notice placed by the copyright holder or
121 | other authorized party saying it may be distributed under the terms of
122 | this Lesser General Public License (also called "this License").
123 | Each licensee is addressed as "you".
124 |
125 | A "library" means a collection of software functions and/or data
126 | prepared so as to be conveniently linked with application programs
127 | (which use some of those functions and data) to form executables.
128 |
129 | The "Library", below, refers to any such software library or work
130 | which has been distributed under these terms. A "work based on the
131 | Library" means either the Library or any derivative work under
132 | copyright law: that is to say, a work containing the Library or a
133 | portion of it, either verbatim or with modifications and/or translated
134 | straightforwardly into another language. (Hereinafter, translation is
135 | included without limitation in the term "modification".)
136 |
137 | "Source code" for a work means the preferred form of the work for
138 | making modifications to it. For a library, complete source code means
139 | all the source code for all modules it contains, plus any associated
140 | interface definition files, plus the scripts used to control compilation
141 | and installation of the library.
142 |
143 | Activities other than copying, distribution and modification are not
144 | covered by this License; they are outside its scope. The act of
145 | running a program using the Library is not restricted, and output from
146 | such a program is covered only if its contents constitute a work based
147 | on the Library (independent of the use of the Library in a tool for
148 | writing it). Whether that is true depends on what the Library does
149 | and what the program that uses the Library does.
150 |
151 | 1. You may copy and distribute verbatim copies of the Library's
152 | complete source code as you receive it, in any medium, provided that
153 | you conspicuously and appropriately publish on each copy an
154 | appropriate copyright notice and disclaimer of warranty; keep intact
155 | all the notices that refer to this License and to the absence of any
156 | warranty; and distribute a copy of this License along with the
157 | Library.
158 |
159 | You may charge a fee for the physical act of transferring a copy,
160 | and you may at your option offer warranty protection in exchange for a
161 | fee.
162 |
163 | 2. You may modify your copy or copies of the Library or any portion
164 | of it, thus forming a work based on the Library, and copy and
165 | distribute such modifications or work under the terms of Section 1
166 | above, provided that you also meet all of these conditions:
167 |
168 | a) The modified work must itself be a software library.
169 |
170 | b) You must cause the files modified to carry prominent notices
171 | stating that you changed the files and the date of any change.
172 |
173 | c) You must cause the whole of the work to be licensed at no
174 | charge to all third parties under the terms of this License.
175 |
176 | d) If a facility in the modified Library refers to a function or a
177 | table of data to be supplied by an application program that uses
178 | the facility, other than as an argument passed when the facility
179 | is invoked, then you must make a good faith effort to ensure that,
180 | in the event an application does not supply such function or
181 | table, the facility still operates, and performs whatever part of
182 | its purpose remains meaningful.
183 |
184 | (For example, a function in a library to compute square roots has
185 | a purpose that is entirely well-defined independent of the
186 | application. Therefore, Subsection 2d requires that any
187 | application-supplied function or table used by this function must
188 | be optional: if the application does not supply it, the square
189 | root function must still compute square roots.)
190 |
191 | These requirements apply to the modified work as a whole. If
192 | identifiable sections of that work are not derived from the Library,
193 | and can be reasonably considered independent and separate works in
194 | themselves, then this License, and its terms, do not apply to those
195 | sections when you distribute them as separate works. But when you
196 | distribute the same sections as part of a whole which is a work based
197 | on the Library, the distribution of the whole must be on the terms of
198 | this License, whose permissions for other licensees extend to the
199 | entire whole, and thus to each and every part regardless of who wrote
200 | it.
201 |
202 | Thus, it is not the intent of this section to claim rights or contest
203 | your rights to work written entirely by you; rather, the intent is to
204 | exercise the right to control the distribution of derivative or
205 | collective works based on the Library.
206 |
207 | In addition, mere aggregation of another work not based on the Library
208 | with the Library (or with a work based on the Library) on a volume of
209 | a storage or distribution medium does not bring the other work under
210 | the scope of this License.
211 |
212 | 3. You may opt to apply the terms of the ordinary GNU General Public
213 | License instead of this License to a given copy of the Library. To do
214 | this, you must alter all the notices that refer to this License, so
215 | that they refer to the ordinary GNU General Public License, version 2,
216 | instead of to this License. (If a newer version than version 2 of the
217 | ordinary GNU General Public License has appeared, then you can specify
218 | that version instead if you wish.) Do not make any other change in
219 | these notices.
220 |
221 | Once this change is made in a given copy, it is irreversible for
222 | that copy, so the ordinary GNU General Public License applies to all
223 | subsequent copies and derivative works made from that copy.
224 |
225 | This option is useful when you wish to copy part of the code of
226 | the Library into a program that is not a library.
227 |
228 | 4. You may copy and distribute the Library (or a portion or
229 | derivative of it, under Section 2) in object code or executable form
230 | under the terms of Sections 1 and 2 above provided that you accompany
231 | it with the complete corresponding machine-readable source code, which
232 | must be distributed under the terms of Sections 1 and 2 above on a
233 | medium customarily used for software interchange.
234 |
235 | If distribution of object code is made by offering access to copy
236 | from a designated place, then offering equivalent access to copy the
237 | source code from the same place satisfies the requirement to
238 | distribute the source code, even though third parties are not
239 | compelled to copy the source along with the object code.
240 |
241 | 5. A program that contains no derivative of any portion of the
242 | Library, but is designed to work with the Library by being compiled or
243 | linked with it, is called a "work that uses the Library". Such a
244 | work, in isolation, is not a derivative work of the Library, and
245 | therefore falls outside the scope of this License.
246 |
247 | However, linking a "work that uses the Library" with the Library
248 | creates an executable that is a derivative of the Library (because it
249 | contains portions of the Library), rather than a "work that uses the
250 | library". The executable is therefore covered by this License.
251 | Section 6 states terms for distribution of such executables.
252 |
253 | When a "work that uses the Library" uses material from a header file
254 | that is part of the Library, the object code for the work may be a
255 | derivative work of the Library even though the source code is not.
256 | Whether this is true is especially significant if the work can be
257 | linked without the Library, or if the work is itself a library. The
258 | threshold for this to be true is not precisely defined by law.
259 |
260 | If such an object file uses only numerical parameters, data
261 | structure layouts and accessors, and small macros and small inline
262 | functions (ten lines or less in length), then the use of the object
263 | file is unrestricted, regardless of whether it is legally a derivative
264 | work. (Executables containing this object code plus portions of the
265 | Library will still fall under Section 6.)
266 |
267 | Otherwise, if the work is a derivative of the Library, you may
268 | distribute the object code for the work under the terms of Section 6.
269 | Any executables containing that work also fall under Section 6,
270 | whether or not they are linked directly with the Library itself.
271 |
272 | 6. As an exception to the Sections above, you may also combine or
273 | link a "work that uses the Library" with the Library to produce a
274 | work containing portions of the Library, and distribute that work
275 | under terms of your choice, provided that the terms permit
276 | modification of the work for the customer's own use and reverse
277 | engineering for debugging such modifications.
278 |
279 | You must give prominent notice with each copy of the work that the
280 | Library is used in it and that the Library and its use are covered by
281 | this License. You must supply a copy of this License. If the work
282 | during execution displays copyright notices, you must include the
283 | copyright notice for the Library among them, as well as a reference
284 | directing the user to the copy of this License. Also, you must do one
285 | of these things:
286 |
287 | a) Accompany the work with the complete corresponding
288 | machine-readable source code for the Library including whatever
289 | changes were used in the work (which must be distributed under
290 | Sections 1 and 2 above); and, if the work is an executable linked
291 | with the Library, with the complete machine-readable "work that
292 | uses the Library", as object code and/or source code, so that the
293 | user can modify the Library and then relink to produce a modified
294 | executable containing the modified Library. (It is understood
295 | that the user who changes the contents of definitions files in the
296 | Library will not necessarily be able to recompile the application
297 | to use the modified definitions.)
298 |
299 | b) Use a suitable shared library mechanism for linking with the
300 | Library. A suitable mechanism is one that (1) uses at run time a
301 | copy of the library already present on the user's computer system,
302 | rather than copying library functions into the executable, and (2)
303 | will operate properly with a modified version of the library, if
304 | the user installs one, as long as the modified version is
305 | interface-compatible with the version that the work was made with.
306 |
307 | c) Accompany the work with a written offer, valid for at
308 | least three years, to give the same user the materials
309 | specified in Subsection 6a, above, for a charge no more
310 | than the cost of performing this distribution.
311 |
312 | d) If distribution of the work is made by offering access to copy
313 | from a designated place, offer equivalent access to copy the above
314 | specified materials from the same place.
315 |
316 | e) Verify that the user has already received a copy of these
317 | materials or that you have already sent this user a copy.
318 |
319 | For an executable, the required form of the "work that uses the
320 | Library" must include any data and utility programs needed for
321 | reproducing the executable from it. However, as a special exception,
322 | the materials to be distributed need not include anything that is
323 | normally distributed (in either source or binary form) with the major
324 | components (compiler, kernel, and so on) of the operating system on
325 | which the executable runs, unless that component itself accompanies
326 | the executable.
327 |
328 | It may happen that this requirement contradicts the license
329 | restrictions of other proprietary libraries that do not normally
330 | accompany the operating system. Such a contradiction means you cannot
331 | use both them and the Library together in an executable that you
332 | distribute.
333 |
334 | 7. You may place library facilities that are a work based on the
335 | Library side-by-side in a single library together with other library
336 | facilities not covered by this License, and distribute such a combined
337 | library, provided that the separate distribution of the work based on
338 | the Library and of the other library facilities is otherwise
339 | permitted, and provided that you do these two things:
340 |
341 | a) Accompany the combined library with a copy of the same work
342 | based on the Library, uncombined with any other library
343 | facilities. This must be distributed under the terms of the
344 | Sections above.
345 |
346 | b) Give prominent notice with the combined library of the fact
347 | that part of it is a work based on the Library, and explaining
348 | where to find the accompanying uncombined form of the same work.
349 |
350 | 8. You may not copy, modify, sublicense, link with, or distribute
351 | the Library except as expressly provided under this License. Any
352 | attempt otherwise to copy, modify, sublicense, link with, or
353 | distribute the Library is void, and will automatically terminate your
354 | rights under this License. However, parties who have received copies,
355 | or rights, from you under this License will not have their licenses
356 | terminated so long as such parties remain in full compliance.
357 |
358 | 9. You are not required to accept this License, since you have not
359 | signed it. However, nothing else grants you permission to modify or
360 | distribute the Library or its derivative works. These actions are
361 | prohibited by law if you do not accept this License. Therefore, by
362 | modifying or distributing the Library (or any work based on the
363 | Library), you indicate your acceptance of this License to do so, and
364 | all its terms and conditions for copying, distributing or modifying
365 | the Library or works based on it.
366 |
367 | 10. Each time you redistribute the Library (or any work based on the
368 | Library), the recipient automatically receives a license from the
369 | original licensor to copy, distribute, link with or modify the Library
370 | subject to these terms and conditions. You may not impose any further
371 | restrictions on the recipients' exercise of the rights granted herein.
372 | You are not responsible for enforcing compliance by third parties with
373 | this License.
374 |
375 | 11. If, as a consequence of a court judgment or allegation of patent
376 | infringement or for any other reason (not limited to patent issues),
377 | conditions are imposed on you (whether by court order, agreement or
378 | otherwise) that contradict the conditions of this License, they do not
379 | excuse you from the conditions of this License. If you cannot
380 | distribute so as to satisfy simultaneously your obligations under this
381 | License and any other pertinent obligations, then as a consequence you
382 | may not distribute the Library at all. For example, if a patent
383 | license would not permit royalty-free redistribution of the Library by
384 | all those who receive copies directly or indirectly through you, then
385 | the only way you could satisfy both it and this License would be to
386 | refrain entirely from distribution of the Library.
387 |
388 | If any portion of this section is held invalid or unenforceable under any
389 | particular circumstance, the balance of the section is intended to apply,
390 | and the section as a whole is intended to apply in other circumstances.
391 |
392 | It is not the purpose of this section to induce you to infringe any
393 | patents or other property right claims or to contest validity of any
394 | such claims; this section has the sole purpose of protecting the
395 | integrity of the free software distribution system which is
396 | implemented by public license practices. Many people have made
397 | generous contributions to the wide range of software distributed
398 | through that system in reliance on consistent application of that
399 | system; it is up to the author/donor to decide if he or she is willing
400 | to distribute software through any other system and a licensee cannot
401 | impose that choice.
402 |
403 | This section is intended to make thoroughly clear what is believed to
404 | be a consequence of the rest of this License.
405 |
406 | 12. If the distribution and/or use of the Library is restricted in
407 | certain countries either by patents or by copyrighted interfaces, the
408 | original copyright holder who places the Library under this License may add
409 | an explicit geographical distribution limitation excluding those countries,
410 | so that distribution is permitted only in or among countries not thus
411 | excluded. In such case, this License incorporates the limitation as if
412 | written in the body of this License.
413 |
414 | 13. The Free Software Foundation may publish revised and/or new
415 | versions of the Lesser General Public License from time to time.
416 | Such new versions will be similar in spirit to the present version,
417 | but may differ in detail to address new problems or concerns.
418 |
419 | Each version is given a distinguishing version number. If the Library
420 | specifies a version number of this License which applies to it and
421 | "any later version", you have the option of following the terms and
422 | conditions either of that version or of any later version published by
423 | the Free Software Foundation. If the Library does not specify a
424 | license version number, you may choose any version ever published by
425 | the Free Software Foundation.
426 |
427 | 14. If you wish to incorporate parts of the Library into other free
428 | programs whose distribution conditions are incompatible with these,
429 | write to the author to ask for permission. For software which is
430 | copyrighted by the Free Software Foundation, write to the Free
431 | Software Foundation; we sometimes make exceptions for this. Our
432 | decision will be guided by the two goals of preserving the free status
433 | of all derivatives of our free software and of promoting the sharing
434 | and reuse of software generally.
435 |
436 | NO WARRANTY
437 |
438 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
439 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
440 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
441 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
442 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
443 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
444 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
445 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
446 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
447 |
448 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
449 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
450 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
451 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
452 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
453 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
454 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
455 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
456 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
457 | DAMAGES.
458 |
459 |
--------------------------------------------------------------------------------
/samples/sysex/BLEFirmataWithLedBlink/BLEFirmataWithLedBlink.ino:
--------------------------------------------------------------------------------
1 | /*
2 | * BLEFirmataSketch
3 | *
4 | * This sketch is for the BLE Arduino App
5 | * It is a modified version of the Standard Firmata
6 | * sketch by adding support for BLE.
7 | *
8 | */
9 |
10 | #define BLE_NAME "BlendMicro"
11 |
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include "BLEFirmata.h"
17 | #include
18 |
19 | /*
20 | * Firmata is a generic protocol for communicating with microcontrollers
21 | * from software on a host computer. It is intended to work with
22 | * any host computer software package.
23 | *
24 | * To download a host software package, please clink on the following link
25 | * to open the download page in your default browser.
26 | *
27 | * http://firmata.org/wiki/Download
28 | */
29 |
30 | /*
31 | Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved.
32 | Copyright (C) 2010-2011 Paul Stoffregen. All rights reserved.
33 | Copyright (C) 2009 Shigeru Kobayashi. All rights reserved.
34 | Copyright (C) 2009-2011 Jeff Hoefs. All rights reserved.
35 |
36 | This library is free software; you can redistribute it and/or
37 | modify it under the terms of the GNU Lesser General Public
38 | License as published by the Free Software Foundation; either
39 | version 2.1 of the License, or (at your option) any later version.
40 |
41 | See file LICENSE.txt for further informations on licensing terms.
42 |
43 | formatted using the GNU C formatting and indenting
44 | */
45 |
46 | /*
47 | * TODO: use Program Control to load stored profiles from EEPROM
48 | */
49 |
50 | // move the following defines to Firmata.h?
51 | #define I2C_WRITE B00000000
52 | #define I2C_READ B00001000
53 | #define I2C_READ_CONTINUOUSLY B00010000
54 | #define I2C_STOP_READING B00011000
55 | #define I2C_READ_WRITE_MODE_MASK B00011000
56 | #define I2C_10BIT_ADDRESS_MODE_MASK B00100000
57 |
58 | #define MAX_QUERIES 8
59 | #define MINIMUM_SAMPLING_INTERVAL 10
60 |
61 | #define REGISTER_NOT_SPECIFIED -1
62 |
63 | /*==============================================================================
64 | * GLOBAL VARIABLES
65 | *============================================================================*/
66 |
67 | /* analog inputs */
68 | int analogInputsToReport = 0; // bitwise array to store pin reporting
69 |
70 | /* digital input ports */
71 | byte reportPINs[TOTAL_PORTS]; // 1 = report this port, 0 = silence
72 | byte previousPINs[TOTAL_PORTS]; // previous 8 bits sent
73 |
74 | /* pins configuration */
75 | byte pinConfig[TOTAL_PINS]; // configuration of every pin
76 | byte portConfigInputs[TOTAL_PORTS]; // each bit: 1 = pin in INPUT, 0 = anything else
77 | int pinState[TOTAL_PINS]; // any value that has been written
78 |
79 | /* timer variables */
80 | unsigned long currentMillis; // store the current value from millis()
81 | unsigned long previousMillis; // for comparison with currentMillis
82 | int samplingInterval = 38; // how often to run the main loop (in ms)
83 |
84 | /* i2c data */
85 | struct i2c_device_info {
86 | byte addr;
87 | byte reg;
88 | byte bytes;
89 | };
90 |
91 | /* for i2c read continuous more */
92 | i2c_device_info query[MAX_QUERIES];
93 |
94 | byte i2cRxData[32];
95 | boolean isI2CEnabled = false;
96 | signed char queryIndex = -1;
97 | unsigned int i2cReadDelayTime = 0; // default delay time between i2c read request and Wire.requestFrom()
98 |
99 | Servo servos[MAX_SERVOS];
100 | /*==============================================================================
101 | * FUNCTIONS
102 | *============================================================================*/
103 |
104 | void readAndReportData(byte address, int theRegister, byte numBytes) {
105 | // allow I2C requests that don't require a register read
106 | // for example, some devices using an interrupt pin to signify new data available
107 | // do not always require the register read so upon interrupt you call Wire.requestFrom()
108 | if (theRegister != REGISTER_NOT_SPECIFIED) {
109 | Wire.beginTransmission(address);
110 | #if ARDUINO >= 100
111 | Wire.write((byte)theRegister);
112 | #else
113 | Wire.send((byte)theRegister);
114 | #endif
115 | Wire.endTransmission();
116 | delayMicroseconds(i2cReadDelayTime); // delay is necessary for some devices such as WiiNunchuck
117 | } else {
118 | theRegister = 0; // fill the register with a dummy value
119 | }
120 |
121 | Wire.requestFrom(address, numBytes); // all bytes are returned in requestFrom
122 |
123 | // check to be sure correct number of bytes were returned by slave
124 | if(numBytes == Wire.available()) {
125 | i2cRxData[0] = address;
126 | i2cRxData[1] = theRegister;
127 | for (int i = 0; i < numBytes; i++) {
128 | #if ARDUINO >= 100
129 | i2cRxData[2 + i] = Wire.read();
130 | #else
131 | i2cRxData[2 + i] = Wire.receive();
132 | #endif
133 | }
134 | }
135 | else {
136 | if(numBytes > Wire.available()) {
137 | BleFirmata.sendString("I2C Read Error: Too many bytes received");
138 | } else {
139 | BleFirmata.sendString("I2C Read Error: Too few bytes received");
140 | }
141 | }
142 |
143 | // send slave address, register and received bytes
144 | BleFirmata.sendSysex(SYSEX_I2C_REPLY, numBytes + 2, i2cRxData);
145 | }
146 |
147 | void outputPort(byte portNumber, byte portValue, byte forceSend)
148 | {
149 | // pins not configured as INPUT are cleared to zeros
150 | portValue = portValue & portConfigInputs[portNumber];
151 |
152 | // only send if the value is different than previously sent
153 | if(forceSend || previousPINs[portNumber] != portValue) {
154 | BleFirmata.sendDigitalPort(portNumber, portValue);
155 | previousPINs[portNumber] = portValue;
156 | }
157 | }
158 |
159 | /* -----------------------------------------------------------------------------
160 | * check all the active digital inputs for change of state, then add any events
161 | * to the Serial output queue using Serial.print() */
162 | void checkDigitalInputs(void)
163 | {
164 | /* Using non-looping code allows constants to be given to readPort().
165 | * The compiler will apply substantial optimizations if the inputs
166 | * to readPort() are compile-time constants. */
167 | if (TOTAL_PORTS > 0 && reportPINs[0]) outputPort(0, readPort(0, portConfigInputs[0]), false);
168 | if (TOTAL_PORTS > 1 && reportPINs[1]) outputPort(1, readPort(1, portConfigInputs[1]), false);
169 | if (TOTAL_PORTS > 2 && reportPINs[2]) outputPort(2, readPort(2, portConfigInputs[2]), false);
170 | if (TOTAL_PORTS > 3 && reportPINs[3]) outputPort(3, readPort(3, portConfigInputs[3]), false);
171 | if (TOTAL_PORTS > 4 && reportPINs[4]) outputPort(4, readPort(4, portConfigInputs[4]), false);
172 | if (TOTAL_PORTS > 5 && reportPINs[5]) outputPort(5, readPort(5, portConfigInputs[5]), false);
173 | if (TOTAL_PORTS > 6 && reportPINs[6]) outputPort(6, readPort(6, portConfigInputs[6]), false);
174 | if (TOTAL_PORTS > 7 && reportPINs[7]) outputPort(7, readPort(7, portConfigInputs[7]), false);
175 | if (TOTAL_PORTS > 8 && reportPINs[8]) outputPort(8, readPort(8, portConfigInputs[8]), false);
176 | if (TOTAL_PORTS > 9 && reportPINs[9]) outputPort(9, readPort(9, portConfigInputs[9]), false);
177 | if (TOTAL_PORTS > 10 && reportPINs[10]) outputPort(10, readPort(10, portConfigInputs[10]), false);
178 | if (TOTAL_PORTS > 11 && reportPINs[11]) outputPort(11, readPort(11, portConfigInputs[11]), false);
179 | if (TOTAL_PORTS > 12 && reportPINs[12]) outputPort(12, readPort(12, portConfigInputs[12]), false);
180 | if (TOTAL_PORTS > 13 && reportPINs[13]) outputPort(13, readPort(13, portConfigInputs[13]), false);
181 | if (TOTAL_PORTS > 14 && reportPINs[14]) outputPort(14, readPort(14, portConfigInputs[14]), false);
182 | if (TOTAL_PORTS > 15 && reportPINs[15]) outputPort(15, readPort(15, portConfigInputs[15]), false);
183 | }
184 |
185 | // -----------------------------------------------------------------------------
186 | /* sets the pin mode to the correct state and sets the relevant bits in the
187 | * two bit-arrays that track Digital I/O and PWM status
188 | */
189 | void setPinModeCallback(byte pin, int mode)
190 | {
191 | if (pinConfig[pin] == I2C && isI2CEnabled && mode != I2C) {
192 | // disable i2c so pins can be used for other functions
193 | // the following if statements should reconfigure the pins properly
194 | disableI2CPins();
195 | }
196 | if (IS_PIN_SERVO(pin) && mode != SERVO && servos[PIN_TO_SERVO(pin)].attached()) {
197 | servos[PIN_TO_SERVO(pin)].detach();
198 | }
199 | if (IS_PIN_ANALOG(pin)) {
200 | reportAnalogCallback(PIN_TO_ANALOG(pin), mode == ANALOG ? 1 : 0); // turn on/off reporting
201 | }
202 | if (IS_PIN_DIGITAL(pin)) {
203 | if (mode == INPUT) {
204 | portConfigInputs[pin/8] |= (1 << (pin & 7));
205 | } else {
206 | portConfigInputs[pin/8] &= ~(1 << (pin & 7));
207 | }
208 | }
209 | pinState[pin] = 0;
210 | switch(mode) {
211 | case ANALOG:
212 | if (IS_PIN_ANALOG(pin)) {
213 | if (IS_PIN_DIGITAL(pin)) {
214 | pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
215 | digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
216 | }
217 | pinConfig[pin] = ANALOG;
218 | }
219 | break;
220 | case INPUT:
221 | if (IS_PIN_DIGITAL(pin)) {
222 | pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver
223 |
224 | // Select your internal pull-up here
225 | digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups
226 | //digitalWrite(PIN_TO_DIGITAL(pin), HIGH); // enable internal pull-ups if you have only a wire to test
227 | pinConfig[pin] = INPUT;
228 |
229 | // hack it only
230 | reportPINs[pin/8] |= (1 << (pin & 7));
231 | }
232 | break;
233 | case OUTPUT:
234 | if (IS_PIN_DIGITAL(pin)) {
235 | digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable PWM
236 | pinMode(PIN_TO_DIGITAL(pin), OUTPUT);
237 | pinConfig[pin] = OUTPUT;
238 | }
239 | break;
240 | case PWM:
241 | if (IS_PIN_PWM(pin)) {
242 | pinMode(PIN_TO_PWM(pin), OUTPUT);
243 | analogWrite(PIN_TO_PWM(pin), 0);
244 | pinConfig[pin] = PWM;
245 | }
246 | break;
247 | case SERVO:
248 | if (IS_PIN_SERVO(pin)) {
249 | pinConfig[pin] = SERVO;
250 | if (!servos[PIN_TO_SERVO(pin)].attached()) {
251 | servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin));
252 | }
253 | }
254 | break;
255 | case I2C:
256 | if (IS_PIN_I2C(pin)) {
257 | // mark the pin as i2c
258 | // the user must call I2C_CONFIG to enable I2C for a device
259 | pinConfig[pin] = I2C;
260 | }
261 | break;
262 | default:
263 | BleFirmata.sendString("Unknown pin mode"); // TODO: put error msgs in EEPROM
264 | }
265 | // TODO: save status to EEPROM here, if changed
266 | }
267 |
268 | void analogWriteCallback(byte pin, int value)
269 | {
270 | if (pin < TOTAL_PINS) {
271 | switch(pinConfig[pin]) {
272 | case SERVO:
273 | if (IS_PIN_SERVO(pin))
274 | servos[PIN_TO_SERVO(pin)].write(value);
275 | pinState[pin] = value;
276 | break;
277 | case PWM:
278 | if (IS_PIN_PWM(pin))
279 | analogWrite(PIN_TO_PWM(pin), value);
280 | pinState[pin] = value;
281 | break;
282 | }
283 | }
284 | }
285 |
286 | void digitalWriteCallback(byte port, int value)
287 | {
288 | byte pin, lastPin, mask=1, pinWriteMask=0;
289 |
290 | if (port < TOTAL_PORTS) {
291 | // create a mask of the pins on this port that are writable.
292 | lastPin = port*8+8;
293 | if (lastPin > TOTAL_PINS) lastPin = TOTAL_PINS;
294 | for (pin=port*8; pin < lastPin; pin++) {
295 | // do not disturb non-digital pins (eg, Rx & Tx)
296 | if (IS_PIN_DIGITAL(pin)) {
297 | // only write to OUTPUT and INPUT (enables pullup)
298 | // do not touch pins in PWM, ANALOG, SERVO or other modes
299 | if (pinConfig[pin] == OUTPUT || pinConfig[pin] == INPUT) {
300 | pinWriteMask |= mask;
301 | pinState[pin] = ((byte)value & mask) ? 1 : 0;
302 | }
303 | }
304 | mask = mask << 1;
305 | }
306 | writePort(port, (byte)value, pinWriteMask);
307 | }
308 | }
309 |
310 |
311 | // -----------------------------------------------------------------------------
312 | /* sets bits in a bit array (int) to toggle the reporting of the analogIns
313 | */
314 | //void FirmataClass::setAnalogPinReporting(byte pin, byte state) {
315 | //}
316 | void reportAnalogCallback(byte analogPin, int value)
317 | {
318 | if (analogPin < TOTAL_ANALOG_PINS) {
319 | if(value == 0) {
320 | analogInputsToReport = analogInputsToReport &~ (1 << analogPin);
321 | } else {
322 | analogInputsToReport = analogInputsToReport | (1 << analogPin);
323 | }
324 | }
325 | // TODO: save status to EEPROM here, if changed
326 | }
327 |
328 | void reportDigitalCallback(byte port, int value)
329 | {
330 | if (port < TOTAL_PORTS) {
331 | reportPINs[port] = (byte)value;
332 | }
333 | // do not disable analog reporting on these 8 pins, to allow some
334 | // pins used for digital, others analog. Instead, allow both types
335 | // of reporting to be enabled, but check if the pin is configured
336 | // as analog when sampling the analog inputs. Likewise, while
337 | // scanning digital pins, portConfigInputs will mask off values from any
338 | // pins configured as analog
339 | }
340 |
341 | /*==============================================================================
342 | * SYSEX-BASED commands
343 | *============================================================================*/
344 |
345 | void sysexCallback(byte command, byte argc, byte *argv)
346 | {
347 | byte mode;
348 | byte slaveAddress;
349 | byte slaveRegister;
350 | byte data;
351 | unsigned int delayTime;
352 |
353 | switch(command) {
354 | case 0x01: // LED Blink Command
355 | if(argc < 3) break;
356 | byte blink_pin;
357 | byte blink_count;
358 | blink_pin = argv[0];
359 | blink_count = argv[1];
360 | delayTime = argv[2] * 100;
361 | pinMode(blink_pin, OUTPUT);
362 | byte i;
363 | for(i = 0; i < blink_count; i++){
364 | digitalWrite(blink_pin, true);
365 | delay(delayTime);
366 | digitalWrite(blink_pin, false);
367 | delay(delayTime);
368 | }
369 | BleFirmata.sendSysex(command, argc, argv); // callback
370 | break;
371 | case I2C_REQUEST:
372 | mode = argv[1] & I2C_READ_WRITE_MODE_MASK;
373 | if (argv[1] & I2C_10BIT_ADDRESS_MODE_MASK) {
374 | BleFirmata.sendString("10-bit addressing mode is not yet supported");
375 | return;
376 | }
377 | else {
378 | slaveAddress = argv[0];
379 | }
380 |
381 | switch(mode) {
382 | case I2C_WRITE:
383 | Wire.beginTransmission(slaveAddress);
384 | for (byte i = 2; i < argc; i += 2) {
385 | data = argv[i] + (argv[i + 1] << 7);
386 | #if ARDUINO >= 100
387 | Wire.write(data);
388 | #else
389 | Wire.send(data);
390 | #endif
391 | }
392 | Wire.endTransmission();
393 | delayMicroseconds(70);
394 | break;
395 | case I2C_READ:
396 | if (argc == 6) {
397 | // a slave register is specified
398 | slaveRegister = argv[2] + (argv[3] << 7);
399 | data = argv[4] + (argv[5] << 7); // bytes to read
400 | readAndReportData(slaveAddress, (int)slaveRegister, data);
401 | }
402 | else {
403 | // a slave register is NOT specified
404 | data = argv[2] + (argv[3] << 7); // bytes to read
405 | readAndReportData(slaveAddress, (int)REGISTER_NOT_SPECIFIED, data);
406 | }
407 | break;
408 | case I2C_READ_CONTINUOUSLY:
409 | if ((queryIndex + 1) >= MAX_QUERIES) {
410 | // too many queries, just ignore
411 | BleFirmata.sendString("too many queries");
412 | break;
413 | }
414 | queryIndex++;
415 | query[queryIndex].addr = slaveAddress;
416 | query[queryIndex].reg = argv[2] + (argv[3] << 7);
417 | query[queryIndex].bytes = argv[4] + (argv[5] << 7);
418 | break;
419 | case I2C_STOP_READING:
420 | byte queryIndexToSkip;
421 | // if read continuous mode is enabled for only 1 i2c device, disable
422 | // read continuous reporting for that device
423 | if (queryIndex <= 0) {
424 | queryIndex = -1;
425 | } else {
426 | // if read continuous mode is enabled for multiple devices,
427 | // determine which device to stop reading and remove it's data from
428 | // the array, shifiting other array data to fill the space
429 | for (byte i = 0; i < queryIndex + 1; i++) {
430 | if (query[i].addr = slaveAddress) {
431 | queryIndexToSkip = i;
432 | break;
433 | }
434 | }
435 |
436 | for (byte i = queryIndexToSkip; i 0) {
454 | i2cReadDelayTime = delayTime;
455 | }
456 |
457 | if (!isI2CEnabled) {
458 | enableI2CPins();
459 | }
460 |
461 | break;
462 | case SERVO_CONFIG:
463 | if(argc > 4) {
464 | // these vars are here for clarity, they'll optimized away by the compiler
465 | byte pin = argv[0];
466 | int minPulse = argv[1] + (argv[2] << 7);
467 | int maxPulse = argv[3] + (argv[4] << 7);
468 |
469 | if (IS_PIN_SERVO(pin)) {
470 | if (servos[PIN_TO_SERVO(pin)].attached())
471 | servos[PIN_TO_SERVO(pin)].detach();
472 | servos[PIN_TO_SERVO(pin)].attach(PIN_TO_DIGITAL(pin), minPulse, maxPulse);
473 | setPinModeCallback(pin, SERVO);
474 | }
475 | }
476 | break;
477 | case SAMPLING_INTERVAL:
478 | if (argc > 1) {
479 | samplingInterval = argv[0] + (argv[1] << 7);
480 | if (samplingInterval < MINIMUM_SAMPLING_INTERVAL) {
481 | samplingInterval = MINIMUM_SAMPLING_INTERVAL;
482 | }
483 | } else {
484 | //Firmata.sendString("Not enough data");
485 | }
486 | break;
487 | case EXTENDED_ANALOG:
488 | if (argc > 1) {
489 | int val = argv[1];
490 | if (argc > 2) val |= (argv[2] << 7);
491 | if (argc > 3) val |= (argv[3] << 14);
492 | analogWriteCallback(argv[0], val);
493 | }
494 | break;
495 | case CAPABILITY_QUERY:
496 | ble_write(START_SYSEX);
497 | ble_write(CAPABILITY_RESPONSE);
498 | for (byte pin=0; pin < TOTAL_PINS; pin++) {
499 | if (IS_PIN_DIGITAL(pin)) {
500 | ble_write((byte)INPUT);
501 | ble_write(1);
502 | ble_write((byte)OUTPUT);
503 | ble_write(1);
504 | }
505 | if (IS_PIN_ANALOG(pin)) {
506 | ble_write(ANALOG);
507 | ble_write(10);
508 | }
509 | if (IS_PIN_PWM(pin)) {
510 | ble_write(PWM);
511 | ble_write(8);
512 | }
513 | if (IS_PIN_SERVO(pin)) {
514 | ble_write(SERVO);
515 | ble_write(14);
516 | }
517 | if (IS_PIN_I2C(pin)) {
518 | ble_write(I2C);
519 | ble_write(1); // to do: determine appropriate value
520 | }
521 | ble_write(127);
522 | }
523 | ble_write(END_SYSEX);
524 | break;
525 | case PIN_STATE_QUERY:
526 | if (argc > 0) {
527 | byte pin=argv[0];
528 | ble_write(START_SYSEX);
529 | ble_write(PIN_STATE_RESPONSE);
530 | ble_write(pin);
531 | if (pin < TOTAL_PINS) {
532 | ble_write((byte)pinConfig[pin]);
533 | ble_write((byte)pinState[pin] & 0x7F);
534 | if (pinState[pin] & 0xFF80) ble_write((byte)(pinState[pin] >> 7) & 0x7F);
535 | if (pinState[pin] & 0xC000) ble_write((byte)(pinState[pin] >> 14) & 0x7F);
536 | }
537 | ble_write(END_SYSEX);
538 | }
539 | break;
540 | case ANALOG_MAPPING_QUERY:
541 | ble_write(START_SYSEX);
542 | ble_write(ANALOG_MAPPING_RESPONSE);
543 | for (byte pin=0; pin < TOTAL_PINS; pin++) {
544 | ble_write(IS_PIN_ANALOG(pin) ? PIN_TO_ANALOG(pin) : 127);
545 | }
546 | ble_write(END_SYSEX);
547 | break;
548 | }
549 | }
550 |
551 | void enableI2CPins()
552 | {
553 | byte i;
554 | // is there a faster way to do this? would probaby require importing
555 | // Arduino.h to get SCL and SDA pins
556 | for (i=0; i < TOTAL_PINS; i++) {
557 | if(IS_PIN_I2C(i)) {
558 | // mark pins as i2c so they are ignore in non i2c data requests
559 | setPinModeCallback(i, I2C);
560 | }
561 | }
562 |
563 | isI2CEnabled = true;
564 |
565 | // is there enough time before the first I2C request to call this here?
566 | Wire.begin();
567 | }
568 |
569 | /* disable the i2c pins so they can be used for other functions */
570 | void disableI2CPins() {
571 | isI2CEnabled = false;
572 | // disable read continuous mode for all devices
573 | queryIndex = -1;
574 | // uncomment the following if or when the end() method is added to Wire library
575 | // Wire.end();
576 | }
577 |
578 | /*==============================================================================
579 | * SETUP()
580 | *============================================================================*/
581 |
582 | void systemResetCallback()
583 | {
584 | // initialize a defalt state
585 | // TODO: option to load config from EEPROM instead of default
586 | if (isI2CEnabled) {
587 | disableI2CPins();
588 | }
589 | for (byte i=0; i < TOTAL_PORTS; i++) {
590 | reportPINs[i] = false; // by default, reporting off
591 | portConfigInputs[i] = 0; // until activated
592 | previousPINs[i] = 0;
593 | }
594 | // pins with analog capability default to analog input
595 | // otherwise, pins default to digital output
596 | for (byte i=0; i < TOTAL_PINS; i++) {
597 |
598 | // skip pin 8, 9 for BLE Shield
599 | //if ((i == 8) || (i == 9))
600 | // continue;
601 |
602 | // skip pin 4, 6, 7 for BlendMicro BLE controll
603 | if ((i == 4) || (i == 6) || (i == 7))
604 | continue;
605 |
606 | // skip SPI pins
607 | if ( (i==MOSI) || (i==MISO) || (i==SCK) || (i==SS) )
608 | continue;
609 |
610 | // Default all to digital pins
611 | if (IS_PIN_ANALOG(i)) {
612 | // turns off pullup, configures everything
613 | setPinModeCallback(i, ANALOG);
614 | } else {
615 | // sets the output to 0, configures portConfigInputs
616 | //setPinModeCallback(i, OUTPUT);
617 | }
618 | }
619 | // by default, do not report any analog inputs
620 | analogInputsToReport = 0;
621 |
622 | /* send digital inputs to set the initial state on the host computer,
623 | * since once in the loop(), this firmware will only send on change */
624 | /*
625 | TODO: this can never execute, since no pins default to digital input
626 | but it will be needed when/if we support EEPROM stored config
627 | for (byte i=0; i < TOTAL_PORTS; i++) {
628 | outputPort(i, readPort(i, portConfigInputs[i]), true);
629 | }
630 | */
631 | }
632 |
633 | void setup()
634 | {
635 | BleFirmata.setFirmwareVersion(FIRMATA_MAJOR_VERSION, FIRMATA_MINOR_VERSION);
636 |
637 | BleFirmata.attach(ANALOG_MESSAGE, analogWriteCallback);
638 | BleFirmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);
639 | BleFirmata.attach(REPORT_ANALOG, reportAnalogCallback);
640 | BleFirmata.attach(REPORT_DIGITAL, reportDigitalCallback);
641 | BleFirmata.attach(SET_PIN_MODE, setPinModeCallback);
642 | BleFirmata.attach(START_SYSEX, sysexCallback);
643 | BleFirmata.attach(SYSTEM_RESET, systemResetCallback);
644 |
645 | // BleFirmata.begin(57600);
646 | systemResetCallback(); // reset to default config
647 |
648 | // Enable serial debug
649 | Serial.begin(57600);
650 |
651 | // Default pins set to 9 and 8 for REQN and RDYN
652 | // Set your REQN and RDYN here before ble_begin() if you need
653 | //ble_set_pins(3, 2);
654 |
655 | // Set your BLE Shield name here, max. length 10
656 | ble_set_name(BLE_NAME);
657 |
658 | // Init. BLE and start BLE library.
659 | ble_begin();
660 | }
661 |
662 | /*==============================================================================
663 | * LOOP()
664 | *============================================================================*/
665 | void loop()
666 | {
667 | byte pin, analogPin;
668 |
669 | /* DIGITALREAD - as fast as possible, check for changes and output them to the
670 | * FTDI buffer using Serial.print() */
671 | checkDigitalInputs();
672 |
673 | /* SERIALREAD - processing incoming messagse as soon as possible, while still
674 | * checking digital inputs. */
675 | while(BleFirmata.available())
676 | BleFirmata.processInput();
677 |
678 | /* SEND FTDI WRITE BUFFER - make sure that the FTDI buffer doesn't go over
679 | * 60 bytes. use a timer to sending an event character every 4 ms to
680 | * trigger the buffer to dump. */
681 |
682 | currentMillis = millis();
683 | if (currentMillis - previousMillis > samplingInterval) {
684 | previousMillis += samplingInterval;
685 | /* ANALOGREAD - do all analogReads() at the configured sampling interval */
686 | for(pin=0; pin -1) {
699 | for (byte i = 0; i < queryIndex + 1; i++) {
700 | readAndReportData(query[i].addr, query[i].reg, query[i].bytes);
701 | }
702 | }
703 | }
704 |
705 | if (!ble_connected())
706 | systemResetCallback();
707 |
708 | ble_do_events();
709 | }
710 |
711 |
--------------------------------------------------------------------------------