Arduino to Processing: Lever switch not constantly printing serial value - processing

I have the below Processing code that reads in serial values from Arduino button switch. When a lever button is pressed and have a certain potentiometer values, it prints "recording scene n". The text here is static, but when I tried to now put in other animation/draw features into Processing, Processing only goes 1 loop of draw() only when the lever switch is clicked, while I want the loop to be going on constantly. I'm not sure why it is keep doing it.
import processing.serial.*;
Serial myPort;
//String val;
int val;
int end = 10;
void setup() {
// initial setup
size(400,400);
//println(Serial.list());
String portName = Serial.list()[1]; //change the 0 to a 1 or 2 etc. to match your port
myPort = new Serial(this, portName, 9600);
}
void draw() {
if (myPort.available() > 0) {
//val = myPort.readStringUntil(end);
//val = myPort.readStringUntil('\n');
val = myPort.read();
println(val);
if (val == 11) {
println(val);
background(127,0,0); //color red
textSize(32);
text("RECORDING SCENE 1", 50, 200);
fill(255, 255, 255);
}
if (val == 22) {
background(127,0,0); //color red
textSize(32);
text("RECORDING SCENE 2", 50, 200);
fill(255, 255, 255);
}
if (val == 33) {
background(127,0,0); //color red
textSize(32);
text("RECORDING SCENE 3", 50, 200);
fill(255, 255, 255);
}
if (val == 44) {
background(127,0,0); //color red
textSize(32);
text("RECORDING SCENE 4", 50, 200);
fill(255, 255, 255);
}
if (val == 55) {
background(127,0,0); //color red
textSize(32);
text("RECORDING SCENE 5", 50, 200);
fill(255, 255, 255);
}
//else {
if (val == 66) {
background(255, 255, 255);
}
}
}
Any help or guides would be appreciated!! Thank you.

Related

How to use custom shapes in a repeating loop pattern?

I already made a custom shape (myFunction), and I also made patterns using simpler shapes. I want to know how to replace those simple shapes with my custom shape while maintaining the pattern drawn on processing...
You're already calling functions such as noFill(), noStroke(), etc.
It's the same for your function: call it by simply using it's name and () (because it has no arguments): myFunction();
Let's say you want to draw it in pattern 1, you could do something like:
if (pattern==1) {
for (int x=50; x<width; x+=100) {
for (int y=20; y<height; y+=100) {
myFunction();
}
}
}
You will need to pay attention to rendering though.
Running the above will not display anything you call in noFill() in myFunction() and also noStroke() in draw(), right after background(): you won't be able to see a shape with no fill and no stroke :)
One suggestion is to add a stroke:
void myFunction() {
noFill();
stroke(255);
ellipse(300, 300, 200, 400);
ellipse(300, 300, 400, 200);
translate(300, 300);
rotate(radians(130));
ellipse(0, 0, 200, 400);
translate(0, 0);
rotate(radians(0));
ellipse(0, 0, 400, 200);
}
Of course feel free to experiment and make this look nicer.
Here's a modified version of your sketch that uses a few key presses to change the pattern type and shape type at runtime:
int pattern = 1;
// 0 = pluseEllipseCluser, 1 = blobs, 2= myFunction spirograph circles
int shape = 0;
void setup() {
size(600, 600);
println("press 1,2 to change pattern");
println("press p/b/c to change shapes");
}
void draw() {
background(30);
noStroke();
if (pattern==1) {
for (int x=50; x<width; x+=100) {
for (int y=20; y<height; y+=100) {
drawSelectedShapes(x, y);
}
}
}
if (pattern==2) {
float rando = random(10, 90);
for (float x= rando; x >= 0; x-=random(2.5)) {
for (float y= rando; y >= 0; y-=random(2.5)) {
drawSelectedShapes(x, y);
}
}
}
}
void drawSelectedShapes(float x, float y){
if(shape == 0){
plusEllipseCluser(x, y);
}
if(shape == 1){
blobs();
}
if(shape == 2){
myFunction();
}
}
void plusEllipseCluser(float x, float y){
fill(random(255), random(255), random(255), random(255));
ellipse(x, y+30, 50, 20); //plus ellipse cluster
ellipse(x, y+30, 20, 50);
}
void blobs(){
noStroke();
fill(random(250), random(120), random(100));
ellipse(random(width), random(height), 20, 50);
noFill();
stroke(random(255));
ellipse(random(width), random(height), 50, 20);
}
void myFunction() {
noFill();
stroke(255);
ellipse(300, 300, 200, 400);
ellipse(300, 300, 400, 200);
translate(300, 300);
rotate(radians(130));
ellipse(0, 0, 200, 400);
translate(0, 0);
rotate(radians(0));
ellipse(0, 0, 400, 200);
}
void keyPressed(){
if(key == '1') {
pattern = 1;
}
if(key == '2') {
pattern = 2;
}
if(key == 'p'){
shape = 0;
}
if(key == 'b'){
shape = 1;
}
if(key == 'c'){
shape = 2;
}
}
Notice that the example above also calls plusEllipseCluser() passing two arguments: it's a basic example of defining and calling a function that takes two arguments. Of course you've already called functions with arguments before (e.g. random(min,max), ellipse(x,y,w,h), etc.)
Have fun with shapes and patterns.

