Difference between revisions of "PIC32MX: Interfacing with Force Sensors from a Scale"

From Mech
Jump to navigationJump to search
Line 41: Line 41:
1. void initSerial(); (Communication between the PC (Processing) and the PIC via RS232)
1. void initSerial(); (Communication between the PC (Processing) and the PIC via RS232)


The purpose of InitSerial(); is to open a serial port on the PC and communicate with the PIC32. The code found here is essentially a modification of the ME333 Lab 4: Motor Control Processing Code written by Nick Marchuk.
The purpose of InitSerial(); is to open a serial port on the PC and communicate with the PIC32. The code found here is essentially a modification of the ME333 Lab 4: Motor Control Processing code written by Nick Marchuk.


2. float xposition();
2. float xposition();
Line 56: Line 56:


Our code was written with the assumption that the inputs from the PIC (that initially comes from the 4 force sensors) will come in the form of a 4x1 array. It does not actually arrive in that form from the PIC, it actually arrives as a string of floats separated by spaces ending with a new line. The new line is deleted and the floats are extracted out, normalized between 0-255, and put into the "mass" array. All of the normalization, window dimension parameters, rectangle dimensions, etc. were set up with the 0-255 range and 1000x700 window size in mind. So if the values are not between 0-255 or the window size is altered, almost all of following code will be messed up. The x-position vs. time and y-position vs. time plots are not implemented as independent functions. The code for these plots are found at the very end of colorbars();.
Our code was written with the assumption that the inputs from the PIC (that initially comes from the 4 force sensors) will come in the form of a 4x1 array. It does not actually arrive in that form from the PIC, it actually arrives as a string of floats separated by spaces ending with a new line. The new line is deleted and the floats are extracted out, normalized between 0-255, and put into the "mass" array. All of the normalization, window dimension parameters, rectangle dimensions, etc. were set up with the 0-255 range and 1000x700 window size in mind. So if the values are not between 0-255 or the window size is altered, almost all of following code will be messed up. The x-position vs. time and y-position vs. time plots are not implemented as independent functions. The code for these plots are found at the very end of colorbars();.




Global Variables
Global Variables

Revision as of 00:04, 9 February 2010

Original Assignment

Do not erase this section!

Your assignment is to use four analog inputs to continuously read four force sensors taken from a bathroom scale, and to display them on a PC screen as bars whose length corresponds to the force at the sensors. You will use Processing for the PC data acquisition and graphics.

Overview

Summarize briefly what the page is about.

Circuit

Include a schematic and give any part numbers. A photo of your circuit is OK, but not as a replacement for a schematic.

Code

Where possible, make it a single piece of well-commented cut-and-pastable code, or at least make each function that way, so others can easily copy it. Most comments should be in the code itself; outside the code (on the wiki) should only be explanatory comments that are too cumbersome to include in the code.

The Processing portion of our lab involves 4 main sections, these are the parts that are actually displayed in the Processing window:

1. colorbars();:

continuously displaying the force applied onto each force sensor by using 4 bars that will grow or shrink depending on the amplitude of mass (force). The bars will also show the amplitude of the mass by changing colors. When 0 or little force is applied, then corresponding bar is black colored, at the max force, the bar is orchid (pink) colored.

2. xyplot();:

continuously displays the x- and y- position of the center of balance calculated between all 4 sensors with a dot on a xy-coordinate plane. So, if the person shifts his weight to the right side of scale, then the dot will move to the right in the x direction. If the person shifts his weight to the front of the sensor, then the dot will move up in the y direction.

3. x-position vs. time (not a separate function):

continuously plots a dot for the x-position along a time axis. This plot will be useful to see how much the person shifts his/her weight to the left or right (sagittal plane) over time. Due to the window size and the speed of processing, the points will be plotted over a time period of about 20 seconds.

4. y-position vs. time (not a separate function):

continuously plots a dot for the y-position along a time axis. This plot will be useful to see how much the person shifts his/her weight forward or backwards (coronal or frontal plane) over time. The code for this section is essentially the same as the x-position but edited to show y-position.


Additional Functions in our Processing Code that are not displayed but are important:

1. void initSerial(); (Communication between the PC (Processing) and the PIC via RS232)

