Very rarely the Raspberry PI might hang even the reboot command has been given.

If you still have shell access you can try the following:

Enable function if not already the case:

echo "1" > /proc/sys/kernel/sysrq

Sync disks to not loose data
echo "s" > /proc/sysrq-trigger
Unmount and mount read only to not damage image
echo "u" > /proc/sysrq-trigger
Do the actual reboot
echo "b" > /proc/sysrq-trigger

Hope it helps.

Chrs

To avoid the need of an I2C mux I enabled the second I2C bus on my PI 2
This as I have two devices running at 0x5C

add 'dtparam=i2c_vc=on' to /boot/config.txt to enable.

Increase frequency use:

dtparam=i2c_arm_baudrate=1500000
& used gpio load i2c 1500 to load

Now I2C 1 is at 1.5Mhz (Howto do so with I2C 0 I have no clue yet.

Chrs

Just instaled a BMP280 with the following code:

// Distributed with a free-will license.
// Use it any way you want, profit or free, provided it fits in the licenses of its associated works.
// BMP280
//
// Compile with gcc -o BMP280  BMP280.c 
//
// This code is designed to work with the BMP280_I2CS I2C Mini Module available from ControlEverything.com.
// https://www.controleverything.com/content/Barometer?sku=BMP280_I2CSs#tabs-0-product_tabset-2

#include <stdio.h>
#include <stdlib.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <math.h>

void main() 
{
        // Create I2C bus
        int file;
        char *bus = "/dev/i2c-1";
        if((file = open(bus, O_RDWR)) < 0) 
        {
                printf("Failed to open the bus. \n");
                exit(1);
        }
        // Get I2C device, BMP280 I2C address is 0x76(108)
        // But you need to ground SDO otherwise its is 0x77!!!
        ioctl(file, I2C_SLAVE, 0x76);

        // Read 24 bytes of data from address(0x88)
        char reg[1] = {0x88};
        write(file, reg, 1);
        char data[24] = {0};
        if(read(file, data, 24) != 24)
        {
                printf("Error : Input/output Error \n");
                exit(1);
        }
        // Convert the data
        // temp coefficents
        int dig_T1 = data[1] * 256 + data[0];
        int dig_T2 = data[3] * 256 + data[2];
        if(dig_T2 > 32767)
        {
                dig_T2 -= 65536;
        }
        int dig_T3 = data[5] * 256 + data[4];
        if(dig_T3 > 32767)
        {
                dig_T3 -= 65536;
        }
        // pressure coefficents
        int dig_P1 = data[7] * 256 + data[6];
        int dig_P2  = data[9] * 256 + data[8];
        if(dig_P2 > 32767)
        {
                dig_P2 -= 65536;
        }
        int dig_P3 = data[11]* 256 + data[10];
        if(dig_P3 > 32767)
        {
                dig_P3 -= 65536;
        }
        int dig_P4 = data[13]* 256 + data[12];
        if(dig_P4 > 32767)
        {
                dig_P4 -= 65536;
        }
        int dig_P5 = data[15]* 256 + data[14];
        if(dig_P5 > 32767)
        {
                dig_P5 -= 65536;
        }
        int dig_P6 = data[17]* 256 + data[16];
        if(dig_P6 > 32767)
        {
                dig_P6 -= 65536;
        }
        int dig_P7 = data[19]* 256 + data[18];
        if(dig_P7 > 32767)
        {
                dig_P7 -= 65536;
        }
        int dig_P8 = data[21]* 256 + data[20];
        if(dig_P8 > 32767)
        {
                dig_P8 -= 65536;
        }
        int dig_P9 = data[23]* 256 + data[22];
        if(dig_P9 > 32767)
        {
                dig_P9 -= 65536;
        }

        // Select control measurement register(0xF4)
        // Normal mode, temp and pressure over sampling rate = 1(0x27)
        char config[2] = {0};
        config[0] = 0xF4;
        config[1] = 0x27;
        write(file, config, 2);

        // Select config register(0xF5)
        // Stand_by time = 1000 ms(0xA0)
        config[0] = 0xF5;
        config[1] = 0xA0;
        write(file, config, 2);
        sleep(1);

        // Read 8 bytes of data from register(0xF7)
        // pressure msb1, pressure msb, pressure lsb, temp msb1, temp msb, temp lsb, humidity lsb, humidity msb
        reg[0] = 0xF7;
        write(file, reg, 1);
        if(read(file, data, 8) != 8)
        {
                printf("Error : Input/output Error \n");
                exit(1);
        }

        // Convert pressure and temperature data to 19-bits
        long adc_p = (((long)data[0] * 65536) + ((long)data[1] * 256) + (long)(data[2] & 0xF0)) / 16;
        long adc_t = (((long)data[3] * 65536) + ((long)data[4] * 256) + (long)(data[5] & 0xF0)) / 16;

        // Temperature offset calculations
        double var1 = (((double)adc_t) / 16384.0 - ((double)dig_T1) / 1024.0) * ((double)dig_T2);
        double var2 = ((((double)adc_t) / 131072.0 - ((double)dig_T1) / 8192.0) *(((double)adc_t)/131072.0 - ((double)dig_T1)/8192.0)) * ((double)dig_T3);
        double t_fine = (long)(var1 + var2);
        double cTemp = (var1 + var2) / 5120.0;
        double fTemp = cTemp * 1.8 + 32;

        // Pressure offset calculations
        var1 = ((double)t_fine / 2.0) - 64000.0;
        var2 = var1 * var1 * ((double)dig_P6) / 32768.0;
        var2 = var2 + var1 * ((double)dig_P5) * 2.0;
        var2 = (var2 / 4.0) + (((double)dig_P4) * 65536.0);
        var1 = (((double) dig_P3) * var1 * var1 / 524288.0 + ((double) dig_P2) * var1) / 524288.0;
        var1 = (1.0 + var1 / 32768.0) * ((double)dig_P1);
        double p = 1048576.0 - (double)adc_p;
        p = (p - (var2 / 4096.0)) * 6250.0 / var1;
        var1 = ((double) dig_P9) * p * p / 2147483648.0;
        var2 = p * ((double) dig_P8) / 32768.0;
        double pressure = (p + (var1 + var2 + ((double)dig_P7)) / 16.0) / 100;

        // Output data to screen
        printf("Press : %.2f hPa \n", pressure);
        printf("Temp in C : %.2f C \n", cTemp);
        printf("Temp in F : %.2f F \n", fTemp);
}

Works like a champ.

For Python try this:

#!/usr/bin/python
#--------------------------------------
#    ___  ___  _ ____
#   / _ \/ _ \(_) __/__  __ __
#  / , _/ ___/ /\ \/ _ \/ // /
# /_/|_/_/  /_/___/ .__/\_, /
#                /_/   /___/
#
#           bme280.py
#  Read data from a digital pressure sensor.
#
#  Official datasheet available from :
#  https://www.bosch-sensortec.com/bst/products/all_products/bme280
#
# Author : Matt Hawkins
# Date   : 25/07/2016
#
# http://www.raspberrypi-spy.co.uk/
#
#--------------------------------------
import smbus
import time
from ctypes import c_short
from ctypes import c_byte
from ctypes import c_ubyte

DEVICE = 0x76 # Default device I2C address


bus = smbus.SMBus(1) # Rev 2 Pi, Pi 2 & Pi 3 uses bus 1
                     # Rev 1 Pi uses bus 0

def getShort(data, index):
  # return two bytes from data as a signed 16-bit value
  return c_short((data[index+1] << 8) + data[index]).value

def getUShort(data, index):
  # return two bytes from data as an unsigned 16-bit value
  return (data[index+1] << 8) + data[index]

def getChar(data,index):
  # return one byte from data as a signed char
  result = data[index]
  if result > 127:
    result -= 256
  return result

def getUChar(data,index):
  # return one byte from data as an unsigned char
  result =  data[index] & 0xFF
  return result

def readBME280ID(addr=DEVICE):
  # Chip ID Register Address
  REG_ID     = 0xD0
  (chip_id, chip_version) = bus.read_i2c_block_data(addr, REG_ID, 2)
  return (chip_id, chip_version)

def readBME280All(addr=DEVICE):
  # Register Addresses
  REG_DATA = 0xF7
  REG_CONTROL = 0xF4
  REG_CONFIG  = 0xF5

  REG_HUM_MSB = 0xFD
  REG_HUM_LSB = 0xFE

  # Oversample setting - page 27
  OVERSAMPLE_TEMP = 2
  OVERSAMPLE_PRES = 2
  MODE = 1

  control = OVERSAMPLE_TEMP<<5 | OVERSAMPLE_PRES<<2 | MODE
  bus.write_byte_data(addr, REG_CONTROL, control)

  # Read blocks of calibration data from EEPROM
  # See Page 22 data sheet
  cal1 = bus.read_i2c_block_data(addr, 0x88, 24)
  cal2 = bus.read_i2c_block_data(addr, 0xA1, 1)
  cal3 = bus.read_i2c_block_data(addr, 0xE1, 7)

  # Convert byte data to word values
  dig_T1 = getUShort(cal1, 0)
  dig_T2 = getShort(cal1, 2)
  dig_T3 = getShort(cal1, 4)

  dig_P1 = getUShort(cal1, 6)
  dig_P2 = getShort(cal1, 8)
  dig_P3 = getShort(cal1, 10)
  dig_P4 = getShort(cal1, 12)
  dig_P5 = getShort(cal1, 14)
  dig_P6 = getShort(cal1, 16)
  dig_P7 = getShort(cal1, 18)
  dig_P8 = getShort(cal1, 20)
  dig_P9 = getShort(cal1, 22)

  dig_H1 = getUChar(cal2, 0)
  dig_H2 = getShort(cal3, 0)
  dig_H3 = getUChar(cal3, 2)

  dig_H4 = getChar(cal3, 3)
  dig_H4 = (dig_H4 << 24) >> 20
  dig_H4 = dig_H4 | (getChar(cal3, 4) & 0x0F)

  dig_H5 = getChar(cal3, 5)
  dig_H5 = (dig_H5 << 24) >> 20
  dig_H5 = dig_H5 | (getUChar(cal3, 4) >> 4 & 0x0F)

  dig_H6 = getChar(cal3, 6)

  # Read temperature/pressure/humidity
  data = bus.read_i2c_block_data(addr, REG_DATA, 8)
  pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4)
  temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4)
  hum_raw = (data[6] << 8) | data[7]

  #Refine temperature
  var2 = (((((temp_raw>>4) - (dig_T1)) * ((temp_raw>>4) - (dig_T1))) >> 12) * (dig_T3)) >> 14
  t_fine = var1+var2
  temperature = float(((t_fine * 5) + 128) >> 8);

  # Refine pressure and adjust for temperature
  var1 = t_fine / 2.0 - 64000.0
  var2 = var1 * var1 * dig_P6 / 32768.0
  var2 = var2 + var1 * dig_P5 * 2.0
  var2 = var2 / 4.0 + dig_P4 * 65536.0
  var1 = (dig_P3 * var1 * var1 / 524288.0 + dig_P2 * var1) / 524288.0
  var1 = (1.0 + var1 / 32768.0) * dig_P1
  if var1 == 0:
    pressure=0
  else:
    pressure = 1048576.0 - pres_raw
    pressure = ((pressure - var2 / 4096.0) * 6250.0) / var1
    var1 = dig_P9 * pressure * pressure / 2147483648.0
    var2 = pressure * dig_P8 / 32768.0
    pressure = pressure + (var1 + var2 + dig_P7) / 16.0

  # Refine humidity
  humidity = t_fine - 76800.0
  humidity = (hum_raw - (dig_H4 * 64.0 + dig_H5 / 16384.8 * humidity)) * (dig_H2 / 65536.0 * (1.0 + dig_H6 / 67108864.0 * humidity * (1.0 + dig_H3 / 67108864.0 * humidity)))
  humidity = humidity * (1.0 - dig_H1 * humidity / 524288.0)
  if humidity > 100:
    humidity = 100
  elif humidity < 0:
    humidity = 0

  return temperature/100.0,pressure/100.0,humidity

