Problem with data processing.

edited August 2015 in Arduino

Hello! Guys, please help me! I'm in desperation!

I have a problem with data processing in Processing and vibration feedback in my prototype.

From the beginning: I made a simple device using a Mega326p processor which should be O.K., for instance with Arduino. I added bluetooth BLUEFRUIT EZ-LINK and a simple vibration motor, like the one on the bottom.

http://learningaboutelectronics.com/images/Vibration-motor-circuit.png

In Processing I wrote a simple program to control one object, and with one obstacle present. For example :We have two ellipses - one of them we have to move form one place to another without touching the other (the obstacle/s). If You make a mistake, you should feel vibrations. And everything is OK if I have just one obstacle. When I am adding more objects/obstacles, vibration feedback is completely useless. It gets jammed, the response is delayed, pulse width modulation is nonexistent in this situation ( which I wanted to measure in three versions :/ ).

If You have ANY IDEA how I can fix this, I will be really greatful.

Thanks!

P.S. I am a beginner in programming, so I am pretty sure that there is better way to write this program. For instance, program with a few objects:

import processing.serial.*;
Serial myPort;

int blueX = 1287;
int blueY = 655;
float blackX, blackY;

int AX, AY;
int BX, BY;
int CX, CY;
int DX, DY;
int EX, EY;
int FX, FY;
int GX, GY;
int HX, HY;

float blueSize = 30;
float blackSize = 40;
int ASize = 50;
int BSize = 30;
int CSize = 75;
int DSize = 75;
int ESize = 120;
int FSize = 75;
int GSize = 27;
int HSize = 75;

color bluecolor;
color blueActive;
color blackcolor;
color Acolor;
color Bcolor;
color Ccolor;
color Dcolor;
color Ecolor;
color Fcolor;
color Gcolor;
color Hcolor;
color colorActiveObstacle;

boolean Overblue = false;
boolean Overblack = false;
boolean OverA = false;
boolean OverB = false;
boolean OverC = false;
boolean OverD = false;
boolean OverE = false;
boolean OverF = false;
boolean OverG = false;
boolean OverH = false;

