Go Down

Topic: alguna idea para mejorar este codigo SOLUCIONADO (Read 1 time) previous topic - next topic

peperruno

Apr 24, 2012, 10:58 pm Last Edit: Apr 25, 2012, 01:08 am by peperruno Reason: 1
/tres pulsadores by peperruno


//boton 1
const int buttonPin = 2;
int estado = 0;
const int ledPin =  13;
//boton 2
const int buttonPin2 = 4;
int estadobutton2 = 0;
const int ledPin2 = 12;
//boton 3
const int buttonPin3 = 7;
int estadobutton3 = 0;
const int ledPin3 = 8;

void setup() {
pinMode(ledPin, OUTPUT);      
pinMode(buttonPin, INPUT);
pinMode(ledPin2, OUTPUT);
pinMode(buttonPin2, INPUT);
pinMode(ledPin3, OUTPUT);
pinMode(buttonPin3, INPUT);
}

void loop(){

 if (digitalRead(buttonPin) == HIGH) {
 delay(500);
   if(estado)
   digitalWrite(ledPin, HIGH);
  else
       digitalWrite(ledPin, LOW);
  estado = ~estado;
 }
if (digitalRead(buttonPin2) == HIGH) {
 delay(500);
   if(estado)
   digitalWrite(ledPin2, HIGH);
  else
       digitalWrite(ledPin2, LOW);
  estado = ~estado;
 }
if (digitalRead(buttonPin3) == HIGH) {
 delay(500);
   if(estado)
   digitalWrite(ledPin3, HIGH);
  else
       digitalWrite(ledPin3, LOW);
  estado = ~estado;
 } }


funciona bien pero no es preciso en cuanto al tiempo que hay que mantener presionados los pulsadores y eso hace que parezca que falla al encender y apagar sobre todo si lo maneja alguien sin conocimiento alguno del proceso real , alguna idea para mejorar este sistema , he probado con  varios valores de delay y bueno mejora pero no es definitivo,  muchas gracias  


peperruno

alguna recomendación de lectura concreta sobre este tema ,  :smiley-eek-blue: principalmente no quiero molestar gracias.-

nayma

Una pregunta,

estado = ~estado;

if(estado) vario

¿que se supone que tienen que hacer? ¿Te compila bien?

peperruno

si creo que si ,  si esta encendido lo apaga y si esta apagado lo enciende eso lo hace bien pero claro el delay es para dar tiempo a pulsar  y ese es el problema que no siempre pulsas el mismo tiempo y a veces no se enciende y hay que volver a pulsar , perdona pero soy muy nuevo y tengo que ir mejorando.-  perdona lo de vario fue un error al copiarlo no esta en el codigo.-

Utiliza la función millis() en vez de utilizar delay's, cada dalay es una pausa en el programa y en tu caso esos 500 ms no son de espera para que pulse alguien sino que se queda parado medio segundo sin más.

peperruno

se queda parado para dar tiempo a pulsar y que no lo lea de nuevo , como lo haría millis() uso el mismo tiempo? gracias

PepeChorva

Lo suyo sería capturar los botones mediante interrupciones, pero si llevas el tema de programación flojillo, mejor no complicarte la vida todavía. Todo se andará.
Por cierto, ¿no sería mejor usa un solo hilo para el código? llevas 2 hilos abiertos y puede que te lies (o te liemos) con varios frentes abiertos.

Con millis(), da juego a que el procesador haga otras tareas mientras hace la espera, pero yo te aconsejo que, de momento, lo dejes así y te mires los ejemplos que hay en el IDE de Arduino y en el playground. Igual allí encuentras código que te ayuda en tu cometido.
---
Saludos,
José Chorva
www.pepechorva.com
@pepechorva on twitter

peperruno

hola PepeChorva , toda la razon lo he probado y va mucho mejor eres un crack queda como sigue , gracias.-//tres pulsadores by peperruno


//boton 1
const int buttonPin = 2;
int estadobuttonPin = 0;
const int ledPin =  13;
//boton 2
const int buttonPin2 = 4;
int estadobuttonPin2 = 0;
const int ledPin2 = 12;
//boton 3
const int buttonPin3 = 7;
int estadobuttonPin3 = 0;
const int ledPin3 = 8;

