matlab - 长时间记录时如何停止跳过数据?

标签 matlab arduino

我正在使用 arduino 实时记录 10 个 PT100 的温度。

我的代码在较短的时间间隔(例如 10 分钟)内运行良好,但在较长的时间间隔(例如 2-7 小时)内,特别是在记录的第 63 个温度上,Matlab 不会从串行打印中获取完整的字符串。无论我将其设置为什么采样率(我尝试过 2.5 分钟、1 分钟和 5 分钟),它总是在第 63 条数据处停止工作 - 特别是 fscanf 中的 y 变量只有 2 个值 - 一个正常值查看温度值和2。

我更改了代码,以便当 y 字符串不是预期的 10 个温度值时,它只绘制 10 个 NaN 值并继续。从此时开始,无论我将采样率设置为多少,它都无法每 4 个样本准确记录一次 10 个温度值。

clear all;
clc;
delete(instrfindall); %pre-emptively close all ports
b = serial('COM7','BaudRate',1000000); % COM is the COM port of the Arduino
 %flush input buffer
flushinput(b);

fopen(b);  % initiate arduino communication


%% Create a figure window to monitor the live data
Tmax = 24*60*60; % Total time for data collection (s)
figure,
grid on,
xlabel ('Time (s)'), ylabel('Tempeature (K)'),
%axis([0 Tmax+1]),

%% Read and plot the data from Arduino
Ts = 150; % Sampling time (s)
ii = 0;
dataa = 0;
datab = 0;
t = 0;
tic % Start timer
mData = [];
while toc <= Tmax
    ii = ii + 1;
    %% Read buffer data

    datab = fscanf(b);
    y = strsplit(datab, ',')
    if(length(str2double(y))<10)
        disp("Output length mismatch");
        y = NaN(10,1);
        t1(ii,1) = str2double(y(1));
        t2(ii,1) = str2double(y(2));
        t3(ii,1) = str2double(y(3));
        t4(ii,1) = str2double(y(4));
        t5(ii,1) = str2double(y(5));
        t6(ii,1) = str2double(y(6));
        t7(ii,1) = str2double(y(7));
        t8(ii,1) = str2double(y(8));
        t9(ii,1) = str2double(y(9));
        t10(ii,1) = str2double(y(10));
    else
        t1(ii,1) = str2double(y(1));
        t2(ii,1) = str2double(y(2));
        t3(ii,1) = str2double(y(3));
        t4(ii,1) = str2double(y(4));
        t5(ii,1) = str2double(y(5));
        t6(ii,1) = str2double(y(6));
        t7(ii,1) = str2double(y(7));
        t8(ii,1) = str2double(y(8));
        t9(ii,1) = str2double(y(9));
        t10(ii,1) = str2double(y(10));
        %sTemp = smooth(data,25);
        %% Read time stamp
        % If reading faster than sampling rate, force sampling time.
        % If reading slower than sampling rate, nothing can be done. Consider
        % decreasing the set sampling time Ts

        t(ii) = toc;
        if ii > 1
            T = toc - t(ii-1);
            while T < Ts
                T = toc - t(ii-1);
            end
        end
        t(ii) = toc;
        grid on
        grid minor
        %% Plot live data
        if ii > 1
            x = [t(ii-1) t(ii)];
            %the two values output by the arduino when the sensor is not
            %attached are 38.98 and 1261.79 - changed these values to 0 using
            %logic
            y1 = [(t1(ii-1)*(t1(ii-1)~=30.98)*(t1(ii-1)~=1261.79)) (t1(ii)*(t1(ii)~=30.98)*(t1(ii)~=1261.79))];
            y2 = [(t2(ii-1)*(t2(ii-1)~=30.98)*(t2(ii-1)~=1261.79)) (t2(ii)*(t2(ii)~=30.98)*(t2(ii)~=1261.79))];
            y3 = [(t3(ii-1)*(t3(ii-1)~=30.98)*(t3(ii-1)~=1261.79)) (t3(ii)*(t3(ii)~=30.98)*(t3(ii)~=1261.79))];
            y4 = [(t4(ii-1)*(t4(ii-1)~=30.98)*(t4(ii-1)~=1261.79)) (t4(ii)*(t4(ii)~=30.98)*(t4(ii)~=1261.79))];
            y5 = [(t5(ii-1)*(t5(ii-1)~=30.98)*(t5(ii-1)~=1261.79)) (t5(ii)*(t5(ii)~=30.98)*(t5(ii)~=1261.79))];
            y6 = [(t6(ii-1)*(t6(ii-1)~=30.98)*(t6(ii-1)~=1261.79)) (t6(ii)*(t6(ii)~=30.98)*(t6(ii)~=1261.79))];
            y7 = [(t7(ii-1)*(t7(ii-1)~=30.98)*(t7(ii-1)~=1261.79)) (t7(ii)*(t7(ii)~=30.98)*(t7(ii)~=1261.79))];
            y8 = [(t8(ii-1)*(t8(ii-1)~=30.98)*(t8(ii-1)~=1261.79)) (t8(ii)*(t8(ii)~=30.98)*(t8(ii)~=1261.79))];
            y9 = [(t9(ii-1)*(t9(ii-1)~=30.98)*(t9(ii-1)~=1261.79)) (t9(ii)*(t9(ii)~=30.98)*(t9(ii)~=1261.79))];
            y10 = [(t10(ii-1)*(t10(ii-1)~=30.98)*(t10(ii-1)~=1261.79)) (t10(ii)*(t10(ii)~=30.98)*(t10(ii)~=1261.79))];
            %replace zero values with nan so they will not be plotted
            y1(y1==0) = nan;
            y2(y2==0) = nan;
            y3(y3==0) = nan;
            y4(y4==0) = nan;
            y5(y5==0) = nan;
            y6(y6==0) = nan;
            y7(y7==0) = nan;
            y8(y8==0) = nan;
            y9(y9==0) = nan;
            y10(y10==0) = nan;
            line(x, y1, 'Color', 'red')
            line(x, y2, 'Color', 'blue')
            line(x, y3, 'Color', 'black')
            line(x, y4, 'Color', 'magenta')
            line(x, y5, 'Color', 'green')
            line(x, y6, 'Color', 'blue')
            line(x, y7, 'Color', 'red')
            line(x, y8, 'Color', 'cyan')
            line(x, y9, 'Color', 'black')
            line(x, y10, 'Color', 'magenta')
            legend ('T1','T2','T3','T4', 'T5', 'T6', 'T7', 'T8', 'T9', 'T10')
            drawnow
        end
    end
