dinsdag 29 september 2015

markerprinter_UPDATE

size/length arms is scaled to model
serial connection/sending data to arduino

connected servo to arduino and so far all works fine
on the image the marker follows the purple line, angle values are printed on screen and send serial to arduino (at the moment only one side)

 

PROCESSING:
markerPrinter mprint1, mprint2;
float move_x, move_y, counter;
int curmillis, prevmillis;

void setup (){
  size(200,300);
  //setup mprint
  mprint1 = new markerPrinter(10, 70, 70, 'l');
  mprint2 = new markerPrinter(-10, 70, 70, 'r');
  move_x = 0;
  //serial
  printArray(Serial.list());
  myPort = new Serial(this, Serial.list()[0], 9600);
  //delay
  curmillis = millis ();
  prevmillis = curmillis;

}

void draw (){
  curmillis = millis ();
  if (curmillis - prevmillis > 20){
    fill (200);
    rect (0, 0, width, height);
    fill (0);
    text (width+"---"+height, 20, height-40);
    for (int i = 0; i < width; i++){
      stroke (250, 0, 250);
      point(i, 130+30*sin (radians (i)));
    }
    move_y = 130+30*sin (radians (move_x));
    mprint1.update(move_x, move_y);
    mprint2.update(move_x, move_y);
    mprint1.display();
    mprint2.display();
    fill (0);
    text ("left : "+degrees (mprint1.angle_sh), width-120, height-50);
    text ("right: "+degrees (mprint2.angle_sh), width-120, height-25);
    myPort.write(int(degrees(mprint2.angle_sh)));
    move_x++;
    if (move_x >= width){
      //noLoop(); //stop when x = width
      move_x = 0;
    }
    prevmillis = curmillis;
  }
}

void mousePressed(){

}

class markerPrinter{
  PVector center = new PVector ();   //position center acxes
  PVector marker = new PVector ();   //position marker
  PVector arms = new PVector ();     //(|arm1|, |arm2|) length arms
  PVector arm1 = new PVector ();     //position hinge
  PVector arm2 = new PVector ();     //position marker, caculated, used to draw arm 2
  char side;           //position servo vs center
  float offsetX;       //offsetX servo vs centerpoint
  float line_sm;       //virtual line marker to servo
  float angle_m;       //angle between X and line_sm
  float angle_mh;      //angle between line_sm and arm1
  float angle_sm;      //angle between arm1 and arm2
  float angle_sh;      //new angle between arm1 and X

  markerPrinter(float tempoffx, float temparm1, float temparm2, char temps){
    offsetX = tempoffx;
    center.set(width/2-offsetX, 50);
    arms.set(temparm1, temparm2);
    side = temps;
  }

  void update(float temp_mx, float temp_my){
    //set markervalue's
    marker.set (temp_mx-center.x, temp_my-center.y);
    //safety position marker.y > position servo.y+10 to avoid collapse marker/servo
    if (marker.y < 10){
      marker.y = 10;
    }
    //calculations angles
    line_sm = sqrt (sq (marker.x)+sq (marker.y));
    angle_m = acos (marker.x/line_sm);
    switch (side){
      case 'l':
        angle_mh = acos ((sq (arms.y)-sq (arms.x)-sq (line_sm))/(-2*arms.x*line_sm));
        angle_sm = acos ((sq (line_sm)-sq (arms.x)-sq (arms.y))/(-2*arms.x*arms.y));
        break;
      case 'r':
        angle_mh = -acos ((sq (arms.y)-sq (arms.x)-sq (line_sm))/(-2*arms.x*line_sm));
        angle_sm = -acos ((sq (line_sm)-sq (arms.x)-sq (arms.y))/(-2*arms.x*arms.y));
        break;
    }
    angle_sh = angle_m + angle_mh;
    //calculations needed for displaying
    arm1.x = arms.x*cos (angle_sh);
    arm1.y = arms.x*sin (angle_sh);
    arm2.x = arms.y*cos (angle_sm-(PI-angle_sh));
    arm2.y = arms.y*sin (angle_sm-(PI-angle_sh));
   
  }

  void display(){
    pushMatrix ();
    translate (center.x, center.y);
    stroke (180);
    line (-center.x, 0, width, 0);   //X-acxe servo
    //line (0, -center.y, 0, height);  //Y-acxe servo
    //stroke (255, 0, 0, 25);
    //line (0, 0, marker.x, marker.y ); //virtual line servomarker
    stroke (0, 0, 255);
    line (0, 0, arm1.x, arm1.y);     //arm1
    translate (arm1.x, arm1.y);      //hingepoint
    line (0, 0, arm2.x, arm2.y);     //arm2
    popMatrix ();
  }
}

