A catapult that almost works
So I sort of understand what’s wrong.
Basically, how it’s set up here is that I’m using the flex sensor to approximate a catapult; you bend the sensor and then release it, like a slingshot. In the code, it looks for that moment of release -when the values change drastically from much higher to much lower- and ideally that change in values would trigger the projectile to launch. I’ve gotten the catapult arm to move along with the flexing of the sensor, but for whatever reason the projectile fails to launch and I don’t quite understand why. I think it has something to do with the fact that it wants to launch the projectile when the value difference is >100, which if I’m right (which, as I’m a programming novice, I might not be) means that it will only launch the projectile if the difference is CONSTANTLY greater than 100. I think this is the reason mainly because the launch animation takes longer than a second, and a second is barely how long the difference in values remains greater than 100. So the period of time in which difference>100 isn’t sufficient for the entire projectile launch to occur, so therefore I’m witnessing nothing happening.
Or maybe I just frankensteined the codes together wrong.
(the code I’m using for the projectile is a modified version of the processing built-in example “Moving on Curves”)
Anyway, my concept was to use the flex sensor as what it pretty literally approximates, which is a catapult. It’s not a super sophisticated concept, but it seemed doable. As far as I’m concerned it still is, but it’ll require me to have a real knock-down drag-out battle with the code, which probably will result in me getting curbstomped by a computer. I’m happy I got the arm to move, at least.
// This Processing program reads serial data for two sensors,
// presumably digitized by and transmitted from an Arduino.
// It displays two rectangles whose widths are proportional
// to the values 0-1023 received from the Arduino.
// Import the Serial library and create a Serial port handler
import processing.serial.*;
Serial myPort;
// Hey you! Use these variables to do something interesting.
// If you captured them with analog sensors on the arduino,
// They're probably in the range from 0 ... 1023:
int valueA; // Sensor Value A
int valueB; // Sensor Value B
int valueBPrevious;
//------------------------------------
void setup() {
size(700,500);
// List my available serial ports
int nPorts = Serial.list().length;
for (int i=0; i < nPorts; i++) { println("Port " + i + ": " + Serial.list()[i]); } // Choose which serial port to fetch data from. // IMPORTANT: This depends on your computer!!! // Read the list of ports printed by the code above, // and try choosing the one like /dev/cu.usbmodem1411 // On my laptop, I'm using port #4, but yours may differ. String portName = Serial.list()[0]; myPort = new Serial(this, portName, 9600); serialChars = new ArrayList(); } //------------------------------------ void draw() { // Process the serial data. This acquires freshest values. processSerial(); background(205,235,255); noStroke(); fill(100,210,170); rect(0,430, 700,500); float x = map(valueB, 700,900, 130,50); float y = map(valueB, 700,900, 320,400); //projectile variables float xcoord = x; // Current x-coordinate float ycoord = y; // Current y-coordinate float beginX = xcoord; // Initial x-coordinate float beginY = ycoord; // Initial y-coordinate float endX = 600; // Final x-coordinate float endY = 430; // Final y-coordinate float distX =endX-beginX; // X-axis distance to move float distY=endY-beginY; // Y-axis distance to move float exponent = 4; // Determines the curve float step = 0.01; // Size of each step along the path float pct = 0.0; // Percentage traveled (0.0 to 1.0) //catapult base fill (255); rect(80,400, 80,30); rect(110,390, 45,10); rect(110,350, 10,40); beginShape(); vertex(120,350); vertex(120,360); vertex(145,390); vertex(155,390); endShape(); //catapult arm strokeWeight(5); stroke(255); line(110,400, x,y); //curve motion adopted and modified from processing's example "moving on curves" //projectile somehow isn't working still, either go to office hours or pester mark int difference = valueBPrevious - valueB; if (difference > 100){
println ("Thing happened!");
xcoord = beginX + (pct * distX);
ycoord = beginY + (pow(pct, exponent) * distY);
}
fill(255);
ellipse(x, y, 10, 10);
pct = 0.0;
valueBPrevious = valueB; // last thing we do.
}
//---------------------------------------------------------------
// The processSerial() function acquires serial data byte-by-byte,
// as it is received, and when it is properly captured, modifies
// the appropriate global variable.
// You won't have to change anything unless you want to add additional sensors.
/*
The (expected) received serial data should look something like this:
A903
B412
A900
B409
A898
B406
A895
B404
A893
B404
...etcetera.
*/
ArrayList serialChars; // Temporary storage for received serial data
int whichValueToAccum = 0; // Which piece of data am I currently collecting?
boolean bJustBuilt = false; // Did I just finish collecting a datum?
void processSerial() {
while (myPort.available () > 0) {
char aChar = (char) myPort.read();
// You'll need to add a block like one of these
// if you want to add a 3rd sensor:
if (aChar == 'A') {
bJustBuilt = false;
whichValueToAccum = 0;
} else if (aChar == 'B') {
bJustBuilt = false;
whichValueToAccum = 1;
} else if (((aChar == 13) || (aChar == 10)) && (!bJustBuilt)) {
// If we just received a return or newline character, build the number:
int accum = 0;
int nChars = serialChars.size();
for (int i=0; i < nChars; i++) { int n = (nChars - i) - 1; int aDigit = ((Integer)(serialChars.get(i))).intValue(); accum += aDigit * (int)(pow(10, n)); } // Set the global variable to the number we captured. // You'll need to add another block like one of these // if you want to add a 3rd sensor: if (whichValueToAccum == 0) { valueA = accum; // println ("A = " + valueA); } else if (whichValueToAccum == 1) { valueB = accum; // println ("B = " + valueB); } // Now clear the accumulator serialChars.clear(); bJustBuilt = true; } else if ((aChar >= 48) && (aChar <= 57)) {
// If the char is between '0' and '9', save it.
int aDigit = (int)(aChar - '0');
serialChars.add(aDigit);
}
}
}