void setup() {
pinMode(ledPin, OUTPUT);     
pinMode(buttonPin, INPUT);
pinMode(ledPin2, OUTPUT);
pinMode(buttonPin2, INPUT);
pinMode(ledPin3, OUTPUT);
pinMode(buttonPin3, INPUT);
}

void loop(){

  if (digitalRead(buttonPin) == HIGH) {
  delay(500);
    if(estadobuttonPin)
    digitalWrite(ledPin, HIGH);
   else
        digitalWrite(ledPin, LOW);
   estadobuttonPin = ~estadobuttonPin;
  }
if (digitalRead(buttonPin2) == HIGH) {
  delay(500);
    if(estadobuttonPin2)
    digitalWrite(ledPin2, HIGH);
   else
        digitalWrite(ledPin2, LOW);
   estadobuttonPin2 = ~estadobuttonPin2;
  }
if (digitalRead(buttonPin3) == HIGH) {
  delay(500);
    if(estadobuttonPin3)
    digitalWrite(ledPin3, HIGH);
   else
        digitalWrite(ledPin3, LOW);
   estadobuttonPin3 = ~estadobuttonPin3;
  } }


PepeChorva

¿Ves lo que te decía? Esta contestación iba para el otro hilo  :smiley-mr-green:
Me alegro que te funcione bien
---
Saludos,
José Chorva
www.pepechorva.com
@pepechorva on twitter

fm

Vamos a ver "a modo" tutorial cómo mejorar un poco el código que nos has planteado. Una alternativa, consiste en codificar de forma eficiente. En esta entrega veremos la utilidad que tienen las funciones, cómo se utilizan y por qué son nuestras aliadas.

En el fragmento de código que nos has planteado, podemos ver que hay ciertos factores comunes y ciertos patrones. Qué sucedería si esto lo sacamos fuera del código en una función que acepta unos valores de entrada y unos valores de salida:

Code: [Select]

//boton 1
const uint8_t buttonPin = 2;
uint8_t estadobuttonPin = 0;
const uint8_t ledPin =  13;

//boton 2
const uint8_t buttonPin2 = 4;
uint8_t estadobuttonPin2 = 0;
const uint8_t ledPin2 = 12;

//boton 3
const uint8_t buttonPin3 = 7;
uint8_t estadobuttonPin3 = 0;
const uint8_t ledPin3 = 8;

void scanAndSet ( uint8_t inPin, uint8_t outPin, uint8_t &state )
{
   if ( digitalRead ( inPin ) == HIGH )
   {
      digitalWrite ( outPin, state );
   }
   state = ~state;
}

void setup()
{
   pinMode(ledPin, OUTPUT);     
   pinMode(buttonPin, INPUT);
   pinMode(ledPin2, OUTPUT);
   pinMode(buttonPin2, INPUT);
   pinMode(ledPin3, OUTPUT);
   pinMode(buttonPin3, INPUT);
}

void loop()
{
   scanAndSet ( buttonPin, ledPin, estadobuttonPin );
   scanAndSet ( buttonPin2, ledPin2, estadobuttonPin2 );
   scanAndSet ( buttonPin3, ledPin3, estadobuttonPin3 );
   delay ( 500 );
}