ARDUINO:

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 90;    // variable to store the servo position

void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  myservo.write(pos);
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed!
  }
}

void loop() {
  if (Serial.available() > 0) {
    // read the incoming byte:
    pos = Serial.read();
    myservo.write(pos);
    delay(15);
  }
}

maandag 28 september 2015

markerprinter_update

markerPrinter mprint1, mprint2;
float move_x, move_y, counter;
int curmillis, prevmillis;
void setup (){
  size(400,600);
  mprint1 = new markerPrinter(70, 250, 250, 'l');
  mprint2 = new markerPrinter(-70, 250, 250, 'r');
  curmillis = millis ();
  prevmillis = curmillis;
  move_x = 0;
}

void draw (){
  curmillis = millis ();
  if (curmillis - prevmillis > 200){
    fill (200);
    rect (0, 0, width, height);
    fill (0);
    text (width+"---"+height, 20, height-40);
    for (int i = 0; i < width; i++){
      stroke (250, 0, 250);
      point(i, 400+30*sin (radians (2*i)));
    }
    move_y = 400+30*sin (radians (2*move_x));
    mprint1.update(move_x, move_y);
    mprint2.update(move_x, move_y);
    mprint1.display();
    mprint2.display();
    fill (0);
    text ("left : "+degrees (mprint1.angle_sh), width-150, height-50);
    text ("right: "+degrees (mprint2.angle_sh), width-150, height-25);
    move_x++;
    if (move_x >= width){
      move_x = 0;
      clear ();
    }
    prevmillis = curmillis;
  }
 
}

void mousePressed(){
 
}

class markerPrinter{
  PVector center = new PVector ();   //position center acxes
  PVector marker = new PVector ();   //position marker
  PVector arms = new PVector ();     //(|arm1|, |arm2|) length arms
  PVector arm1 = new PVector ();     //position hinge
  PVector arm2 = new PVector ();     //position marker, caculated, used to draw arm 2
  char side;         //position servo vs center
  float offsetX;     //offsetX servo vs centerpoint
  float line_sm;     //virtual line marker to servo
  float angle_m;     //angle between X and line_sm
  float angle_mh;    //angle between line_sm and arm1
  float angle_sm;    //angle between arm1 and arm2
  float angle_sh;    //angle between arm1 and X
 
  markerPrinter(float tempoffx, float temparm1, float temparm2, char temps){
    offsetX = tempoffx;
    center.set(width/2-offsetX, 50);
    arms.set(temparm1, temparm2);
    side = temps;
  }
 
  void update(float temp_mx, float temp_my){
    marker.set (temp_mx-center.x, temp_my-center.y);
    if (marker.y < 0){
      marker.y = 0;
    }
    line_sm = sqrt (sq (marker.x)+sq (marker.y));
    angle_m = acos (marker.x/line_sm);
    switch (side){
      case 'l':
        angle_mh = acos ((sq (arms.y)-sq (arms.x)-sq (line_sm))/(-2*arms.x*line_sm));
        angle_sm = acos ((sq (line_sm)-sq (arms.x)-sq (arms.y))/(-2*arms.x*arms.y));
        break;
      case 'r':
        angle_mh = -acos ((sq (arms.y)-sq (arms.x)-sq (line_sm))/(-2*arms.x*line_sm));
        angle_sm = -acos ((sq (line_sm)-sq (arms.x)-sq (arms.y))/(-2*arms.x*arms.y));
        break;
    }
    angle_sh = angle_m + angle_mh;
    arm1.x = arms.x*cos (angle_sh);
    arm1.y = arms.x*sin (angle_sh);
    arm2.x = arms.y*cos (angle_sm-(PI-angle_sh));
    arm2.y = arms.y*sin (angle_sm-(PI-angle_sh));
  }
 
  void display(){
    pushMatrix ();
    translate (center.x, center.y);
    stroke (180);
    line (-center.x, 0, width, 0);   //X-acxe servo
    //line (0, -center.y, 0, height);  //Y-acxe servo
    //stroke (255, 0, 0, 25);
    //line (0, 0, marker.x, marker.y ); //virtual line servomarker
    stroke (0, 0, 255);
    line (0, 0, arm1.x, arm1.y);     //arm1
    translate (arm1.x, arm1.y);      //hingepoint
    line (0, 0, arm2.x, arm2.y);     //arm2
    popMatrix ();
  }
}
 

