Drawing Problem


#1

Okay, I made a program that uses a accelerometer on a Arduino Circuit Playground that tracks where the accelerometer is heading, and now in need to turn the “point(x,y);” into a drawing, where it places a point where the accelerometer goes, kind of like using a mouse to draw on Paint.net, except your holding a arduino. Here is my current code :

int numDataPoints = 50000;
int dataIndex = 1;
String[] dataStrings = new String[numDataPoints]; // Save up to 10k values
import processing.serial.*;
float[] portValues = new float[8];
Serial myPort;
String inString;


void setup()
{
  size(750,750);
  frameRate(60);
  
  myPort = new Serial(this, "/dev/cu.usbmodem1411", 9600);
  
  for(int i = 0; i<8; i++)
  {
    portValues[i] = 0;
  }
  dataStrings[0] = "x,y,z,leftButton,rightButton,lightSensor,soundSensor,tempSensor";
  
}

String buildDataString(float[] v) {
  String result = "";
  for(int i = 0; i<v.length-1; i++) {
   result += str(v[i]) + ","; 
  }
  result += str(v[7]);
  return result;
}

void draw() { 
  background(255); // make a white background
  
   // this if statement makes sure that Processing is actually
   // reading data from the Circuit Playground BEFORE it runs the function
   // processSensorValues()  
  if (inString != null) {
    portValues = processSensorValues(inString); // get data
    // manage data points
    dataIndex++;
    if(dataIndex > numDataPoints - 1) {
     dataIndex = 1; 
    }
    dataStrings[dataIndex] = buildDataString(portValues);
    saveStrings("values.csv",dataStrings);
    text(dataIndex,width-80,40);
  }
  
  
  
  // get the x value from the acceleromoter, use to move object horizontally
  float x = map(portValues[1],-10,10,0,width);
   
  // get the y value from the accelerometer, use to move object vertically
  float y = map(portValues[0],-10,10,0,height);
 
 
  // draw point using accelerometer values for position
  strokeWeight(10);
  stroke(1,1,1);
  point(x,y);
  
  
  // Show the data coming in from the Circuit Playground in the 
  // console.  You'll see a stream of numbers "flowing" in the
  // console which is below the code window when the code is 
  // running.
  println(inString);
} 

//  this code gets data from the Circuit Playground
// and packages it up inside of an array.  You can go 
// here to learn more about arrays in Processing: 
// https://processing.org/reference/Array.html
//
// There is some error checking here to make sure the 
// Circuit Playground is reporting values
// the code is still a bit buggy.  If you have any errors
// in lines 138 - 164, just press stop and try again.
float[] processSensorValues(String valString) {
  
  String[] temp = {"0", "0", "0", "0", "0", "0", "0", "0"};
  
  temp = split(valString,"\t");
  
  if(temp == null) {
    for(int i = 0; i<8; i++) {
      temp[i] = "0"; 
    }
  }
  
  float[] vals = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
  for(int i = 0; i<8; i++)
  {
    if(temp != null) 
    {
      vals[i] = float(temp[i]); 
    }
    
    else
    {
      vals[i] = 0; 
    }
    
  }
  return vals;
}

void serialEvent(Serial p) { 
  inString = myPort.readStringUntil(10);  
}

Can anyone help me?


#2

We would love to help, but first off, could you please format your code? Just makes it a little bit easier to read :smiley:

You can do that by highlighting the whole thing, and pressing Control + Shift + C.

Secondly, what exactly is happening when you try to do what it is you want to do? I can’t run your code because I don’t have an Arduino on me, but what is the problem? Also, I would check the map values, just to make sure that you aren’t just drawing your points somewhere you can’t see them.

Hopefully this helps?

EnhancedLoop7


#3

[code updated above]

What I want to do is to draw a circle 30 times a second where the x and y values of the mouse are, and this is now what I have. It would act like a paintbrush. So far, I have the mouse following the movements of the accelerometer, but I can’t get it to draw. Do you have any suggestions?


#4

So this is what I did. Please read through the code, see how I formatted it, and also read the comments. As of now this is what I did:

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import processing.serial.*;

Robot robby;
Serial myPort;

int r = 10;
int g = 10;
int b = 10;
int tempR, tempG, tempB; 
int t, j;
int numDataPoints = 50000;
int dataIndex = 1;
String[] dataStrings = new String[numDataPoints]; // Save up to 10k values
float[] portValues = new float[8];
String inString;

