Tuesday, May 31, 2016

Arduino to MATLAB Serial Communication

Please Check Click Here for the Latest Release of the VIPER Blog
It includes a MATLAB Simulink tutorial for the Incremental Rotary Encoder using the Keyes KY-040 module.

31 May 2016

For the VIPER Radio Telescope an angle (angel) encoder is being used to determine the angle at which the telescope is at any point in time. For this we are currently using the Keyes KY-040 Arduino Rotary Encoder on an Arduino Uno using the Arduino IDE to code for rotation from this site, which shows exactly how to wire, upload, quite literally everything. This was found on Mike's blogs that he had directed me to, thanks Mike. 

--------------------------------------------------------------------------------------------------------------------------
------------------------------------ ANGLE ENCODER ARDUINO CODE ------------------------------------
--------------------------------------------------------------------------------------------------------------------------
NOTE: The following code is directly copied from the website linked above.  This is the code for the NON-PUSHBUTTON because we will reset the counter via the Zedboard when that is necessary. 
--------------------------------------------------------------------------------------------------------------------------
//From bildr article: http://bildr.org/2012/08/rotary-encoder-arduino/

//these pins can not be changed 2/3 are special pins
int encoderPin1 = 2;
int encoderPin2 = 3;

volatile int lastEncoded = 0;
volatile long encoderValue = 0;

long lastencoderValue = 0;

int lastMSB = 0;
int lastLSB = 0;

void setup() {
  Serial.begin (9600);

  pinMode(encoderPin1, INPUT); 
  pinMode(encoderPin2, INPUT);

  digitalWrite(encoderPin1, HIGH); //turn pullup resistor on
  digitalWrite(encoderPin2, HIGH); //turn pullup resistor on

  //call updateEncoder() when any high/low changed seen
  //on interrupt 0 (pin 2), or interrupt 1 (pin 3) 
  attachInterrupt(0, updateEncoder, CHANGE); 
  attachInterrupt(1, updateEncoder, CHANGE);

}

void loop(){ 
  //Do stuff here

  Serial.println(encoderValue);
  delay(1000); //just here to slow down the output, and show it will work  even during a delay
}


void updateEncoder(){
  int MSB = digitalRead(encoderPin1); //MSB = most significant bit
  int LSB = digitalRead(encoderPin2); //LSB = least significant bit

  int encoded = (MSB << 1) |LSB; //converting the 2 pin value to single number
  int sum  = (lastEncoded << 2) | encoded; //adding it to the previous encoded value

  if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue ++;
  if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue --;

  lastEncoded = encoded; //store this value for next time

}
--------------------------------------------------------------------------------------------------------------------------
The only edit that was made to the code employed in the working model is riding the code of the delay(1000); entirely, so that the code will spit out the current value as fast as it can.

To start the small scale testing the serial monitor of the Arduino IDE was used as a check. These values changed at increments of 1 or -1 depending upon rotation and the wiring of the CLK and DT pins. 


Here it goes from 2 to 3, and so on. Initially when I started running the first bits were 0, this must be 0 at the start. You can also get the EXACT location on the computer of the serial feed (COM PORT). In my case the serial feed is "/dev/cu.usbmodem1411". When this address (COM PORT) is entered into MATLAB it will be changed slightly to ('/dev/tty.usbmodem1411'). In MATLAB the ' ' must go around the location of your COM PORT.

The Arduino side is working, did someone say MATLAB? Matlab.

Reading serial data into MATLAB is quite simple, once every forum has been sifted through. I will do my best to be as thorough as possible.

links used:
Locating COM PORT PC/MAC/LINUX
fgets fclose fopen
ArduinoMatlab.org/serial MORE USEFUL VIDEO

Connecting Arduino to a Mac for Serial to Matlab

First I will directly past the working code, it is not perfect, but it currently what is needed.

--------------------------------------------------------------------------------------------------------------------------
--------------------------------------Matlab Serial Reading for Angle Encoder----------------------------------
--------------------------------------------------------------------------------------------------------------------------
% Date: 31 May 2016
% Start serial communication between an Arduino and MatLAB.
% If setup is complete the arduino will output a 1, else a 0.
%% SET CONDITIONS for MatLAB to read in ARDUINO SERIAL CHARACTER OUTPUT
s = serial('/dev/tty.usbmodem1411'); % Set com location, this is for a Mac
set(s,'DataBits',8);   % Set to same values on Arduino, can be found at arduino.cc 
set(s,'StopBits',1); 
set(s,'BaudRate',9600); % important, needed, double check for this error
set(s,'Parity','none');

% This can also be entered in in one (1) line as follows:
% s = serial('/dev/tty.usbmodem1411','DataBits',8,'StopBits',1,'BaudRate',9600,'Parity','none');
%% Open the connection to MatLAB
fopen(s); % connects serial object 's' to the arduino
%% Using an infinite loop read (GET) the INFORMATION that is RELEVANT
while (1==1)
    fgets(s) % Use a ';' if you want this info to not be seen this is the 
             % information that it is wanted for the Angel Encoder.
             % This will returned IDENTICAL to that of the Arduino IDE
             % serial output.
   
end
--------------------------------------------------------------------------------------------------------------------------

If you find that to end your code you must close MATLAB down entirely check out this quick video that was made to get around the horror of restarting MATLAB.

Future work.
1. Connect to a PID controller to regulate a motor that will spin something that this encoder measures.
2. Using a planetary gear system create a ratio that is useful to scientists. For example: if 1/10th of a degree is useful to these folks make a gear ratio of 10 to 1, (encoder to Viper Journal Bearing Mount)






1 comment:

  1. video link

    https://drive.google.com/a/siena.edu/file/d/0BxqffdnqgsDQUnJMOWZIbFRzM1k/view

    ReplyDelete