void setup()
{
String portName = Serial.list()[0];
myPort = new Serial(this, portName, 9600);
size(500, 500);



bluecolor = color(#0000FF);
blueActive = color(#CC00FF);
blackcolor = color(000000);
colorActiveObstacle = color(34);

Acolor = color(225);
Bcolor = color(225);
Ccolor = color(225);
Dcolor = color(225);
Ecolor = color(225);
Fcolor = color(225);
Gcolor = color(225);
Hcolor = color(225);


blackX = 20;
blackY = 20;

blueX = 450;
blueY = 450;

AX = 200;
AY = 40;

BX = 320;
BY = 60;

CX = 430;
CY = 150;

DX = 300;
DY = 80;

EX = 250;
EY = 180;

FX = 100;
FY = 100;

GX = 1240;
GY = 130;

HX = 300;
HY = 500;
}

void draw()
{
background(78);
if(mousePressed)
{
fill(blueActive);
blueX = mouseX;
blueY = mouseY;
// myPort.write('H');
} else {
fill(bluecolor);
myPort.write('L');
}
ellipse(blueX, blueY, blueSize, blueSize);

fill(blackcolor);
ellipse(blackX, blackY, blackSize, blackSize);




if(overA(AX,AY, ASize))
{
fill(Acolor);
//fill(colorActiveObstacle);
myPort.write('H');
} else {
fill(Acolor);
myPort.write('L');
}
ellipse(AX, AY, ASize, ASize);



if(overB(BX,BY, BSize))
{
fill(Bcolor);
//fill(colorActiveObstacle);
myPort.write('H');
} else {
myPort.write('L');
fill(Bcolor);
}
ellipse(BX, BY, BSize, BSize);


if(overC(CX,CY, CSize))
{
fill(Ccolor);
//fill(colorActiveObstacle);
myPort.write('H');
} else {

myPort.write('L');

fill(Ccolor);
}
ellipse(CX, CY, CSize, CSize);


if(overD(DX,DY, DSize))
{
fill(Dcolor);
//fill(colorActiveObstacle);
myPort.write('H');
} else {

myPort.write('L');
fill(Dcolor);
}
ellipse(DX, DY, DSize, DSize);

if(overE(EX,EY, ESize))
{
fill(Ecolor);
// fill(colorActiveObstacle);
myPort.write('H');
} else {

myPort.write('L');
fill(Ecolor);
}
ellipse(EX, EY, ESize, ESize);

if(overF(FX,FY, FSize))
{
fill(Fcolor);
//fill(colorActiveObstacle);
myPort.write('H');
} else {

myPort.write('L');
fill(Fcolor);
}
ellipse(FX, FY, FSize, FSize);

if(overG(GX,GY, GSize))
{
fill(Gcolor);
//fill(colorActiveObstacle);
myPort.write('H');
} else {

fill(Gcolor);
myPort.write('L');
fill(Gcolor);
}
ellipse(GX, GY, GSize, GSize);


if(overH(HX,HY, HSize))
{
fill(Gcolor);
myPort.write('H');
} else {

myPort.write('L');
fill(Hcolor);
}
ellipse(HX, HY, HSize, HSize);
}


boolean overA(int x, int y, int diameter) {
float disX = x - mouseX;
float disY = y - mouseY;
if (sqrt(sq(disX) + sq(disY)) < 60) {
return true;
} else {
return false;
}
}
boolean overB(int x, int y, int diameter) {
float disX = x - mouseX;
float disY = y - mouseY;
if (sqrt(sq(disX) + sq(disY)) < 50) {
return true;
} else {
return false;
}
}
boolean overC(int x, int y, int diameter) {
float disX = x - mouseX;
float disY = y - mouseY;
if (sqrt(sq(disX) + sq(disY)) < 73) {
return true;
} else {
return false;
}
}
boolean overD(int x, int y, int diameter) {
float disX = x - mouseX;
float disY = y - mouseY;
if (sqrt(sq(disX) + sq(disY)) < 73) {
return true;
} else {
return false;
}
}
boolean overE(int x, int y, int diameter) {
float disX = x - mouseX;
float disY = y - mouseY;
if (sqrt(sq(disX) + sq(disY)) < 95) {
return true;
} else {
return false;
}
}
boolean overF(int x, int y, int diameter) {
float disX = x - mouseX;
float disY = y - mouseY;
if (sqrt(sq(disX) + sq(disY)) < 73) {
return true;
} else {
return false;
}
}
boolean overG(int x, int y, int diameter) {
float disX = x - mouseX;
float disY = y - mouseY;
if (sqrt(sq(disX) + sq(disY)) < 50) {
return true;
} else {
return false;
}
}
boolean overH(int x, int y, int diameter) {
float disX = x - mouseX;
float disY = y - mouseY;
if (sqrt(sq(disX) + sq(disY)) < 73) {
return true;
} else {
return false;
}
}


Tagged:

Answers

  • You'll get a better response if you format your code. Here's how:

    http://forum.processing.org/two/discussion/8045/how-to-format-code-and-text

  • Thanks. ;) Your right. I completely ignored this and it can be useful. :)

  • edited August 2015

    this version is better readable since I use ctrl-t in processing to autoformat.

    And here in the forum ctrl-o to format as code

    Also, all your overA overB functions are the same. You just forgot to use diameter in it.

    But you can reduce them to one function "over" and use it

    anyway shouldn't you send L ("vibrate not") only when all overs gave false?

    import processing.serial.*;
    Serial myPort;
    
    int blueX = 1287;
    int blueY = 655;
    float blackX, blackY;
    
    int AX, AY;
    int BX, BY;
    int CX, CY;
    int DX, DY;
    int EX, EY;
    int FX, FY;
    int GX, GY;
    int HX, HY;
    
    float blueSize = 30;
    float blackSize = 40;
    int ASize = 50;
    int BSize = 30;
    int CSize = 75;
    int DSize = 75;
    int ESize = 120;
    int FSize = 75;
    int GSize = 27;
    int HSize = 75;
    
    color bluecolor;
    color blueActive;
    color blackcolor;
    color Acolor;
    color Bcolor;
    color Ccolor;
    color Dcolor;
    color Ecolor;
    color Fcolor;
    color Gcolor;
    color Hcolor;
    color colorActiveObstacle;
    
    boolean Overblue = false;
    boolean Overblack = false;
    boolean OverA = false;
    boolean OverB = false;
    boolean OverC = false;
    boolean OverD = false;
    boolean OverE = false;
    boolean OverF = false;
    boolean OverG = false;
    boolean OverH = false;
    
    void setup()
    {
      String portName = Serial.list()[0];
      myPort = new Serial(this, portName, 9600);
      size(500, 500);
    
      bluecolor = color(#0000FF);
      blueActive = color(#CC00FF);
      blackcolor = color(000000);
      colorActiveObstacle = color(34);
    
      Acolor = color(225);
      Bcolor = color(225);
      Ccolor = color(225);
      Dcolor = color(225);
      Ecolor = color(225);
      Fcolor = color(225);
      Gcolor = color(225);
      Hcolor = color(225);
    
    
      blackX = 20;
      blackY = 20;
    
      blueX = 450;
      blueY = 450;
    
      AX = 200;
      AY = 40;
    
      BX = 320;
      BY = 60;
    
      CX = 430;
      CY = 150;
    
      DX = 300;
      DY = 80;
    
      EX = 250;
      EY = 180;
    
      FX = 100;
      FY = 100;
    
      GX = 1240;
      GY = 130;
    
      HX = 300;
      HY = 500;
    } // func 
    
    void draw()
    {
      background(78);
      if (mousePressed)
      {
        fill(blueActive);
        blueX = mouseX;
        blueY = mouseY;
        // myPort.write('H');
      } 
      else {
        fill(bluecolor);
        myPort.write('L');
      }
      ellipse(blueX, blueY, blueSize, blueSize);
    
      fill(blackcolor);
      ellipse(blackX, blackY, blackSize, blackSize);
    
      checkOvers();
    }
    
    // -------------------------------------------------------------
    
    void checkOvers() 
    {
    
      if (over(AX, AY, ASize))
      {
        fill(Acolor);
        //fill(colorActiveObstacle);
        myPort.write('H');
      } 
      else {
        fill(Acolor);
        myPort.write('L');
      }
      ellipse(AX, AY, ASize, ASize);
    
      if (over(BX, BY, BSize))
      {
        fill(Bcolor);
        //fill(colorActiveObstacle);
        myPort.write('H');
      } 
      else {
        myPort.write('L');
        fill(Bcolor);
      }
      ellipse(BX, BY, BSize, BSize);
    
    
      if (over(CX, CY, CSize))
      {
        fill(Ccolor);
        //fill(colorActiveObstacle);
        myPort.write('H');
      } 
      else {
    
        myPort.write('L');
    
        fill(Ccolor);
      }
      ellipse(CX, CY, CSize, CSize);
    
    
      if (over(DX, DY, DSize))
      {
        fill(Dcolor);
        //fill(colorActiveObstacle);
        myPort.write('H');
      } 
      else {
    
        myPort.write('L');
        fill(Dcolor);
      }
      ellipse(DX, DY, DSize, DSize);
    
      if (over(EX, EY, ESize))
      {
        fill(Ecolor);
        // fill(colorActiveObstacle);
        myPort.write('H');
      } 
      else {
    
        myPort.write('L');
        fill(Ecolor);
      }
      ellipse(EX, EY, ESize, ESize);
    
      if (over(FX, FY, FSize))
      {
        fill(Fcolor);
        //fill(colorActiveObstacle);
        myPort.write('H');
      } 
      else {
    
        myPort.write('L');
        fill(Fcolor);
      }
      ellipse(FX, FY, FSize, FSize);
    
      if (over(GX, GY, GSize))
      {
        fill(Gcolor);
        //fill(colorActiveObstacle);
        myPort.write('H');
      } 
      else {
    
        fill(Gcolor);
        myPort.write('L');
        fill(Gcolor);
      }
      ellipse(GX, GY, GSize, GSize);
    
    
      if (over(HX, HY, HSize))
      {
        fill(Gcolor);
        myPort.write('H');
      } 
      else {
    
        myPort.write('L');
        fill(Hcolor);
      }
      ellipse(HX, HY, HSize, HSize);
    }
    
    boolean over(int x, int y, int diameter) {
      float disX = abs(x - mouseX); // abs? 
      float disY = abs(y - mouseY);
      if (sqrt(sq(disX) + sq(disY)) < diameter) {
        return true;
      } 
      else {
        return false;
      }
    }
    
    
    //
    
  • I added this function:

    if( over(AX, AY, ASize) == false && over(BX, BY, BSize) == false && over(CX, CY, CSize) == false && over(DX, DY, DSize) == false && over(EX, EY, ESize) == false && over(FX, FY, FSize) == false && over(GX, GY, GSize) == false && over(HX, HY, HSize) == false) { myPort.write('L'); }

    and Yeah, it's great, because a signal is strong and constant. I know, it is not look the best but it work ^^.

    I tried write one function like "over" but then You got a signal even if you did not touch the object. It was enough to feel vibration when you were just close to obstacle. When I added Your code, it was this same problem. I backed to functions overA , overB, etc. and ( I have no idea why ) I had to change each diameters, overall minuse 20 points.

    But... damn! it works! ;)

    I will change my programs and I hope, that everything will be O.K.

    Thank you so much!

  • Congratulations!

    Chrisir ;-)

  • instead

    if (sqrt(sq(disX) + sq(disY)) < diameter) {

    maybe diameter / 2

    because you need the radius ;-)

    if (sqrt(sq(disX) + sq(disY)) < diameter/2) {

  • edited August 2015

    There's absolutely no need to use abs() when we sq() them! For the result is always positive after all!
    Even better, cut the sqrt() and sq() the radius: :bz

    boolean isMouseOver(int x, int y, int diam) {
      int distX = mouseX - x, distY = mouseY - y, rad = diam >> 1;
      return distX*distX + distY*distY < rad*rad;
    }
    
  • oups....

  • edited August 2015

    I will try with this in weekend, I have deadline for tomorrow so, now it just has to work :)
    but I have another question, if I can?
    I wrote program with lines and two objects. Some of lines are diagonal. It is obvious how write function for haptic feedback when lines are straight and mouse is on the line. But I do not know how write this with a diagonal lines and increase an activity area. For now, you have to exactly put point of the mouse on the line and press to feel vibration. For instance, I need something like this: mouseX + 10, mouseY +10 as an activity area.
    Goal of this program is moving blue an object to black, on the lines When everything is OK, you feel vibration, if you move your an object to far away from the line, vibration is stop.
    I tried to use beginShape(), or beginShape(LINES) but then was just worse, worse... If I can ask for any suggestions I will be really grateful!
    This is a code which I wrote:

    import processing.serial.*;
    Serial myPort;

    int blueX = 450;
    int blueY = 450;
    int blackX = 50;
    int blackY = 50;


    int blueSize = 36;
    int blackSize = 50;


    color bluecolor;
    color blueActive;
    color blackcolor;


    color colorActiveObstacle;

    boolean overBlack = false;
    boolean overLine = false;

    void setup()
    {
    String portName = Serial.list()[0];
    myPort = new Serial(this, portName, 9600);
    size(500,500);

    bluecolor = color(#0000FF);
    blueActive = color(#CC00FF);
    blackcolor = color(000000);


    }

    void draw()
    {
    background(225);
    if(mousePressed)
    {

    fill(bluecolor);
    blueX = mouseX;
    blueY = mouseY;

    if((blueX==50 && blueY>50 && blueY<150)||(blueX == 450 && blueY>340 && blueY<450) || (blueX > 150 && blueX< 300 && blueY== 450) || (blueX> 100 && blueX<140 && blueY ==400)) <br> {
    myPort.write('H');
    } else {
    myPort.write('L');
    }


    } else {

    fill(bluecolor);
    }
    ellipse(blueX, blueY, blueSize, blueSize);



    line(50,50,50,150); //(x1,y1,x2,y2);
    line(50,150,150,60);
    line(150,60,400,120);
    line(400,120,230,230);
    line(230,230,150,120);
    line(150,120,100,400);
    line(100,400,140,400);
    line(140,400,200,340);
    line(200,340,150,450);
    line(150,450,300,450);
    line(300,450,400,290);
    line(400,290,450,340);
    line(450,340,450,450);

    if(overBlack(blackX,blackY, blackSize) )
    {
    fill(colorActiveObstacle);
    myPort.write('L');
    } else {
    fill(blackcolor);
    //myPort.write('L');
    }
    ellipse(blackX, blackY, blackSize, blackSize);


    }


    boolean overBlack(int x, int y, int diameter) {
    float disX = x - mouseX;
    float disY = y - mouseY;
    if (sqrt(sq(disX) + sq(disY)) < 24) {
    return true;
    } else {
    return false;
    }
    }

    Thank You!

Sign In or Register to comment.