The purpose of InitSerial(); is to open a serial port on the PC and communicate with the PIC32. The code found here is essentially a modification of the ME333 Lab 4: Motor Control Processing code written by Nick Marchuk.

2. float xposition();

Calculates the x-position based on the contribution of each force sensor output and returns the resulting float value.

3. float yposition();

Calculates the x-position based on the contribution of each force sensor output and returns the resulting float value.


General Notes:

Our code was written with the assumption that the inputs from the PIC (that initially comes from the 4 force sensors) will come in the form of a 4x1 array. It does not actually arrive in that form from the PIC, it actually arrives as a string of floats separated by spaces ending with a new line. The new line is deleted and the floats are extracted out, normalized between 0-255, and put into the "mass" array. All of the normalization, window dimension parameters, rectangle dimensions, etc. were set up with the 0-255 range and 1000x700 window size in mind. So if the values are not between 0-255 or the window size is altered, almost all of following code will be messed up. The x-position vs. time and y-position vs. time plots are not implemented as independent functions. The code for these plots are found at the very end of colorbars();.


Global Variables

 //initialization of the serial variable that will hold the values sent from the PIC via RS232
 import processing.serial.*; 
 Serial[] myPorts = new Serial[1];

 //the PIC will output 4 floats and we will first store the values into these 4 variables
 float input0;
 float input1;
 float input2;
 float input3;

 //dimensions of our window will be 1000x700
 float window_height = 700;
 float window_width = 1000;
 PFont fontA;  //initializing our text font

 //the main "mass" 4x1 array that holds the values continuously sent from the 4 force sensors
 //we will refer to this array as the "mass array" in our comments
 float[] mass = new float[4]; 

 //window dimension variable that is used to make the bargraph.  The bx and by variables are
 //used so that the bargraph section could be more easily formatted in case we change the
 //window size.
 float bx = window_width/2/8;
 float by = window_height/2/8;
 int index;  

 //color variables used to indicate the amplitude of the force applied to each sensor
 color c0;
 color c1;
 color c2;
 color c3;

Main Setup Function

void setup() {
  
  index = 0;
  InitSerial();
  smooth();

  //splitting the window into 5 separate areas and filling them with a 102 gray color
  size(int(window_width),int(window_height));
  fill(102);
  rect(0,0,window_width/2,window_height/3);
  fill(102);
  rect(0,window_height/3,window_width/2,window_height/3);
  fill(102);
  rect(0,window_height*2/3,window_width/2,window_height/3);
  fill(102);
  rect(window_width/2,0,window_width/2,window_height/2);
  fill(102);
  rect(window_width/2,window_height/2,window_width/2,window_height/2);

  //filling inside of the x-position vs. time and y-position vs. time plots with white color
  fill(255);
  rect(25, int(window_height/3)+29, int(window_width/2)-49, int(window_height/3)-59);
  fill(255);
  rect(25, int(window_height*2/3)+29, int(window_width/2)-49, int(window_height/3)-59);
}

Main Draw Function

void draw() {
  
  //when we first tried to see if each of the 4 parts in our code worked, we assigned the mass array to pick
  //up the cursor position in the window.  
  /*
  mass[0] = ((1000-mouseX)/7.84314)+((700-mouseY)/5.4902);
  mass[1] = (mouseX/7.84314)+((700-mouseY)/5.4902);
  mass[2] = ((1000-mouseX)/7.84314)+(mouseY/5.4902);
  mass[3] = (mouseX/7.84314)+(mouseY/5.4902);
  */

  //initializing font we want to use
  fontA = loadFont("Calibri-Bold-16.vlw");
  textFont(fontA);
  
  /*calling our xy-plot and colorbars functions.  The x-position vs. time and y-position vs. time plots 
    are not actually separate functions.  They are a short section of code found at the very end of the 
    colorbars function.  In order to make the x-position vs. time and y-position vs. time plots work we 
    needed variables found only in colorbars.
  */
  xyplot();
  colorbars();
}

Communication between the PC (Processing) and the PIC via RS232

