Go Down

Topic: Programa Gotas de Água (Read 3370 times) previous topic - next topic

Latas

Nov 08, 2011, 07:13 pm Last Edit: Nov 08, 2011, 07:17 pm by Latas Reason: 1
Ola.

Estou a montar um mecanismo baseado em arduino para controlar gotas de liquidos para fotografar. Mas estou com duvidas.





Correntemente estou a usar este programa

Code: [Select]
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;  // the number of the LED pin
const int FlashPin =  11;  // the number of the flash pin
int sensorPin = A0;    // select the input pin for the potentiometer
int sensorValue = 0;  // variable to store the value coming from the sensor
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
 // initialize the LED pin as an output:
 pinMode(ledPin, OUTPUT);    
// initialize the flash pin as an output:
 pinMode(FlashPin, OUTPUT);      
 // initialize the pushbutton pin as an input:
 pinMode(buttonPin, INPUT);    
}

void loop(){
 // read the state of the pushbutton value:
 buttonState = digitalRead(buttonPin);

 // check if the pushbutton is pressed.
 // if it is, the buttonState is HIGH:
 if (buttonState == HIGH) {    
   // turn LED on:    
   // read the value from the sensor:
 sensorValue = analogRead(sensorPin);    
 // turn the ledPin on
 digitalWrite(ledPin, HIGH);  
 // stop the program for <sensorValue> milliseconds:
 delay(20);          
 // turn the ledPin off:        
 digitalWrite(ledPin, LOW);
 // stop the program for <sensorValue> milliseconds:
 delay(130);
 digitalWrite(ledPin, HIGH);  
 // stop the program for <sensorValue> milliseconds:
 delay(20);          
 // turn the ledPin off:        
 digitalWrite(ledPin, LOW);
 // stop the program for <sensorValue> milliseconds:
 delay(295);
 // turn the FlashPin on
 digitalWrite(FlashPin, HIGH);  
 // stop the program for <sensorValue> milliseconds:
 delay(5);
 // turn the FlashPin off:        
 digitalWrite(FlashPin, LOW);  
 // stop the program for for <sensorValue> milliseconds:
 delay(50);              // wait for a second;
 }
 else {
   // turn LED off:
   digitalWrite(ledPin, LOW);
 }
}


E uma coisa simples que quando carrego num botão ele corre uma sequência de comandos que controlam através de Delay os flashes e a válvula.
O problema que estou a ter e que Sempre que altero os valores do Delay da válvula altera-me também o do flash que faz com que tenha de estar constantemente a corrigi-lo demorando uma eternidade.

O que eu queria era separar os delays de forma a decidir que quero que os flashes disparem imaginem 300ms depois de carregar o botão e que independentemente disso possa controlar as gotas e o numero de gotas sem ter que estar sempre a recalcular o valor necessário para os flashes.

Eu criei este mas não faço a mínima ideia se funciona. Que acham? Têm algum sugestão que me possa ajudar?
E que sou completamente novato nisto e não consigo.

Code: [Select]
#define DEFAULTFLASHDELAY 500

// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;  // the number of the LED pin
const int FlashPin =  11;  // the number of the flash pin

int delayValue = DEFAULTFLASHDELAY; // Flash delay
int sensorPin = A0;    // select the input pin for the potentiometer
int sensorValue = 0;  // variable to store the value coming from the sensor
int buttonState = 0;         // variable for reading the pushbutton status

void dischargeFlash() {
 // Discharge the flash with a 10ms pulse to the opto-isolator...
 digitalWrite(FlashPin, HIGH);
 delay(10);
 digitalWrite(FlashPin, LOW);
}

void setup() {
 // initialize the LED pin as an output:
 pinMode(ledPin, OUTPUT);    
// initialize the flash pin as an output:
 pinMode(FlashPin, OUTPUT);      
 // initialize the pushbutton pin as an input:
 pinMode(buttonPin, INPUT);    
}

void loop(){
 // read the state of the pushbutton value:
 buttonState = digitalRead(buttonPin);

 // check if the pushbutton is pressed.
 // if it is, the buttonState is HIGH:
 if (buttonState == HIGH) {
   
 delay(delayValue);
   dischargeFlash();
   // turn LED on:    
   // read the value from the sensor:
 sensorValue = analogRead(sensorPin);    
 // turn the ledPin on
 digitalWrite(ledPin, HIGH);  
 // stop the program for <sensorValue> milliseconds:
 delay(20);          
 // turn the ledPin off:        
 digitalWrite(ledPin, LOW);
 // stop the program for <sensorValue> milliseconds:
 delay(130);
 digitalWrite(ledPin, HIGH);  
 // stop the program for <sensorValue> milliseconds:
 delay(20);          
 // turn the ledPin off:        
 digitalWrite(ledPin, LOW);
 // stop the program for for <sensorValue> milliseconds:
 delay(50);              // wait for a second;
 }
 else {
   // turn LED off:
   digitalWrite(ledPin, LOW);
 }
}


