pezi / dart_periphery

dart_periphery is a Dart port of the native c-periphery library
BSD 3-Clause "New" or "Revised" License
36 stars 9 forks source link

Error Using dart_periphery (flutter-pi) #1

Closed samkhan2050 closed 3 years ago

samkhan2050 commented 3 years ago

Hi, I am running flutter pi on an RPI 3B. When i use the flutter_gpiod package, it works well and i can access the GPIOs but when i try using dart_periphery and test a basic I2C function, i get an error as below. I dont know what is the issue or what to check.

Code: var i2c = I2C(1); try { print('I2C info:' + i2c.getI2Cinfo()); } finally { i2c.dispose(); }

Error: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════ flutter: The following ArgumentError was thrown building MyHomePage(dirty, state: _MyHomePageState#9daba): flutter: Invalid argument(s): join(null, "src", "native", "dart_periphery_32.1.0.0.so"): part 0 was null, but flutter: part 1 was not.

pezi commented 3 years ago

Hi! Flutter is on the roadmap - but currently I never tested dart_periphery with flutter. Do you use flutter-pi for your test?

samkhan2050 commented 3 years ago

Hi, Oh, i dont know why i assumed that everything which works on dart would also work on flutter. Yes, i am using flutter-pi. Your package is pretty good as it covers all the peripherals in one package. I would love to see it working on flutter if possible. Since, i have experience working with flutter only, i dont know how to run only dart on RPI. Can you point me in the right direction so i can try. Thanks

pezi commented 3 years ago

Hi! I installed flutter-pi on my rasperry pi - I will try to nail down the problem. Peter

pezi commented 3 years ago

Hi!

There is a workaround for your problem - please use the setCustomLibrary() method to set the absolute path to the native library https://github.com/pezi/dart_periphery/blob/main/lib/src/native/dart_periphery_static_32.1.0.0.so Version 0.8.7-beta - please run pub get to update dart_periphery

      setCustomLibrary('/home/pi/test/test/dart_periphery_static_32.1.0.0.so');
      I2C i2c = I2C(1);
      info = i2c.getI2Cinfo();

Reason for this problem - the mechanism for resolving the absolute path of a file inside a package is a little weired in Dart . I used following code from this project. But this code fails inside the flutter-pi environment.

Please, do not close this issue - I will investigate which is the best fix for this problem - documentation, or a code fix.

samkhan2050 commented 3 years ago

@pezi HI, thanks, your solution worked, Now i can access the I2C port. Really appreciate your support. I will be doing some more tests related to the functionality, i will keep you posted if you want for further improvement.

samkhan2050 commented 3 years ago

Hi, Sorry to bother you again, but i was just wondering how to add additional libraries to the package. For example, i am going to use an MPU6050 Accelerometer on I2C bus. There is a standard C library available for this at this link: https://github.com/Harinadha/STM32_MPU6050lib.

Can i simply add it to the folder C:\flutter.pub-cache\hosted\pub.dartlang.org\dart_periphery-0.8.8-beta\lib\src\hardware or to C:\flutter.pub-cache\hosted\pub.dartlang.org\dart_periphery-0.8.8-beta\lib\src\native, or do i have to carry out some additional steps. I am sorry if its a stupid question, but i am just a beginner in this field. Thanks.

pezi commented 3 years ago

You can not directly add a C library. You must write a Dart<->C library binding using dart:ffi to be able to call native methods.

dart_periphery uses this mechanism to bind the c-periphery library. dart_periphery was developed to be able access the I2C bus from Dart. This is fine, but if a sensor implementation is missing, you must port code from C or Java to Dart.

I started the porting of some popular environment sensors. BMP280 using this project diozero as a template.

I found a simple MPU6050 implementation for the arduino. https://elektro.turanis.de/html/prj075/index.html#h8

But porting sensor code is a puzzling job.

pezi commented 3 years ago

If you are little patient - I can write code for this sensor - using this source https://elektro.turanis.de/html/prj075/index.html#h8.

samkhan2050 commented 3 years ago

You can not directly add a C library. You must write a Dart<->C library binding using dart:ffi to be able to call native methods.

dart_periphery uses this mechanism to bind the c-periphery library. dart_periphery was developed to be able access the I2C bus from Dart. This is fine, but if a sensor implementation is missing, you must port code from C or Java to Dart.

I started the porting of some popular environment sensors. BMP280 using this project diozero as a template.

I found a simple MPU6050 implementation for the arduino. https://elektro.turanis.de/html/prj075/index.html#h8

But porting sensor code is a puzzling job.

Oh, i understand. Thanks for the explanation

samkhan2050 commented 3 years ago

If you are little patient - I can write code for this sensor - using this source https://elektro.turanis.de/html/prj075/index.html#h8.

That would be awesome. I look forward to it. In the meantime, if you know any online tutorial which i can follow to learn how to use Dart FFi to port an external C Library. Please advise, so that i can also add some libraries to your package if possible. Thanks

pezi commented 3 years ago

My first version of the MPU6550 sensor code written in Dart is ready. I ordered a MPU6550 sensor over Amazon - the sensor will be delivered tomorrow - so I can test new code.

samkhan2050 commented 3 years ago

Thanks a lot! Really appreciate your help

pezi commented 3 years ago

Please update to 0.8.9-beta - First version of MPU6050 sensor support is available https://github.com/pezi/dart_periphery/blob/main/example/MPU6050_test.dart

Please, do not forget to upate also the https://github.com/pezi/dart_periphery/blob/main/lib/src/native/dart_periphery_static_32.1.0.0.so binary inside the flutter environment.

Please be aware this MPU6050 sensor code is out-of-the box from https://elektro.turanis.de/html/prj075/index.html#h8

The better way would be to port this code https://github.com/Raspoid/raspoid/blob/master/src/main/com/raspoid/additionalcomponents/MPU6050.java Seems to be more complete than the snippet code.

Also this Java code can be used to verifying the ported Dart code - but this task would be more time consuming. If you need this code for a commerical project, you can contact me for developing a professional dart version of this sensor.

pezi commented 3 years ago

I closed this issue - docu update for flutter-pi is available and a correct exception is available for the flutter-pi environment.

samkhan2050 commented 3 years ago

Thanks @pezi. Really appreciate it. I may contact you in a few days for a commercial development separately.

samkhan2050 commented 3 years ago

Hi, I made the changes and tried using the MPU 6050, but i am getting only a set value of Acc and Gyro. Its not changing at all. When i tried printing the various intermittent values, i figured that the buffer is getting only zeros. Here is my minor modifications with just extra print commands and the output i am getting. I double checked the MPU 6050 wiring connections as well.

import 'package:dart_periphery/dart_periphery.dart';

import 'package:dart_periphery/src/hardware/util.dart';
import 'dart:io';

const int MPU6050_ADRESS = 0x68;

const int ACCEL_OFFSET = 200;
const int GYRO_OFFSET = 151; // 151
const int GYRO_SENSITITY = 131; // 131 is sensivity of gyro from data sheet
const double GYRO_SCALE = 0.2; //  0.02 by default - tweak as required
const double LOOP_TIME = 0.15; // 0.

int map(int x, int inMin, int inMax, int outMin, int outMax) =>
    (x - inMin) * (outMax - outMin) ~/ (inMax - inMin) + outMin;

int constrain(int amt, int low, int high) =>
    ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt)));