void setup()
{
 
 background(255); //set the background here instead so you can have it ony be "painted" white once 
 frameRate(2000); //set a really high frame rate to decrease choppiness
 
  try
   {
    robby = new Robot();
   }
  catch (AWTException e)
  {
    println("Robot class not supported by your system!");
    exit();
  }

  size(750, 750);
  //myPort = new Serial(this, "/dev/cu.usbmodem1411", 9600); 

  for (int i = 0; i<8; i++)
   {
    portValues[i] = 0;
   }
  dataStrings[0] = "x, y, z, leftButton, rightButton, lightSensor, soundSensor, tempSensor";
}


String buildDataString(float[] v) {
  String result = "";
  for (int i = 0; i<v.length-1; i++) {
    result += str(v[i]) + ", ";
  }
  result += str(v[7]);
  return result;
}


void draw() {
  //background(255); // make a white background (REMOVE THIS IF YOU DON'T WANT THE BACKGROUND GETTING "REPAINTED" WHITE) 
  // this if statement makes sure that Processing is actually
  // reading data from the Circuit Playground BEFORE it runs the function
  // processSensorValues()  
  if (inString != null) {
    portValues = processSensorValues(inString); // get data
    // manage data points
    dataIndex++;
    if (dataIndex > numDataPoints - 1) {
      dataIndex = 1;
    }
    dataStrings[dataIndex] = buildDataString(portValues);
    saveStrings("values.csv", dataStrings);
    text(dataIndex, width-80, 40);
  }
 
 //use a switch function instead  
  switch(key) 
  {
   case 'r': 
    key = ' '; 
    if(r < 255) { r++;  } 
    else { r = 0; }  
   break;
   
   case 'g': 
    key = ' '; 
    if(g < 255) { g++; } 
    else { g = 0; }  
   break;
   
   case 'b': 
    key = ' '; 
    if(b < 255) { b++;  } 
    else { b = 0; }  
   break;
   
  }
  
  //draw everything AFTER any type of loop
  
  //set temp variables. remember up where you made key=' ' that's why the value doesn't change
  tempR = r;
  tempG = g;
  tempB = b; 
 
  j=mouseX;
  t=mouseY;
  fill(tempR, tempG, tempB); //fill before you draw it 
  ellipse(j, t, 10, 10); //you are using j and t, but make sure you use values from your accelerometer
  noStroke();
  rect(0, 0, 100, 12);
  fill(255);
  text((r  +  ", "  +  g  +  ", "  +  b), 10, 10);
 
 
 //I DON'T HAVE AN ARDUINO SO I COMMENTED THIS OUT. IT WILL STILL WORK. JUST UNCOMMENT WHEN YOU USE THIS 
  /**
      // get the x value from the acceleromoter, use to move object horizontally
      float x = map(portValues[1],-10,10,0,width);
      // get the y value from the accelerometer, use to move object vertically 
      float y = map(portValues[0],-10,10,0,height);
      // get the z value from the accelerometer, use to change rect. size.
    
      float z = map(portValues[2],-10,10,50,150);
      int c = (int) (x);
      int v = (int) (y);
      

    
     robby.mouseMove(c,v);
     
  **/

      // draw rectangle using accelerometer values for position and size    
      // use lightValue to change the roundedness of the rectangle. 
      //  
      // see the reference for rect(a,b,c,d,r) to learn more: 
      // https://processing.org/reference/rect_.html
      // Show the data coming in from the Circuit Playground in the 
      // console.  You'll see a stream of numbers "flowing" in the
      // console which is below the code window when the code is 
      // running.
    
      println(inString);
    } 
    
    //  this code gets data from the Circuit Playground  
    // and packages it up inside of an array.  You can go    
    // here to learn more about arrays in Processing:   
    // https://processing.org/reference/Array.html  
    //   
    // There is some error checking here to make sure the   
    // Circuit Playground is reporting values  
    // the code is still a bit buggy.  If you have any errors
    // in lines 138 - 164, just press stop and try again.
    
     float[] processSensorValues(String valString) {
      
      String[] temp = {"0", "0", "0", "0", "0", "0", "0", "0"};
      
      temp = split(valString,"\t");
      
      if(temp == null) {
        for(int i = 0; i<8; i++) {
          temp[i] = "0";
        }
      }

      float[] vals = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
    
      for(int i = 0; i<8; i++)
      {
          if(temp != null)
          {
            vals[i] = float(temp[i]);
          }    
          else  
          {
            vals[i] = 0; 
          }
       }  
        return vals;
     }
    
    void serialEvent(Serial p) {
    
      inString = myPort.readStringUntil(10);  
    }

What I basically did, is set temporary variables for your color variables. When you would check if a key was pressed, you would then set that variable to a space like key = ' '; And so, nothing would happen when you drew your new ellipse. (Also, you have to draw your ellipses AFTER doing all that key pressed checking).

Hopefully this helps, if you have any questions on my comments in the code I would love to help you out further.

EnhancedLoop7