arduino - Using a distance sensor in Processing to control the attributes of shapes -


i'm trying make program use readings gets distance sensor control attributes of circles (size, xy , colour). i'm trying make record current value , apply value when press relevant key (eg. press 's' , changes size whatever distance @ point). - ideally i'd circle change whatever field next dynamically move hand on sensor, seems bit beyond me.

i've tried as can, i'm not sure of i've commented out. tips or advice? i'm not sure i'm doing when comes classes , constructors.

edit: when run code, nothing happens.

import processing.serial.*;  int xpos, ypos, s, r, g, b;  circle circle; int shapesize, distance; string comportstring; serial myport;   void setup(){  size(displaywidth,displayheight); //use entire screen size.  //open serial port communication arduino myport = new serial(this, "/dev/cu.usbmodem1411", 9600); myport.bufferuntil('\n'); // trigger serialevent on new line }  void draw(){  background(0);  delay(50); //delay used refresh screen  println(distance); }   void serialevent(serial cport){ comportstring = (new string(cport.readbytesuntil('\n')));  if(comportstring != null) {  comportstring=trim(comportstring);   /* use distance received arduino modify y position  of first square (others follow). should match  code settings on arduino. in case 200 maximum  distance expected. distance mapped value  between 1 , height of screen */  distance = int(map(integer.parseint(comportstring),1,200,1,height));  if(distance<0){  /*if computer receives negative number (-1),  sensor reporting "out of range" error. convert  of these distance of 0. */  distance = 0;  }  } }    void keypressed() {   // n new circle (and keep old one)   if((key == 'n') || (key == 'n')) {     println("n");   circle = new circle(1,1,1,1,1,1);     }      //r - change red       if((key == 'r') || (key == 'r')) {     float red = map(distance, 0, 700, 0, 255);      r = int(red);     println("r " + r);     }         //g - change green       if((key == 'g') || (key == 'g')) {     float green = map(distance, 0, 700, 0, 255);    g = int(green);      println("g " + g);     }            //b - change blue       if((key == 'b') || (key == 'b')) {     float blue = map(distance, 0, 700, 0, 255);      b = int(blue);      println("b " + b);      }      //s - change size       if((key == 's') || (key == 's')) {        s = distance;         println("s " + s);     }      //x - change x  pos       if((key == 'x') || (key == 'x')) {      xpos = distance;          println("x " + xpos);     }      //y - change y pos       if((key == 'y') || (key == 'y')) {             ypos = distance;       println("y " + ypos);     }   }     class circle {     circle(int xpos, int ypos, int s, int r, int g, int b){    ellipse(xpos, ypos, s, s);    color(r, g, b);    }    int getx(){      return xpos;    }       int gety(){      return ypos;    }   }  

i split steps/tasks:

  1. connecting arduino
  2. reading values arduino
  3. mapping read values
  4. controlling mapping

you've got arduino part pretty there, things messy when trying map read values circle on screen. now, simplicity reasons, let's ignore classes , focus on drawing single ellipse x,y,size,r,g,b properties.

to read of jitter should update property ellipse continuously, not when pressing key. on key event should change property gets updated. use variables keep track of ellipse properties you're updating.

here's refactored version of code based on points above:

import processing.serial.*;  int xpos,ypos,s,r,g,b; int distance;  int propertyid = 0;//keep track of property should updated on distance int prop_xpos = 0; int prop_ypos = 1; int prop_s = 2; int prop_r = 3; int prop_g = 4; int prop_b = 5;  void setup(){   size(400,400);   //setup defaults see on screen   xpos = ypos = 200;   s = 20;   r = g = b = 127;   //initialize arduino - search port based on osx name   string[] portnames = serial.list();   for(int = 0 ; < portnames.length; i++){     if(portnames[i].contains("usbmodem")){       try{         serial arduino = new serial(this,portnames[i],9600);         arduino.bufferuntil('\n');         return;       }catch(exception e){         showserialerror();       }     }   }   showserialerror(); } void showserialerror(){   system.err.println("error connecting arduino!\nplease check usb port"); } void draw(){   background(0);   fill(r,g,b);   ellipse(xpos,ypos,s,s); } void serialevent(serial arduino){   string rawstring = arduino.readstring();//fetch raw string   if(rawstring != null){     string trimmedstring = rawstring.trim();//trim raw string     int rawdistance = int(trimmedstring);//convert integer     distance = (int)map(rawdistance,1,200,1,height);     updatepropsondistance();//continously update circle properties   } } void updatepropsondistance(){   if(propertyid == prop_xpos) xpos = distance;   if(propertyid == prop_ypos) ypos = distance;   if(propertyid == prop_s) s = distance;   if(propertyid == prop_r) r = distance;   if(propertyid == prop_g) g = distance;   if(propertyid == prop_b) b = distance; } void keyreleased(){//only change proprty changes on key press   if(key == 'x' || key == 'x') propertyid = prop_xpos;   if(key == 'y' || key == 'y') propertyid = prop_ypos;   if(key == 's' || key == 's') propertyid = prop_s;   if(key == 'r' || key == 'r') propertyid = prop_r;   if(key == 'g' || key == 'g') propertyid = prop_g;   if(key == 'b' || key == 'b') propertyid = prop_b; } //usually idea test - in case use mousey instead of distance sensor void mousedragged(){   distance = mousey;   updatepropsondistance(); } 

if makes sense, can encapsulated in class. use array store properties, if props[0] x, props1 y, etc. harder read, use intdict allows index values based on string instead of value (so can props["x"] instead of props[0]).

here's encapsulated version of code:

import processing.serial.*;  circle circle = new circle();  void setup(){   size(400,400);   //initialize arduino - search port based on osx name   string[] portnames = serial.list();   for(int = 0 ; < portnames.length; i++){     if(portnames[i].contains("usbmodem")){       try{         serial arduino = new serial(this,portnames[i],9600);         arduino.bufferuntil('\n');         return;       }catch(exception e){         showserialerror();       }     }   }   showserialerror(); } void showserialerror(){   system.err.println("error connecting arduino!\nplease check usb port"); } void draw(){   background(0);   circle.draw(); } void serialevent(serial arduino){   string rawstring = arduino.readstring();   if(rawstring != null){     string trimmedstring = rawstring.trim();     int rawdistance = int(trimmedstring);     int distance = (int)map(rawdistance,1,200,1,height);     circle.update(distance);   } } void keyreleased(){   circle.setupdateproperty(key+"");//update circle property based on key gets pressed. +"" quick way make string char } //usually idea test - in case use mousey instead of distance sensor void mousedragged(){   circle.update(mousey); }  class circle{   //an intdict (integer dictionary) associative array instead of accessing values integer index (e.g. array[0]   //you access them string index (e.g. array["name"])   intdict properties = new intdict();    string updateproperty = "x";//property update    circle(){     //defaults     properties.set("x",200);     properties.set("y",200);     properties.set("s",20);     properties.set("r",127);     properties.set("g",127);     properties.set("b",127);   }    void draw(){     fill(properties.get("r"),properties.get("g"),properties.get("b"));     ellipse(properties.get("x"),properties.get("y"),properties.get("s"),properties.get("s"));   }    void setupdateproperty(string prop){     if(properties.haskey(prop)) updateproperty = prop;     else{       println("circle not contain property: " + prop+"\navailable properties:");       println(properties.keyarray());     }    }    void update(int value){     properties.set(updateproperty,value);      }  } 

in both examples can test distance value dragging mouse on y axis.

regarding hc-sr04 sensor, can find code on arduino playground distance in cm. haven't used sensor myself yet, notice other people has issues it, it's worth checking this post well. if want roll own arduino code, no problem, can use hc-sr04 datasheet(pdf link) formula:

formula: / 58 = centimeters or / 148 =inch; or: range = high level time * velocity (340m/s) / 2; suggest use on 60ms measurement cycle, in order prevent trigger signal echo signal.

it's important accurate values (you'll avoid jitter when using these draw in processing). additionally can use easing or moving average.

here's basic moving average example:

int historysize = 25;//remember number of past values int[] x = new int[historysize]; int[] y = new int[historysize];  void setup(){   size(400,400);   background(255);   nofill(); } void draw(){   //draw original trails in red   stroke(192,0,0,127);   ellipse(mousex,mousey,10,10);    //compute moving average    float avgx = average(x,mousex);   float avgy = average(y,mousey);    //draw moving average in green   stroke(0,192,0,127);   ellipse(avgx,avgy,10,10);  } void mousereleased(){   background(255); } float average(int[] values,int newvalue){   //shift elements 1, last 2nd: count backwards   float total = 0;   int size = values.length;   for(int = size-1; > 0; i--){//count backwards     values[i] = values[i-1];//copy previous value current     total += values[i];//add values total   }   values[0] = newvalue;//add newest value @ start of list   total += values[0];//add latest value total   return (float)total/size;//return average } 

Comments

Popular posts from this blog

html - Firefox flex bug applied to buttons? -

html - Missing border-right in select on Firefox -

c# - two queries in same method -