class MPU6050 {
  final I2C i2c;
  MPU6050(this.i2c) {
    i2c.writeByte(MPU6050_ADRESS, 0x6B);
    print('I2C ID: ${i2c.getI2Cfd()}');
    print('I2C INFO: ${i2c.getI2Cinfo()}');
    print('I2C READBYTE: ${i2c.readByte(MPU6050_ADRESS)}');
    i2c.writeByte(MPU6050_ADRESS, 0);
  }

  void getValues() {
    i2c.writeByte(MPU6050_ADRESS, 0x3B);
    var buf = ByteBuffer(i2c.readBytes(MPU6050_ADRESS, 14), ByteBufferSrc.I2C,
        BitOrder.MSB_LAST);
    print('Buffer: ${buf.data}');
    var accAngle = <int>[];
    var gyroAngle = <double>[];
    double temperature;
    for (var i = 0; i < 3; ++i) {
      var accCorr = buf.getInt16() - ACCEL_OFFSET;
      print('Initial AccCorr: $accCorr');
      accCorr = map(accCorr, -16800, 16800, -90, 90);
      print('Mapped AccCorr: $accCorr');
      accAngle.add(constrain(accCorr, -90, 90));
      print('AccAngle: $accAngle');
    }
    temperature = (buf.getInt16() + 12412.0) / 340.0;
    for (var i = 0; i < 3; ++i) {
      var gyroCorr = ((buf.getInt16() / GYRO_SENSITITY) - GYRO_OFFSET);
      gyroAngle.add((gyroCorr * GYRO_SCALE) * -LOOP_TIME);
    }
    print(
        'ACCEL_X: ${accAngle[0]}  ACCEL_Y: ${accAngle[1]} ACCEL_Z: ${accAngle[2]}');
    print('Temperature: ${temperature.toStringAsFixed(2)}');
    print(
        'GYRO_XOUT: ${gyroAngle[0]}  GYRO_YOUT: ${gyroAngle[1]} GYRO_ZOUT: ${gyroAngle[2]}');
  }
}

