¿Puedo hacer que una secuencia de imágenes en el procesamiento se mueva / juegue con un sensor ultrasónico Arduino?

Sydney

Esta es mi primera publicación, así que me disculpo de antemano si algo no está claro e intentaré aprender rápidamente. También soy un novato en lo que respecta a la programación. Usando Arduino Uno, Sensor Ultrasónico HC-SR04, Procesando3.5.3

En el procesamiento y los bocetos de Arduino que proporcioné, puedo reproducir una secuencia de imágenes, y cuando el sensor ultrasónico detecta la distancia de un objeto, se imprime un "1" en la consola de procesamiento.

Me pregunto si puedo usar este "1" para hacer una declaración if. Si la consola imprime un número mayor que 0, haga que se reproduzca la secuencia de imágenes; de lo contrario, solo se dibujará una imagen (el gif se detendrá). He probado un par de versiones de esto, pero no quiero fingir que sé lo que estoy haciendo.

¡Cualquier pista que pueda seguir sería maravillosa! ¡O tutoriales en línea!

Siento que hay algo increíblemente simple que simplemente me estoy perdiendo ... Supongo que nada es tan simple. Gracias por tu tiempo :))

CÓDIGO ARDUINO:

#define trigPin 9
#define echoPin 10

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

void loop() {
  long distance;
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);           //CHANGE THIS??
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  distance = pulseIn(echoPin, HIGH);

  if (distance <= 2000) { //raise this number to raise the distance to wave hand
    Serial.print("1");
  } else {
    Serial.print("0");
  }
  delay(500);  
}

PROCESANDO

import processing.serial.*;

int numFrames = 22; //number of frames in animation
int currentFrame = 0;
PImage[] image = new PImage[22];
Serial myPort;
String instring = "";

void setup() {
  myPort = new Serial(this, Serial.list()[1], 9600);
  myPort.bufferUntil('\n');
  size(1600, 900);
  frameRate(30);
  background(0);
  
  //Load images below
  for(int i = 0; i<image.length; i++) {
    image[i] = loadImage("PatMovingFace" + i + ".png");
  }
}

void draw() {
  //ALL BELOW connects to arduino sensor
  while (myPort.available () > 0) {
    instring = myPort.readString();
    println(instring);
    int sensorAct = Integer.parseInt(instring, 10);
  }
  playGif();   
}

// ALL BELOW will make the pic array animate! Image moves! 

void playGif() {
  currentFrame = (currentFrame+1) % numFrames; //use % to cycle through frames!
  int offset = 0;

  for (int i = 0; i < image.length; i++) {
    //image(image[i] % numFrames), 0, 0);
    image(image[(currentFrame + offset) % numFrames], 0, 0);
    offset += 0;
    image(image[(currentFrame + offset) % numFrames], 0, 0);
    offset+= 0;
  }
}
George Profenza

Primero podría simplificar / limpiar playGif():

  • offset no parece hacer nada en este momento (se "incrementa" de 0 a 0)
  • image()se llama dos veces con las mismas coordenadas sobredibujando el mismo contenido sobre sí mismo. una vez que la image()llamada debería hacer
  • probablemente no necesite el bucle for ya que está dibujando un cuadro a la vez
  • currentFramees un incremento al siguiente fotograma y vuelve al inicio al principio de playGif(), sin embargo, al renderizar la imagen, el índice de la matriz se incrementa offsetnuevamente en (0). no está claro cuál es la intención. puedes prescindir
  • currentFramepuede controlar la reproducción / pausa: si aumenta, se reproduce, de lo contrario, se detiene. es bueno tener una separación entre actualizar datos ( currentFrame) y renderizar con datos actualizados ( image(image[currentFrame],0,0))
  • también puede cambiar el nombre de la imagematriz para imagesque sea más representativa de lo que es y es más difícil confundirse entre eso y la image()función

Por ejemplo, playGif()podría recurrir a:

void playGif(){
      currentFrame = (currentFrame+1) % numFrames; //use % to cycle through frames!
      image(image[currentFrame], 0, 0);
}

Con respecto al control usando Arduino, como se mencionó anteriormente, simplemente verifique si obtiene un "1" para actualizar currentFrame(de lo contrario, permanecerá (en pausa) en el mismo valor):

void playGif(){
      if(instring.equals("1")){
         currentFrame = (currentFrame+1) % numFrames; //use % to cycle through frames!
      }
      image(image[currentFrame], 0, 0);
}

Estoy usando equals()arriba, porque es un String, aunque está enviando un solo carácter. (alternativamente, comparar el primer carácter habría funcionado if(instring.charAt(0) == '1'))