Acham que isso permite alterar os valores do DEFAULTFLASHDELAY 500 independentemente da valvula? (esta descrito como Led no programa mas funciona na mesma :) )

Qualquer ajuda que me possam dar era preciosa.

Abraço

Wagner Sartori Junior

Os códigos estão muito difícil de ler. Por favor, edite seu post e utilize a tag "code"(é o ícone # acima) nos seus códigos.

Latas

Peço desculpa. Assim esta melhor?

Wagner Sartori Junior

Opa, muito melhor! Facilita a visualização para todo mundo.

Seu projeto é muito legal.

Acho que captei o que você quer. Você quer ter múltiplos delays no seu loop() e não pausar o programa inteiro enquanto espera certo?

Se for isto, você pode usar a função millis() do arduino. Ele é um contador unsigned long que conta em milisegundos desde que você ligou seu arduino.

Dê uma olhada neste exemplo: http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay.

Latas

Obrigado pela resposta rapida.

A ideia e que os flashes disparem no momento que eu defino. Por exemplo no momento que ve em baixo que e o tempo que a gota demora a chegar à agua+o tmpo que demora a voltar a subir ate bater na segunda gota.


Independentemente deste valor depois gostaria de poder acrescentar gotas ou por mais delay entre elas mas sem alterar o tempo de disparo do flash.

Por exemplo descubro que a 1ª gota demora 300ms a chegar ao ponto que quero. Depois e so criar uma 2ª gota e afinar o entrevalo entre elas para que colidam nesse ponto. O que me acontece agora e que sempre que mudo nas gotas tenho de compensar com o flash.

Esse exemplo já o estive a ver mas não percebo bem como e que posso fazer para controlar independentemente.


MarceloBoeira

mas tome cuidado pois o delay(), e o millis() ambos não são precisos, dependem da volta da void loop,...

eu fiz um relógio, que adiantava a hora, depois juntei um sistema de leitura de temperatura ele atrasou a hora....
My Toys:
Raspberry Pi (Model B)
Arduino MEGA 1280: ( Shield LCD 16x2, Ethernet, RFID )
Freescale Kinetis KL25Z [/

MarceloBoeira

como que se usa a função millis()?
My Toys:
Raspberry Pi (Model B)
Arduino MEGA 1280: ( Shield LCD 16x2, Ethernet, RFID )
Freescale Kinetis KL25Z [/

Wagner Sartori Junior

Crie 2 variáveis para gravar o millis() e coloca 2 if's no seu programa para você ter os 2 momentos.

Code: [Select]

unsigned long tempo1 = 0;
unsigned long tempo2 = 0;

void setup() {
 tempo1 = millis();
 tempo2 = millis();
}

void loop() {
 unsigned long currentMillis = millis();

 if(currentMillis - tempo1 > 300) {
   // Passou 300ms desde a última vez aqui
   tempo1 = millis();
 } else if(currentMillis - tempo2 > 500) {
   // Passou 500ms desde a última vez aqui
   tempo2 = millis();
 }
}


é pura lógica de programação.

Latas

Hum....

Como e que ponho a valvula a abrir e fechar duas vezes para sairem duas gotas?

Wagner Sartori Junior


Hum....

Como e que ponho a valvula a abrir e fechar duas vezes para sairem duas gotas?


Onde ta o comentário "Passou 300ms desde a última vez aqui", você pode colocar o código que abre a válvula pela segunda vez(ela vai abrir depois de 300ms). Você também pode controlar quantas gotas você quer criando um contador.

É pura lógica de programação. Se estiver difícil, faça um fluxograma do que vc quer. É muito difícil eu te ajudar com isto.

Latas

#10
Nov 08, 2011, 08:03 pm Last Edit: Nov 08, 2011, 08:07 pm by Latas Reason: 1
Isto e como está. com mais descrição para tentar esplicar melhor.
Code: [Select]
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;  // the number of the LED pin
const int FlashPin =  11;  // the number of the flash pin
int sensorValue = 0;  // variable to store the value coming from the sensor
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
 // initialize the LED pin as an output:
 pinMode(ledPin, OUTPUT);    
// initialize the flash pin as an output:
 pinMode(FlashPin, OUTPUT);      
 // initialize the pushbutton pin as an input:
 pinMode(buttonPin, INPUT);    
}

void loop(){
 // read the state of the pushbutton value:
 buttonState = digitalRead(buttonPin);

 // check if the pushbutton is pressed.
 // if it is, the buttonState is HIGH:
 if (buttonState == HIGH) {    

// 1ª Gota com 20ms ......................................................................
 digitalWrite(ledPin, HIGH);  
 delay(20);          
 digitalWrite(ledPin, LOW);

//tempo entre a 1ª gota e a 2ª ......................................................................
 delay(130);

// 2ª Gota com 20ms ......................................................................
 digitalWrite(ledPin, HIGH);  
 delay(20);          
 digitalWrite(ledPin, LOW);

//tempo entre a 2ª gota e o momento que quero disparar o flash ......................................................................
 delay(295);

//disparo do flash ......................................................................
 digitalWrite(FlashPin, HIGH);  
 delay(5);      
 digitalWrite(FlashPin, LOW);  

 delay(50);            
 }
 else {
   // turn LED off:
   digitalWrite(ledPin, LOW);
 }
}


Code: [Select]
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;  // the number of the LED pin
const int FlashPin =  11;  // the number of the flash pin
int sensorValue = 0;  // variable to store the value coming from the sensor
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
 // initialize the LED pin as an output:
 pinMode(ledPin, OUTPUT);    
// initialize the flash pin as an output:
 pinMode(FlashPin, OUTPUT);      
 // initialize the pushbutton pin as an input:
 pinMode(buttonPin, INPUT);    
}

void loop(){
 // read the state of the pushbutton value:
 buttonState = digitalRead(buttonPin);

 // check if the pushbutton is pressed.
 // if it is, the buttonState is HIGH:
 if (buttonState == HIGH) {    

//tempo entre a a 1ª abertura da valvula e o momento que quero disparar o flash ......................................................................
 FlashPin delay(500);

//disparo do flash consoante o delay acima definido ......................................................................
 digitalWrite(FlashPin, HIGH);  
 delay(5);      
 digitalWrite(FlashPin, LOW);  

// 1ª Gota com 20ms ......................................................................
 digitalWrite(ledPin, HIGH);  
 delay(20);          
 digitalWrite(ledPin, LOW);

//tempo entre a 1ª gota e a 2ª ......................................................................
 delay(130);

// 2ª Gota com 20ms ......................................................................
 digitalWrite(ledPin, HIGH);  
 delay(20);          
 digitalWrite(ledPin, LOW);

 delay(50);            
 }
 else {
   // turn LED off:
   digitalWrite(ledPin, LOW);
 }
}


Eu sei que os codigos estão mal mas e tipo esquema para entenderem o que quero.
Desta forma o flash dispara sempre a 500ms independentemente do tamanho ou quantidade de gotas que tenha.

Latas

Boas.

Já vi que não deu para entender :)