void main() {
  setCustomLibrary('/home/pi/test8/dart_periphery_static_32.1.0.0.so');
  var i2c = I2C(1);
  print('I2C Path: ${i2c.path}');
  print('I2C Path: ${i2c.busNum}');
  try {
    var mpu = MPU6050(i2c);
    while (true) {
      mpu.getValues();
      sleep(Duration(milliseconds: (LOOP_TIME * 1000).toInt()));
    }
  } finally {
    i2c.dispose();
  }
}

OUTPUT:

lutter: I2C Path: /dev/i2c-1 flutter: I2C Path: 1 flutter: I2C ID: 25 flutter: I2C INFO: I2C (fd=25) flutter: I2C READBYTE: 64 flutter: Buffer: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] flutter: Initial AccCorr: -200 flutter: Mapped AccCorr: -2 flutter: AccAngle: [-2] flutter: Initial AccCorr: -200 flutter: Mapped AccCorr: -2 flutter: AccAngle: [-2, -2] flutter: Initial AccCorr: -200 flutter: Mapped AccCorr: -2 flutter: AccAngle: [-2, -2, -2] flutter: ACCEL_X: -2 ACCEL_Y: -2 ACCEL_Z: -2 flutter: Temperature: 36.51 flutter: GYRO_XOUT: 4.53 GYRO_YOUT: 4.53 GYRO_ZOUT: 4.53 flutter: Buffer: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] flutter: Initial AccCorr: -200 flutter: Mapped AccCorr: -2 flutter: AccAngle: [-2] flutter: Initial AccCorr: -200 flutter: Mapped AccCorr: -2 flutter: AccAngle: [-2, -2] flutter: Initial AccCorr: -200 flutter: Mapped AccCorr: -2 flutter: AccAngle: [-2, -2, -2] flutter: ACCEL_X: -2 ACCEL_Y: -2 ACCEL_Z: -2 flutter: Temperature: 36.51 flutter: GYRO_XOUT: 4.53 GYRO_YOUT: 4.53 GYRO_ZOUT: 4.53 flutter: Buffer: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] flutter: Initial AccCorr: -200 flutter: Mapped AccCorr: -2 flutter: AccAngle: [-2] flutter: Initial AccCorr: -200 flutter: Mapped AccCorr: -2 flutter: AccAngle: [-2, -2] flutter: Initial AccCorr: -200 flutter: Mapped AccCorr: -2 flutter: AccAngle: [-2, -2, -2] flutter: ACCEL_X: -2 ACCEL_Y: -2 ACCEL_Z: -2 flutter: Temperature: 36.51 flutter: GYRO_XOUT: 4.53 GYRO_YOUT: 4.53 GYRO_ZOUT: 4.53 flutter: Buffer: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] flutter: Initial AccCorr: -200 flutter: Mapped AccCorr: -2 flutter: AccAngle: [-2] flutter: Initial AccCorr: -200 flutter: Mapped AccCorr: -2 flutter: AccAngle: [-2, -2] flutter: Initial AccCorr: -200 flutter: Mapped AccCorr: -2 flutter: AccAngle: [-2, -2, -2] flutter: ACCEL_X: -2 ACCEL_Y: -2 ACCEL_Z: -2 flutter: Temperature: 36.51 flutter: GYRO_XOUT: 4.53 GYRO_YOUT: 4.53 GYRO_ZOUT: 4.53 flutter: Buffer: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] flutter: Initial AccCorr: -200 flutter: Mapped AccCorr: -2 flutter: AccAngle: [-2] flutter: Initial AccCorr: -200 flutter: Mapped AccCorr: -2 flutter: AccAngle: [-2, -2] flutter: Initial AccCorr: -200 flutter: Mapped AccCorr: -2 flutter: AccAngle: [-2, -2, -2] flutter: ACCEL_X: -2 ACCEL_Y: -2 ACCEL_Z: -2 flutter: Temperature: 36.51 flutter: GYRO_XOUT: 4.53 GYRO_YOUT: 4.53 GYRO_ZOUT: 4.53 flutter: Buffer: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] flutter: Initial AccCorr: -200 flutter: Mapped AccCorr: -2 flutter: AccAngle: [-2] flutter: Initial AccCorr: -200 flutter: Mapped AccCorr: -2 flutter: AccAngle: [-2, -2] flutter: Initial AccCorr: -200 flutter: Mapped AccCorr: -2 flutter: AccAngle: [-2, -2, -2] flutter: ACCEL_X: -2 ACCEL_Y: -2 ACCEL_Z: -2 flutter: Temperature: 36.51 flutter: GYRO_XOUT: 4.53 GYRO_YOUT: 4.53 GYRO_ZOUT: 4.53 flutter: Buffer: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] flutter: Initial AccCorr: -200 flutter: Mapped AccCorr: -2 flutter: AccAngle: [-2] flutter: Initial AccCorr: -200 flutter: Mapped AccCorr: -2 flutter: AccAngle: [-2, -2] flutter: Initial AccCorr: -200 flutter: Mapped AccCorr: -2 flutter: AccAngle: [-2, -2, -2] flutter: ACCEL_X: -2 ACCEL_Y: -2 ACCEL_Z: -2 flutter: Temperature: 36.51 flutter: GYRO_XOUT: 4.53 GYRO_YOUT: 4.53 GYRO_ZOUT: 4.53

