# Creating a Simulink Function based on Legacy 1-Wire Add on Library

27 views (last 30 days)
Christopher Harness on 1 Aug 2019
Hello all,
I am trying to develop a Simulink model that reads and identifies values from the Dallas Temperature sensor: DS18B20. This sensor does not read analog signals, and instead utilizes the "One-Wire Protocol". Thankfully there is a compatible library (see link: https://www.mathworks.com/matlabcentral/fileexchange/57897-legacy-1-wire-add-on-library-for-arduino) for this method, and a sample code is given. This code essentially calls upon the Arduino library, "OneWire", and takes the serial data taken from the sensor, and further modifies/converts the incoming data into a readable, decimal value.
I modified this code so that it can perform the following:
• Read sensor/temperature data for any # of iterations that a user can define (the N value)
• Generate two subplots for the converted Celsius and Fahrenheit values that reads the input data for any # of iternations
From this code, my goal is to create a simple user interface, via Simulink, that a high school student can execute and plot data based on a custom amount of iterations they create (this can be a constant block used as an input). I have tried using both the S-Function block and the Matlab Function/System blocks, but have not been able to successfully execute this code since it cannot call upon the Arduino "OneWire" library, or successfully read the Arduino and Sensor functions. Below I have an image of a draft of my Simulink model, and I have a sample of the modified "OneWire" Matlab code that will generate raw data only (the temperature conversions will be done in Simulink, so that students can visually see the unit conversions).
If anyone can help me on designing this Simulink model (the sensor reading and raw data production), or at least give me some assistance in how to implement the following Matlab/Arduino code for Simulink use, I would be incredibly grateful! Matlab OneWire Code:
%% Create OneWire Device Object
clear
clc
i = 1;
% Create arduino connection with PaulStoffregen/OneWire add-on library included.
a = arduino('COM5', 'Mega2560', 'Libraries', 'PaulStoffregen/OneWire');
% Create a 1-Wire object for all devices connected on digital pin 10.
% Create a Number of Instances
N = 50; % Every 10 instances = 1 sec
% Start Data Collection
while i < N
% 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).
% Reset the device, which is required before any operation.
% Then, start conversion with command '44' and also turn on parasite power mode.
reset(sensor);
% Make sure temperature conversion is done. This is necessary if all commands run continuosly in a script.
% 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);
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')
end
% 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');
end