É dificil uma pessoa que não percebe nada disto explicar :P

E assim:
Tenho um botão ligado para começar o sistema
Tenho uma válvula solenoid ligada ao pin13.
Tenho os flashes ligados através de um MOC 3020 OPTOCOUPLER. Pin11

O que eu quero que aconteça é:
1º - Carrego no botão para activar o sistema.
2º - Depois de carregar no botão começa uma contagem para os flashes (pin11) dispararem. Exemplo 300ms
3º - A válvula (pin13) abre 20ms e fecha (as vezes que eu quiser) ao mesmo tempo que a contagem do flash continua.

Desta forma posso programar o Flash para disparar a 300ms e mesmo que adicione ou altere o nº de gotas o momento em que o flash dispara será sempre 300ms desde que carrego no botão.

Acho que assim já da para entender não?

Sei que é uma chatice estar-vos a chatear mas não me estou a safar sozinho.
Abraço

Latas

#12
Nov 10, 2011, 11:15 am Last Edit: Nov 10, 2011, 01:12 pm by Latas Reason: 1
Bem depois de dar muito com a cabeça cheguei a este.

Code: [Select]
// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 2;     // the number of the pushbutton pin
const int valPin =  13;  // the number of the Valve pin
const int vallPin =  12;  // the number of the second Valve pin
const int FlashPin =  11;  // the number of the flash pin
//Define Variables
int sysloop = 0;             // Start Program System Loop
int buttonState = 0;         // variable for reading the pushbutton status
int FlashDelay = 300;        // Delay before flash is fired   ----- Millisecond
int ValveDelay = 130;        // Delay betwin drops  ----- Microsecond
int DropSize = 20;           // Droplet size ----- Microsecond
int DropSizeII = 20;           // Droplet size ----- Microsecond