pezi commented 3 years ago

Sorry for this mess - I released this code too fast.

I think the problem is caused by

var buf = ByteBuffer(i2c.readBytesReg(MPU6050_ADRESS, 0x3B, 14),
        ByteBufferSrc.I2C, BitOrder.MSB_FIRST);

as a replacment for the arduino

  Wire.requestFrom(MPU6050_ADRESS, 7*2, true)

which waits until 14 bytes are available.

If you take a look at https://github.com/Harinadha/STM32_MPU6050lib/blob/master/MPU6050.c

void MPU6050_I2C_BufferRead(u8 slaveAddr, u8* pBuffer, u8 readAddr, u16 NumByteToRead)

the way of reading data is more complicated.

pezi commented 3 years ago

Ups - i found an error - the byte order was wrong - now the temperature seems to be correct - currently I can not test the sensor - the pins header isn't soldered, only trapped by a weight. I must solder the pin in the company.

import 'package:dart_periphery/dart_periphery.dart';

import 'package:dart_periphery/src/hardware/util.dart';
import 'dart:io';

const int MPU6050_ADRESS = 0x68;

const int ACCEL_OFFSET = 200;
const int GYRO_OFFSET = 151; // 151
const int GYRO_SENSITITY = 131; // 131 is sensivity of gyro from data sheet
const double GYRO_SCALE = 0.2; // 0.02 by default - tweak as required
const double LOOP_TIME = 0.15; // 0.

int map(int x, int inMin, int inMax, int outMin, int outMax) =>
    (x - inMin) * (outMax - outMin) ~/ (inMax - inMin) + outMin;

int constrain(int amt, int low, int high) =>
    ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt)));

class MPU6050 {
  final I2C i2c;
  MPU6050(this.i2c) {
    i2c.writeByteReg(MPU6050_ADRESS, 0x6B, 0);
    print('I2C ID: ${i2c.getI2Cfd()}');
    print('I2C INFO: ${i2c.getI2Cinfo()}');
  }

