pezi / dart_periphery

dart_periphery is a Dart port of the native c-periphery library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can you add one-wire driver?

tsuiwade opened this issue · comments

Nice contribution! Thanks!

Can you add one-wire driver?

I had used IO to simulate the time sequence, and the result is very unstable.

Please give me your precious advice!

Hi!

For the most SoCs, Raspberry Pi and Armbian based. The one-wire integrations inside the device tree works well.

Raspberry Pi https://pinout.xyz/pinout/1_wire#
Armbian example: https://forum.armbian.com/topic/17383-bananapi-m1-with-armbian-2102-one-wire-temperature-sensor-and-tv-output/?tab=comments#comment-121649)
For Armbian the integration of the one-interface is probably more tricky - you must google to get one-wire running on your board.

Therefore the question -

  • which board,
  • which OS and
  • why not one-write-tree device integration?

Hi!
I'm new in Raspberry Pi and dart.I may not be able to realize dht22 sensor based on one-wire protocol.
So I'm glad to see your dart peripherals sharing on GitHub, but unfortunately, there is no one wire peripheral.
I'm sorry that I can't find dart implementation of one-wire on the Internet.
So I dare to ask if you have the relevant inventory code.
Thank you all the same!

Hi!

One-write device tree integration means, that the sensor can be read as a simple file.

See this more elaborated documentation for accessing the DHT22 sensor

cat /sys/bus/w1/devices/28-00000674869d/w1_slave

At this point you can accress the acutal value of the sensor.

alt text

And with Dart you can read the value in this way:

 import 'dart:io';
 ...
 var cmd = File('/sys/bus/w1/devices/28-00000674869d/w1_slave').readAsBytesSync();
 var s2 = s1.substring(s1.indexOf('t=') + 2);
 var v = double.parse(s2.substring(0, 2) + '.' + s2.substring(2));

Not tested!

Thank you very much for your nice answer!

I had read the information you provided me.

document provides DS18B20 which is also a one-wire device.

I have set up W1 by tutorial,
But in / sys / bus / W1 / devices , there is only W1_ bus_ Master1 folder, no slave folder, my raspberry pie doesn't recognize my sensor.

So I have seen more information , do w1.h / w1_family.h provide the driver of dht22?

Can the sensor be read without setting the timing?

Thank you very much all the same!

Sorry - I am wrong, I wrote DHT22, I mean DS18B20. DS18B20 is a one-wire device.
DHT22 is GPIO based sensor - years ago, I wrote a Java/JNI bridge to access this native C DHT22 library.

https://github.com/adafruit/Adafruit_Python_DHT/tree/master/source/Raspberry_Pi_2

The Java/Native Lib bridge worked, but this sensor is disappointing - sometimes many retries were necessary to get valid results, looking at the C code - the programming is very time sensitive. dart_periphery supports MMIO as the C-library. Probably you can port the C code, but perhaps you run into irresolvable timing problems - or you use this native code via Dart FFI mechansim - probably the fastest and the simpelst method.

But if possible, I would change the sensor - e.g BME280

But perhaps this more simple code can be ported to Dart
https://github.com/nebulx29/dht22/blob/master/dht22.c

Thank you very much for your guidance!

I may not have the concept of these at present.

I'd better change to other sensors at present.

After I have a concept of C interface, I will go back to this issue and try again.

Thank you!!!

If you a little patient, at the weekend I have time to try to port this code
https://github.com/nebulx29/dht22/blob/master/dht22.c
to Dart.

Thanks a bunch!
😊 😊 😊

DHT22/11 Code is ported, but I must find the DHT22 sensor for a real HW test.

// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// https://github.com/nebulx29/dht22/blob/master/dht22.c
// https://stackoverflow.com/questions/41120541/dht22-sensor-pi4j-java
//

// import '../gpio.dart';
import 'package:dart_periphery/dart_periphery.dart';
import 'dart:io';

const int MAX_TIMINGS = 85;

/// [DHT22] measured data: temperature and humidity.
class DHT22result {
  final bool isValid;

  /// temperature in °C
  final double temperature;

  /// relative humidity %
  final double humidity;

  DHT22result(this.temperature, this.humidity) : isValid = true;
  DHT22result.invalid()
      : temperature = -1,
        humidity = -1,
        isValid = false;