También tengo algunas notas sobre eso:

  • en el código Arduino que usa print(), no println(), lo que significa que no \nse enviará, por lo tanto, no es necesario myPort.bufferUntil('\n');niinstring = myPort.readString();
  • puede leer un solo carácter con myPort.read();(que, por cierto, puede comparar con ==(en lugar de String equals()) (por ejemplo if(myPort.read() == '1'){...)
  • whileestá bloqueando y recomiendo no usarlo. No hará una gran diferencia en su caso, ya que está enviando un solo byte, pero en programas más complejos que envían más bytes, esto impedirá que Processing procese un solo cuadro hasta que reciba todos los datos.

He aquí un ejemplo:

import processing.serial.*;

int numFrames = 22; //number of frames in animation
int currentFrame = 0;
PImage[] images = new PImage[numFrames];
Serial myPort; 

void setup() {
  myPort = new Serial(this, Serial.list()[1], 9600);  
  
  size(1600, 900);                                    
  frameRate(30);                                      
  background(0);

  //Load images below
  for (int i = 0; i < numFrames; i++)
  { 
    images[i] = loadImage("PatMovingFace" + i + ".png");
  }
}

void draw() {
  // if there's at least one byte to read and it's '1'
  if(myPort.available() > 0 && myPort.read() == '1'){
    // increment frame, looping to the start
    currentFrame = (currentFrame+1) % numFrames; //use % to cycle through frames!
  }
  // render current frame
  image(images[currentFrame], 0, 0);
}

Una versión más cautelosa, verificando qué podría salir mal (conexión en serie, carga de datos) se vería así:

import processing.serial.*;
    
int numFrames = 22; //number of frames in animation
int currentFrame = 0;
PImage[] images = new PImage[numFrames];
Serial myPort; 

void setup() {
  String[] ports = Serial.list();
  int portIndex = 1;
  if(ports.length <= portIndex){
    println("serial ports index " + portIndex + " not found! check cable connection to Arduino");
    println("total ports: " + ports.length);
    printArray(ports);
    exit();
  }
  try{
    myPort = new Serial(this, ports[portIndex], 9600);  
  }catch(Exception e){
    println("error connecting to serial port: double check the cable is connected and no other program (e.g. Serial Monitor) uses this port");
    e.printStackTrace();
  }  
  size(1600, 900);                                    
  frameRate(30);                                      
  background(0);

  //Load images below
  try{
    for (int i = 0; i < numFrames; i++)
    { 
      images[i] = loadImage("PatMovingFace" + i + ".png");
    }
  }catch(Exception e){
    println("image loading error");
    e.printStackTrace();
  }
}

void draw() {
  // if Arduino connection was successfull
  if(myPort != null){
    // if there's at least one byte to read and it's '1'
    if(myPort.available() > 0 && myPort.read() == '1'){
      // increment frame, looping to the start
      currentFrame = (currentFrame+1) % numFrames; //use % to cycle through frames!
    }
  }else{
    text("serial port not initialised", 10, 15);
  }
  
  if(images[currentFrame] != null){
    // render current frame
    image(images[currentFrame], 0, 0);
  }else{
    text("serial port not loaded", 10, 15);
  }
}

o con lo mismo en funciones agrupadas usando:

import processing.serial.*;

int numFrames = 22; //number of frames in animation
int currentFrame = 0;
PImage[] images = new PImage[numFrames];

final int SERIAL_PORT_INDEX = 1;
final int SERIAL_BAUD_RATE  = 9600;
Serial myPort; 

void setup() {
  size(1600, 900);                                    
  frameRate(30);                                      
  background(0);
  
  setupArduino();
  //Load images below
  loadImages();
}

void setupArduino(){
  String[] ports = Serial.list();
  int numSerialPorts = ports.length;
  // optional debug prints: useful to double check serial connection 
  println("total ports: " + numSerialPorts);
  printArray(ports);
  // exit if requested port is not found  
  if(numSerialPorts <= SERIAL_PORT_INDEX){
    println("serial ports index " + SERIAL_PORT_INDEX + " not found! check cable connection to Arduino");
    //exit();
  }
  // try to open port, exit otherwise
  try{
    myPort = new Serial(this, ports[SERIAL_PORT_INDEX], SERIAL_BAUD_RATE);  
  }catch(Exception e){
    println("error connecting to serial port: double check the cable is connected and no other program (e.g. Serial Monitor) uses this port");
    e.printStackTrace();
    //exit();
  }
}

void loadImages(){
  try{
    for (int i = 0; i < numFrames; i++)
    { 
      images[i] = loadImage("PatMovingFace" + i + ".png");
    }
  }catch(Exception e){
    println("image loading error");
    e.printStackTrace();
    //exit();
  }
}

void serialUpdateImage(){
  // if Arduino connection was successfull
  if(myPort != null){
    // if there's at least one byte to read and it's '1'
    if(myPort.available() > 0 && myPort.read() == '1'){
      // increment frame, looping to the start
      currentFrame = (currentFrame+1) % numFrames; //use % to cycle through frames!
    }
  }else{
    text("serial port not initialised", 10, 15);
  }
}

void displayCurrentImage(){
  if(images[currentFrame] != null){
    // render current frame
    image(images[currentFrame], 0, 0);
  }else{
    text("image " + currentFrame + " not loaded", 10, 25);
  }
}

void draw() {
  
  serialUpdateImage();
  
  displayCurrentImage();
}

Este artículo se recopila de Internet, indique la fuente cuando se vuelva a imprimir.

En caso de infracción, por favor [email protected] Eliminar

Editado en
0

Déjame decir algunas palabras

0Comentarios
Iniciar sesiónRevisión de participación posterior

Artículos relacionados