  void getValues() {
    var buf = ByteBuffer(i2c.readBytesReg(MPU6050_ADRESS, 0x3b, 14),
        ByteBufferSrc.I2C, BitOrder.MSB_FIRST);
    print('Buffer: ${buf.data}');
    var accAngle = [];
    var gyroAngle = [];
    double temperature;
    for (var i = 0; i < 3; ++i) {
      var accCorr = buf.getInt16() - ACCEL_OFFSET;
      print('Initial AccCorr: $accCorr');
      accCorr = map(accCorr, -16800, 16800, -90, 90);
      print('Mapped AccCorr: $accCorr');
      accAngle.add(constrain(accCorr, -90, 90));
      print('AccAngle: $accAngle');
    }
    temperature = buf.getInt16() / 340.0 + 36.53;
    for (var i = 0; i < 3; ++i) {
      var gyroCorr = ((buf.getInt16() / GYRO_SENSITITY) - GYRO_OFFSET);
      gyroAngle.add((gyroCorr * GYRO_SCALE) * -LOOP_TIME);
    }
    print(
        'ACCEL_X: ${accAngle[0]} ACCEL_Y: ${accAngle[1]} ACCEL_Z: ${accAngle[2]}');
    print('Temperature: ${temperature.toStringAsFixed(2)}');
    print(
        'GYRO_XOUT: ${gyroAngle[0]} GYRO_YOUT: ${gyroAngle[1]} GYRO_ZOUT: ${gyroAngle[2]}');
  }
}

void main() {
  var i2c = I2C(1);
  print('I2C Path: ${i2c.path}');
  print('I2C Path: ${i2c.busNum}');
  try {
    var mpu = MPU6050(i2c);
    while (true) {
      mpu.getValues();
      sleep(Duration(milliseconds: (LOOP_TIME * 1000).toInt()));
    }
  } finally {
    i2c.dispose();
  }
}
samkhan2050 commented 3 years ago

Thanks a lot. Your solution worked. I created a small code just to get the data in a stream and display it in a small widget so that the whole screen doesn't rebuild on every value change from the sensor. Below is the code for anyone who may need it. your just have to call Homepage() from your main.dart file. Added are some tripping levels for the angles, temp and gyro values with a basic UI of change in the background color with the tripping values. Also, there is a small error in the code which goes off once the sensor start streaming values, so it wont be a testing problem. I will remove it later. Hope it helps someone.


import 'package:flutter/material.dart';
import 'package:dart_periphery/dart_periphery.dart';

// ignore: implementation_imports
import 'package:dart_periphery/src/hardware/util.dart';

const int MPU6050_ADRESS = 0x68;
const int ACCEL_OFFSET = 200;
const int GYRO_OFFSET = 151; // 151
const int GYRO_SENSITITY = 131; // 131 is sensivity of gyro from data sheet
const double GYRO_SCALE = 0.2; // 0.02 by default - tweak as required
const double LOOP_TIME = 0.15; // 0.

int map(int x, int inMin, int inMax, int outMin, int outMax) =>
    (x - inMin) * (outMax - outMin) ~/ (inMax - inMin) + outMin;

int constrain(int amt, int low, int high) =>
    ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt)));

class MPU6050 {
  final I2C i2c;
  MPU6050(this.i2c) {
    i2c.writeByteReg(MPU6050_ADRESS, 0x6B, 0);
    print('I2C ID: ${i2c.getI2Cfd()}');
    print('I2C INFO: ${i2c.getI2Cinfo()}');
  }

  Map<String, double> getValues() {
    Map<String, double> dataMap = {};

    var buf = ByteBuffer(i2c.readBytesReg(MPU6050_ADRESS, 0x3b, 14),
        ByteBufferSrc.I2C, BitOrder.MSB_FIRST);
    print('Buffer: ${buf.data}');
    List<int> accAngle = [];
    var gyroAngle = [];
    double temperature;
    for (var i = 0; i < 3; ++i) {
      var accCorr = buf.getInt16() - ACCEL_OFFSET;
      print('Initial AccCorr: $accCorr');
      accCorr = map(accCorr, -16800, 16800, -90, 90);
      print('Mapped AccCorr: $accCorr');
      accAngle.add(constrain(accCorr, -90, 90));
      print('AccAngle: $accAngle');
    }
    temperature = buf.getInt16() / 340.0 + 36.53;
    for (var i = 0; i < 3; ++i) {
      var gyroCorr = ((buf.getInt16() / GYRO_SENSITITY) - GYRO_OFFSET);
      gyroAngle.add((gyroCorr * GYRO_SCALE) * -LOOP_TIME);
    }
    print(
        'ACCEL_X: ${accAngle[0]} ACCEL_Y: ${accAngle[1]} ACCEL_Z: ${accAngle[2]}');
    print('Temperature: ${temperature.toStringAsFixed(2)}');
    print(
        'GYRO_XOUT: ${gyroAngle[0]} GYRO_YOUT: ${gyroAngle[1]} GYRO_ZOUT: ${gyroAngle[2]}');

    dataMap = {
      'AngleX': accAngle[0].toDouble(),
      'AngleY': accAngle[1].toDouble(),
      'AngleZ': accAngle[2].toDouble(),
      'Temp': temperature.toDouble(),
      'GyroX': gyroAngle[0].toDouble(),
      'GyroY': gyroAngle[1].toDouble(),
      'GyroZ': gyroAngle[2].toDouble()
    };

    return dataMap;
  }
}