  @override
  String toString() =>
      'DHT22result [isValid=$isValid,temperature=$temperature, humidity=$humidity]';

  /// Returns a [DHT22result] as a JSON string. [fractionDigits] controls the number fraction digits.
  String toJSON([int fractionDigits = 2]) {
    return '{"temperature":"${temperature.toStringAsFixed(fractionDigits)}","humidity":"${humidity.toStringAsFixed(fractionDigits)}"';
  }
}

class DHT22 {
  int pin;
  GPIO gpio;

  DHT22(this.pin) : gpio = GPIO(pin, GPIOdirection.GPIO_DIR_OUT);

  DHT22result getValues() {
    var lastState = true;
    var dht22_dat = List<int>.filled(5, 0);
    var j = 0;
    gpio.setGPIOdirection(GPIOdirection.GPIO_DIR_OUT);
    gpio.write(false);
    sleep(Duration(milliseconds: 18));
    gpio.write(false);
    gpio.setGPIOdirection(GPIOdirection.GPIO_DIR_IN);
    for (var i = 0; i < MAX_TIMINGS; i++) {
      var counter = 0;
      while (gpio.read() == lastState) {
        counter++;
        sleep(Duration(microseconds: 1));
        if (counter == 255) {
          break;
        }
      }

      lastState = gpio.read();

      if (counter == 255) {
        break;
      }

      // ignore first 3 transitions
      if (i >= 4 && i % 2 == 0) {
        // shove each bit into the storage bytes
        dht22_dat[j >> 3] <<= 1;
        if (counter > 16) {
          dht22_dat[j >> 3] |= 1;
        }
        j++;
      }
    }
    if (j >= 40 && checkParity(dht22_dat)) {
      var humidity = ((dht22_dat[0] << 8) + dht22_dat[1]) / 10;

      if (humidity > 100) {
        humidity = dht22_dat[0].toDouble();
      }
      var temperature = (((dht22_dat[2] & 0x7F) << 8) + dht22_dat[3]) / 10;
      if (temperature > 125) {
        temperature = dht22_dat[2].toDouble(); // for DHT11
      }
      if (dht22_dat[2] & 0x80 != 0) {
        temperature = -temperature; // for DHT11
      }
      return DHT22result(temperature, humidity);
    }
    return DHT22result.invalid();
  }

  bool checkParity(List<int> dht22_dat) {
    return dht22_dat[4] ==
        (dht22_dat[0] + dht22_dat[1] + dht22_dat[2] + dht22_dat[3] & 0xFF);
  }
}

void main() {
  var dht22 = DHT22(3);
  for (var i = 0; i < 5; ++i) {
    print(dht22.getValues());
    sleep(Duration(seconds: 5));
  }
}

When I see your timely reply and help, I feel very happy and grateful!

I tested your code immediately.
But, only DHT22result [isValid=false,temperature=-1.0, humidity=-1.0] .

I guess I didn't get the GPIO pin wrong.

I just realized that there is such a convenient way to convert the existing C code into dart code.
I also tested your recommended project https://github.com/nebulx29/dht22 . The results show that there is no problem with my existing sensors

C code relies on the traditional <wiringPi.h>.
And your code depends on 'dart:io' and 'package:dart_periphery/dart_periphery.dart'.
Thank you for your ideas. I think I can draw inferences from one instance.

But is the failure of this code due to the features of dart language?

I found my DHT11 senor - but neither the original C code nor the ported Dart code works.

But the Python code for this sensor works - this code uses also a C lib. I must take a closer look at this code.

It's really a tough problem.

For me, C code and Python code works.

Maybe I can only cheer for you behind your back. 🤦‍♂️🤦‍♂️🤦‍♂️

I'm not in a hurry. If you are interested, you can have a look at it when you are free.

I found my DHT22 and tried to port C code, which works, to Dart - GPIO or MMIO access - but the all these attempts failed - timing problems prevented reading the correct bit sequence from the sensor.

Yes, you would likely have to do it using existing w1-gpio device driver. See https://pinout.xyz/pinout/1_wire
This driver would handle the timing problems.

I was able to do dynamic overlay loading and it would recognize my device (DS28E10) using shell commands. But I haven't yet figured out the specifics of the how to access it properly. It would read the ID ... but next steps were not so clear.

Seems each DSxxx device may have slightly different file operations that are possible. I'm learning ...