Forcing a sphere to spin

I am working on an animation of a simplified solar system and want to apply rotation to the Sun. It seems to be a simple task, but somehow it won't work. I try to write my program using object-oriented paradigm, so each planet, moon and the Sun is an object of the CelestialBody class.
I tried to put the rotate(angle) line in an following excerpt from the CelestialBody class, as follows:
if(Type == 4){
emissive(255, 255, 255);
pointLight(255, 255, 255, 0, 0, 0); //for the normal behaviour of the sun light
lightFalloff(0, 0, 0.00020); //light falls off right behind the surface of the sun
ambientLight(255, 255, 255, 0, 0, 0); //ambientLight in the center of the sun
rotate(angle);
}
Sadly, it does nothing. How to fix this and make the sun rotate, for example along the x-axis?
Here's my code:
Main file:
import peasy.*; //<>//
PImage bg;
float angle = 0;
CelestialBody planet1;
CelestialBody planet2;
CelestialBody planet3;
CelestialBody planet4;
CelestialBody planet5;
CelestialBody sun;
PImage sunTexture;
PImage rocketTexture;
PShape rocket;
PeasyCam cam;
void setup() {
fullScreen(P3D);
bg = loadImage("background.jpg");
sunTexture = loadImage("sun.jpg");
cam = new PeasyCam(this, 1200);
rocket = loadShape("rocket.obj");
noStroke();
sun = new CelestialBody(70, 0, 0, 255, 200, 50, 4);//4 - type: sun
sun.planet.setTexture(sunTexture);
//noStroke();
//emissive(0, 0, 0);
planet1 = new CelestialBody(16, 150, 0.01, 150, 50, 255, 1);
planet1.spawnMoon(2);
planet2 = new CelestialBody(25, 300, 0.014, 50, 100, 255, 1);
planet2.spawnMoon(3);
planet3 = new CelestialBody(35, 450, -0.015, 255, 100, 40, 2);
planet3.spawnMoon(1);
planet4 = new CelestialBody(50, 650, 0.011, 50, 200, 255, 1);
planet4.spawnMoon(2);
planet5 = new CelestialBody(65, 900, -0.014, 0, 100, 0, 1);
planet5.planet = rocket;
planet5.planet.scale(0.9);
}
void makeOrbit(int a, int r){
for(int i=0; i<a; i++){
stroke(255, 10);
ellipse(height/2,width/2,r,r);
r-=180;
}
noStroke();
}
void draw() {
background(bg);
//lights();
noFill();
//translate(width/2, height/2);
stroke(#FFFFFF);
//ellipse(0,0,300,300);
//ellipse(0,0,600,600);
//ellipse(0,0,900,900);
//ellipse(0,0,planet4.distance,planet4.distance
// int z = 100;
//for (int i = 0; i<2; i++){
// z = -z;
// pointLight(255, 255, 255, -100, -100, z);
// pointLight(255, 255, 255, 100, -100, z);
// pointLight(255, 255, 255, 100, 100, z);
// pointLight(255, 255, 255, -100, 100, z);
//}
//emissive(255, 255, 255);
//pointLight(255, 255, 255, 0, 0, 0); //for the normal behaviour of the sun light
//lightFalloff(0, 0, 0.00025); //light falls off right behind the surface of the sun
//ambientLight(255, 255, 255, 0, 0, 0); //ambientLight in the center of the sun
sun.show();
planet1.show();
planet1.orbit();
planet2.show();
planet2.orbit();
planet3.show();
planet3.orbit();
planet4.show();
planet4.orbit();
planet5.show();
planet5.orbit();
}
CelestialBody class:
class CelestialBody {
float radius;
float angle = random(TWO_PI);
float distance;
float orbitSpeed;
PShape planet;
CelestialBody[] moons;
int red;
int green;
int blue;
PVector v;
//PShape globe;
int Type;
CelestialBody(float _radius, float _distance, float _orbitSpeed, int _red, int _green, int _blue, int type) {
v = PVector.random3D();
radius = _radius;
distance = _distance;
v.mult(distance);
orbitSpeed = _orbitSpeed;
red = _red;
green = _green;
blue = _blue;
//stroke(red, green, blue);
fill(red, green, blue);
if(type == 1 || type == 4){
planet = createShape(SPHERE, _radius);
}
else if(type == 2){
planet = createShape(BOX, _radius);
}
Type = type;
}
void orbit() {
angle += orbitSpeed;
if (moons != null) {
for (int i = 0; i < moons.length; i++) {
moons[i].orbit();
}
}
}
void spawnMoon(int total){
moons = new CelestialBody[total];
for(int i = 0; i < moons.length; i++){
float r = radius / random(2,5);
float d = random((radius + r), (radius + r)*2);
float o = random(0.01, 0.05);
moons[i] = new CelestialBody(r, d, o, (int)random(0, 256), (int)random(0, 256), (int)random(0, 256), 1);
}
}
void show() {
pushMatrix();
PVector v2 = new PVector(1,0,1);
PVector p = v.cross(v2);
rotate(angle,p.x, p.y, p.z);
translate(v.x, v.y, v.z);
if(Type == 4){
emissive(255, 255, 255);
pointLight(255, 255, 255, 0, 0, 0); //for the normal behaviour of the sun light
lightFalloff(0, 0, 0.00020); //light falls off right behind the surface of the sun
ambientLight(255, 255, 255, 0, 0, 0); //ambientLight in the center of the sun
}
//shape(globe);
shape(planet);
if (moons != null) {
for (int i = 0; i < moons.length; i++) {
moons[i].show();
}
}
noStroke();
popMatrix();
}
}

p5.js not drawing a 3d box

I am creating a simulator using P5.js. Within the simulator, I need a green box, however it does not seem to be appearing. The code is below:
var outputs = [];
function setup() {
createCanvas(600, 400, WEBGL);
background(200);
for (var i = 0; i < 1; i++) {
drop = new Water(width / 2, height / 2, 0, 1);
outputs[i] = drop;
}
}
function draw() {
push();
translate(200, 150, 0);
stroke(0, 100, 0);
fill(0, 255, 0);
box(150, 150, 150);
pop();
for (var i = 0; i < outputs.length; i++) {
outputs[i].update();
}
background(200);
}
Here is the water class:
function Water(x_, y_, z_, yVel_) {
this.r = random(0.25, 1);
this.xOff = random(-(this.r / 10), (this.r / 10));
this.zOff = random(-(this.r / 10), (this.r / 10));
this.x = x_ + this.xOff;
this.y = y_;
this.z = z_ + this.zOff;
this.yVel = yVel_;
this.pos = createVector(this.x, this.y, this.z);
this.show = function() {
push();
translate(this.pos.x, this.pos.y, this.pos.z);
noStroke();
fill(0, 0, 255);
sphere(this.r * 2);
pop();
}
this.update = function() {
this.vel = createVector(random(-(this.r / 10), (this.r / 10)),
this.yVel, random(-(this.r / 10),
(this.r / 10)));
this.pos.add(this.vel);
this.show();
}
}
This is a web based simulation, with another module which appears to be working fine.
Any help would be greatly appreciated. Thanks in advance!
Removing the parts that require the Water class, and moving the background function call to the top of draw, it seems to work just fine.
So, the problem is
Either that you forgot to put background on top
Or something's wrong with the Water class.
Here's your code with the mentioned problems fixed.
var outputs = [];
function setup() {
createCanvas(600, 400, WEBGL);
}
function draw() {
background(200);
push();
translate(200, 150, 0);
stroke(0, 100, 0);
fill(0, 255, 0);
box(150, 150, 150);
pop();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.1/p5.min.js"></script>
Its not rendering because you're background is over your scene
function draw() {
background(200);
push();
translate(200, 150, 0);
stroke(0, 100, 0);
fill(0, 255, 0);
box(150, 150, 150);
pop();
for (var i = 0; i < outputs.length; i++) {
outputs[i].update();
}
}
What your doing is drawing the box and the drops and you cover it all up with your background
if you don't have a background you will see how p5.js renders animation
p5.js not moving it, its just looping through draw every frame and the background covers up the previous frame

Traffic Light sequence in Processing

I am trying to get this bit of code I have got and add another traffic light and car but going from right to left not from bottom to top. The car only moves when the light is amber or green and stops when red. I have tried copying the code and changing the names of the values but it just will not work. I have tried naming them all different names but it won't even show the other image I tried to put in for the other car. Can someone please tell/show me how I could add another traffic light and car but they move at different times?
TrafficLight light1 = new TrafficLight(100, 40);
int onTime = 2000;
int startTime = millis();
PImage car;
int carX, carY;
void setup() {
size(800, 600);
light1.changeColour("red");
light1.display();
car = loadImage("Car.png");
carX = 150;
carY = 300;
}
void draw() {
background(255);
if (millis() - startTime > onTime && light1.lightOn == "red") {
light1.changeColour("amber");
startTime = millis();
}
if (millis() - startTime > onTime && light1.lightOn == "amber") {
light1.changeColour("green");
startTime = millis();
}
if (millis() - startTime > onTime && light1.lightOn == "green") {
light1.changeColour("red");
startTime = millis();
}
light1.display();
image(car, carX, carY);
if (light1.lightOn == "green") {
carY -= 2;
}
{
}
if (light1.lightOn == "red") {
carY -= 0;
}
{
}
if (light1.lightOn == "amber") {
carY -= 1;
}
{
}
if (carY <= -200) {
carY = 500;
}
}
class TrafficLight {
int xpos;
int ypos;
String lightOn = "red";
TrafficLight(int x, int y) {
xpos = x;
ypos = y;
}
void changeColour(String lightColour) {
lightOn = lightColour;
}
void display() {
String lightColour = lightOn;
fill(0, 0, 0);
rect(xpos, ypos, 100, 220);//back panel
if (lightColour == "red") {
fill(255, 0, 0);
lightOn = "red";
} else {
fill(100, 0, 0);
}
ellipse(xpos + 50, ypos + 40, 60, 60);//red
if (lightColour == "amber") {
fill(255, 255, 0);
lightOn = "amber";
} else {
fill(100, 100, 0);
}
ellipse(xpos + 50, ypos + 110, 60, 60);//amber
if (lightColour == "green") {
fill(0, 255, 0);
lightOn = "green";
} else {
fill(0, 100, 0);
}
ellipse(xpos + 50, ypos + 180, 60, 60);//green
}
}
The code you've posted only contains one car, which makes this question hard to answer. Stack Overflow isn't really designed for general "how do I do this" type questions. It's more designed for specific "I tried X, expected Y, but got Z instead" type questions. That being said, I'll try to answer in a general sense:
Here's the short answer: you need to create a state for a second car, and then work with that state exactly how you work with the state of the first car. This might be easier if you encapsulate that state into a class, and then use two instances of that class.
Let's start out with a simpler example of a circle that moves vertically, and stops when we press the mouse:
MovingCircle verticalCircle;
void setup() {
size(600, 600);
verticalCircle = new MovingCircle(250, 250, 0, 5);
}
void mousePressed() {
verticalCircle.moving = !verticalCircle.moving;
}
void draw() {
background(0);
verticalCircle.step();
}
class MovingCircle {
float x;
float y;
float xSpeed;
float ySpeed;
boolean moving = true;
public MovingCircle(float x, float y, float xSpeed, float ySpeed) {
this.x = x;
this.y = y;
this.xSpeed = xSpeed;
this.ySpeed = ySpeed;
}
void step() {
if (moving) {
x+=xSpeed;
y+=ySpeed;
if (x > width) {
x = 0;
}
if (y > height) {
y = 0;
}
}
ellipse(x, y, 25, 25);
}
}
This program creates a circle that moves down the screen, and stops and starts when you click the mouse. Notice that I've encapsulated all of the information I need inside the MovingCircle class, so now if I want to add another one, I can just create another instance of that class and interact with it however I want.
Here's how I would add a horizontally moving circle:
MovingCircle verticalCircle;
MovingCircle horizontalCircle;
void setup() {
size(600, 600);
verticalCircle = new MovingCircle(250, 250, 0, 5);
horizontalCircle = new MovingCircle(250, 250, 5, 0);
}
void mousePressed() {
verticalCircle.moving = !verticalCircle.moving;
}
void keyPressed() {
horizontalCircle.moving = !horizontalCircle.moving;
}
void draw() {
background(0);
verticalCircle.step();
horizontalCircle.step();
}
This is just an example, but the principle is the same in your code: you need to encapsulate your state into a class, and then you can work with two instances of that class in order to have two moving cars.
Also, you should never use == to compare String values! Use the .equals() function instead!
if(lightColour.equals("red")){

Clearing out canvas

I'm trying to program an intro. I want the canvas to erase itself after it. I already have the trigger, but I do not know how to clear the canvas. Would just changing the background work? I still want to make stuff after it.
Here is the code:
void setup () {
frameRate(10);
stroke(255, 255, 255);
noFill();
rect(100,155,300,300);
size(500, 500);
}
void square () {
for (int x = 100; x <= 300; x += 100) {
for (int y = 155; y <= 355; y += 100) {
fill(random(0, 255), random(0, 255), random(0, 255));
rect(x, y,100,100);
}
}
};
void draw () {
int time = 0;
int logoLength = 100;
if (time < logoLength) {
fill(255, 255, 255);
background(0, 0, 0);
textFont(createFont("Lucida console", 19));
textAlign(CENTER,CENTER);
text("Ghost Cube Games presents",250,59);
time++;
print(time);
square();
} else if (time == logoLength) {
background(255, 255, 255);
}
}
You can simply call the background() function.
background(0); draws a black background.
background(255); draws a white background.
background(255, 0, 0); draws a red background.
More info can be found in the reference.
For a more specific example, if you want to show an intro screen, you can simply keep track of whether the intro screen is showing in a boolean variable. If that variable is true, then draw the intro screen. If not, then draw whatever else you want to draw. If you do this from the draw() function, then you don't really have to worry about clearing the screen, since calling the background() function will do that for you:
boolean showingIntro = true;
void draw() {
background(0);
if (showingIntro) {
text("INTRO", 20, 20);
} else {
ellipse(50, 50, 25, 25);
}
}
void mouseClicked() {
showingIntro = false;
}

Resources