1

我正在使用 Arduino Uno 从编码器收集学位数据,然后使用 USB 将该数据发送到 MATLAB。为了也获得旋转速度,我在每个度数数据点从 Arduino 到 MATLAB 之后生成并发送时间戳。数据在 Arduino 端完美生成——串行监视器上没有任何问题。

然而,在 MATLAB 中,我的数据矩阵充满了相当多的 NaN,以及偶尔缺少第一位数字的整数。例如,不是 216 度,而是 16 度,或者不是 7265900 微秒,而是 265900 微秒。

我已经能够通过使用 Arduino 的 millis() 时钟而不是 micros() 时钟并在编码器读取后添加 50 毫秒的延迟来解决丢失时间数据的问题。如果我在毫秒()时钟之后增加延迟,度数数据丢失的问题就会消失,但是度数数据采集变得太慢而无法使用。

任何帮助将非常感激!

代码粘贴在下面。首先是 Arduino 代码,然后是 MATLAB 代码。

谢谢!

大卫

#include <Adafruit_LEDBackpack.h>

#include <Adafruit_GFX.h>
#include <gfxfont.h>

#include <SPI.h>                                                                   //Include the SPI library in this sketch.
#include <Wire.h> // Enable this line if using Arduino Uno, Mega, etc.
//#include <TinyWireM.h> // Enable this line if using Adafruit Trinket, Gemma, etc.

#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"

Adafruit_7segment matrix = Adafruit_7segment();



//Variables for SPI rotary encoder
boolean knob_detected = false;
byte slave_select = 10;       //Slave select pin.
byte mosi = 11;               //MOSI pin.
byte miso = 12;               //MISO pin.
byte spi_clock  = 13;       //Clock pin.
byte read_counter = 96;
byte write_mode0 = 137;
byte write_mode1 = 144;
byte count1;
byte count2;
int count;
int val; 

int button = 7;
int b = 0; 

int degree;
int absolute;

unsigned long time;

// SETUP //
void setup() {

  //Connect the 4 communication pins between the Arduino and the quadrature counter.


  #ifndef __AVR_ATtiny85__
  Serial.begin(9600);
  //Serial.println("7 Segment Backpack Test");
#endif
  matrix.begin(0x70);


  pinMode(slave_select, OUTPUT);
  pinMode(mosi, OUTPUT);
  pinMode(miso, INPUT);
  pinMode(spi_clock, OUTPUT);
  // pinMode(button,INPUT);

  SPI.begin();                                                             //Begin SPI communication.
  SPI.setBitOrder(MSBFIRST);                                               //Bytes read into SPI will be read in MSB style.
  SPI.setDataMode(SPI_MODE0);                                              //Set the data to shift on the low clock phase with normal (non-inverted) clock polarity.
  digitalWrite(slave_select, HIGH);                                        //Close the SPI communication port.
  SPI.setClockDivider(SPI_CLOCK_DIV128);                                   //Set the SPI clock to 125 kHz (This can be changed).

  digitalWrite(slave_select, LOW);                                         //Set slave select low to enable communication.
  SPI.transfer(write_mode0);                                               //Select mode 0 for modifying.
  SPI.transfer(0b01000011);                                                //Write to mode 0: Synchronous Index, disable index, range-limit count mode, x4 quadrature.
  digitalWrite(slave_select, HIGH);                                        //Set slave select high to disable communication

  digitalWrite(slave_select, LOW);                                         //Set slave select low to enable communication
  SPI.transfer(write_mode1);                                               //Select mode 1 for modifying.
  SPI.transfer(2);                                                         //Write across a 0b01 to mode1 to enable 2 byte data transfers
  digitalWrite(slave_select, HIGH);                                        //Set slave select high to disable communication

  Serial.begin(9600);                                                      //Set the baud rate for serial data transmission.
  //Serial.println("READY");                                                 //Print "READY" to the serial line to indicate that initialization is complete.
}


// MAIN LOOP //
void loop() { 

  digitalWrite(slave_select, LOW);                                           //Set slave_select pin low to begin tranmission  .
  SPI.transfer(read_counter);                                                //Read from the read_counter register.
  count1 = SPI.transfer(0);                                                  //Send a null transfer to read byte1 values.
  count2 = SPI.transfer(0);                                                  //Send a null transfer to read byte2 values.
  digitalWrite(slave_select, HIGH);                                          //Set slave_select high to end transmission.
  count = word(count1, count2);                                              //Type cast the 2 bytes as a word.


  degree = count / 4;
  absolute = abs(degree);

                                                   //Send back the value of the register over the serial line.

  b =  digitalRead(button);
  if (b == HIGH) {
    digitalWrite(absolute,LOW);
     }
     else {}

  if (absolute == LOW)
  {
      absolute = 0;
  }
  else {}


Serial.println(absolute);                                                  //Send back the value of the register over the serial line.
  matrix.print(absolute,DEC);
  matrix.writeDisplay();
  delay(50);        //Pause for 50 milliseconds before re-looping.

time = millis();
Serial.println(time);
delay(10);
}

clear all;
close all;
clc;
delete(instrfind); %delete connected ports
p=getserialport;
[m,n] = listdlg('PromptString','Select Your Bluetooth device:','SelectionMode','single','ListString',p);
com=cell2mat(p(m));
s=serial(com);
fopen(s);
csd = figure;
set(csd,'Name','Plotting Arduino Data on MATLAB','NumberTitle','off'); % open Figure
t=1:100;% total Figure
hAx(1) = subplot(211);
hLine(1) = line('XData',t, 'YData',nan(size(t)), 'Color','b', 'Parent',hAx(1));
xlabel('Samples'), ylabel('Degrees');
hAx(2) = subplot(212);
hLine(2) = line('XData',t, 'YData',nan(size(t)), 'Color','b', 'Parent',hAx(2));
xlabel('Samples'), ylabel('Velocity');
set(hAx, 'Box','on', 'YGrid','on');
axis(hAx(1),[0,100,0,100]);
axis(hAx(2),[0,100,0,100000]);
d=zeros(1,100); %buffer of 100 elements
sm=zeros(1,10); %buffer of 10 elements
t10=zeros(1,10); %buffer of 10 elements
t100=zeros(1,100); %buffer of 100 elements

while(1)
j=1;  
while(j<=10)
        flushinput(s);
        sc=(fscanf(s));
        if(length(sc)<6)    %1000 degree units = 6 char (was <7 for micros() clock)
            sm(j)=str2double(sc);
        else                %i.e. else, if a timestamp (more than 7 chars)
            t10(j)=str2double(sc);

         j=j+1;

        end  

end

    t100 = [t100,t10];
    t100 = t100(11:end);
    d=[d,sm];           %Add new Samples
    d=d(11:end);        %Remove old Samples
    %d(end)
    set(hLine(1), 'YData',d);      %draw Degrees
    set(hLine(2), 'YData',t100);               %draw Velocity (currently just timestamps)
    drawnow %# force MATLAB to flush any queued displays

end

(getserialport 函数由以下 m 文件定义)

function x=getserialport
serialInfo = instrhwinfo('serial');
x=serialInfo.SerialPorts;
 end
4

0 回答 0