zaterdag 26 september 2015

Markerprinter

PVector marker = new PVector (40, 250);
PVector arms = new PVector (200, 250);
PVector arm1 = new PVector ();
PVector arm2 = new PVector ();
float line_sm;
float angle_m;
float angle_mh;
float angle_sm;
float angle_sh;
void setup (){
 
}
void draw (){
  fill (200, 80);
  rect (0, 0, width, height);
 
  line_sm = sqrt (sq (marker.x)+sq (marker.y));
  angle_m = acos (marker.x/line_sm);
  angle_mh = acos ((sq (arms.y)-sq (arms.x)-sq (line_sm))/(-2*arms.x*line_sm));
  angle_sm = acos ((sq (line_sm)-sq (arms.x)-sq (arms.y))/(-2*arms.x*arms.y));
  angle_sh = angle_m + angle_mh;
  arm1.x = arms.x*cos (angle_sh);
  arm1.y = arms.x*sin (angle_sh);
  arm2.x = arms.y*cos (angle_sm-(PI-angle_sh));
  arm2.y = arms.y*sin (angle_sm-(PI-angle_sh));
 
  pushMatrix ();
  translate (width/2, 200);
  stroke (255, 0, 0);
  line (0, 0, marker.x, marker.y);
  stroke (0, 0, 255);
  line (0, 0, arm1.x, arm1.y);
  translate (arm1.x, arm1.y);
  line (0, 0, arm2.x, arm2.y);
  popMatrix ();
 
  marker.set (mouseX-width/2, mouseY-200);
}

maandag 21 september 2015

gauge clock2

Created another simple gauge class (GaugeII), then used it for a clock



code:

GaugeII second, minute, hour;
int secold, minold, hourold;

void setup(){
  size(800, 270);
  second = new GaugeII(250, 0, 59, 5, "second"); //(width, begin, end, division lines, name gauge)
  minute = new GaugeII(250, 0, 59, 5, "minute");
  hour = new GaugeII(250, 0, 11, 3,  "hour");
  secold = 100;  //val can never be 100, first run will always draw
  minold = 100;
  hourold = 100;
}

void draw(){
  //to save resource, only redraw when time has changed
  if (second() != secold){
    second.update(second());
    pushMatrix();
    translate(530, 10);
    second.display();
    popMatrix();
    secold = second();
  }
  if (minute() != minold){
    minute.update(minute());
    pushMatrix();
    translate(270, 10);
    minute.display();
    popMatrix();
    minold = minute();
  }
  if (hour() != hourold){
    //time received is 24 hour notation, gauge has scale of 12
    if (hour() <= 11){
      hour.update(hour());
    } else {
      hour.update(hour()-12);
    }
    pushMatrix();
    translate(10, 10);
    hour.display();
    popMatrix();
    hourold = hour();
  }
}


class GaugeII{
  PVector gsize;    //gauge(size, rotationpoint needle/scale)
  PVector gneedle;  //needle(size, angle)
  PVector gscale;   //scale(start, stop)
  int gsteps;       //scale, number of steps
  int gline;        //scale, division lines
  String gname;     //name gauge
 
  GaugeII(int temp_size, float temp_start, float temp_stop, int temp_line, String temp_name){
    gsize = new PVector(temp_size, temp_size-(temp_size/10));
    gneedle = new PVector(-7*temp_size/10, 0);
    gscale = new PVector(temp_start, temp_stop);
    gline = temp_line;
    gsteps = int(temp_stop - temp_start)+1;
    gname = temp_name;
  }
 
  void display(){
    //back
    stroke(0);
    strokeWeight(5);
    fill(255);
    rect(0, 0, gsize.x, gsize.x);
    fill(0);
    textAlign(CENTER);
    textSize(14);
    text(gname, gsize.x/4, 20);
   
    //scale
    stroke(0);
    strokeWeight(2);
    for (int i = 0; i < gsteps; i++){
      pushMatrix();
      translate(gsize.y, gsize.y);
      rotate(map(i, gscale.x, gscale.y, 0, HALF_PI));
      if (i%gline == 0){
        line(gneedle.x-5, 0, gneedle.x+5, 0);
        fill(0);
        translate(gneedle.x-10, 0);
        rotate(-HALF_PI);
        textSize(9);
        text(i, 0, 0);
      } else {
        point(gneedle.x, 0);
      } 
      popMatrix();
    }
   
    //needle
    pushMatrix();
    translate(gsize.y, gsize.y);
    rotate(gneedle.y);
    noStroke();
    fill(255, 0, 0);
    ellipseMode(CENTER);
    ellipse(0, 0, 15, 15);
    stroke(255, 0, 0);
    strokeWeight(2);
    line(0, 0, gneedle.x, 0);
    noStroke();
    popMatrix();
  }
 
