Skip to content

Commit

Permalink
queryPinState
Browse files Browse the repository at this point in the history
  • Loading branch information
nfrancois committed Apr 11, 2015
1 parent e23d93f commit ea6edc5
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 11 deletions.
4 changes: 2 additions & 2 deletions lib/src/firmata_internal.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ const int ANALOG_MESSAGE = 0xE0;
//const int EXTENDED_ANALOG = 0x6F;
const int CAPABILITY_QUERY = 0x6B;
const int CAPABILITY_RESPONSE = 0x6C;
//const int PIN_STATE_QUERY = 0x6D;
//const int PIN_STATE_RESPONSE = 0x6E;
const int PIN_STATE_QUERY = 0x6D;
const int PIN_STATE_RESPONSE = 0x6E;
const int ANALOG_MAPPING_QUERY = 0x69;
const int ANALOG_MAPPING_RESPONSE = 0x6A;
const int SERVO_CONFIG = 0x70;
Expand Down
10 changes: 9 additions & 1 deletion lib/src/internal/board.dart
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ abstract class Board {
/// Asks the arduino to tell us its analog pin mapping
Future queryAnalogMapping();

/// Asks the arduino to tell the state of a pin
Future queryPinState(int pin);

/// Close the connection
Future close();

Expand Down Expand Up @@ -126,6 +129,7 @@ class BoardImpl implements Board {
Stream<PinState> _analogReadStream;
Stream<Map<int, List<int>>> _capabilityStream;
Stream<List<int>> _analogMappingStream;
Stream<PinState> _pinStateStream;
final Map<int, int> _pins = {};
final SysexParser _parser = new SysexParser();
final List<int> _digitalOutputData = new List.filled(16, 0);
Expand All @@ -141,6 +145,7 @@ class BoardImpl implements Board {
_firmataVersionStream = _parser.onFirmataVersion.asBroadcastStream();
_analogMappingStream = _parser.onAnalogMapping.asBroadcastStream();
_capabilityStream = _parser.onCapability.asBroadcastStream();
_pinStateStream = _parser.onPinState.asBroadcastStream();
}

Future open() async {
Expand Down Expand Up @@ -193,7 +198,10 @@ class BoardImpl implements Board {
return _firmataVersionStream.first;
}

//Future<bool> queryPinState(int pin) => sendSysex( PIN_STATE_QUERY, [pin]);
Future<PinState> queryPinState(int pin) {
sendSysex( PIN_STATE_QUERY, [pin]);
return _pinStateStream.first;
}

Future queryCapability() {
sendSysex(CAPABILITY_QUERY);
Expand Down
21 changes: 19 additions & 2 deletions lib/src/internal/sysex_parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

part of firmata_internal;

enum ParserAnalyse { NONE, REPORT_VERSION, DIGITAL_MESSAGE, ANALOG_MESSAGE, ANALOG_MAPPING, CAPACITY}
enum ParserAnalyse { NONE, REPORT_VERSION, DIGITAL_MESSAGE, ANALOG_MESSAGE, ANALOG_MAPPING, CAPACITY, PIN_STATE}

/// Parser which read message sent from arduino
class SysexParser {
Expand All @@ -24,6 +24,7 @@ class SysexParser {
final _analogMessageController = new StreamController<Map<int, int>>();
final _analogMappingController = new StreamController<List<int>>();
final _capabilityController = new StreamController<Map<int, List<int>>>();
final _pinStateController = new StreamController<PinState>();
final List<int> _buffer = [];
int _currentAnalyse = 0;
bool hasReceiveVersion;
Expand All @@ -43,8 +44,9 @@ class SysexParser {
|| (hasReceiveVersion && (byte == DIGITAL_MESSAGE ||
(byte >= ANALOG_MESSAGE && byte <= ANALOG_MESSAGE+0x0F)) ||
(byte == QUERY_FIRMWARE) ||
(byte == CAPABILITY_RESPONSE) ||
(byte == ANALOG_MAPPING_RESPONSE) ||
(byte == CAPABILITY_RESPONSE)
(byte == PIN_STATE_RESPONSE)
)
){
_currentAnalyse = byte;
Expand All @@ -71,6 +73,9 @@ class SysexParser {
} else if(_currentAnalyse == CAPABILITY_RESPONSE && byte == END_SYSEX){
_decodeCapability(_buffer);
_reset();
} else if(_currentAnalyse == PIN_STATE_RESPONSE && byte == END_SYSEX){
_decodePinState(_buffer);
_reset();
}
}
}
Expand Down Expand Up @@ -132,6 +137,16 @@ class SysexParser {
_capabilityController.add(capabilities);
}

void _decodePinState(List<int> message){
int pin = message[1];
List<int> valueAsBytes = message.getRange(3, message.length-1).toList();
var value = 0;
for(int i=0; i<valueAsBytes.length; i++){
value += valueAsBytes[i] << (7*i);
}
_pinStateController.add(new PinState(pin, value));
}

/// Stream that sent FirmataVersion
Stream<FirmataVersion> get onFirmataVersion => _firmataVersion.stream;

Expand All @@ -147,4 +162,6 @@ class SysexParser {
/// Stream capability
Stream<Map<int, List<int>>> get onCapability => _capabilityController.stream;

/// Stream pinState
Stream<PinState> get onPinState => _pinStateController.stream;
}
52 changes: 46 additions & 6 deletions test/test_sysex_parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -187,11 +187,11 @@ void main() {
//
parser.append(ANALOG_MAPPING_RESPONSE_BYTES);
});

test('Capability query response', (){
// given
parser = new SysexParser(true);
parser = new SysexParser(true);

// then
parser.onCapability.first.then(expectAsync((Map<int, List<int>> capabilities){
expect(capabilities.length, 20);
Expand All @@ -216,15 +216,55 @@ void main() {
expect(capabilities[18], [PinModes.INPUT, PinModes.OUTPUT, PinModes.ANALOG, PinModes.SERVO, PinModes.I2C]);
expect(capabilities[19], [PinModes.INPUT, PinModes.OUTPUT, PinModes.ANALOG, PinModes.SERVO, PinModes.I2C]);
}));

new Timer(new Duration(seconds: 1), () {
fail('event not fired in time');
});

// when
parser.append(CAPABILITY_QUERY_RESPONSE_BYTES);

});

test('Pin State response pin 13 is off', (){
// given
parser = new SysexParser(true);

// then
parser.onPinState.first.then(expectAsync((PinState pinState){
expect(pinState.pin, 13);
//expect(pinState.mode, PinModes.INPUT);
expect(pinState.value, PinValue.LOW);
}));

new Timer(new Duration(seconds: 1), () {
fail('event not fired in time');
});

// when
parser.append([0xF0, 0x6E, 0x0D, 0x01, 0x00, 0xF7]);
});

test('Pin State response pin 13 is on', (){
// given
parser = new SysexParser(true);

// then
parser.onPinState.first.then(expectAsync((PinState pinState){
expect(pinState.pin, 13);
//expect(pinState.mode, PinModes.INPUT);
expect(pinState.value, PinValue.HIGH);
}));

new Timer(new Duration(seconds: 1), () {
fail('event not fired in time');
});

// when
parser.append([0xF0, 0x6E, 0x0D, 0x01, 0x01, 0xF7]);
});

// TODO analog pinState + unknow pinState

});
}

0 comments on commit ea6edc5

Please sign in to comment.