def main():

  (chip_id, chip_version) = readBME280ID()
  print "Chip ID     :", chip_id
  print "Version     :", chip_version

  temperature,pressure,humidity = readBME280All()

  print "Temperature :", temperature, "C"
  print "Pressure    :", pressure, "hPa"
  print "Humidity    :", humidity, "%"

if __name__=="__main__":
   main()

However only with the BME280 you will get the humidity of course.

Also found a Perl script but that did not work for me it read out values (constant so thats ok) but wrong on my system.
Maybe thats because of a difference bewteen BMP18 and BMP280? Anyone?

#!/usr/bin/perl

# Copyright 2014 by Jason Seymour
# Rev 1.0
# Rev 1.1 by Jason Miller
# https://github.com/JasonSeymour/rpi-perl-bmp180/blob/master/readBMP180.pl
# https://www.linkedin.com/in/jason-seymour-10513b2
# This is a Perl script to read temperature and barometric
# pressure from an Adafruit BMP180 breakout board.

use Device::SMBus;
use Time::HiRes qw( usleep ualarm gettimeofday tv_interval nanosleep
                    clock_gettime clock_getres clock_nanosleep clock
                    stat );


# Instantiate an SMBus object referring to the correct I2C bus
# and the device address of the sensor. The Adafruit BMP180
# sensor always has an address of 0x77. The rev2 RPi puts the
# primary I2C bus on i2c-1. The rev1 uses i2c-0.

my $bmp180 = Device::SMBus->new(
  I2CBusDevicePath => '/dev/i2c-1',
  I2CDeviceAddress => 0x76,
);

# Use this constant to enable or disable printing diagnostic data

use constant DIAG               => False;

# Define a standard list of operating modes for the sensor.
# These control the number of samples per second that the 
# sensor takes internally.

use constant BMP180_ULTRALOWPOWER       => 0;
use constant BMP180_STANDARD            => 1;
use constant BMP180_HIRES       => 2;
use constant BMP180_ULTRAHIRES          => 3;

# Define the sensor registers. Many of these store calibration data
# which is used to calculate temperature compensated pressure readings.

use constant BMP180_CAL_AC1     => 0xAA;     # Calibration data (16 bit)
use constant BMP180_CAL_AC2     => 0xAC;     # Calibration data (16 bit) 
use constant BMP180_CAL_AC3     => 0xAE;     # Calibration data (16 bit)
use constant BMP180_CAL_AC4     => 0xB0;     # Calibration data (16 bit)
use constant BMP180_CAL_AC5     => 0xB2;     # Calibration data (16 bit)
use constant BMP180_CAL_AC6     => 0xB4;     # Calibration data (16 bit)
use constant BMP180_CAL_B1      => 0xB6;     # Calibration data (16 bit)
use constant BMP180_CAL_B2      => 0xB8;     # Calibration data (16 bit)
use constant BMP180_CAL_MB      => 0xBA;     # Calibration data (16 bit)
use constant BMP180_CAL_MC      => 0xBC;     # Calibration data (16 bit)
use constant BMP180_CAL_MD      => 0xBE;     # Calibration data (16 bit)
use constant BMP180_CONTROL     => 0xF4;
use constant BMP180_TEMPDATA            => 0xF6;
use constant BMP180_PRESSUREDATA        => 0xF6;
use constant BMP180_READTEMPCMD         => 0x2E;
use constant BMP180_READPRESSURECMD     => 0x34;

# Define a list of variables to store the calibration data into.

my $cal_AC1     = 0;
my $cal_AC2     = 0;
my $cal_AC3     = 0;
my $cal_AC4     = 0;
my $cal_AC5     = 0;
my $cal_AC6     = 0;
my $cal_B1      = 0;
my $cal_B2      = 0;
my $cal_MB      = 0;
my $cal_MC      = 0;
my $cal_MD      = 0;

# The Device::SMBus module provides methods for reading 8 and 16 bit values
# from the sensor, but these methods don't differentiate between signed and
# unsigned values. We need to create our own functions to read signed values
# and handle them correctly.

sub readS8 {
        my ($bmp180,$register) = @_;
        my $readVal = $bmp180->readByteData($register);
        if($readVal > 127) {
                $readVal -= 256;
        }
        return $readVal;
}

sub readS16 {
        my ($bmp180,$register) = @_;
        my $readValHi = readS8($bmp180,$register);
        my $readValLo = $bmp180->readByteData($register+1);
        my $bufferHi = $readValHi << 8;
        my $retVal = $bufferHi + $readValLo;
        return $retVal;
}

sub readU16 {
        my ($bmp180,$register) = @_;
        my $readValHi = $bmp180->readByteData($register);
        my $readValLo = $bmp180->readByteData($register+1);
        my $bufferHi = $readValHi << 8;
        my $retVal = $bufferHi + $readValLo;
        return $retVal;
}

# Read the calibration data from the sensor's eeprom and store it locally

$cal_AC1 = readS16($bmp180,BMP180_CAL_AC1);
$cal_AC2 = readS16($bmp180,BMP180_CAL_AC2);
$cal_AC3 = readS16($bmp180,BMP180_CAL_AC3);
$cal_AC4 = readU16($bmp180,BMP180_CAL_AC4);
$cal_AC5 = readU16($bmp180,BMP180_CAL_AC5);
$cal_AC6 = readU16($bmp180,BMP180_CAL_AC6);
$cal_B1  = readS16($bmp180,BMP180_CAL_B1);
$cal_B2  = readS16($bmp180,BMP180_CAL_B2);
$cal_MB  = readS16($bmp180,BMP180_CAL_MB);
$cal_MC  = readS16($bmp180,BMP180_CAL_MC);
$cal_MD  = readS16($bmp180,BMP180_CAL_MD);

