Llevo días intentando resolver un problema pero no lo consigo.
Utilizo el sensor de temperatura con la placa de Arduino Uno y mirando la terminal de Arduino parece que mi código funciona correctamente pero en cambio el mismo dato, cuando se "envía" a Processing (se escribe al serial y desde Processing se lee), es cómo si algo fallara. Yo tengo la hipótesis que es porque la velocidad de ejecución y de escritura/lectura es diferente. Como Arduino no envía el dato continuamente, sino cada 3 segundos de acuerdo a lo que he puesto en el código, Processing cuando no tiene el dato se inventa el valor (me salen temperaturas cambiantes continuamente desde -91 °C cuando la escribo en la ventana de ejecución dentro de draw() ), es cómo si estuviera loco. Y en consecuencia no funciona bien el resto de cosas que he programado en Processing porque dependen del valor de esta temperatura.
Si el problema es este, cómo lo puedo hacer para coordinarlos "temporalmente"? (había puesto la frameRate a 1 y tampoco funciona
Y si no, puede ser debido a otra cosa?
Código (muy simplificado):
ARDUINO
// Esta línea está dentro del loop(), se executa cada 3 segundos:
Serial.write(int(round(temperature)) + 100); // Enviamos la temperatura (proveniente del sensor) sumandole 100 porque solo permite valores entre 0 y 250 y así aseguramos que enviamos la temperatura correcta también si es negativa
Serial.write(switchState); // Envío otra variable que aquí no nos influye
PROCESSING
void draw() {
/* más código aquí*/
temp = myPort.read() - 100; // Temperatura, restamos los 100ºC que hemos sumado para no perder los valores negativos
state = myPort.read(); // Leemos el otro dato
text(temp, 200, 100); // Escribimos la temperatura por la ventana, pero está loco; a los 3 segundo es correcto muchas veces pero entre los intervalos de 3 segundos no para de cambiar de número y son números negativos
" Using Arduino - Interfacing w/ Software on the Computer"
This is an international category and must be in English.
You are writing in a language other than English.
Ask a moderator to redirect your thread
Moderador:
Por favor, lee las Normas del foro
Si posteas en el foro en inglés usa idioma inglés para expresarte.
Si escribes en español debes usar el foro Arduino en español.
Este mensaje lo envío porque tu hilo fue movido del foro en inglés y por eso tenemos una respuesta anterior en ese idioma. A partir de ahora todos responden en español.
Nunca pongas códigos parciales.
Si sabes cual es el problema entonces también tu podrías resolverlo, entonces cuando tengas un problema postea todo el código para que nosotros podamos o bien evaluar que esta mal o bien reproducir tu problema.
En processing se trabaja de manera similar a Arduino
//"Si hay algo en el puerto serial". En esta línea estamos accediendo a la función de escucha dentro de la clase Serial, por medio de nuestra copia personalizada 'port'.
if(port.available()>0){
//Igualamos a nuestra variable de texto a lo que nos devuelva la función readStringUntil.
//Dicha función lee todo lo que haya en el puerto serial hasta que encuentre un 'Enter', representado por el caracter especial '\n'.
//Cabe destacar que este 'Enter' es el mismo que el Arduino escribe al final de cada línea por usar Serial.println
mensaje = port.readStringUntil('\n');
}
Si hay algo en el puerto entonces lo convierte a un mensaje con elque luego trabaja.
Si no haces eso pierdes datos.
No hay inventos del código y me refiero al -91, lo que si hay es errores que cometemos por omitir los métodos adecuados.
Revisa el ejemplo que te he puesto y verás que podrás resolverlo.
Primero de todo pido disculpas por mis errores. No lo he hecho con ninguna mala intención y ahora voy a hacerlo como indicáis.
Con tu respuesta no he logrado solucionarlo aún. Yo utilizo la función "Serial.write()" para pasar los datos tal y como lo explica el libro de Arduino físico que compré. Y no envío Strings, sinó "int"'s.
Copio los códigos enteros (no lo había hecho para no liar, pero ya los he simplificado y traducido al español):
Arduino:
/* El proyecto consiste en poder conocer si una cisterna está con un nivel de agua demasiado baja
(con un sensor de inclinación), una temperatura demasiado baja (se puede helar)
o alguien ha abierto la apertura (sensor de luz)
*/
// Variables
// Pines y datos de los sensores
int const sensorTemp = A0; // pin analogico sensor de temperatura
int const sensorLight = A1; // pin analogico sensor de luz
int sensorTempVal = 0; // guardaremos valor temperatura sensor
int sensorLightVal = 0; // guardaremos valor luz sensor
float temperature; // variable para indicar valor temperatura actual
bool open = false; // variable para indicar si está abierto
int thresholdLightVal = 1000; // a partir de esta intensidad luminosa se activa la alarma
const float baselineTemp = 2.0; // por debajo de esta temperatura, saltará una alerta
const int switchPin = 12; // pin digital sensor de inclinación
const int ledPin = 13; // nombre de pin del led de la placa
const int redPin = 9; // pin digital led rojo
const int greenPin = 8; // pin digital led verde
// Tiempo
unsigned long previousTime = 0;
const int timeCycle = 3000; // Ciclos de 3 segundos
bool startDetecting = true; // Indica si está en modo detección o no
int switchState = 1; // Estado sensor de inclinación
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(switchPin, INPUT);
delay(500);
digitalWrite(ledPin, LOW);
}
void loop() {
unsigned long currentTime = millis(); // Tiempo actual
// MODE DETECCIÓ
if (currentTime - previousTime > timeCycle) { // Si está en modo detección
previousTime = currentTime; // para detectar el próximo ciclo de tiempo,
switchState = digitalRead(switchPin); // lee valor sensor de inclinación
sensorLightVal = analogRead(sensorLight); // lee valor sensor de luz
sensorTempVal = analogRead(sensorTemp); // lee valor sensor de temperatura
// Transforma el valor del sensor de temperatura a un valor de temperatura en ºC
temperature = (sensorTempVal / 1024.0 * 5.0 - .5) * 100;
// Si está abiero, lo indicamos
if (sensorLightVal > thresholdLightVal) open = true;
else open = false;
delay(1);
// Lo imprimimos
Serial.print("switchState: ");
Serial.println(switchState);
Serial.print("Temperatura: ");
Serial.println(temperature);
Serial.print("Luz: ");
Serial.println(sensorLightVal);
// Enviamos algunos datos a través del puerto de serie para utilitzar con Processing.
Serial.write(int(round(temperature)) + 100); // Enviamos la temperatura sumandole 100
Serial.write(switchState); // 1 significa nivel correcto y 0 incorrecto
Serial.write(open); // true es que está abierta; false que no
delay(5);
// Si está inclinado o la temperatura es muy baja o está abierta
if (switchState == 0 || temperature < baselineTemp || open) {
digitalWrite(redPin, HIGH);
Serial.print("ALERTA!!!");
digitalWrite(redPin, LOW);
}
// Si todo está bien,
else {
digitalWrite(greenPin, HIGH); // LED verde encendido
delay(1000); // durante un segundo
digitalWrite(greenPin, LOW); // y se apaga
}
delay(10);
}
delay(10);
}
Processing:
import processing.serial.*;
Serial myPort;
// Variables
String level; // Nivel de auga
String temperatura; // Temperatura
int state; // Guardamos si el nivel de agua es correcto o bajo
int temp; // Guardamos la temperatura actual
int open; // Guardamos si está abierta o no
void setup() {
surface.setSize(900,900);
surface.setLocation(987, 70);
println("Available serial ports: ");
println(Serial.list()); // Arduino está connectado al COM5 (elemento 2)
myPort = new Serial(this, Serial.list()[2], 9600);
// Texto
fill(255);
textSize(16);
// Inicialización de variables
level = "Nivel agua: ";
temperatura = "Temperatura: ";
frameRate(4);
}
void draw() {
background(#282828);
// Miramos si llegan datos de Arduino
if (myPort.available() > 0) {
// Guardamos la información que hay al buffer
temp = myPort.read() - 100; // Temperatura, restamos los 100ºC que hemos sumado en Arduino
state = myPort.read(); // Estado nivel de agua
open = myPort.read(); // Abierto o no
temp = -5;
state = 1;
open = 0;
// NIVEL AGUA
if (state == 1) {
// Hay agua
level = "Nivel agua: Correcto";
}
else if (state == 0) {
// Queda poca agua
level = "Nivel agua: Bajo (ALERTA!)";
}
// TEMPERATURA
// Mostramo por pantalla la temperatura actual detectada por el sensor
temperatura = "Temperatura: " + temp + " ºC";
if (temp < 2) {
// Si la temperatura es muy baja
temperatura += " (ALERTA!)";
}
}
// Escribimos el texto por pantalla
textAlign(CENTER);
textSize(16);
text("DATOS EN TIEMPO REAL \n(actualizado cada 3 segundos)", width/2, height/3);
textAlign(LEFT);
text(level, width/2, height/2);
if (temp < 2) fill(color(224, 92, 38));
text(temperatura, width/2, height*2/3);
}
Si usaras algo mas moderno como Python muchos podríamos ayudarte.
TIenes todo el derecho pero por qué elegiste Processing?
NOTA: Por lo visto el equivocado soy yo. Pensé que no tenía actualizaciones y veo que no es el caso
Acabo de instalarlo porque como se que es Java y estoy haciendo un curso de Java me va a resultar amigable digamos.
Probaré tu problema. Luego edito aquí mismo si es que nadie lo hace antes.3
Bueno, esto me esta funcionando: Arduino:
/* El proyecto consiste en poder conocer si una cisterna está con un nivel de agua demasiado baja
(con un sensor de inclinación), una temperatura demasiado baja (se puede helar)
o alguien ha abierto la apertura (sensor de luz)
*/
//#define DEBUG
#ifdef DEBUG
#define DEBUG_PRINT(x) Serial.println (x)
#else
#define DEBUG_PRINT(x)
#endif
// Variables
// Pines y datos de los sensores
int const sensorTemp = A0; // pin analogico sensor de temperatura
int const sensorLight = A1; // pin analogico sensor de luz
int sensorTempVal = 0; // guardaremos valor temperatura sensor
int sensorLightVal = 0; // guardaremos valor luz sensor
float temperature; // variable para indicar valor temperatura actual
bool open = false; // variable para indicar si está abierto
int thresholdLightVal = 1000; // a partir de esta intensidad luminosa se activa la alarma
const float baselineTemp = 2.0; // por debajo de esta temperatura, saltará una alerta
const int switchPin = 12; // pin digital sensor de inclinación
const int ledPin = 13; // nombre de pin del led de la placa
const int redPin = 9; // pin digital led rojo
const int greenPin = 8; // pin digital led verde
// Tiempo
unsigned long previousTime= 0;
const int timeCycle = 3000; // Ciclos de 3 segundos
bool startDetecting = true; // Indica si está en modo detección o no
int switchState = 1; // Estado sensor de inclinación
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(switchPin, INPUT);
delay(500);
digitalWrite(ledPin, LOW);
}
void loop() {
unsigned long currentTime = millis(); // Tiempo actual
// MODE DETECCIÓ
if (currentTime - previousTime > timeCycle) { // Si está en modo detección
previousTime = currentTime; // para detectar el próximo ciclo de tiempo,
switchState = digitalRead(switchPin); // lee valor sensor de inclinación
sensorLightVal = analogRead(sensorLight); // lee valor sensor de luz
sensorTempVal = analogRead(sensorTemp); // lee valor sensor de temperatura
// Transforma el valor del sensor de temperatura a un valor de temperatura en ºC
temperature = (sensorTempVal / 1023 * 5.0 - .5) * 100;
// Si está abierto, lo indicamos
open = sensorLightVal > thresholdLightVal?true:false;
delay(1);
// Lo imprimimos
DEBUG_PRINT("switchState: " + String(switchState));
DEBUG_PRINT("Temperatura: " + String(temperature));
DEBUG_PRINT("Luz: " + String(sensorLightVal));
temperature = (float) random(300, 350)/10;
switchState = random(0,1)?true:false;
open = random(0,1)?true:false;
// Enviamos algunos datos a través del puerto de serie para utilitzar con Processing.
Serial.write(int(round(temperature)) + 100); // Enviamos la temperatura sumandole 100
Serial.write(switchState); // 1 significa nivel correcto y 0 incorrecto
Serial.write(open); // true es que está abierta; false que no
delay(5);
// Si está inclinado o la temperatura es muy baja o está abierta
if (switchState == 0 || temperature < baselineTemp || open) {
digitalWrite(redPin, HIGH);
DEBUG_PRINT("ALERTA!!!");
digitalWrite(redPin, LOW);
}
// Si todo está bien,
else {
digitalWrite(greenPin, HIGH); // LED verde encendido
delay(1000); // durante un segundo
digitalWrite(greenPin, LOW); // y se apaga
}
delay(10);
}
delay(10);
}
Processing 4.0
import processing.serial.*;
Serial myPort;
// Variables
String level; // Nivel de auga
String temperatura; // Temperatura
int state; // Guardamos si el nivel de agua es correcto o bajo
int temp; // Guardamos la temperatura actual
int open; // Guardamos si está abierta o no
void setup() {
surface.setSize(600,600);
surface.setLocation(987, 70);
println("Available serial ports: ");
println(Serial.list()); // Arduino está connectado al COM5 (elemento 2)
myPort = new Serial(this, Serial.list()[1], 9600);
// Texto
fill(255);
textSize(16);
// Inicialización de variables
level = "Nivel agua: ";
temperatura = "Temperatura: ";
frameRate(4);
}
void draw() {
background(#282828);
// Miramos si llegan datos de Arduino
if (myPort.available() > 0) {
// Guardamos la información que hay al buffer
temp = myPort.read() - 100; // Temperatura, restamos los 100ºC que hemos sumado en Arduino
textSize(16);
text(temp, 10, 10);
state = myPort.read(); // Estado nivel de agua
open = myPort.read(); // Abierto o no
//temp = -5;
//state = 1;
//open = 0;
// NIVEL AGUA
if (state == 1) {
// Hay agua
level = "Nivel agua: Correcto";
}
else if (state == 0) {
// Queda poca agua
level = "Nivel agua: Bajo (ALERTA!)";
}
// TEMPERATURA
// Mostramo por pantalla la temperatura actual detectada por el sensor
temperatura = "Temperatura: " + temp + " ºC";
if (temp < 2) {
// Si la temperatura es muy baja
temperatura += " (ALERTA!)";
}
}
// Escribimos el texto por pantalla
textAlign(CENTER);
textSize(16);
text("DATOS EN TIEMPO REAL \n(actualizado cada 3 segundos)", width/2, height/3);
textAlign(LEFT);
text(level, width/2, height/2);
if (temp < 2) fill(color(224, 92, 38));
text(temperatura, width/2, height*2/3);
}
¡Muchísimas gracias por la rapidez en responder! Parece que ahora funciona.
He buscado qué es la función "DEBUG_PRINT" en la web y no encuentro nada que me lo explique. Mi pregunta es: ¿Dónde veo lo que "imprimo" con esta función? En la Salida y en el Monitor Serie de Arduino no sale nada.
Es una macro que creó @Surbyte , en resumen, al momento de compilar se reemplaza
DEBUG_PRINT(x)
por
Serial.println (x)
o por una línea vacía, según esté habilitada o no
#define DEBUG
La salida claramente es por puerto serial y ahí radica tu problema.
Usas el puerto Serial para enviar unos mensajes a consola y otros a Processing, y eso está evidente mal.
Processing espera leer un byte cuando tu mandas cadenas como las que te marqué antes en #6.
Para hacer ambas cosas deberías usar SoftwareSerial para crear un puerto serie por software y usar un conversor TTL/USB para conectar este otro puerto al pc.