Jump to: navigation, search

1-Wire Bus for MP02


Adding a 1-Wire bus capability to the MP2 allows the use of a range of sensor devices including Temperature, Voltage and Current.

To provide a 1-Wire bus, one spare GPIO pin is used along with several driver and utility software modules.

The MP02 has a 'Router' connector on the main board which is used to accommodate a range of daughter boards such as the FXS telephony board. The required GPIO line is are available on this connector, along with power lines, making it easy to connect 1-Wire sensors.

This article describes describes how to connect a DS18B20 temperature sensor as an example. This device is readily available for under $5 and provides a precision temperature measurement.

Setting up the 1-Wire Bus

In order to use GPIO line for the 1-Wire bus, it is necessary to install several additional packages, specifically 'kmod-w1', 'kmod-w1-gpio-custom', 'kmod-w1-master-gpio' and kmod-w1-therm'.

If building the firmware, run 'make menuconfig' and select the packages in 'Kernel modules / W1 Support' as follows:

 <*> kmod-w1.......................................... Dallas's 1-wire support
 <*>   kmod-w1-gpio-custom...................... Custom GPIO-based 1-wire device
 -*-   kmod-w1-master-gpio........................ GPIO 1-wire bus master driver
 <*>   kmod-w1-slave-therm........................ Thermal family implementation

There are additional optional packages available for specific devices:

 < >   kmod-w1-master-ds2482................ DS2482 1-wire i2c bus master driver
 < >   kmod-w1-master-ds2490................ DS2490 1-wire usb bus master driver
 < >   kmod-w1-slave-ds2413..................... DS2413 2 Ch. Addressable Switch
 < >   kmod-w1-slave-ds2431............................ DS2431 1kb EEPROM driver
 < >   kmod-w1-slave-ds2433............................ DS2433 4kb EEPROM driver
 < >   kmod-w1-slave-ds2760. Dallas 2760 battery monitor chip (HP iPAQ & others)
 < >   kmod-w1-slave-smem............. Simple 64bit memory family implementation

If adding the packages to existing firmware, use opkg as follows:

 > opkg update
 > opkg install kmod-w1
 > opkg install kmod-w1-gpio-custom
 > opkg install kmod-w1-slave-therm

To create the I2C bus using particular GPIO lines it is necessary to pass the GPIO number to the kernel module.

To set this up automatically at boot time, create/edit the file '/etc/modules.d/55-w1-gpio-custom' to contain the following:

   w1-gpio-custom bus0=0,20,0

Note that nominated GPIO line must be available for use or the kernel module will fail to install, with an error message in the 'dmesg' output.

You can include several bus definitions up to a maximum of four, i.e.:

   w1-gpio-custom bus0=0,20,0 bus1=1,21,0 ....

If you do this you must make sure the busses have different IDs.

On devices other than the MP2, you may have to use different GPIO lines depending on which lines are available.

When the 1-Wire bus is set up, you should see it appear in '/sys/devices' as a directory called 'w1_bus_master1'. A second bus will appear as 'w1_bus_master2' and so on.

Within this directory you will find a number of files including 'w1_master_slaves_count' which shows the number of devices connected to the 1-Wire bus, and 'w1_master_slaves' which contains a list of the device identifiers.

There will also be a directory for each device, named as the identifier for the device.

For the DS18B20, the device identifiers start with '28-' followed by a unique device serial number.

Connecting to the I2C Bus Lines

The MP2 has a 'Router' connector on the main PCB which is used to plug in various daughter boards such as the FXS telephony board. The power and signal lines required for the I2C bus appear on this connector as follows:

 Gnd             Pin 4
 Vcc  3.3V       Pin 1
 W1   GPIO-20    Pin 5

It is necessary to connect a pullup resistor of 4.7 kOhms between the W1 line and the 3.3V Vcc line.

You can also use the 5V line available on Pin 2 of the 'Router' connector, depending on the voltage capabilities of the conencted 1-Wire devices. The DS18B20 can operate from 3.0V to 5.5V

It is also possible to operate the 1-Wire bus with just the Gnd and W1 lines, with the sensors deriving power 'parasitically' from the W1 line.

In this configuration, the sensor Vcc line is connected to its Gnd line. The DS18B20 sensor requires up to 1.5mA of current to be available during the temperature reading process, and so it is better to use the pullup resistor connected to the 5V line to ensure there is sufficient current available.

Accessing the DS18B20 W1 Data

To check that the DS18B20 temperature sensor(s) has been successfully connected to the 1-Wire bus, you can check in the directory '/sys/devices/w1_bus_master1' for sub directories corresponding to the device identifiers of the sensors e.g. for DS18B20 the directories will be named '28-xxxxxx'.

Within each device directory, there is a file called 'w1_slave'. Reading the contents of this file initiates the temperature reading process in the sensor and outputs the result as follows:

 # cat /sys/devices/w1_bus_master1/28-03168b1234ff/w1_slave 
   4d 01 4b 46 7f ff 0c 10 c0 : crc=c0 YES
   4d 01 4b 46 7f ff 0c 10 c0 t=20812

This shows that the temperature being recorded is 20.812 C

Note that the default temperature reading is 85 C before the temperature reading process has completed correctly, so if you see 't=85000' then you know that the process has probably not completed correctly.

The temperature reading process can take some time to complete. The default resolution of the DS18B20 device is 12 bits, and the time taken to produce the reading at this resolution is 750mSec. So it may be worthwhile to run the read command as a background process to preven the CPU blocking while waiting for the result.








Sample Code

Get the temperature from the DS18B20 sensors on the first bus:

 # cat /sys/devices/w1_bus_master1/28-*/w1_slave
   9b 01 4b 46 7f ff 0c 10 dc : crc=dc YES
   9b 01 4b 46 7f ff 0c 10 dc t=25937

Get the temperature and format the string:

 # awk -F= '/t=/ {printf "%.03f\n", $2/1000}' /sys/devices/w1_bus_master1/28-*/w1_slave

Script to return a string containing temperature readings from the sensors on the first bus:

 #! /bin/sh
 # /bin/gettemp.sh
 # Get temp data from DS18B20
 echo $(awk -F= '/t=/ {printf "%.03f\n", $2/1000}' /sys/devices/w1_bus_master1/28-*/w1_slave &) " C"

Running the script with two devices on the bus:

 # /bin/gettemp.sh 
   21.562  22.510 C