# DIAG: Print out the calibration data to validate that we're working up to this point
if(DIAG eq "True") {
        print "Calibration Data\n";
        print "----------------\n";
        printf "AC1 = %6d\n",$cal_AC1;
        printf "AC2 = %6d\n",$cal_AC2;
        printf "AC3 = %6d\n",$cal_AC3;
        printf "AC4 = %6d\n",$cal_AC4;
        printf "AC5 = %6d\n",$cal_AC5;
        printf "AC6 = %6d\n",$cal_AC6;
        printf "B1 = %6d\n",$cal_B1;
        printf "B2 = %6d\n",$cal_B2;
        printf "MB = %6d\n",$cal_MB;
        printf "MC = %6d\n",$cal_MC;
        printf "MD = %6d\n",$cal_MD;
}

# Read the raw (uncompensated) temperature from the sensor

sub readRawTemp {
        my ($bmp180) = @_;
        $bmp180->writeByteData(BMP180_CONTROL,BMP180_READTEMPCMD);
        # usleep takes microseconds, so this is 5 milliseconds
        usleep(5000);
        my $rawTemp = readU16($bmp180,BMP180_TEMPDATA);
        if(DIAG eq "True") {
                my $temp = $rawTemp & 0xFFFF;
                printf "Raw Temp: 0x%x (%d)\n", $temp, $rawTemp;
        }
        return $rawTemp;
}

# Read the raw (uncompensated) barometric pressure from the sensor

sub readRawPressure {
        my ($bmp180,$mode) = @_;
        my $writeVal = BMP180_READPRESSURECMD + ($mode << 6);
        $bmp180->writeByteData(BMP180_CONTROL,$writeVal);
        if ($mode == BMP180_ULTRALOWPOWER) {
                usleep(5000);
        }
        elsif ($mode == BMP180_HIRES) {
                usleep(14000);
        }
        elsif ($mode == BMP180_ULTRAHIRES) {
                usleep(26000);
        }
        else {
                usleep(8000);
        }
        my $msb = $bmp180->readByteData(BMP180_PRESSUREDATA);
        my $lsb = $bmp180->readByteData(BMP180_PRESSUREDATA+1);
        my $xlsb = $bmp180->readByteData(BMP180_PRESSUREDATA+2);
        my $rawPressure = (($msb << 16) + ($lsb << 8) + $xlsb) >> (8 - $mode);
        if(DIAG eq "True") {
                my $press =  $rawPressure & 0xFFFF;
                printf "Raw Pressure value: 0x%X (%d)\n", $press, $rawPressure;
        }
        return $rawPressure;
}

# Read the compensated temperature

sub readTemp {
        my ($bmp180) = @_;
        my $UT = 0;
        my $X1 = 0;
        my $X2 = 0;
        my $B5 = 0;
        my $temp = 0.0;

        $UT = readRawTemp($bmp180);
        use integer;
        $X1 = (($UT - $cal_AC6) * $cal_AC5) >> 15;
        $X2 = ($cal_MC << 11) / ($X1 + $cal_MD);
        $B5 = $X1 + $X2;
        no integer;
        $temp = (($B5 + 8) >> 4) / 10.0;
        return $temp;
}

# Read the compensated barometric pressure

sub readPressure {
        my ($bmp180,$mode) = @_;
        my $UT = readRawTemp($bmp180);
        my $UP = readRawPressure($bmp180,$mode);

        # Calculate true temperature, but don't convert to simple output format yet
        use integer;
        my $X1 = (($UT - $cal_AC6) * $cal_AC5) >> 15;
        my $X2 = ($cal_MC << 11) / ($X1 + $cal_MD);
        my $B5 = $X1 + $X2;
        no integer;
        my $temp = (($B5 + 8) >> 4) / 10.0;

        # Calculate compensated pressure
        use integer;
        my $B6 = $B5 - 4000;
        #printf "B6 = $B6\n";
        my $X1 = ($cal_B2 * ($B6 * $B6) >> 12) >> 11;
        #printf "X1 = $X1\n";
        my $X2 = ($cal_AC2 * $B6) >> 11;
        my $X3 = $X1 + $X2;
        my $B3 = ((($cal_AC1 * 4 + $X3) << $mode) + 2) /4;
        $X1 = ($cal_AC3 * $B6) >> 13;
        $X2 = ($cal_B1 * (($B6 * $B6)) >> 12 ) >> 16;
        $X3 = (($X1 + $X2) + 2) >> 2;
        my $B4 = ($cal_AC4 * ($X3 + 32768)) >> 15;
        my $B7 = ($UP - $B3) * (50000 >> $mode);
        my $p = 0;
        if ($B7 < 0x80000000) {
                $p = ($B7 * 2) / $B4;
        } else {
                $p = ($B7 / $B4) * 2;
        }
        $X1 = ($p >> 8) * ($p >> 8);
        $X1 = ($X1 * 3038) >> 16;
        $X2 = (-7357 * $p) >> 16;
        $p = $p + (($X1 + $X2 + 3791) >> 4);
        #printf "Calibration pressure is %d Pa\n", $p;
        return $p;
}

# Print the raw uncorrected temperature
#my $RawTemp = readRawTemp($bmp180);

# Call the compensated temp function to print temperature
#my $Temperature = readTemp($bmp180);



# Call the compensated pressure function to print barometric pressure
my $Temperature = readTemp($bmp180);
my $Pressure = readPressure($bmp180,BMP180_STANDARD) / 100.0;

my $TemperatureF = (($Temperature * 9) / 5) + 32;

printf "Temperature: %.2f C\n", $Temperature;
printf "Temperature: %.2f F\n", $TemperatureF;
printf "Pressure: %.2f hPa\n", $Pressure;

Temperature: 82.70 C
Temperature: 180.86 F
Pressure: -43852.45 hPa

Hmmmm....

But interesting using perl with SMBUS..

Chrs

http://pi.gids.nl:81/temp/img/ina219.png

Today I added a power measurement board in between the 3.3 volt and the complete breadboards where all my sensors reside.
As I could not find any working C code on the net I used a Python library instead.

I had to shorten A1 as address 0x40 was already in use by my HTU21.
Now its set to 0x44 so also adjusted the Subfact_ina219.py
__INA219_ADDRESS                         = 0x44

See here : https://github.com/scottjw/subfact_pi_ina219 for the Python code.

Its working nicely : http://pi.gids.nl:81/temp/gauges.php

If someone has a C code tool I would be interested in it to try out and compare performance.

Chrs ...

And to measure IR and Lux I tried this setup: http://dino.ciuffetti.info/2014/03/tsl2 … y-pi-in-c/

To compile run this:

#!/bin/sh
#
# http://dino.ciuffetti.info/2014/03/tsl2561-light-sensor-on-raspberry-pi-in-c/
#
gcc -lm -o TSL2561 TSL2561.c TSL2561_test.c 
#
#

I hope this helps...

Chrs..

Hello,

This is how I was able to activate the  MPL3115A2 on my PI.
Its using Perl to get the date:

See http://cpansearch.perl.org/src/MDOOTSON/

If there is anyone out here that has some good C code please let me know.

HiPi is found here http://raspberrypi.znix.com/hipidocs/contents.htm
Sources from other HiPi versions here : http://raspberrypi.znix.com/hipifiles/

For those who like Python see http://ciaduck.blogspot.nl/2014/12/mpl3 … ry-pi.html

This is some C code I found https://github.com/ControlEverythingCom … PL3115A2.c

// Distributed with a free-will license.
// Use it any way you want, profit or free, provided it fits in the licenses of its associated works.
// MPL3115A2
// This code is designed to work with the MPL3115A2_I2CS I2C Mini Module available from ControlEverything.com.
// https://www.controleverything.com/products

#include <stdio.h>
#include <stdlib.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <fcntl.h>

