Programa Gotas de Água

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

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.

#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 :slight_smile: )

Qualquer ajuda que me possam dar era preciosa.

Abraço

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.

Peço desculpa. Assim esta melhor?

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.

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.

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....

como que se usa a função millis()?

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

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.

Hum....

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

Latas:
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.

Isto e como está. com mais descrição para tentar esplicar melhor.

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); 
  }
}
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.

Boas.

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

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

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

Bem depois de dar muito com a cabeça cheguei a este.

// 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

Resultados ate agora

Abraço

Boas.

O que falavam do Millis era isto?

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?

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.

//..............................................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

Parabéns... Seu projeto é muito legal!

Eu não ajudei nada, apenas te passei como utilizar o millis().

[]s

Wagner Sartori Junior

Latas, muito interessante seu projeto, parabéns! Conseguiu realizar o teste com as válvulas ligadas?

Teria como dar mais informações dos componentes/ligações que estão nas protoboards, à algum tempo venho pesquisando um sistema simples para fazer fotos de splash e colisões de gotas utilizando eletro-válvula e este seu seria exatamente o que venho procurando.

Desde já agradeço.

Boas.

Acabei de testar tudo e correu tuto como eu queria. O unico problema agora e que as duas valvulas disparam das duas vezes. uma com delay 0ms e outra a 130ms.

Não me parece que seja do programa pq acho que esta tudo devidamente separado. Talvez seja nas ligações? estão a assumir as duas valvulas nos pins 13 e 11? será?

O estranho e que os LED's que estão ligados em serie com as valvulas so ligam na sua vez. 1x cada um. o pin13 aos 0ms e o pin11 aos 130ms. Pq será que as valvulas não?

Mais logo vou abrir a caixa para verificar.

Depois ponho aí mais promenores das ligações para verem.

Abraço

Resolvido. Era só um fio mal ligado.

Abraço

Latas,

Qual modelo de valvula solenóide está utilizando? Encontrei algumas automotivas utilizadas nos sistemas de partida à frio.

Meu arduino chegou ontem, na segunda começo meus testes de verdade, estava só simulando via Proteus.

Abs