//difine if Buton are Input or Output
void setup() {
 // initialize the Valve pin as an output:
 pinMode(valPin, OUTPUT);
 // initialize the second Valve pin as an output:
 pinMode(vallPin, OUTPUT);  
// initialize the flash pin as an output:
 pinMode(FlashPin, OUTPUT);      
 // initialize the pushbutton pin as an input:
 pinMode(buttonPin, INPUT);    
}

//Loop that ocures every time you press button pin2
void loop(){
 // read the state of the pushbutton value:
 buttonState = digitalRead(buttonPin);
 // check if the pushbutton is pressed.
 // if it is, the buttonState is HIGH:
 if (buttonState == HIGH) {    
   sysloop = 0;
   } else {
   dropWater();  
     while(sysloop != 1){
     detectFlash();
     }
    sysloop = 0;
   }    
     // stop the program for for xxx milliseconds:
 delay(100);              // wait for a 1/100 of a second;
 
}
   
// turn the VallPin on
int dropWater(){
 digitalWrite(valPin, HIGH);
 delay(DropSize);            
 digitalWrite(valPin, LOW);
 
 // stop the program for ValveDelay milliseconds:
 delay(ValveDelay);
 
// turn the VallPin on
 digitalWrite(valPin, HIGH);
 delay(DropSizeII);            
 digitalWrite(valPin, LOW);  
}

 // turn the FlashPin on
int detectFlash(){
 delay(FlashDelay);
 
 digitalWrite(FlashPin, HIGH);  
 delay(5);    
 digitalWrite(FlashPin, LOW);  
 
}



Acham que faz aquilo que quero?
Precisava mesmo de saber


Aqui fica umas imagens e videos do Setup

Com o programa antigo
http://www.youtube.com/watch?v=LwLZknUJHXY







Resultados ate agora
http://www.youtube.com/watch?v=KGSJYd7GWVE

Abraço

Latas

#13
Nov 11, 2011, 05:24 pm Last Edit: Nov 11, 2011, 05:26 pm by Latas Reason: 1
Boas.

O que falavam do Millis era isto?

Code: [Select]
long FlashDelay = 1000;
long AberturavalvulaDelay = 2000;        // Interval befor restart Valve Cycle ----- Microsecond
int DropSize = 50;                       // Droplet size ----- Microsecond
int DropSize2 = 50;                      // Droplet size ----- Microsecond
int ValveDelay = 130;                    // Delay betwin drops  ----- Microsecond

boolean VALstate = false;      // the LED will turn ON in the first iteration of loop()
boolean VAL2state = false;      // the LED will turn ON in the first iteration of loop()
boolean FLASHstate = false;     // need to seed the light to be OFF
long waitUntil13 = 0;
long waitUntil11 = 0;
long waitUntil10 = FlashDelay;         // the seed will determine time between LEDs


const int buttonPin = 2;     // the number of the pushbutton pin
const int VALPin =  13;  // the number of the Valve pin
const int VAL2Pin =  11;  // the number of the second Valve pin
const int FlashPin =  10;  // the number of the flash pin

int buttonState = 0; // variable for reading the pushbutton status