void main() 
{
    // Create I2C bus
    int file;
    char *bus = "/dev/i2c-1";
    if((file = open(bus, O_RDWR)) < 0) 
    {
        printf("Failed to open the bus. \n");
        exit(1);
    }
    // Get I2C device, TSL2561 I2C address is 0x60(96)
    ioctl(file, I2C_SLAVE, 0x60);

    // Select control register(0x26)
    // Active mode, OSR = 128, altimeter mode(0xB9)
    char config[2] = {0};
    config[0] = 0x26;
    config[1] = 0xB9;
    write(file, config, 2);
    // Select data configuration register(0x13)
    // Data ready event enabled for altitude, pressure, temperature(0x07)
    config[0] = 0x13;
    config[1] = 0x07;
    write(file, config, 2);
    // Select control register(0x26)
    // Active mode, OSR = 128, altimeter mode(0xB9)
    config[0] = 0x26;
    config[1] = 0xB9;
    write(file, config, 2);
    sleep(1);

    // Read 6 bytes of data from address 0x00(00)
    // status, tHeight msb1, tHeight msb, tHeight lsb, temp msb, temp lsb
    char reg[1] = {0x00};
    write(file, reg, 1);
    char data[6] = {0};
    if(read(file, data, 6) != 6)
    {
        printf("Error : Input/Output error \n");
        exit(1);
    }

    // Convert the data
    int tHeight = ((data[1] * 65536) + (data[2] * 256 + (data[3] & 0xF0)) / 16);
    int temp = ((data[4] * 256) + (data[5] & 0xF0)) / 16;
    float altitude = tHeight / 16.0;
    float cTemp = (temp / 16.0);
    float fTemp = cTemp * 1.8 + 32;

    // Select control register(0x26)
    // Active mode, OSR = 128, barometer mode(0x39)
    config[0] = 0x26;
    config[1] = 0x39;
    write(file, config, 2);
    sleep(1);

    // Read 4 bytes of data from register(0x00)
    // status, pres msb1, pres msb, pres lsb
    reg[0] = 0x00;
    write(file, reg, 1);
    read(file, data, 4);

    // Convert the data to 20-bits
    int pres = ((data[1] * 65536) + (data[2] * 256 + (data[3] & 0xF0))) / 16;
    float pressure = (pres / 4.0) / 1000.0;
    
    // Output data to screen
    printf("Pressure : %.2f kPa \n", pressure);
    printf("Altitude : %.2f m \n", altitude);
    printf("Temperature in Celsius : %.2f C \n", cTemp);
    printf("Temperature in Fahrenheit : %.2f F \n", fTemp);
}

However after you have ran the C code the perl stops to run and the board needs a power reset for the HiPi to be working again.
Need to find out why... Anyone maybe an idea?

Chrs..

I played a bit with the HTU21 and checked some code.
The best that worked for me are on https://github.com/maasdoel/HTU21D-F

I addapted it a bit n its ourput to parse to other scripts but this is the original code:

/*  (Dev)   -  (Pi)
    SDA     -  SDA
    SCL     -  SCL
    GND     -  GND
    VCC     -  3.3V
    Note: Check your pin out
    Note: Make sure you connect the PI's 3.3 V line to the HTU21DF boards Vcc 'IN' line not the 3.3v 'OUT' 
    
    How to compile, @ command line type
    
        gcc -Wall -lm -o htu21dev4 ./htu21dev4.c

    the '-lm' is required for 'math.h'
    
    for constants such as O_RWRD or I2C_M_RD checkout i2c.h & i2c-dev.h
    this also contains the definition of 'struct i2c_msg' so if you want to see what is
    possible check it out. 
    also have a look at
    
>>>>>  https://www.kernel.org/doc/Documentation/i2c/i2c-protocol <<<<<<<<<< NB! read it 
    
    There are no examples of the 'Write User Register' available, so back to basics and RTFM to
    create it from the above documentation.
    
    In general communication functions return an integer < 0 on failure 0 for success and > 0 if a 'handle' is
    being returned. If a value of a conversion is required it is return via a variable passed to the
    function 'by-ref' ie a pointer. look in 'main' for 'MyTemp' and 'MyHum'.
    
    Conversion functions return a double
    
    I have mixed float and double types, should change everything to double (math.h needs it most)
    this is more for consistency and style then any other reason.
    
    PS there are better dew point formulae.
        
    Use as you see fit.
    
    Eric Maasdorp 2014-08-28
*/
     
#include <stdio.h>
#include <stdint.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <linux/i2c-dev.h>
// #include <linux/i2c.h>
#include <sys/ioctl.h>
#include <math.h>
#include "htu21dev4.h"     

#define sleepms(ms)  usleep((ms)*1000)   
#define I2CBus             "/dev/i2c-1"      //New Pi's 
//#define I2CBus             "/dev/i2c-0"    //Old, but not stale Pi's

// Returns a file id for the port/bus
int i2c_Open(char *I2CBusName){
  int fd;
  //Open port for reading and writing
  if ((fd = open(I2CBusName, O_RDWR)) < 0){
    printf ("\n");
    printf ("%s : Failed to open the i2c bus, error : %d\n",__func__,errno);
    printf ("Check to see if you have a bus: %s\n",I2CBusName); 
    printf ("This is not a slave device problem, I can not find the bus/port with which to talk to the device\n"); 
    printf ("\n");
    // Only one of the following lines should be used
    // the second line allows you to retry another bus, PS disable all the printf 's 
    exit(1);      //Use this line if the function must terminate on failure
    //return fd;  //Use this line if it must return to the caller for processing
    }
    else{
     return fd;
    }
}

void i2c_commonsenderror(int fd,uint8_t DeviceAddress){
   printf("\n");
    printf("This means that device with address :0x%0x failed to receive this command\n",DeviceAddress);
    printf("This command was preceded by others if they worked\n");
    printf("and this failed, then possible causes are delay timing to short (overclock stuffing timing up)\n");
    printf("or bus unstable ,wire length to long,power supply unstable, terminating resistors missing or incorrect.\n");
    printf("\n");
}    

//START: htu21df specific code

int htu21df_crcdata(const uint8_t *Data, uint16_t *ConvertedValue){
  uint32_t dataandcrc;
  // Generator polynomial: x**8 + x**5 + x**4 + 1 = 1001 1000 1
  *ConvertedValue = 0;

  const uint32_t poly = 0x98800000;
  int i;
  
  //Check how many bytes are there (expect 3 got 4???)  
  int nElements = sizeof(Data) / sizeof(Data[0]); 
  //What am I missing?
  //printf("Elements:%i\n",nElements);
  
  if (nElements != 4) return -1;        //Expected 3 why are there 4
  if (Data == NULL) return -1;
  dataandcrc = (Data[0] << 24) | (Data[1] << 16) | (Data[2] << 8);
  for (i = 0; i < 24; i++) {
    if (dataandcrc & 0x80000000UL) dataandcrc ^= poly;
    dataandcrc <<= 1;
  }
  // 2 Low bits are status, mask them 'C' > 1100b
  *ConvertedValue = ((Data[0] << 8) | Data[1]) & 0xFFFC;
  return (dataandcrc != 0);
}

int htu21df_ReadUserReg(int fd, int *retValue){
  uint8_t replymessage[2];
  int rc;
  struct i2c_rdwr_ioctl_data messagebuffer;
  uint8_t deviceAction=HTU21DF_READREG;

  //Build a user register read command
  //Requires a one complete message containing a command
  //and anaother complete message for the rely 
  struct i2c_msg read_user_reg[2]={
    {HTU21DF_I2CADDR,0,1,&deviceAction},
    {HTU21DF_I2CADDR,I2C_M_RD,1,replymessage}
  };
  
  messagebuffer.nmsgs = 2;                   //Two message/action
  messagebuffer.msgs = read_user_reg;        //load the 'read_user_reg' message into the buffer
  rc = ioctl(fd, I2C_RDWR, &messagebuffer);  //Send the buffer to the bus and returns a send status
  if (rc < 0 ){
    printf("\n");
    printf("%s :htu21df User Reg Read command failed with error :%d\n",__func__,errno);
    printf("This means that device with address :0x%0x failed to receive this command\n",HTU21DF_I2CADDR);
    printf("This command was preceded by a reset if that worked\n");
    printf("and this failed, then possible causes are Delay timing to short (overclock stuffing timing up)\n");
    printf("or bus unstable ,wire length,power supply unstable, terminating resistors.\n");
    printf("\n");
    // Only one of the following lines should be used
    //exit(1);       //Use this line if the function must terminate on failure
    return rc;       //Use this line if it must return to the caller for processing
  }
  *retValue = replymessage[0];
  return 0;
}

int htu21df_WriteUserReg(int fd,int NewValue){
  int UserRegVal;
  uint8_t datatosend[2];
  int rc;
  struct i2c_rdwr_ioctl_data messagebuffer;

  if ( htu21df_ReadUserReg(fd,&UserRegVal) != 0) return -1;

  //Preserve the reserved bits  
  UserRegVal &=0x38;
  UserRegVal |=(NewValue & 0xC7);  //Dont allow modification of bits 3,4,5
  
  //Unlike the read commands the write
  //requires the command and data to be sent in
  //one message  
  datatosend[0]=HTU21DF_WRITEREG;
  datatosend[1]=UserRegVal;

  //Build a user register write  command
  struct i2c_msg write_user_reg[1]={
    {HTU21DF_I2CADDR,0,2,datatosend}
  };
  
  messagebuffer.nmsgs = 1;                   //One message/action
  messagebuffer.msgs = write_user_reg;       //load the 'writ_user_reg' message into the buffer
  rc = ioctl(fd, I2C_RDWR, &messagebuffer);  //Send the buffer to the bus and returns a send status
  //printf("RC:%i\n",rc);
  if (rc < 0 ) return -1;
  return 0;
}