end
fclose(b);

实际结果如下。非常感谢任何帮助!

( https://www.mathworks.com/matlabcentral/answers/uploaded_files/235007/Capture.png )

( https://www.mathworks.com/matlabcentral/answers/uploaded_files/235006/Capture1.png )

(编辑:图片来自 mathworks,因为我上周在那里发布了同样的问题,但没有收到任何回复)


#include <Adafruit_MAX31865.h>
#include<SPI.h>
#include <Wire.h>



// Use software SPI: CS, DI, DO, CLK
//Adafruit_MAX31865 max_1 = Adafruit_MAX31865(A0,12,11,13);
//Adafruit_MAX31865 max_2 = Adafruit_MAX31865(2,12,11,13);
//Adafruit_MAX31865 max_3 = Adafruit_MAX31865(3,12,11,13);
//Adafruit_MAX31865 max_4 = Adafruit_MAX31865(4,12,11,13);
//Adafruit_MAX31865 max_5 = Adafruit_MAX31865(5,12,11,13);
//Adafruit_MAX31865 max_6 = Adafruit_MAX31865(6,12,11,13);
//Adafruit_MAX31865 max_7 = Adafruit_MAX31865(7,12,11,13);
//Adafruit_MAX31865 max_8 = Adafruit_MAX31865(8,12,11,13);
//Adafruit_MAX31865 max_9 = Adafruit_MAX31865(9,12,11,13);
//Adafruit_MAX31865 max_10 = Adafruit_MAX31865(10,12,11,13);

// use hardware SPI, just pass in the CS pin
Adafruit_MAX31865 max_1 = Adafruit_MAX31865(A0);
Adafruit_MAX31865 max_2 = Adafruit_MAX31865(2);
Adafruit_MAX31865 max_3 = Adafruit_MAX31865(3);
Adafruit_MAX31865 max_4 = Adafruit_MAX31865(4);
Adafruit_MAX31865 max_5 = Adafruit_MAX31865(5);
Adafruit_MAX31865 max_6 = Adafruit_MAX31865(6);
Adafruit_MAX31865 max_7 = Adafruit_MAX31865(7);
Adafruit_MAX31865 max_8 = Adafruit_MAX31865(8);
Adafruit_MAX31865 max_9 = Adafruit_MAX31865(9);
Adafruit_MAX31865 max_10 = Adafruit_MAX31865(10);


// The value of the Rref resistor. Use 430.0 for PT100 and 4300.0 for PT1000
#define RREF      430.0
// The 'nominal' 0-degrees-C resistance of the sensor
// 100.0 for PT100, 1000.0 for PT1000
#define RNOMINAL  100.0
float kelvin1;
float kelvin2;
float kelvin3;
float kelvin4;
float kelvin5;
float kelvin6;
float kelvin7;
float kelvin8;
float kelvin9;
float kelvin10;

void setup() {
  Serial.begin(115200);
  Wire.begin();


  //Serial.println("Adafruit MAX31865 PT100 Sensor Test!");
  max_1.begin(MAX31865_4WIRE);  // set to 2WIRE or 4WIRE as necessary
  max_2.begin(MAX31865_4WIRE);
  max_3.begin(MAX31865_4WIRE);
  max_4.begin(MAX31865_4WIRE);
  max_5.begin(MAX31865_4WIRE);
  max_6.begin(MAX31865_4WIRE);
  max_7.begin(MAX31865_4WIRE);
  max_8.begin(MAX31865_4WIRE);
  max_9.begin(MAX31865_4WIRE);
  max_10.begin(MAX31865_4WIRE);
}


void loop() {

  uint16_t rtd1 = max_1.readRTD();
  uint16_t rtd2 = max_2.readRTD();
  uint16_t rtd3 = max_3.readRTD();
  uint16_t rtd4 = max_4.readRTD();
  uint16_t rtd5 = max_5.readRTD();
  uint16_t rtd6 = max_6.readRTD();
  uint16_t rtd7 = max_7.readRTD();
  uint16_t rtd8 = max_8.readRTD();
  uint16_t rtd9 = max_9.readRTD();
  uint16_t rtd10 = max_10.readRTD();

  //  Serial.print("RTD value: "); Serial.println(rtd);
  float ratio1 = rtd1;
  ratio1 /= 32768;
  float ratio2 = rtd2;
    ratio2 /= 32768;
    float ratio3 = rtd3;
    ratio3 /= 32768;
    float ratio4 = rtd4;
    ratio4 /= 32768;
    float ratio5 = rtd5;
    ratio5 /= 32768;
    float ratio6 = rtd6;
    ratio6 /= 32768;
    float ratio7 = rtd7;
    ratio7 /= 32768;
    float ratio8 = rtd8;
    ratio8 /= 32768;
    float ratio9 = rtd9;
    ratio9 /= 32768;
    float ratio10 = rtd10;
    ratio10 /= 32768;

  kelvin1 = (max_1.temperature(RNOMINAL, RREF)) + 273;
  kelvin2 = (max_2.temperature(RNOMINAL, RREF))+273;
    kelvin3 = (max_3.temperature(RNOMINAL, RREF))+273;
    kelvin4 = (max_4.temperature(RNOMINAL, RREF))+273;
    kelvin5 = (max_5.temperature(RNOMINAL, RREF))+273;
    kelvin6 = (max_6.temperature(RNOMINAL, RREF))+273;
    kelvin7 = (max_7.temperature(RNOMINAL, RREF))+273;
    kelvin8 = (max_8.temperature(RNOMINAL, RREF))+273;
    kelvin9 = (max_9.temperature(RNOMINAL, RREF))+273;
    kelvin10 = (max_10.temperature(RNOMINAL, RREF))+273;

  //Serial.print("Ratio = "); Serial.println(ratio1,8);
  Serial.print(kelvin1);
  Serial.print(", ");
  Serial.print(kelvin2);
    Serial.print(", ");
    Serial.print(kelvin3);
    Serial.print(", ");
    Serial.print(kelvin4);
    Serial.print(", ");
    Serial.print(kelvin5);
    Serial.print(", ");
    Serial.print(kelvin6);
    Serial.print(", ");
    Serial.print(kelvin7);
    Serial.print(", ");
    Serial.print(kelvin8);
    Serial.print(", ");
    Serial.print(kelvin9);
    Serial.print(", ");
    Serial.print(kelvin10);
    Serial.print(", ");


  Serial.println();

  /*
      // Check and print any faults
      uint8_t fault = max_1.readFault();
      if (fault) {
        Serial.print("Fault 0x"); Serial.println(fault, HEX);
        if (fault & MAX31865_FAULT_HIGHTHRESH) {
          Serial.println("RTD High Threshold");
        }
        if (fault & MAX31865_FAULT_LOWTHRESH) {
          Serial.println("RTD Low Threshold");
        }
        if (fault & MAX31865_FAULT_REFINLOW) {
          Serial.println("REFIN- > 0.85 x Bias");
        }
        if (fault & MAX31865_FAULT_REFINHIGH) {
          Serial.println("REFIN- < 0.85 x Bias - FORCE- open");
        }
        if (fault & MAX31865_FAULT_RTDINLOW) {
          Serial.println("RTDIN- < 0.85 x Bias - FORCE- open");
        }
        if (fault & MAX31865_FAULT_OVUV) {
          Serial.println("Under/Over voltage");
        }
        max_1.clearFault();
      }
  */
  delay(50);

}

最佳答案

所以,我查看了@Wolfie的建议(发现Arduino nano的缓冲区是64位,符合这个理论)并添加了

flushinput(b);

从串行输入读取值后,刷新输入缓冲区。刚刚测试了一下,效果非常好 - 感谢您的帮助!

关于matlab - 长时间记录时如何停止跳过数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57671471/

相关文章:

c# - 使用 Matlab 从 C# 控制台应用程序创建图形或绘图?

matlab - 如何将文档添加到 matlab 包中?

arduino - 可编程电源

c++ - 将 ino sketch 转换为 C++ 类,无效使用非静态成员函数

matlab - 如何缩短这个符号表达呢?

matlab - 使用 fft 和 ifft 改变频率不使用整数

performance - 比较两个神经网络(Matlab 中的 nntool)

c - 需要一点帮助来修复 Arduino RFID 程序

java - 通过 USB 从 Java 程序读取时,Arduino 出现 Serial.readbytes() 问题

c - 响应某些命令的 Sketch 是如何完成的?