class AngleWidget extends StatefulWidget {
  final Map<String, double> dataMap;

  AngleWidget(this.dataMap);
  @override
  _AngleWidgetState createState() => _AngleWidgetState();
}

class _AngleWidgetState extends State<AngleWidget> {
  @override
  Widget build(BuildContext context) {
    final data = widget.dataMap;

    return Container(
      child: ListView(
        children: [
          ListTile(
            title: Text('Angle X'),
            trailing: Text(data['AngleX'].toStringAsFixed(0)),
            tileColor: data['AngleX'] > 20 || data['AngleX'] < -20
                ? Colors.red
                : Colors.grey[50],
          ),
          ListTile(
            title: Text('Angle Y'),
            trailing: Text(data['AngleY'].toStringAsFixed(0)),
            tileColor: data['AngleY'] > 20 || data['AngleY'] < -20
                ? Colors.red
                : Colors.grey[50],
          ),
          ListTile(
            title: Text('Angle Z'),
            trailing: Text(data['AngleZ'].toStringAsFixed(0)),
            tileColor: data['AngleZ'] > 20 || data['AngleZ'] < -20
                ? Colors.red
                : Colors.grey[50],
          ),
          ListTile(
            title: Text('Gyro X'),
            trailing: Text(data['GyroX'].toStringAsFixed(2)),
            tileColor: data['GyroX'] > 5 || data['GyroX'] < -5
                ? Colors.red
                : Colors.grey[50],
          ),
          ListTile(
            title: Text('Gyro Y'),
            trailing: Text(data['GyroY'].toStringAsFixed(2)),
            tileColor: data['GyroY'] > 5 || data['GyroY'] < -5
                ? Colors.red
                : Colors.grey[50],
          ),
          ListTile(
            title: Text('Gyro Z'),
            trailing: Text(data['GyroZ'].toStringAsFixed(2)),
            tileColor: data['GyroZ'] > 5 || data['GyroZ'] < -5
                ? Colors.red
                : Colors.grey[50],
          ),
          ListTile(
            title: Text('Temperature'),
            trailing: Text(data['Temp'].toStringAsFixed(2)),
            tileColor: data['Temp'] > 30 || data['Temp'] < 20
                ? Colors.red
                : Colors.grey[50],
          ),
        ],
      ),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  Map<String, double> anglesMap = {};

  Stream<Map<String, double>> angleStream() async* {
    var mpu = MPU6050(I2C(1));
    while (true) {
      await Future.delayed(Duration(milliseconds: (LOOP_TIME * 1000).toInt()));
      anglesMap = mpu.getValues();
      yield anglesMap;
    }
  }

  @override
  void initState() {
    setCustomLibrary('/home/pi/test8/dart_periphery_static_32.1.0.0.so');

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('RPI MPU6050 Demo'),
      ),
      body: Center(
        child: Container(
          padding: EdgeInsets.all(20),
          child: StreamBuilder(
            builder: (ctx, snapshot) {
              return AngleWidget(snapshot.data);
            },
            stream: angleStream(),
          ),
        ),
      ),
    );
  }
}
pezi commented 3 years ago

The main problem of the first approach was the wrong combination of the I2C write commands.

 i2c.writeByte(MPU6050_ADRESS, 0x6B);
 i2c.writeByte(MPU6050_ADRESS, 0);

must be translated from the Ardiono Code as

   i2c.writeByteReg(MPU6050_ADRESS, 0x6B, 0);

The Arduino I2C command can to be translated 1:1 is some cases.

FYI: Flutter 2.0 is out - flutter pi has released binaries for this new release and I updated also my package to dart 2.12.0 including null-saftey