int htu21df_init(int fd){
  int rc;
  int UserReg;
  struct i2c_rdwr_ioctl_data messagebuffer;
  
  uint8_t deviceAction=HTU21DF_RESET;

  //Build a reset command for the htu21df
  struct i2c_msg reset[1] = {
    {HTU21DF_I2CADDR,0,1,&deviceAction}
  };
  
  messagebuffer.nmsgs = 1;                   //Only one message/action
  messagebuffer.msgs = reset;                //load the 'reset' message into the buffer
  rc = ioctl(fd, I2C_RDWR, &messagebuffer);  //Send the buffer to the bus and returns a send status
  if (rc < 0 ){
    printf("\n");
    printf("%s :htu21df Reset command 'sending' failed with error :%d\n",__func__,errno);
    printf("This means that device with address :0x%0x failed to receive this command\n",HTU21DF_I2CADDR);
    printf("Possible that the device is not connected to the bus specified, or the device is not 'live' due to wiring\n");
    printf("\n");
    // Only one of the following lines should be used
    // the second line allows you to retry, PS disable all the printf 's 
    //exit(1);       //Use this line if the function must terminate on failure
    return rc;       //Use this line if it must return to the caller for processing
  }

  // wait for the HTU21 to reset
  sleepms(HTU21DF_ResetDelay);
  
  if (htu21df_ReadUserReg(fd,&UserReg) == 0){
    /*
    if ( UserReg != 0x02){
      printf("\n");
      printf("%s :htu21df User Reg should have contained 2 but contained :%i\n",__func__,rc);
      printf("By this time you should be able to figure this one out yourself\n");
      printf("Hint it may not be an actual fault! RTFM\n");
      printf("\n");
      //exit(1);       //Use this line if the function must terminate on failure
      return 0;       //Use this line if it must return to the caller for processing
      }
     */ 
      return 0;
  }else{
    return -1;
    //exit (1);
  }
}

int htu21df_getValue(int fd, float *Value, const uint8_t YourBiddingMaster ){
  uint8_t replymessage[2]; //Appears this gets redimentioned in the ioctl call??
  int rc;
  uint16_t deviceValue;
  struct i2c_rdwr_ioctl_data messagebuffer;
  
  uint8_t deviceAction=0;
  
  switch (YourBiddingMaster)
  {
    case HTU21DF_READTEMP:
      deviceAction=HTU21DF_READTEMP;
      break;
    case HTU21DF_READHUM:
      deviceAction=HTU21DF_READHUM;
      break;
    default:
      return -1;
      //exit (1);
      break;
  }

  //Build a convert_start command for the htu21df
  struct i2c_msg convert_start[1] = {
    {HTU21DF_I2CADDR,0,1,&deviceAction}
  };
  
  messagebuffer.nmsgs = 1;                   //One message/action
  messagebuffer.msgs = convert_start;        //load the 'convert_start' message into the buffer
  rc = ioctl(fd, I2C_RDWR, &messagebuffer);  //Send the buffer to the bus and returns a send status
  //printf("RC:%i\n",rc);
  if (rc < 0 ){                              
    i2c_commonsenderror(fd,HTU21DF_I2CADDR);      
    return rc;
    //exit (1);
  }
  else{
    //Create a read 3 byte message
    struct i2c_msg read_value[1] = {
      {HTU21DF_I2CADDR,I2C_M_RD,3,replymessage}
    };
    int i=0;
    sleepms(HTU21DF_MinDelay);
    do{
      //Try 20 times pausing for HTU21DF_RetryDelay ie 20 * 5 ms + HTU21DF_MinDelay > 116 ms
      //Physical max times should be 50 ms but assuming usleep() does not work correctly during overclocking
      //required delay could be  50*1000MHz/700MHz = 72 ms which is less than 116 ms
      //dont stress max wasted time would be < HTU21DF_RetryDelay '5 ms'
      //dont reduce this time to much as you still have the bus speed to contend with
      //NO point in checking faster than the bus can operate.
      sleepms(HTU21DF_RetryDelay);
      messagebuffer.nmsgs = 1;
      messagebuffer.msgs = read_value;
      //Send the message, if data is ready for collection then collect
      rc = ioctl(fd,I2C_RDWR, &messagebuffer);
      //If not rc will be < 0 and we pause and try again        
      //printf ("Index:%i, RC:%i\t%i\t%i\t%i\n",i,rc,replymessage[2],replymessage[1],replymessage[0]);
      i++;
    }while (rc<0 && i <20);
    
    if (rc < 0 ){
      //printf("%s: I2C_RDWR Error %d\n",__func__,errno);
      return rc;
      //exit (1);
    }    
  }
  if (htu21df_crcdata(replymessage,&deviceValue)){
    printf("%s:CRC Failed\n",__func__);
    return -1;
  }

  switch (YourBiddingMaster)
  {
    case HTU21DF_READTEMP:
      *Value = ((deviceValue / 65536.0) * 175.72) - 46.85;  
      break;
    case HTU21DF_READHUM:
      *Value = ((deviceValue / 65536.0) * 125.0) - 6.0;    
      break;
    default:
      return -1;
      //exit (1);
      break;
  }
  //printf("Device temp 0x%x\n", deviceValue);
  return 0;
}

float htu21df_compensatedRH(float RH,float TempCell){
  return ( RH+((25-TempCell)*-0.15) ) ;
}

float htu21df_pptamb(float Temp){
  float TempValue=htu21df_ACo-(htu21df_BCo/(Temp+htu21df_CCo));
  double ppTamb =  pow (10,TempValue);
  return ppTamb;
}

float htu21df_DewPoint(float Temp, float Hum){
  double TempValue=htu21df_ACo-(htu21df_BCo/(Temp+htu21df_CCo));
  double ppTamb =  pow (10,TempValue);
  double DewP= -(( htu21df_BCo /  ((log10 (Hum*ppTamb/100))-htu21df_ACo))+htu21df_CCo);
  return DewP;
}

//END: htu21df specific code


int main(int argc, char **argv){
//  int rc;
  int fd = i2c_Open(I2CBus); //program will terminate within function if bus not present.
  float myTemp,myHum;

  int htu21rc = htu21df_init(fd);
//  printf("\nDevice accessed via File descriptor:%0i\t at Address:0x%0x\t has returned:%0i\n",fd,HTU21DF_I2CADDR,htu21rc);   

  if (htu21rc == 0){
    int UserRegVal;
    htu21df_ReadUserReg(fd,&UserRegVal);
//    printf("User Reg\tBefore\t:0x\%0x\n",UserRegVal);
    //htu21df_WriteUserReg(fd,0x03);  //try 0x03 my chip default is 0x02
    //sleepms(100);
    htu21df_ReadUserReg(fd,&UserRegVal);
//    printf("User Reg\tAfter\t:0x\%0x\n\n",UserRegVal);
    
    printf ("%.2f\n",htu21df_getValue(fd,&myTemp,HTU21DF_READTEMP),myTemp);
    printf ("%.2f\n",htu21df_getValue(fd,&myHum,HTU21DF_READHUM),myHum);
    float ComRH=htu21df_compensatedRH(myHum,myTemp);
    printf ("%.2f\n",ComRH);
//    printf ("Partial  \tPressure\t:%.2fpp\n",htu21df_pptamb(myTemp));
    printf ("%.2f\n",htu21df_DewPoint(myTemp, ComRH));
  }
  close (fd);   
  return 0;
}

And the .H

//All the following is from the htu21df manual
#define HTU21DF_I2CADDR    0x40
#define HTU21DF_READTEMP   0xF3 //No Hold
#define HTU21DF_READHUM    0xF5 //No Hold
#define HTU21DF_WRITEREG   0xE6
#define HTU21DF_READREG    0xE7
#define HTU21DF_RESET      0xFE

static const int HTU21DF_ResetDelay = 15;
static const int HTU21DF_MinDelay   = 11; //Should be 16-RetryDelay (16 or so for hum 50 for temp)
static const int HTU21DF_RetryDelay = 5; 

static const float htu21df_ACo=8.1332;
static const float htu21df_BCo=1762.39;
static const float htu21df_CCo=235.66;