void setup() {
  pinMode(13, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(buttonPin, INPUT);
}


void loop() {
 // read the state of the pushbutton value:
 buttonState = digitalRead(buttonPin);
    // check if the pushbutton is pressed.
    // if it is, the buttonState is HIGH:
 if (buttonState == HIGH) {    
   
  digitalWrite(13, VALstate);     // each iteration of loop() will set the IO pins,
  digitalWrite(11, VAL2state);
  digitalWrite(10, FLASHstate);
  // checking to see if enough time has elapsed
  if (millis() >= waitUntil13) {
     dropWater();
     waitUntil13 = millis() + AberturavalvulaDelay;
     // this if-statement will not execute for another 2000 milliseconds
  }
 
  if (millis() >= waitUntil10) {
     detectFlash();
     waitUntil10 = millis() - FlashDelay;
     
     // stop the program for for xxx milliseconds:
    }  else {
   // turn LED off:
  }
}
}

// turn the VallPin on
int dropWater(){
 digitalWrite(VALPin, HIGH);
 delay(DropSize);            
 digitalWrite(VALPin, LOW);
 
 // stop the program for ValveDelay milliseconds:
 delay(ValveDelay);
 
// turn the VallPin on
 digitalWrite(VAL2Pin, HIGH);
 delay(DropSize2);            
 digitalWrite(VAL2Pin, LOW);  
}

 // turn the FlashPin on
int detectFlash(){
 
 digitalWrite(FlashPin, HIGH);  
 delay(5);    
 digitalWrite(FlashPin, LOW);
 
}


E que aparentamente não consigo controlar o delay do flash independentemente.
Da para ajudar?

Latas

Boas.

Depois de 16h a dar com a cabeça no teclado la fiz o que precisava. Ainda falta testar com as valvulas ligadas, mas aparentemente só com os leds funciona perfeitamente.

Coloquei todas a variáveis logo no inicio para ser facil editar e likei-as em baixo.


Code: [Select]
//..............................................Use these Values.....................................................

int ValveDelay1 = 0;
int DropSize = 20;            // Droplet size ----- Microsecond
int DropSize2 = 20;           // Droplet size ----- Microsecond
int ValveDelay2 = 130;        // Delay betwin drops  ----- Microsecond
int FlashDelay = 400;         // Delay before flash is fired   ----- Millisecond
int FlashDuration = 5;        // Flash Pulse   ----- Millisecond

int GLOBAlReset = 500;        // Global Reset   ----- Millisecond

//..............................................Use these Values.....................................................




//.................................................Dont Touch........................................................

const int VAL1Pin = 13;                        // the number of the Valve pins
const int VAL2Pin = 11 ;

const int FLASHPin = 10 ;                      // opto-isolator anode connected to digital pin 10

int buttonPin = 2;                             // The Number of the Button Pin


int globalReset = GLOBAlReset;                 // time to activate button again.
int VAL1Delay = ValveDelay1 ;                  // time until Valve 1 fires
int VAL1Duration = DropSize ;                  //duration of Valve 1 fire
int VAL2Delay = ValveDelay2;                   // time until Valve 2 fires
int VAL2Duration = DropSize2;                  //duration of Valve 2 fire
int FLASHDelay = FlashDelay;                   // time until Flash fires
int FLASHDuration = FlashDuration;             //duration of Flash fire

int VAL1Timer = VAL1Delay+VAL1Duration ;       //total time of delay and duration
int VAL2Timer = VAL2Delay+VAL2Duration;
int FLASHTimer = FLASHDelay+FLASHDuration;

unsigned long btnMillis = 0; //clock value to be stored at the time milli() is called



void setup()
{
  pinMode(VAL1Pin, OUTPUT);                    // initialize the Valve1 pins as an output:
  pinMode(VAL2Pin, OUTPUT);                    // initialize the Valve2 pins as an output:   
  pinMode(FLASHPin, OUTPUT);                   // declare flashPin as as OUTPUT
  digitalWrite(VAL1Pin, LOW);                  // initialize Valves at Closed
  digitalWrite(VAL2Pin, LOW);                  // initialize Valves at Closed
  pinMode(buttonPin, INPUT);                   // Initialize Button as input

}

void loop()
{

  if (btnMillis != 0)
  { 
    unsigned long timePassed = millis() - btnMillis;
   

    //Flash.............................................................................
    if ((timePassed >= FLASHDelay) && (timePassed <= FLASHTimer))
    {
        digitalWrite(FLASHPin, HIGH); // trigger flash by bringing digital output to high
    }
    else {
         digitalWrite(FLASHPin, LOW); // set it back to low
    }
   
   
    //VALVE 1............................................................................
    if ((timePassed >= VAL1Delay) && (timePassed <= VAL1Timer))
    {
digitalWrite(VAL1Pin, HIGH); //turn on Relay 1 pin
    }
    else {
digitalWrite(VAL1Pin, LOW); //turn off Relay 1 pin
    }


    //VALVE 2............................................................................
    if (timePassed >= VAL2Delay && timePassed <= VAL2Timer)
    {
digitalWrite(VAL2Pin, HIGH); //turn on Relay 2 pin
    }
    else {
digitalWrite(VAL2Pin, LOW); //turn off Relay 2 pin
    }
   
   
    //Longest off time, to re-enable the button.........................................
    if (timePassed >= globalReset)
    {
btnMillis = 0;
    }
  } else { // i.e. btnMillis==0
    if (digitalRead(2) == HIGH)
    btnMillis=millis();
  } // end the big if
}


//.....................................................THE END..........................


Obrigado a todos pelas ajudas.

Abraço

Go Up