  void update(float tempval){
    float gvalue = tempval;
    gneedle.y = map(gvalue, gscale.x, gscale.y, 0, HALF_PI);
  }
}

vrijdag 18 september 2015

gauge clock UPDATED

gauge clock

created a class to draw a simple gauge, then used it to show the time

screen shot:



Update:
- added scale values
- scale quotation can be altered at creation



code:

Gauge second, minute, hour;
int secold, minold, hourold;

void setup(){
  size(790, 210);
  second = new Gauge(250, 0, 59, 5, "second"); //(width, begin, end, quotation scale, name gauge)
  minute = new Gauge(250, 0, 59, 5, "minute");
  hour = new Gauge(250, 0, 11, 3,  "hour");
  secold = 100;  //val can never be 100, first run will always draw
  minold = 100;
  hourold = 100;
}

void draw(){
  //to save resource, only redraw when time has changed
  if (second() != secold){
    second.update(second());
    pushMatrix();
    translate(530, 10);
    second.display();
    popMatrix();
    secold = second();
  }
  if (minute() != minold){
    minute.update(minute());
    pushMatrix();
    translate(270, 10);
    minute.display();
    popMatrix();
    minold = minute();
  }
  if (hour() != hourold){
    //time received is 24 hour notation, gauge has scale of 12
    if (hour() <= 11){
      hour.update(hour());
    } else {
      hour.update(hour()-12);
    }
    pushMatrix();
    translate(10, 10);
    hour.display();
    popMatrix();
    hourold = hour();
  }
}

class Gauge{
  PVector gsize;  //width & height gauge
  PVector gscale;  //start & end value scale
  PVector gneedle; //length & angle needle
  int gsteps;
  float gline;
  String gname;
   
  Gauge(float tempx, float templow, float temphigh, float templine, String tempname){
    float gwidth = tempx;
    float gheight = 26*tempx/35;
    float glow = templow;
    float ghigh = temphigh;
    gline = templine;
    gname = tempname;
    gsteps = int(temphigh - templow) + 1;
    gsize = new PVector(gwidth, gheight);
    gscale = new PVector(glow, ghigh);
    gneedle = new PVector(5*gsize.y/8, map(second(), 0, 59, radians(35), radians(145)));
  }
 
  void display(){
    noStroke();
    //backcover
    fill(50);
    rect(0, 0, gsize.x, gsize.y);
    fill(255);
    textAlign(CENTER);
    textSize(14);
    text(gname, gsize.x/2, 15);
    //scale
    stroke(255, 200);
    strokeWeight(2);
    for (int i = 0; i < gsteps; i++){
      pushMatrix();
      translate(gsize.x/2, 11*gsize.y/12);
      rotate(PI + map(i, gscale.x, gscale.y, radians(35), radians(145)));
      if (i%gline == 0){
        line(gneedle.x-5, 0, gneedle.x+5, 0);
        translate(gneedle.x+10, 0);
        rotate(HALF_PI);
        textSize(9);
        text(i, 0, 0);
      } else {
        point(gneedle.x, 0);
      } 
      popMatrix();
    }
    noStroke();
    //needle
    stroke(255, 0, 0);
    strokeWeight(3);
    pushMatrix();
    translate(gsize.x/2, 11*gsize.y/12);
    rotate(PI + gneedle.y);
    line(0, 0, gneedle.x, 0);
    popMatrix();
    noStroke();
    //frontcover
    fill(150, 180);
    rect(0, 4.5*gsize.y/6, gsize.x, 1.5*gsize.y/6);
    fill(255, 0, 0);
    ellipseMode(CENTER);
    ellipse(gsize.x/2, 11*gsize.y/12, 10, 10);
  }
 
  void update(float tempgval){
    float gvalue = tempgval;
    gneedle.y = map(gvalue, gscale.x, gscale.y, radians(35), radians(145));
  }
}