int         i2c_Open             (char *I2CBusName);
void        i2c_commonsenderror  (int fd, uint8_t DeviceAddress);
int         htu21df_crcdata      (const uint8_t *Data, uint16_t *ConvertedValue);
int         htu21df_ReadUserReg  (int fd, int *retValue);
int         htu21df_WriteUserReg (int fd,int NewValue);
int         htu21df_init         (int fd);
int         htu21df_getValue     (int fd, float *Value, const uint8_t YourBiddingMaster );
float       htu21df_compensatedRH(float RH,float TempCell);
float       htu21df_pptamb       (float Temp);
float       htu21df_DewPoint     (float Temp, float Hum);

Its realy fast in execution.

Just to see how it works I added a MCP23017 port extender and that was working quite well.

I used a small test bash script with a led on GPA0

#!/bin/bash
#
#
# MCP23017 test
#

GPA=0x14 # MCP23017 use GPA
GPB=0x15 # MCP23017 use GPB
I2C=0x20 # I2C address of MCP23017 A0 A1 A2 grounded
COUNT=0
SLEEPER=0.2
LOWEST=0
if [ -t 0 ]; then stty -echo -icanon time 0 min 0; fi

echo
echo "Press 'q' to quit 's' for slower blinking and 'f' for faster."
echo

while :
do
      read -t 0.01 -n 1 key
      /usr/sbin/i2cset -y 1 $I2C $GPA 0x01  # MCP23017 led on (pin 21 if GPA)
      sleep $SLEEPER
      /usr/sbin/i2cset -y 1 $I2C $GPA 0x00  # MCP23017 led off (pin 21 if GPA)
      sleep $SLEEPER
      let count+=1
      if [[ $key = q ]]
      then
          if [ -t 0 ]; then stty sane; fi
          echo "Led blinked" $count "times."
#         TEST=($SLEEPER | bc | awk '{printf "%0.3d", $1}') 
          echo "Last blinking delay $SLEEPER sec."
          echo
          break
      fi
      if [[ $key = s ]]
      then
       SLEEPER=$(echo "$SLEEPER + 0.01" |bc)
      fi
      if [[ $key = f ]]
      then
       if (( $(echo "$LOWEST < $SLEEPER" | bc -l ) ));
       then
         SLEEPER=$(echo "$SLEEPER - 0.01" |bc)
       fi
      fi
done

exit 0

Or a smile script:
You need 2 * 10 Segment Digital Red LED Bar Graph Display Ultra Bright (from ebay at $1,57)

http://pi.gids.nl:81/images/10leddisp.png

#!/bin/bash
#
#
i2cset -y 1 0x20 0x00 0x00 # configure Port A pins GPA0-6 as outputs
i2cset -y 1 0x20 0x01 0x00 # configure Port B pins GPA0-6 as outputs
#
RIGHT="/usr/sbin/i2cset -y 1 0x20 0x14"
LEFT="/usr/sbin/i2cset -y 1 0x20 0x15"
x=1
T=0.01

if [ -z "$1" ];
then
  COUNT=20
else
  COUNT=$1
fi

while [ $x -le $COUNT ]
do
   $RIGHT 1
   $LEFT 128
   sleep $T
   $RIGHT 2
   $LEFT 64
   sleep $T
   $RIGHT 4
   $LEFT 32
   sleep $T
   $RIGHT 8
   $LEFT 16
   sleep $T
   $RIGHT 16
   $LEFT 8
   sleep $T
   $RIGHT 32
   $LEFT 4
   sleep $T
   $RIGHT 64
   $LEFT 2
   sleep $T
   $RIGHT 128
   $LEFT 1
   sleep $T
   $RIGHT 64
   $LEFT 2
   sleep $T
   $LEFT 4
   $RIGHT 32
   sleep $T
   $LEFT 8
   $RIGHT 16
   sleep $T
   $LEFT 16
   $RIGHT 8
   sleep $T
   $LEFT 32
   $RIGHT 4
   sleep $T
   $LEFT 64
   $RIGHT 2
   sleep $T
   $LEFT 128
   $RIGHT 1
   sleep $T
   let "x++"
done
$LEFT 0
$RIGHT 0
#
#
# End

Use with ./{scriptname] x where x is number of walks

Or for some C coding see also http://wiringpi.com/extensions/i2c-mcp23008-mcp23017/ this page.
He build a Wiring Pi solution

Any other good examples, please let me know...

Using WebIOPI one get a nice web besed interface to use this device (and others)

My WebIOPI config [DEVICES] part:

[DEVICES]
# Device configuration syntax:
# name = device [args...]
#   name   : used in the URL mapping
#   device : device name
#   args   : (optional) see device driver doc
# If enabled, devices configured here are mapped on REST API /device/name
# Devices are also accessible in custom scripts using deviceInstance(name)
# See device driver doc for methods and URI scheme available

# Raspberry native UART on GPIO, uncomment to enable
# Don't forget to remove console on ttyAMA0 in /boot/cmdline.txt
# And also disable getty on ttyAMA0 in /etc/inittab
#serial0 = Serial device:ttyAMA0 baudrate:9600

# USB serial adapters
#usb0 = Serial device:ttyUSB0 baudrate:9600
#usb1 = Serial device:ttyACM0 baudrate:9600

#temp0 = TMP102
#temp1 = TMP102 slave:0x49
temp2 = DS18B20
#temp3 = DS18B20 slave:28-0000049bc218

bmp = BMP085

#gpio0 = PCF8574
#gpio1 = PCF8574 slave:0x21

#light0 = TSL2561T
#light1 = TSL2561T slave:0b0101001

gpio0 = MCP23017
#gpio1 = MCP23017 slave:0x21
#gpio2 = MCP23017 slave:0x22

#pwm0 = PCA9685
#pwm1 = PCA9685 slave:0x41

adc = MCP3208

http://pi.gids.nl:81/images/webiopi1.png

Chrs

I have added a MCP3208 and that was quite a struggle to get it to work correct with Python and C coding.
I created a web page to see the whole story.

http://pi.gids.nl:81/adc

Just check it if you are interested.

You can see it in action here :

http://pi.gids.nl:81/temp/gauges.php

Chrs

A nice audio card for the RPI can be found http://www.element14.com/community/comm … wolfson_pi here. Looks like good specs to me. Have to get me one..
Another link here http://liliputing.com/2014/03/raspberry … ch-pc.html

Wolfson Audio Card:

http://pi.gids.nl:81/bb/pic/WolfsonAudioCardcallout.png

My used code...

# I2C writes =D0=0                                                                                                                                  
# MMA7455 I2C address 1D (3A ,3B) write , read                                                                                                      
# AN3745 app note for calibration                                                                                                                   
# byte read , write 1D , write address, read 1D ,DATA                                                                                               
# Byte write, write 1D , write address, write data.                                                                                                 
# addresses,                                                                                                                                        
# 06 XOUT8                                                                                                                                          
# 07 YOUT8                                                                                                                                          
# 08 ZOUT8                                                                                                                                          
# 09 STATUS  D0 1=data ready                                                                                                                        
# 0A detection source                                                                                                                               
# 0F who am i                                                                                                                                       
# 16 Mode Control  x1000101 measure 2gmode 0x45                                                                                                     
# 16 Mode Control  x1000001 measure 8gmode 0x41                                                                                                     
# 16 Mode Control  x1000100 standby 2gmode 0x84                                                                                                     
# 16 Mode Control  x1010101 ston measure 2gmode 0x55                                                                                                
# 18 Control1  D7 filter 0=62Hz,1=125Hz other 0                                                                                                     
# 19 Control2  default 0                                                                                                                            
#!/usr/bin/python                                                                                                                                   
import smbus
import time
import os
# import graphics                                                                                                                                   
# Define a class called Accel                                                                                                                       
class Accel():
    b = smbus.SMBus(1)
    def setUp(self):
        # Setup the Mode                                                                                                                            
        self.b.write_byte_data(0x1D,0x16,0x55)
        # Setup Calibration                                                                                                                         
        self.b.write_byte_data(0x1D,0x10,0)
        self.b.write_byte_data(0x1D,0x11,0)
        self.b.write_byte_data(0x1D,0x12,0)
        self.b.write_byte_data(0x1D,0x13,0)
        self.b.write_byte_data(0x1D,0x14,0)
        self.b.write_byte_data(0x1D,0x15,0)

    def getValueX(self):
        return self.b.read_byte_data(0x1D,0x06)

    def getValueY(self):
        return self.b.read_byte_data(0x1D,0x07)

    def getValueZ(self):
        return self.b.read_byte_data(0x1D,0x08)

MMA7455 = Accel()
MMA7455.setUp()

