How can I read multiple sensors through the serial?
Show older comments
I want to read 3 thermocouple sensor from my Arduino which is connected through serial port. I have succecssfully read the 3 temperature but the result is combine in only 1 graph. So how to make it display in 3 graph for each the sensor.
Matlab Code:
clear all
s = serial('COM4');
fopen(s);
i=1;
while(1)
data(i) = str2double(fscanf(s));
plot(data);
pause(0.1);
i=i+1;
end
Arduino Code:
#include "max6675.h" // max6675.h file is part of the library
//thermocouple 1
int so1Pin = 4;// SO1 = Serial Out
int cs1Pin = 5;// CS1 = chip select CS pin
int sck1Pin = 6;// SCK1 = Serial Clock pin
//thermocouple 2
int so2Pin = 8;// SO1 = Serial Out
int cs2Pin = 9;// CS1 = chip select CS pin
int sck2Pin = 10;// SCK1 = Serial Clock pin
//thermocouple 3
int so3Pin = 11;// SO1 = Serial Out
int cs3Pin = 12;// CS1 = chip select CS pin
int sck3Pin = 13;// SCK1 = Serial Clock pin
MAX6675 temp1 (sck1Pin, cs1Pin, so1Pin);// create instance object of MAX6675
MAX6675 temp2 (sck2Pin, cs2Pin, so2Pin);// create instance object of MAX6675
MAX6675 temp3 (sck3Pin, cs3Pin, so3Pin);// create instance object of MAX6675
void setup() {
Serial.begin(9600);// initialize serial monitor with 9600 baud
//Serial.println("MAX6675");
}
void loop() {
// basic readout test, just print the current temp
// MAX6675 Temperature reading on Serial monitor
Serial.print("");
Serial.println(temp1.readCelsius());// Read temperature in Degree Celcius unit
delay(100);// Update interval is 1 sec
Serial.print("");
Serial.println(temp2.readCelsius());// Read temperature in Degree Celcius unit
delay(100);// Update interval is 1 sec
Serial.print("");
Serial.println(temp3.readCelsius());// Read temperature in Degree Celcius unit
delay(100);// Update interval is 1 sec
}
Answers (1)
Walter Roberson
on 27 Aug 2021
Edited: Walter Roberson
on 27 Aug 2021
clear all
s = serial('COM4');
fopen(s);
ah(1) = animatedLine('Color','k');
ah(2) = animatedLine('Color','b');
ah(3) = animatedLine('Color','g');
starttime = tic;
while true
data = fscanf(s, '%f%f%f');
if length(data) < 3
fprintf('Data shortage, stopping\n');
break;
end
curtime = toc(starttime);
addpoint(ah(1), curtime, data(1));
addpoint(ah(2), curtime, data(2));
addpoint(ah(30, curtime, data(3));
pause(0.1);
end
with
#include "max6675.h" // max6675.h file is part of the library
//thermocouple 1
int so1Pin = 4;// SO1 = Serial Out
int cs1Pin = 5;// CS1 = chip select CS pin
int sck1Pin = 6;// SCK1 = Serial Clock pin
//thermocouple 2
int so2Pin = 8;// SO1 = Serial Out
int cs2Pin = 9;// CS1 = chip select CS pin
int sck2Pin = 10;// SCK1 = Serial Clock pin
//thermocouple 3
int so3Pin = 11;// SO1 = Serial Out
int cs3Pin = 12;// CS1 = chip select CS pin
int sck3Pin = 13;// SCK1 = Serial Clock pin
MAX6675 temp1 (sck1Pin, cs1Pin, so1Pin);// create instance object of MAX6675
MAX6675 temp2 (sck2Pin, cs2Pin, so2Pin);// create instance object of MAX6675
MAX6675 temp3 (sck3Pin, cs3Pin, so3Pin);// create instance object of MAX6675
void setup() {
Serial.begin(9600);// initialize serial monitor with 9600 baud
//Serial.println("MAX6675");
}
void loop() {
// basic readout test, just print the current temp
// MAX6675 Temperature reading on Serial monitor
Serial.print(temp1.readCelsius());// Read temperature in Degree Celcius unit
Serial.print(" ");
Serial.print(temp2.readCelsius());// Read temperature in Degree Celcius unit
Serial.print(" ");
Serial.println(temp3.readCelsius());// Read temperature in Degree Celcius unit
delay(100);// Update interval is 1 sec
}
Notice that you (probably) only need one delay of 100 for all three sensors together
The timing I do for the X axis could be improved: you could have the arduino keep track of its timing and send that information along with the temperatures, so that what you were plotting was the time of collection rather than the time MATLAB collected the data.
I would even say that you should change the
pause(0.1);
to just
drawnow();
and let MATLAB just sit at the fscanf() until it got data from the arduino -- less risk of the delays on the two sides getting badly ouf of synchronization.
9 Comments
Nazmi Rosly
on 27 Aug 2021
Walter Roberson
on 27 Aug 2021
Yes, sorry, that should be a call to toc() instead of tic()
Nazmi Rosly
on 27 Aug 2021
Nazmi Rosly
on 27 Aug 2021
Walter Roberson
on 27 Aug 2021
Unfortunately I have not used ThingSpeak .
Are you getting that serial error even when you do not attempt to write to ThingSpeak ?
Nazmi Rosly
on 28 Aug 2021
Walter Roberson
on 29 Aug 2021
You are right. And the strange thing is that I checked both of those names when I was posting, and managed to post the wrong way for both of them.
Nazmi Rosly
on 30 Aug 2021
Walter Roberson
on 30 Aug 2021
You can store the values as they are received; the difficulty is in storing them efficiently . It is not advisable to fwrite() each set of points as it is received, and it is not advisable to extend arrays as each set of points is received.
animatedline() deals with the situation internally by having fixed-length buffers (5000 points by default) and keeping track of the position within the current buffer; when a buffer fills, then it adds on a new buffer -- but it only has to move pointers to do that, rather than copying data each time.
It is possible to get all of the point locations after the loop is terminated (which happens in the code I posted when a data read fails.) Using ah(1), ah(2), ah(3) as the handles to the animatedlines, then
ah(1).SegmentContainer.Children
is an object array that you can treat as a struct array. The fields to look at are XData, YData, ZData.
ah(1).NumPointsAdded
is the total over all segments (buffers). Remember that the last segment will probably not be full, so use
mod(ah(1).NumPointsAdded-1, ah(1).SegmentSize) + 1
to calculate the number of points actually used in the last segment.
Categories
Find more on MATLAB Support Package for Arduino Hardware in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!