MATLAB Examples

Communicate with 1-Wire® Devices on Arduino® Hardware

This example shows how to use the MATLAB® Support Package for Arduino® Hardware to communicate with DS18B20 temperature sensor and DS2431 EEPROM

Contents

Hardware Requirements

  • Arduino board
  • DS18B20 digital temperature sensor
  • DS2431 1024-bit EEPROM
  • 4.7K Pull-up resistor

Hardware Setup

  • Connect the center pins of the two 1-Wire devices to pin D10 on Arduino board.
  • Connect the pull-up resistor between the center pins and 5V pin on Arduino board.
  • Connect the other two pins of the two 1-Wire devices to GND pin on Arduino board.

Create OneWire Device Object

Create arduino connection with PaulStoffregen/OneWire add-on library included.

a = arduino('COM38', 'Uno', 'Libraries', 'PaulStoffregen/OneWire')
a = 

  arduino with properties:

                    Port: 'COM38'
                   Board: 'Uno'
           AvailablePins: {'D2-D13', 'A0-A5'}
               Libraries: {'PaulStoffregen/OneWire'}

Create a 1-Wire object for all devices connected on digital pin 10.

sensor = addon(a, 'PaulStoffregen/OneWire', 'D10')
sensor = 

  OneWire with properties:

               Pins: 'D10'
 AvailableAddresses: '28A58925060000B1', '2D8C181010000070'

Control DS18B20 Temperature Sensor

Store the ROM address of the first detected device, which is the DS18B20 digital temperature sensor(start with '28' family code).

addr = sensor.AvailableAddresses{1};

Reset the device, which is required before any operation. Then, start conversion with command '44' and also turn on parasite power mode.

reset(sensor);
write(sensor, addr, hex2dec('44'), true);

% Make sure temperature conversion is done. This is necessary if all commands run continuosly in a script.
pause(1);

Read the device's scratchpad memory which is consisted of eight data bytes and another byte of CRC, computed from the data bytes.

reset(sensor);
write(sensor, addr, hex2dec('BE')); % read command - 'BE'
data = read(sensor, addr, 9);
crc = data(9);
sprintf('Data = %x %x %x %x %x %x %x %x  CRC = %x\n', ...
    data(1), data(2), data(3), data(4), data(5), data(6), data(7), data(8), crc)
if ~checkCRC(sensor, data(1:8), crc, 'crc8')
    error('Invalid data read.');
end
ans =

  1×39 char array

Data = 8a 1 4b 46 7f ff 6 10  CRC = 2c


Combine LSB and MSB of the temperature reading into one value using the first and second byte of the scratchpad data.

raw = bitshift(data(2),8)+data(1);

Get the R0 and R1 bits in the config register, which is the fifth byte in scratchpad data. R0 and R1 together determines the resolution configuration.

cfg = bitshift(bitand(data(5), hex2dec('60')), -5);
switch cfg
    case bin2dec('00')  % 9-bit resolution, 93.75 ms conversion time
        raw = bitand(raw, hex2dec('fff8'));
    case bin2dec('01')  % 10-bit resolution, 187.5 ms conversion time
        raw = bitand(raw, hex2dec('fffC'));
    case bin2dec('10')  % 11-bit resolution, 375 ms conversion time
        raw = bitand(raw, hex2dec('fffE'));
    case bin2dec('11')  % 12-bit resolution, 750 ms conversion time
    otherwise
        error('Invalid resolution configuration');
end
% Convert temperature reading from unsigned 16-bit value to signed 16-bit.
raw = typecast(uint16(raw), 'int16');

Convert to the actual floating point value since the last bit of LSB represents $2^{-4}$.

celsius = double(raw) / 16.0;
fahrenheit = celsius * 1.8 + 32.0;
sprintf('Temperature = %.4f Celsius, %.4f Fahrenheit', celsius, fahrenheit)
ans =

  1×49 char array

Temperature = 24.6250 Celsius, 76.3250 Fahrenheit

Control DS2431 EEPROM

Store the address of the second detected device, which is the DS2431 1024-bit EEPROM(start with '2D' family code).

addr = sensor.AvailableAddresses{2};

Define new eight bytes of data to write to device memory.

newData = 11:18;
sprintf('New scratchpad values: %02x %02x %02x %02x %02x %02x %02x %02x\n', ...
                                            newData(1), newData(2), newData(3), newData(4), ...
                                            newData(5), newData(6), newData(7), newData(8))
ans =

  1×47 char array

New scratchpad values: 0b 0c 0d 0e 0f 10 11 12


Reset the device, which is required before any operation. Then, issue "Write Scratchpad" command('0F') and also turn on parasite power mode.

reset(sensor);
writeCmd = hex2dec('0F');
write(sensor, addr, writeCmd, 1);
% Write new data starting at the target address by appending two bytes of target address(TA1 and TA2) in the beginning.
targetAddress = [hex2dec('20'), hex2dec('00')];
write(sensor, addr, [targetAddress, newData]);
% Read back the returned inverted 16-bit CRC computed by the device on data received
% as two bytes.
crc = read(sensor, addr, 2);

Check write data integrity. Note that CRC is computed on all messages received including command, target address and data.

if ~checkCRC(sensor, [writeCmd, targetAddress, newData], crc, 'crc16')
    error('Invalid Write Data..Do not copy scratchpad to memory');
end

Issue "Read Scratchpad" command('AA').

reset(sensor);
readCmd = hex2dec('AA');
write(sensor, addr, readCmd);
% Read first three bytes as target address and E/S(transfer status
% register).
settings = read(sensor, addr, 3);
sprintf('Current register values: TA1 %02x, TA2 %02x, E/S %02x\n', settings(1), settings(2), settings(3))
% Read the next ten bytes which are current eight data bytes starting at target address and another two bytes of inverted CRC.
data = read(sensor, addr, 10);
sprintf('Current scratchpad values: %02x %02x %02x %02x %02x %02x %02x %02x\n', ...
                                            data(1), data(2), data(3), data(4), ...
                                            data(5), data(6), data(7), data(8))
ans =

  1×48 char array

Current register values: TA1 20, TA2 00, E/S 07



ans =

  1×51 char array

Current scratchpad values: 0b 0c 0d 0e 0f 10 11 12


Check read data integrity. Note that CRC is computed on all messages received including command, target address, E/S and data.

crc = data(9:10);
if ~checkCRC(sensor, [readCmd;settings;data(1:8)], crc, 'crc16')
    error('Invalid Read Data.');
end

Issue "Copy Scratchpad" command to store the scratchpad data into actual device memory.

reset(sensor);
copyCmd = hex2dec('55');
write(sensor, addr, copyCmd);
% Pass in the read-back settings for authorization purpose
write(sensor, addr, settings);
status = read(sensor, addr);
if status ~= readCmd
    error('Copy fails...');
end
disp('Copy success!');
Copy success!

Issue "Read Memory" command.

reset(sensor);
readMemoryCmd = hex2dec('F0');
write(sensor, addr, readMemoryCmd);
write(sensor, addr, targetAddress);
% read 8 bytes of data
data = read(sensor, addr, 8);
sprintf('Current scratchpad values: %02x %02x %02x %02x %02x %02x %02x %02x\n', ...
                                            data(1), data(2), data(3), data(4), ...
                                            data(5), data(6), data(7), data(8))
reset(sensor);
ans =

  1×51 char array

Current scratchpad values: 0b 0c 0d 0e 0f 10 11 12


Clean Up

clear sensor
clear a