Donde "&" (sin entrar mucho en detalles y simplificando, le dice a C++ que es un valor de "entrada y de salida" de tal forma que las modificaciones que se hagan tengan efecto en quien las llama. Este código hace lo mismo que has publicado, pero en vez de tardar 1.5s, funciona de la misma forma pero usando 0.5s.

¿Pero para qué sirven las funciones? vale, vale, que el código queda más compacto y más legible.

Supongamos que el autor de este código lo que realmente quería es conseguir que: al pulsar el botón el LED se encienda y cuando vuelva a pulsar el botón se apague, casi instantaneamente. En vez de que el LED se encienda y se apague cada 3 segundos y si dejo pulsado el botón, o que tarde en encenderse 1.5s (aprox).

En la próxima entrega, veremos cómo se puede hacer cambiar el comportamiento del programa solo cambiando en un punto el código, en vez de hacer recorta pega por doquier.
   

fm

#11
Apr 25, 2012, 10:00 pm Last Edit: Apr 25, 2012, 10:03 pm by fm Reason: 1
En esta segunda entrega vamos a ver cómo cambiando la función "scanAndSet", podemos conseguir que el programa se comporte como un interruptor. Es decir: pulso el botón, el LED se enciende, lo vuelvo a pulsar y el LED se apaga. Además, vamos a ver cómo puede hacerse para que de la sensación de que es muy rápido.

Si reemplazamos la función "scanAndSet" por esta:
Code: [Select]

void scanAndSet ( uint8_t inPin, uint8_t outPin, uint8_t &state )
{
   if ( digitalRead ( inPin ) == HIGH )
   {
      switch ( state )
      {
      case 0:
         state = 1;
         digitalWrite ( outPin, HIGH );
         break;
      case 2:
         digitalWrite ( outPin, LOW );
         state = 3;
         break;
      default:
        break;
      }
   }
   if ( digitalRead ( inPin ) == LOW )
   {
      switch ( state )
      {
      case 1:
         state = 2;
         break;
      case 3:
         state = 0;
         break;
      default:
         break;
      }
   }
}

Conseguimos el efecto que buscamos. ¿Pero cómo leñes funciona?

Para aclararnos un poco, veamos la imagen adjunta. Cuando el estado es 0, el LED asociado al pin está apagado. Si pulso el botón, cambio el estado a 1 y enciendo el LED. Si mantengo pulsado el botón, me quedo en el estado 1 la siguiente vez que lo llame (0.5s después). Si suelto el botón, estado (state) pasa a valer 2 y me mantengo en este estado hasta que alguien pulse el botón otra vez. Al pulsar el botón otra vez con estado en 2, apago el LED y mi cambio el estado a 3. Si sigo manteniendo el botón pulsado más de 0.5 segundos, me quedo como estoy, pero si lo suelto vuelvo a 0.

Ahora vamos a poner nombres útiles a 0, 1, 2, 3 y veremos lo importante que es dar un valor significativo a las variables y constantes de nuestro código:
0 - APAGADO
1 - ENCENDIDO_BOTON_PULSADO
2 - ENCENDIDO
3 - APAGADO_BOTON_PULSADO

Por ejemplo.

Si además, el delay anterior los reducimos a 100ms, el bucle se ejecutará cada 100ms, dando la percepción al usuario de que se ha encendido la luz de forma instantánea. El delay de 100ms, se puede reducir hasta 50us-100us, menos no, porque sino veríamos los efectos de los rebotes que tienen los pulsadores. Por cierto, esta es una forma muy fácil de implementar un código anti-rebotes.

Si os han parecido útiles estas entregas y os interesa, mañana podemos ver cómo crear un librería que implemente una "variable" tecla y una "variable" interruptor LED, que incluso podáis compartir con otros usuarios. Vamos, a lo C++.
   

nayma

Todavía se podría depurar un poco con una matriz. Una matriz es una tabla de n elementos. Es como un armario con cajones, el primer cajón es el cajon cero,...
perruno, intentalo, mirate http://arduino.cc/es/Reference/Array

fm

#13
Apr 26, 2012, 08:32 am Last Edit: Apr 26, 2012, 11:13 pm by fm Reason: 1
Efectivamente, el autómata se puede hacer mucho mas rápido con una mariz bidimensional y se puede definir una estructura de datos que modele el interuptor. Tal vez lo más importante es definir un tipo enumerado que defina los estados, por claridad.
   

yOPERO

#14
Apr 26, 2012, 06:05 pm Last Edit: Apr 26, 2012, 06:09 pm by yOPERO Reason: 1
Yo uso este código cuando tengo que usar muchos pins, asigno outputs/inputs(setup) y solo edito las lineas1 y2
Code: [Select]

byte pins_input[] = {0,1,2,3,4,5,6,7,16,17};//Pins donde están los inputs
byte pins_output[] = {8,9,10,11,12,13,14,15};//Pins donde están los outputs
#define NUMEROIN sizeof(pins_input)
#define NUMEROOUT sizeof(pins_output)


void setup() {
 byte i,j;
 // Asignar los inputs con pull ups.
 for (i=0; i< NUMEROIN; i++) {
   pinMode(pins_input[i], INPUT);
   digitalWrite(pins_input[i], HIGH);
 //Asignar outputs en estado LOW
 for (j=0; j< NUMEROOUT; j++) {
   pinMode(pins_output[j], OUTPUT);
   digitalWrite(pins_output[j], LOW);

 }
}
Engineering is the art of
making what you want from
things you can get.

     

[SOLUCIONADO]

Go Up