void InitSerial() {        
  // initialize the serial port
  // List all the available serial ports
  // you want the one that you plugged in
  println(Serial.list());

  String portList = Serial.list()[0];
  // this assumes the COM port you want is the first one, change the 0 to the place of your comport in the list that appears in the debug window
  myPorts[0] = new Serial(this, portList, 19200);

  // read bytes into a buffer until you get a linefeed (ASCII 10):
  myPorts[0].bufferUntil('\n');
}

// serial event, check which port generated the event, just in case there are more than 1 ports open
void serialEvent(Serial thisPort) { 
  // variable to hold the number of the port:
  int portNumber = -1;

  // iterate over the list of ports opened, and match the 
  // one that generated this event:
  for (int p = 0; p < myPorts.length; p++) {
    if (thisPort == myPorts[p]) {
      portNumber = p;
    }
  }

  // read the serial buffer until a newline appears
  String myString = thisPort.readStringUntil('\n');

  // if you got any bytes other than the newline
  if (myString != null) {
    
    myString = trim(myString); // ditch the newline

    // split the string at the spaces, save as integers
    float line_received[] = float(split(myString, ' '));

    // grab the data
    if ((line_received.length == 4) && (portNumber==0)){
      if (index >= 4){
        index = 0;
      }
      /*setting the ranges for the values received to be between 0-255, then
      putting those values into our mass array

      Right now, we are using a intermediate variable (inputx) to carry
      the value to the mass array just incase we need a variable to edit
      without having to edit the mass array values.
      */
      input0 = map(line_received[0],-1000,1000,510,0);
      input1 = map(line_received[1],-1000,1000,510,0);
      input2 = map(line_received[2],-1000,1000,510,0);
      input3 = map(line_received[3],-1000,1000,510,0);
      
      if (input0 < 0) {
        mass[0] = 0;
      }
      else if (input0 >= 0) {
        mass[0] = input0;
      }
      if (input1 < 0) {
        mass[1] = 0;
      }
      else if (input1 >= 0) {
        mass[1] = input1;
      }
      if (input2 < 0) {
        mass[2] = 0;
      }
      else if (input2 >= 0) {
        mass[2] = input2;
      }
      if (input3 < 0) {
        mass[3] = 0;
      }
      else if (input3 >= 0) {
        mass[3] = input3;
      }
      index++;
    }
  }
} // end serialEvent

XY-Plot

void xyplot(){
  
  //setting xy-plot window dimensions, plotting x-axis and y-axis lines, and plotting the actual point that
  //moves around in the xy-coordinate plane
  float sizeofwindow = window_width/2-2*window_width/10;
  float j = 510;
  fill(255);
  strokeWeight(1);
  rect(window_width/2+window_width/10,window_height/2+window_height/28,sizeofwindow,sizeofwindow);
  strokeWeight(1);
  stroke(75);
  line(.75*window_width, window_height/2+window_height/28, .75*window_width, window_height-window_height/28);
  line(window_width/2+window_width/10, .75*window_height, window_width-window_width/10, .75*window_height);
  float x = (sizeofwindow/j)*xposition();
  float y = (sizeofwindow/j)*yposition();
  stroke(c3);
  fill(0);
  strokeWeight(5);
  point(x+window_width*3/4,y+window_height*3/4);
  strokeWeight(1);

  //displaying text and titles, note that titles may be different than just "colorbars" and "xy-plot,"
  //but they are the same thing.  
  fill(0);
  text("Team 26: Tod Reynolds, Pill Park, Joshua Peng", 4, 16);
  text("Lab 5: PIC32MX: Interfacing with Force Sensors from a Scale", 4, 36);
  text("Mass Amplitude Colorbars", window_width/2+5, 16);
  text("Center of Balance Plot", window_width/2+5, window_height/2+16);
  text("X-position", window_width*3/4-window_width/23,window_height-10);
  text("Y-position", window_width/2+15, window_height*3/4);
  text("Sagittal Shift / Time", 5, window_height/3+16);
  text("Coronal Shift / Time", 5, window_height*2/3+16);
  text("left", (window_width/4)-15, window_height/3+26);
  text("forward", (window_width/4)-30, window_height*2/3+26);
  text("right", (window_width/4)-20, window_height*2/3-16);
  text("backward", (window_width/4)-35, window_height-16);
}