for a in range(10000):
    x = MMA7455.getValueX()
    y = MMA7455.getValueY()
    z = MMA7455.getValueZ()

    print "x=", x , "\t[" , "=" * (80 * x / 256) , " " *  (80 - (80 * x / 256)) , "] " , (80 * x / 256) , "%"
    print "y=", y , "\t[" , "=" * (80 * y / 256) , " " *  (80 - (80 * y / 256)) , "] " , (80 * y / 256) , "%"
    print "z=", z , "\t[" , "=" * (80 * z / 256) , " " *  (80 - (80 * z / 256)) , "] " , (80 * z / 256) , "%"

    time.sleep(0.1)
    os.system('clear')

Have fun..

For Python:
I am using https://github.com/adafruit/Adafruit-Ra … ython-Code this and that's working fine.

For C there is :
https://github.com/technion/lol_dht22

and

// How to access GPIO registers from C-code on the Raspberry-Pi
// Example program
// 15-January-2012
// Dom and Gert
//
// Access from ARM Running Linux
#define BCM2708_PERI_BASE 0x20000000
#define GPIO_BASE (BCM2708_PERI_BASE + 0x200000) /* GPIO controller */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <fcntl.h>
#include <assert.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <bcm2835.h>
#include <unistd.h>
#define MAXTIMINGS 100
//#define DEBUG
#define DHT11 11
#define DHT22 22
#define AM2302 22
int readDHT(int type, int pin);
int main(int argc, char **argv)
{
if (!bcm2835_init())
return 1;
if (argc != 3) {
printf("usage: %s [11|22|2302] GPIOpin#\n", argv[0]);
printf("example: %s 2302 4 - Read from an AM2302 connected to GPIO #4\n", argv[0]);
return 2;
}
int type = 0;
if (strcmp(argv[1], "11") == 0) type = DHT11;
if (strcmp(argv[1], "22") == 0) type = DHT22;
if (strcmp(argv[1], "2302") == 0) type = AM2302;
if (type == 0) {
printf("Select 11, 22, 2302 as type!\n");
return 3;
}
int dhtpin = atoi(argv[2]);
if (dhtpin <= 0) {
printf("Please select a valid GPIO pin #\n");
return 3;
}
printf("Using pin #%d\n", dhtpin);
readDHT(type, dhtpin);
return 0;
} // main
int bits[250], data[100];
int bitidx = 0;
int readDHT(int type, int pin) {
int counter = 0;
int laststate = HIGH;
int j=0;
// Set GPIO pin to output
bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_OUTP);
bcm2835_gpio_write(pin, HIGH);
usleep(500000); // 500 ms
bcm2835_gpio_write(pin, LOW);
usleep(20000);
bcm2835_gpio_fsel(pin, BCM2835_GPIO_FSEL_INPT);
data[0] = data[1] = data[2] = data[3] = data[4] = 0;
// wait for pin to drop?
while (bcm2835_gpio_lev(pin) == 1) {
usleep(1);
}
// read data!
for (int i=0; i< MAXTIMINGS; i++) {
counter = 0;
while ( bcm2835_gpio_lev(pin) == laststate) {
counter++;
//nanosleep(1); // overclocking might change this?
if (counter == 1000)
break;
}
laststate = bcm2835_gpio_lev(pin);
if (counter == 1000) break;
#ifdef DEBUG
bits[bitidx++] = counter;
#endif
if ((i>3) && (i%2 == 0)) {
// shove each bit into the storage bytes
data[j/8] <<= 1;
if (counter > 200)
data[j/8] |= 1;
j++;
}
}
#ifdef DEBUG
for (int i=3; i<bitidx; i+=2) {
printf("bit %d: %d\n", i-3, bits[i]);
printf("bit %d: %d (%d)\n", i-2, bits[i+1], bits[i+1] > 200);
}
#endif
printf("Data (%d): 0x%x 0x%x 0x%x 0x%x 0x%x\n", j, data[0], data[1], data[2], data[3], data[4]);
if ((j >= 39) &&
(data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) ) {
// yay!
if (type == DHT11)
printf("Temp = %d *C, Hum = %d \%\n", data[2], data[0]);
if (type == DHT22) {
float f, h;
h = data[0] * 256 + data[1];
h /= 10;
f = (data[2] & 0x7F)* 256 + data[3];
f /= 10.0;
if (data[2] & 0x80) f *= -1;
printf("Temp = %.1f *C, Hum = %.1f \%\n", f, h);
}
return 1;
}
return 0;
}

Use this makefile:

CC = gcc
CFLAGS = -std=c99 -I. -lbcm2835
DEPS =
OBJ = Adafruit_DHT.o

%.o: %.c $(DEPS)
        $(CC) -c -o $@ $< $(CFLAGS)

Adafruit_DHT: $(OBJ)
        gcc -o $@ $^ $(CFLAGS)

At Ebay purchased a DS1307 module with battery for $1.80 and want to connect it to the I2C system.

It was not that easy to get it to run and I am still struggling a bit:

However this site http://www.raspberrypi.org/phpBB3/viewt … mp;t=16218 is giving more pointers that the ones below:

Added with this http://www.raspberrypi.org/phpBB3/viewt … mp;t=20619 link the RC works but
root@pi:~# i2cget -y 1 0x68 0         
Error: Could not set address to 0x68: Device or resource busy (still produces an error)

See http://learn.adafruit.com/adding-a-real … t-rtc-time

Or check http://www.youtube.com/watch?v=YaTeTCEgkk4

Or http://www.element14.com/community/grou … pi-via-i2c for a more complete overview.

Or if you can read German use this page as its the best match for my real time clock module. See here: http://www.forum-raspberrypi.de/Thread- … -betreiben same sort of link here http://ruessel.in-chemnitz.de/arm/rtc.html

O noticed that the drift is quite high so played the bidding game on Ebay and got a high precision RTC module for about $2.

Will put the experience here shortly.

Chrs

See http://www.bitwizard.nl/wiki/index.php/ … spberry_Pi this link.

Chrs

I have attached the original code that I use on my website.

However I noticed that overtime things changed on my RPi in relation to the I2C setup.
If you also encounter I2C compile errors use the second file bmp085-i2c.zip unzip and run doit.sh.

Chrs

Wanted a web based SMS gateway and found a nice wavecom USB modem on Ebay $20

http://pi.gids.nl:81/bb/pic/wavecom.jpg

$ apt-get install minicom

