read method

Future<List<Frame>> read(
  1. int numFrames
)

Reads acquisition frames from the device. This method returns when all requested frames are received from the device, or when a timeout occurs.

Parameters

numFrames : int Number of frames to retrieve from the device

Returns

frames : List<Frame> List of Frame objects retrieved from the device

Exceptions

DEVICE_NOT_IN_ACQUISITION : if the device is not in acquisition mode. NOT_SUPPORTED : if the device API is in BITALINO mode UNKNOWN_ERROR : if the device stopped sending frames for some unknown reason.

Implementation

Future<List<Frame>> read(int numFrames) async {
  //final bf = List.filled(_packetSize, null);
  final List<Frame?> frames = List.filled(numFrames, null, growable: false);

  if (!connected) throw SenseException(SenseErrorType.DEVICE_NOT_FOUND);

  if (_numChs == 0)
    throw SenseException(SenseErrorType.DEVICE_NOT_IN_ACQUISITION);

  bool midFrameFlag;
  List<int>? bf;
  Frame f;
  for (int it = 0; it < numFrames; it++) {
    midFrameFlag = false;
    bf = await _recv(_packetSize);

    // if CRC check failed, try to resynchronize with the next valid frame
    while (!_checkCRC4(bf, _packetSize)) {
      bf.replaceRange(0, _packetSize - 1, bf.sublist(1));
      bf.last = -1;

      //  checking with one new byte at a time
      final result = await _recv(1);
      bf[_packetSize - 1] = result.first;

      if (bf.last == -1)
        // a timeout has occurred
        return List<Frame>.from(
            frames.where((Frame? frame) => frame != null));
    }

    f = Frame(_numChs);
    if (_apiMode == ApiMode.SCIENTISST) {
      // Get seq number and IO states
      f.seq = bf.last >> 4;
      for (int i = 0; i < 4; i++) {
        f.digital[i] = ((bf[_packetSize - 2] & (0x80 >> i)) != 0);
      }

      // Get channel values
      int currCh;
      int byteIt = 0;
      int index = 0;
      for (int i = 0; i < _numChs; i++) {
        index = _numChs - 1 - i;
        currCh = _chs[index]!;
        // If it's an AX channel
        if (currCh == AX1 || currCh == AX2) {
          f.a[index] =
              _uint8List2int(bf.sublist(byteIt, byteIt + 4)) & 0xFFFFFF;
          byteIt += 3;
          // If it's an AI channel
        } else {
          if (!midFrameFlag) {
            f.a[index] =
                _uint8List2int(bf.sublist(byteIt, byteIt + 2)) & 0xFFF;
            byteIt += 1;
            midFrameFlag = true;
          } else {
            f.a[index] = _uint8List2int(bf.sublist(byteIt, byteIt + 2)) >> 4;
            byteIt += 2;
            midFrameFlag = false;
          }
        }
      }
    } else if (_apiMode == ApiMode.JSON) {
      //
      f = Frame(_numChs);
    } else {
      throw SenseException(SenseErrorType.NOT_SUPPORTED);
    }

    frames[it] = f;
  }
  return List<Frame>.from(
    frames.where(
      (Frame? frame) => frame != null,
    ),
  );
}