mporizador para contar um tempo que é divisor comum dos três, digamos, tempoComum, i.e.
int tempoComum= 34286; // Este valor depende do seu problema no caso digamos representando meio segundo
Use um vetor para estabelecer o limite de cada relê com referência ao tempo comum. Se
#define NUMRELES 3
// portas dos reles
int ligueRele[NUMRELES]={10,11,12};
int limiteDeCadaRele[NUMRELES]= {6,6,6};
Use outro vetor para o contador de tempo de cada relê, digamos
int contadorDeCadaRele[NUMRELES]={0,0,0};
E também um vetor de flags para saber que contador está ativado, por exemplo:
byte releAtivado[NUMRELES]={false,false,false};
Agora faça uma função para ativar a contagem de um relê, tipo:
void ativeRele(int rele)
{
if(rele < NUMRELES)
{
if(releAtivado[rele])
return; // caso já tenha ativado
// desative interrupções
noInterrupts();
releAtivado[rele] = true;
contadorDeCadaRele[rele]=0;
// reative interrupçoes
interrupts();
}
}
// Faça uma função para desativar relês
void desativeRele(int rele)
{
if(rele < NUMRELES)
{
if(!releAtivado[rele])
return; // caso o rele não esteja ativo
// desative interrupções
noInterrupts();
releAtivado[rele] =false;
contadorDeCadaRele[rele]=0;
// reative interrupçoes
interrupts();
}
}
// Agora use o codigo baixado em 6/11/2014, 16:35, do site a href="http://www.hobbytronics.co.uk/arduino-timer-interrupts>" target="_blank">http://www.hobbytronics.co.uk/arduino-timer-interrupts>
modificando-o para contemplar seu problema
/* Example Timer1 Interrupt Flash LED every second */ #define ledPin 13 int timer1_counter; void setup() { int i; for(i=0;i<NUMRELES; i++) pinMode(ligueRele[i],OUTPUT); //pinMode(ledPin, OUTPUT); // initialize timer1 noInterrupts(); // disable all interrupts TCCR1A = 0; TCCR1B = 0; // Set timer1_counter to the correct value for our interrupt interval //timer1_counter = 64886; // preload timer 65536-16MHz/256/100Hz //timer1_counter = 64286; // preload timer 65536-16MHz/256/50Hz //timer1_counter = 34286; // preload timer 65536-16MHz/256/2Hz TCNT1 = tempoComun; // timer1_counter; // preload timer TCCR1B |= (1 CS12); // 256 prescaler TIMSK1 |= (1 TOIE1); // enable timer overflow interrupt interrupts(); // enable all interrupts } // a rotina do serviço é modificada por mim assim: ISR(TIMER1_OVF_vect) // interrupt service routine { int i; TCNT1 = tempoComun; // timer1_counter; // preload timer // digitalWrite(ledPin, digitalRead(ledPin) ^ 1); for(i=0;i<NUMRELES; i++) if(releAtivado[i]) { if(++contadorDeCadaRele[i] >=limiteDeCadaRele[i]) { contadorDeCadaRele[i]=0; digitalWrite(ligueRele[i],HIGH); // USANDO UM ACIONAMENTO EM ALTA // Se tiver que desligar a bomba depois de uma certa contagem de tempo o código deve ser modificado } } } void loop() { // your program here... }Finalmente, na minha sugestão acima não estou controlando o tempo que cada bomba dosaria mas a ativação de cada uma pelos relês.S.M.J.Obrigado,Professor Almir…
gal...
/* AC Light Control Ryan McLaughlin <ryanjmclaughlin@gmail.com> The hardware consists of an Triac to act as an A/C switch and an opto-isolator to give us a zero-crossing reference. The software uses two interrupts to control dimming of the light. The first is a hardware interrupt to detect the zero-cross of the AC sine wave, the second is software based and always running at 1/128 of the AC wave speed. After the zero-cross is detected the function check to make sure the proper dimming level has been reached and the light is turned on mid-wave, only providing partial current and therefore dimming our AC load. Thanks to http://www.andrewkilpatrick.org/blog/?page_id=445 and http://www.hoelscher-hi.de/hendrik/english/dimmer.htm */ /* Modified by Mark Chester <mark@chesterfamily.org> to use the AC line frequency (half-period) as a reference point and fire the triacs based on that plus a dimmer delay value. I removed the second timer-based interrupt and replaced it with a means to reference the zero-crossing point as per interrupt 0.*/
// Generalunsigned long int ZeroXTime1 = 0; // Timestamp in micros() of the latest zero crossing interruptunsigned long int ZeroXTime2 = 0; // Timestamp in micros() of the previous zero crossing interruptunsigned long int NextTriacFire[4]; // Timestamp in micros() when it's OK to fire the triacs again.unsigned long int DimStep; // How many micros() in each step of dimmingint Dimmer[4]; // The dimmer input variable. One for each channelbyte TriacPin[4] = {3,5,6,7}; // Which digital IO pins to useboolean OKToFire[4]; // Bit to say it's OK for the triacs to firevolatile boolean zero_cross = 0; // Boolean to store a "switch" to tell us if we have crossed zero
void setup() { // Begin setuppinMode(TriacPin[0], OUTPUT); // Set the Triac pin as output pinMode(TriacPin[1], OUTPUT); // Set the Triac pin as output pinMode(TriacPin[2], OUTPUT); // Set the Triac pin as output pinMode(TriacPin[3], OUTPUT); // Set the Triac pin as output attachInterrupt(0, zero_cross_detect, FALLING); // Attach an Interupt to Pin 2 (interupt 0) for Zero Cross Detection delay(50); // Give the interrupt time to capture a few AC cycles} // End setup void zero_cross_detect() { // function to be fired at the zero crossing zero_cross = 1; // All we do is set a variable that's picked up later in the code}
void loop() { // Main Loop if ( zero_cross ) { // Did we detect a zero cross? ZeroXTime2 = ZeroXTime1; // shift the current zero cross value to the previous ZeroXTime1 = micros(); // set the new current zero cross time in micros() DimStep = (ZeroXTime1 - ZeroXTime2)/768; // Calc the duration of each dimming step Dimmer[0] = map(analogRead(0), 0, 1022, 255, 0); // Read in a dimmer value (change to suit needs) Dimmer[1] = map(analogRead(1), 0, 1022, 255, 0); Dimmer[2] = map(analogRead(2), 0, 1022, 255, 0); Dimmer[3] = map(analogRead(3), 0, 1022, 255, 0);
NextTriacFire[0] = ZeroXTime1 + (Dimmer[0] * DimStep); // Calc the next triac fire time NextTriacFire[1] = ZeroXTime1 + (Dimmer[1] * DimStep); NextTriacFire[2] = ZeroXTime1 + (Dimmer[2] * DimStep); NextTriacFire[3] = ZeroXTime1 + (Dimmer[3] * DimStep); OKToFire[0] = 1; // Tell us it's OK to fire the triacs OKToFire[1] = 1; OKToFire[2] = 1; OKToFire[3] = 1; zero_cross = 0; // Done. Don't try again until we cross zero again }
if ( OKToFire[0] && micros() >= NextTriacFire[0] && Dimmer[0] < 255 && Dimmer[0] > 0) { // Are we OK and past the delay time? digitalWrite(TriacPin[0], HIGH); // Fire the Triac mid-phase OKToFire[0] = 0; // We fired - no longer OK to fire digitalWrite(TriacPin[0], LOW); // Turn off the Triac gate (Triac will not turn off until next zero cross) } else if (Dimmer[0] == 0){ digitalWrite(TriacPin[0], HIGH); // Fire the Triac mid-phase } else if (Dimmer[0] == 255) { digitalWrite(TriacPin[0], LOW); // Fire the Triac mid-phase }
if ( OKToFire[1] && micros() >= NextTriacFire[1] && Dimmer[1] < 255 && Dimmer[1] > 0) { // Are we OK and past the delay time? digitalWrite(TriacPin[1], HIGH); // Fire the Triac mid-phase OKToFire[1] = 0; // We fired - no longer OK to fire digitalWrite(TriacPin[1], LOW); // Turn off the Triac gate (Triac will not turn off until next zero cross) } else if (Dimmer[1] == 0){ digitalWrite(TriacPin[1], HIGH); // Fire the Triac mid-phase } else if (Dimmer[1] == 255) { digitalWrite(TriacPin[1], LOW); // Fire the Triac mid-phase }
if ( OKToFire[2] && micros() >= NextTriacFire[2] && Dimmer[2] < 255 && Dimmer[2] > 0) { // Are we OK and past the delay time? digitalWrite(TriacPin[2], HIGH); // Fire the Triac mid-phase OKToFire[2] = 0; // We fired - no longer OK to fire digitalWrite(TriacPin[2], LOW); // Turn off the Triac gate (Triac will not turn off until next zero cross) } else if (Dimmer[2] == 0){ digitalWrite(TriacPin[2], HIGH); // Fire the Triac mid-phase } else if (Dimmer[2] == 255) { digitalWrite(TriacPin[2], LOW); // Fire the Triac mid-phase } if ( OKToFire[3] && micros() >= NextTriacFire[3] && Dimmer[3] < 255 && Dimmer[3] > 0) { // Are we OK and past the delay time? digitalWrite(TriacPin[3], HIGH); // Fire the Triac mid-phase OKToFire[3] = 0; // We fired - no longer OK to fire digitalWrite(TriacPin[3], LOW); // Turn off the Triac gate (Triac will not turn off until next zero cross) } else if (Dimmer[3] == 0){ digitalWrite(TriacPin[3], HIGH); // Fire the Triac mid-phase } else if (Dimmer[3] == 255) { digitalWrite(TriacPin[3], LOW); // Fire the Triac mid-phase }}
Vou fazer esse rele de estado sólido agora para testar, acho que a unica modificação que vou precisar fazer será do resistor de 2K, como estou usando o MOC3021 vou usar o resistor de 390Ohms.
O pessoal que manja mais de eletronica, esse Rele da imagem é seguro?
Abraços…
Adicionado por Tiago Struck ao 17:08 em 24 junho 2013