Start minicom set the proper device and see if your modem responds. (start minicom not as root to set device)
Use the AT command set features for that [http://en.wikipedia.org/wiki/Hayes_command_set]

Used http://blog.sleeplessbeastie.eu/2012/07 … y-at-home/ this link to set up Kalkun to be found http://kalkun.sourceforge.net/.

Ensure you set up all using MySQL to ensure it al runs....

First setup gammu and Kalkun as mentioned https://github.com/back2arie/Kalkun/wiki/Installation

After that follow the next steps:

First step

Install your favourite Linux distribution, Gammu and Gammu SMS daemon (gammu-smsd) with all dependencies

Second step

Connected my WaveCom GPRS modem to the USB port.

You can see below that that I will have to use the /dev/ttyUSB0 device.

$ dmesg | grep pl23
[   19.090354] usbcore: registered new interface driver pl2303
[   19.281783] USB Serial support registered for pl2303
[   19.441386] pl2303 1-1.2:1.0: pl2303 converter detected
[   19.636015] usb 1-1.2: pl2303 converter now attached to ttyUSB0

$ lsusb
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 004: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port

Edit /etc/gammurc file:

[gammu]
device = /dev/ttyUSB0
connection = at9600

gammu --identify
Device               : /dev/ttyUSB0
Manufacturer   : Wavecom
Model                : MULTIBAND  900E  1800 (MULTIBAND  900E  1800)
Firmware          : 430d09gm.2C 1208564 012102 12:43
IMEI                    : xxxxxxxxxxxxxxxxxxx
SIM IMSI            : yyyyyyyyyyyyyyyyyyy

Third step

Install web server with php support, MySQL database server and Kalkun.
Kalkun installation instructions can be found at github.com/back2arie/Kalkun/wiki.

Final /etc/gammu-smsdrc configuration file should look like this:

[gammu]
device = /dev/ttyUSB0
connection = at9600

[smsd]
PIN=9999
runonreceive = /var/www/kalkun/scripts/daemon.sh
logfile = /var/log/gammu.log
commtimeout = 10
sendtimeout = 20
deliveryreport = log
phoneid = WaveCom
transmitformat = auto

# Storage - MySQL
service = SQL
driver = native_mysql
database = kalkun
user = kalkun
password = kalkun_password
pc = localhost

# Storage - Files
# service = FILES
# Paths where messages are stored
#inboxpath = /var/spool/gammu/inbox/
#outboxpath = /var/spool/gammu/outbox/
#sentsmspath = /var/spool/gammu/sent/
#errorsmspath = /var/spool/gammu/error/
# inboxformat = standard

debuglevel = 1
# Use 255 to see all issues if it is not working well.....

# Limit SQL polling on the PI (causes the website to display Not Connected but works fine
# Only add after all is working fine

StatusFrequency = 0
CommTimeout = 60
CheckSecurity = 0
CheckBattery = 0
CheckSignal = 0
PhoneID = WaveCom
ReceiveFrequency = 60
LoopSleep = 30


To start Gammu SMS daemon execute command:

$ gammu-smsd

You can send a SMS using the console command (if you want to check your configuration):

$ gammu-smsd-inject TEXT 0612345678 -text "Test message"

Your good to go.....

As alternative you can use http://playsms.org/ but than you should not use Gammu in MySQL mode as thats not supported with playsms. I wish it was. Playsms offers more control but not tested that yet fully.

The PI has not that much RAM and once the swap is used its tricky to find where the memory goes.

However see this easy script:

#!/bin/bash
#
# show swap used by processes
#
(for PROCESS in /proc/*/; do
  swapused=$(awk 'BEGIN { total = 0 } /^Swap:[[:blank:]]*[1-9]/ { total = total + $2 } END { print total }' ${PROCESS}/smaps 2>/dev/null || echo 0)
  if [ $swapused -gt 0 ]; then
    /bin/echo -e "${swapused}k\t$(cat ${PROCESS}/cmdline)"
  fi
done ) | sort -nr
#

Does the trick very well.

Rgds.

Add this to your /boot/config.txt

# Badly named option, means 'enable frequency scaling':
force_turbo=0
# The lowest frequency we will allow the RPi to run at:
arm_freq_min=100
# for more options see http://elinux.org/RPi_config.txt

run

root@pi:~# apt-get install cpufrequtils

Do a:

root@pi:~# cpufreq-set -g ondemand

This is the default anyway..

And run
root@pi:~# watch -n 1 'cpufreq-info | grep "current CPU frequency is"'

Now perform a web request and see the speed go up... If idle it drops to 100 Mhz hence cooling down and being green.

With
root@pi:~# apt-get install cpufrequtils

and

root@pi:~# cpufreq-info
cpufrequtils 008: cpufreq-info (C) Dominik Brodowski 2004-2009
Report errors and bugs to cpufreq@vger.kernel.org, please.
analyzing CPU 0:
  driver: BCM2835 CPUFreq
  CPUs which run at the same hardware frequency: 0
  CPUs which need to have their frequency coordinated by software: 0
  maximum transition latency: 355 us.
  hardware limits: 100.0 MHz - 1000 MHz
  available cpufreq governors: conservative, ondemand, userspace, powersave, performance
  current policy: frequency should be within 100.0 MHz and 1000 MHz.
                  The governor "ondemand" may decide which speed to use
                  within this range.
  current CPU frequency is 100.0 MHz (asserted by call to hardware).

It shows you the details...

Just get a RS232 module from Ebay and than connect it to your PI.
A description has been made http://davidhunt.ie/?p=3091 here.
Another one can be found http://putokaz.wordpress.com/2013/03/12 … s-revisit/ here also...


Chrs

A very nice tool to stream to your media devices.
Even works well on Showcenter 1000 200 250

Check this http://wiki.daviddarts.com/RaspberryPi link.

Works fine here...


MiniDLNA

MiniDLNA is server software with the aim of being fully compliant with DLNA/UPnP clients. The MiniDNLA daemon serves media files (music, pictures, and video) to clients on a network. Example clients include applications such as XBMC, and devices such as portable media players, smartphones, and televisions. MiniDLNA is a simple, lightweight alternative to MediaTomb, but has fewer features. It does not have a web interface for administration and must be configured by editing a text file.

1. Install MiniDLNA:

apt-get install minidlna

2. Set correct ownerships to MiniDLNA's database and log file:

chown minidlna:minidlna /var/lib/minidlna/
chown minidlna:minidlna /var/log/

3. Create a media directory and set permissions:

mkdir /mnt/data/Media
chmod -R 777 /mnt/data/Media

4. Edit MiniDLNA's config file:

nano /etc/minidlna.conf

Be sure to uncomment, name and set the correct directories for:

media_dir=/mnt/data/Media 
db_dir=/var/lib/minidlna
log_dir=/var/log
friendly_name=minidlna
inotify=yes
notify_interval=895

5. Reboot:

reboot

Note: you can manually start MiniDLNA but it should start automatically after each reboot.

/etc/init.d/minidlna start

Note: MiniDLNA requires time to index your Media. In the event of an error, try deleting the database and reindexing your media:

/etc/init.d/minidlna stop
rm /var/lib/minidlna/files.db
/etc/init.d/minidlna start

To correct the inotify warning in the minidlna.log file, do the following:

nano /etc/sysctl.conf

Append this to the bottom of the file:

fs.inotify.max_user_watches = 100000

Reboot.

Chrs

BH1750FVI

http://pi.gids.nl:81/temp/img/BH1750FVI.png

Some good code was provided by the community thanks:

C code.....:

/*
 Sample code for the BH1750 Light sensor for Raspberry Pi
 Connection:
 VCC-5v (Raspberry pin 1)
 GND-GND(Raspberry pin 6)
 SCL-SCL(Raspberry pin 5)
 SDA-SDA(Raspberry pin 3)
 ADD-NC or GND
 * 
 * gcc -o bh1750fvi bh1750fvi.c 
 * 
 */
#include <stdio.h>
#include <stdint.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <math.h>
#include <linux/i2c-dev.h>
// #include <linux/i2c.h>
#include <sys/ioctl.h>
// #include "smbus.h"

# You need to play with the <linux/i2c-dev.h> & smbus.h I got errors loading them ....!!

#define BH1750FVI_I2C_ADDRESS 0x23 // ADDR > 0.7 VCC)
//#define BH1750FVI_I2C_ADDRESS  0x53 // ADDR < 0.3 VCC)
#define DEBUG 0

#define PowerDown    0x00
#define PowerOn    0x01
#define Reset      0x07
#define ContinuHigh   0x10
#define ContinuLow   0x13
#define OneTimeHigh   0x20
#define OneTimeLow   0x23

int main(int argc, char **argv)
{
    int fd;
    char *fileName = "/dev/i2c-1";
    int retCode;
    int readSize;
    unsigned int res;
    unsigned int lux;
    char buf[5];
    int i;

    // Open port for reading and writing
    if ((fd = open(fileName, O_RDWR)) < 0) {
        printf("open error\n");
        exit(1);
    }
   
    // Set the port options and set the address of the device
    if (ioctl(fd, I2C_SLAVE, BH1750FVI_I2C_ADDRESS) < 0) {
        printf("ioctl error\n");
        close(fd);
        exit(1);
    }

    retCode=i2c_smbus_write_byte(fd, PowerOn);
if(DEBUG)printf("Power On retCode=%d\n",retCode);
    if (retCode < 0) {
        printf("PowerOn error\n");
        close(fd);
        exit(1);
    }
   
    retCode=i2c_smbus_write_byte(fd, ContinuHigh);
if(DEBUG)printf("ContinuHigh retCode=%d\n",retCode);
    if (retCode < 0) {
        printf("ContinuHigh error\n");
        close(fd);
        exit(1);
    }

    for(i=0;i<20;i++) {
//        sleep(1);
        readSize = read (fd, buf, 2);
if(DEBUG)printf("read readSize=%d %x %x\n",readSize,buf[0],buf[1]);

        res = buf[0]*256+buf[1];
if(DEBUG)printf("res=%x\n",res);
        lux = res / 1.2;
        printf("Lux=%d\n",lux);
    }

    retCode=i2c_smbus_write_byte(fd, PowerDown);
    close(fd);

    exit (0);
}

And a quite simple Python code:

#!/usr/bin/python
# -*- encoding: utf-8 -*-

import time
import smbus
import decimal

# bus = smbus.SMBus(0) #(256MB)
bus = smbus.SMBus(1) #(512MB)

addr = 0x23 # i2c adress

# while True:
count = 0
while (count < 10):
    data = bus.read_i2c_block_data(addr,0x11)
#  lux1 = "Luminosity " + str((data[1] + (256 * data[0])) / 1.2) + " lx"
    lux2 = str((data[1] + (256 * data[0])) / 1.2)
    lux  = decimal.Decimal(lux2).quantize(decimal.Decimal('.01'), rounding=decimal.ROUND_UP)
    outlux = str(lux)
    print "Luminosity " + outlux + " lx"
    time.sleep(0.25)
    count = count + 1

Let us know your setup.

Chrs

Hello,

Please feel free to update your code here of place pictures of your own setup.
I will start uploading my info also and all code under the proper headings.

Rgds Paul