conmutador toggle switch de 3 posiciones para distintas funciones

Hola, tengo un sistema de riego automático que funciona bastante bien… es un arduino uno, conectado a un relé y del relé a una electroválvula para el riego. Para saber cuando regar tiene un sensor de humedad también conectado al arduino al igual que una pantalla LCD que me va mostrando los datos como la hora, la humedad del suelo y si se está regando o no… es decir, una maravilla jejejeje ahora se me ha ocurrido ampliar un poco y añadirle un conmutador toggle switch de tres posiciones como este:

Como podrán ver, es un conmutador con tres posiciones, podemos llamarlas “arriba” “centro” y “abajo”. Siendo arriba el cable negro, centro cable blanco y abajo cable rojo. Pues lo que quiero hacer es que cuando esté “arriba” la electroválvula encienda independientemente del resto del código, lo que sería una apertura manual de riego. Cuando esté en el “centro” siga como está ahora, de manera automática. Y cuando esté “abajo” la electroválvula quede cerrada independientemente del resto del código.

Para empezar estaba intentando que cuando suba la palanca a la posición de “arriba” en el serial monitor me aparezca la palabra arriba, cuando ponga la palanca al “centro” en el serial monitor me aparezca la palabra centro, y cuando ponga la palanca en la posición de “abajo” en el serial monitor me aparezca la palabra abajo.

¿Alguna idea de cómo hacer eso??

Si consigo diferenciar las tres posiciones de la palanca del conmutador, luego veré cómo hacerlo funcionar con el siguiente código, ya que uso la función Alarm.alarmRepeat la cual está en el setup, y no sabría cómo meterla dentro de un if para condicionarla a dónde esté la palanca del conmutador… no sé si me habré explicado con claridad…

#include <Time.h>
#include <TimeAlarms.h>
#include <DS1307RTC.h>
#include <LiquidCrystal.h>

// Creamos un objeto lcd con los pines a los que está conectado
LiquidCrystal lcd(7, 8, 9, 10, 11 , 12);

// Declaramos la entrada del pin del sensor de humdad de tierra
const int sensorPin = A0; 

// Declaramos la salida del pin del Relé, LOW para abrir electroválvula y HIGH para cerrar.
const int relePin = 2; 

void setup() {
  // Iniciamos el pin del sensor de humedad del suelo como input
  pinMode(sensorPin, INPUT);
  //definir el pin del relé como salida
  pinMode(relePin, OUTPUT);  
  // Preparar la interfaz serial
  Serial.begin(9600);

  //cargamos un objeto lcd e iniciamos la pantalla con 20 caracteres por línea y 4 líneas
  lcd.begin(20, 4);

  // Configurar los pines de salida de relevadores desactivados al inicio
  // recordamos que los modulos de reles se activan con un estado bajo
  digitalWrite(relePin, HIGH);

  // Ponemos la palabra no en el LCD en la parte donde pone Regando:, para así que siempre empiece en no y se modique cuando se está regando o cuando ha parado de regar.
  lcd.setCursor(9,1);
  lcd.write("NO");

  // Cargar la hora actual desde el RTC e indicar que esto suceda de forma automática durante loop()
  // Utilizamos el método RTC.get() de la libreria DS1307RTC. El RTC debe estar conectado como se
  // indica en el texto y debe tener la fecha y hora correctas
  setSyncProvider(RTC.get);
  if (timeStatus() != timeSet)
    Serial.println("Fallo de RTC");
  else
    Serial.println("Sincronizado con RTC");
    

  // Crear las alarmas y configurar las funciones correspondientes a cada una
  Alarm.alarmRepeat(20, 26, 0, aperturaelectrovalvula);
  Alarm.alarmRepeat(21, 59, 0, aperturaelectrovalvula);

}

void loop() {

  Serial.println("");
  // Mostrar el reloj en el monitor serial
  Serial.print("Hora: ");
  digitalClockDisplay();
  // Mostrar el reloj en el LCD2004
  LCD1602ClockDisplay();

  // función map para ver porcentajes de humedad suelo en vez de un valor
  int valorHumedad = map(analogRead(sensorPin), 0, 1023, 100, 0);
  int humedad = analogRead(sensorPin);

  // Imprimimos por pantalla los valores de humedad y su porcentaje
  Serial.print("Humedad en porcentaje: ");
  Serial.print(valorHumedad);
  Serial.println("%");

  Serial.print("Humedad en valor: ");
  Serial.println(humedad);

 // Imprimimos en pantalla si se está regando o no.
  Serial.println("Regando: NO"); 
  Serial.println("");
  
 // llamamos a la función humedadporcentaje, pasándole el valorHumedad en porcentaje, para que valore si está por debajo del 10, que mueva los caracteres en el LCD para una correcta visualización
  humedadPorcentaje(valorHumedad);

 // llamamos a la función humedadValor, pasándole la humedad, para que valore si está por debajo del 10, que mueva los caracteres en el LCD para una correcta visualización
  humedadValor(humedad);

  // Esperar 1 segundo y procesar las Alarmas mientras tanto...
  // El metodo Alarm.delay() procesa en el fondo las alarmas y llamara a las funciones indicadas
  Alarm.delay(1000);
  
  lcd.setCursor(0,0);
  lcd.write("Hora:");
  lcd.setCursor(0,1);
  lcd.write("Regando: ");
  lcd.setCursor(0,2);
  lcd.write("Humedad: ");
  lcd.setCursor(9,2);
  lcd.print(humedad);

  digitalWrite(relePin, HIGH);
  lcd.setCursor(9,1);
  lcd.write("NO");
  
}

void aperturaelectrovalvula(){
  
  while(int humedad = analogRead(sensorPin)  > 500)
   { 

   // llamamos a la función humedadporcentaje, pasándole el valorHumedad en porcentaje, para que valore si está por debajo del 10, que mueva los caracteres en el LCD para una correcta visualización    
  int valorHumedad = map(analogRead(sensorPin), 0, 1023, 100, 0);

  // Cogemos la información del sensor de humedad por segunda vez.
  int humedad2 = analogRead(sensorPin);

  // Mostrar el reloj en el monitor serial
   Serial.print("Hora: ");
  digitalClockDisplay();
  
  // Imprimimos por pantalla los valores de humedad y su porcentaje tanto en LCD como en Serial Monitor.
  Serial.print("Humedad en porcentaje: ");
  Serial.print(valorHumedad);
  Serial.println("%");

  Serial.print("Humedad en valor: ");
  Serial.println(humedad2);
  
  lcd.setCursor(9,2);
  lcd.print(humedad2);

  // Ponemos el relé en LOW por lo que se abrirá la electroválvula.
  digitalWrite(relePin, LOW);

  // Imprimimos en el LCD la palabra SI donde pone regando: y antes ponía NO.
  lcd.setCursor(9,1);
  lcd.write("SI");

  // Imprimimos en pantalla si se está regando o no.
  Serial.println("Regando: SI"); 
  Serial.println("");

  // Mostrar el reloj en el LCD2004
  LCD1602ClockDisplay();

  // llamamos a la función humedadValor, pasándole la humedad, para que valore si está por debajo del 10, que mueva los caracteres en el LCD para una correcta visualización
  humedadValor(humedad2);

  // llamamos a la función humedadporcentaje, pasándole el valorHumedad en porcentaje, para que valore si está por debajo del 10, que mueva los caracteres en el LCD para una correcta visualización
  humedadPorcentaje(valorHumedad);

  delay(1000);
   }
}


/**
   Funciones para la impresion del reloj al monitor serial de arduino
*/
void digitalClockDisplay() {
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.println();
}

void LCD1602ClockDisplay(){

lcd.setCursor(6,0);
printDigitsLCDHora(hour() );

lcd.setCursor(8,0);
lcd.print(':');

lcd.setCursor(9,0);
printDigitsLCD(minute());;

lcd.setCursor(11,0);
lcd.print(':');

lcd.setCursor(12,0);
printDigitsLCD(second());
}


// Si los minutos o segundos son inferiores a 10, pone un cero a la izquierda en la pantalla del Monitor Serie.
void printDigits(int digits) {
  Serial.print(":");
  if (digits < 10)
    Serial.print('0');
    Serial.print(digits);
}


// Si los minutos o segundos son inferiores a 10, pone un cero a la izquierda en la pantalla LCD.
void printDigitsLCD(int digits) {
  if (digits < 10)
    lcd.print('0');
    lcd.print(digits);
}

// Si la hora es inferior a 10, pone un cero a la izquierda en la pantalla LCD
void printDigitsLCDHora(int digits) {
  if (digits < 10)
    lcd.print(' ');
    lcd.print(digits);
}


// Si el porcentaje de humedad es inferior a 10, movemos los caracteres para que no se quede el último visualizado en pantalla y parezca un dato incorrecto.
void humedadPorcentaje(int valorHumedad){
      if (valorHumedad < 10){
  lcd.setCursor(15,2);
  lcd.print(' ');
  lcd.setCursor(16,2);
  lcd.print(valorHumedad);
  lcd.setCursor(17,2);
  lcd.print('%');
    }else{
      lcd.setCursor(15,2);
      lcd.print(valorHumedad);
      lcd.setCursor(17,2);
      lcd.print('%');
      }
}

// Si el valor numérico del sensor de humedad es inferior a 1000, ajusta los caractéres para una correcta visualización en el display LCD
void humedadValor(int humedad){
    if(humedad < 1000){
  lcd.setCursor(12,2);
  lcd.print(' ');
      }
}

Muchas gracias!

Parece que el cable del medio seria un comun a los de los extremos(puedes probarlo con un tester).Entonces podrias conectar los extremos a dos pines digitales declarados como entradas y activar sus resistencias de pullup,el cable central a gnd.Con el interruptor al centro deberias leer HIGH en las dos entradas ,con el interruptor arriba o abajo dejara en LOW la entrada a la que este conectada y la otra en HIGH.Osea tendras 3 posibilidades en las entradas:HIGH-HIGH,HIGH-LOW,LOW-HIGH.

Ok jose, más o menos entiendo lo que me dices, y he probado con el siguiente código:

const int buttonPin = 2;     // Pin del pulsador
const int buttonPin2 = 4;     // Pin del pulsador

void setup() { 
  // pin del pulsador de entrada
  Serial.begin(9600);
  pinMode(buttonPin, INPUT);     
  pinMode(buttonPin2, INPUT); 
}

void loop(){

  // Si el valor del pin del pulsador es HIGH es que esta pulsado
  if (digitalRead(buttonPin) == HIGH) {     
    // Se enciende el LED:    
    Serial.println("Pulsado 1");  
  } 
  else if (digitalRead(buttonPin2) == HIGH){
    // Se apaga el LED:
    Serial.println("Pulsado 2");  
  }
}

y de esta manera, si tengo el pulsado “arriba” obtengo “Pusado 1” en repetidas ocasiones… si lo pongo al “medio” también obtengo “Pulsado 1”, y si lo pongo “abajo” obtengo “Pulsado 2”, lo que no sé es cómo hacer para que cuando esté el pulsador arriba sea 1, cuando esté al medio sea 2 y cuando esté abajo sea 3 por ejemplo…

Gracias!

Hi, Para que te trabaje tienes que connectar el centro a ground. Cuando lo tienes en el centro ambos pines van estar HIGH.

Tienes que activar las resistencias PULL-UP en el Setup():

pinMode(buttonPin, INPUT_PULLUP);     
pinMode(buttonPin2, INPUT_PULLUP);

Las lecturas con interruptor al centro deberian ser HIGH en ambas entradas y LOW en la entrada que actives con el interruptor(La conectas con GND a traves del cable central)

Si si eso lo entiendo... Lo que no entiendo y por más que pruebo no consigo.. Es que me imprima por pantalla "Serial Monitor" la palabra arriba cuando este la palanca arriba, centro cuando esté la palanca al centro y abajo cuando la palanca esté abajo...

Alguna idea??

Gracias

const int buttonPin = 2;     // Pin del pulsador
const int buttonPin2 = 4;     // Pin del pulsador

void setup() {
  // pin del pulsador de entrada
  Serial.begin(9600);
  pinMode(buttonPin, INPUT_PULLUP);     
  pinMode(buttonPin2, INPUT_PULLUP);
}

void loop(){

  // Si el valor del pin del pulsador es HIGH es que esta pulsado
  if (digitalRead(buttonPin) == LOW) {     
    // Se enciende el LED:   
    Serial.println("Pulsado 1"); 
  }
  else if (digitalRead(buttonPin2) == LOW){
    // Se apaga el LED:
    Serial.println("Pulsado 2"); 
  }
  else {
    Serial.println("Posicion central");
  }
}

Tendrias que verificar con el tester que el interruptor trabaja como suponemos.

Hi, Tienes que tener cuidado con switches no son como tu piensas que trabajan. Siguiendo la sequencia del retrato hay tre cables uno rojo, gris y el negro. Si bajas el switches para abajo vas a conectar el rojo a zero y sube el swtches vas conctar el negre a zero. Usa un voltimetro y veras lo que arriba explique.

jose casi lo tenía!! funciona perfectamente!! muchas gracias!!.. Aunque ahora viene la parte más complicada diría yo…

Yo tengo un código como decia, para un riego automático que funciona muy bien… cuando llega cierta hora, si el suelo está seco… riega. Esa funcionalidad que tiene quiero que funcione cuando la palanca esté en el centro… pero cuando esté “arriba” quiero que riegue independientemente del sensor de humedad del suelo y de la hora, y cuando esté abajo quiero que pare de regar también independientemente de todo… el problema que veo es que para que comience a regar a cierta hora tengo hecho un Alarm.alarmRepeat en el Setup() del sckech, por lo que no sé ahora cómo sacarlo de ahí para meterlo en el if del comnutador…

Dejo el código que tengo del sistema de riego a ver si alguien me puede echar una mano…

#include <Time.h>
#include <TimeAlarms.h>
#include <DS1307RTC.h>
#include <LiquidCrystal.h>

// Creamos un objeto lcd con los pines a los que está conectado
LiquidCrystal lcd(7, 8, 9, 10, 11 , 12);

// Declaramos la entrada del pin del sensor de humdad de tierra
const int sensorPin = A0; 

// Declaramos la salida del pin del Relé, LOW para abrir electroválvula y HIGH para cerrar.
const int relePin = 2; 

void setup() {
  // Iniciamos el pin del sensor de humedad del suelo como input
  pinMode(sensorPin, INPUT);
  //definir el pin del relé como salida
  pinMode(relePin, OUTPUT);  
  // Preparar la interfaz serial
  Serial.begin(9600);

  //cargamos un objeto lcd e iniciamos la pantalla con 20 caracteres por línea y 4 líneas
  lcd.begin(20, 4);

  // Configurar los pines de salida de relevadores desactivados al inicio
  // recordamos que los modulos de reles se activan con un estado bajo
  digitalWrite(relePin, HIGH);

  // Ponemos la palabra no en el LCD en la parte donde pone Regando:, para así que siempre empiece en no y se modique cuando se está regando o cuando ha parado de regar.
  lcd.setCursor(9,1);
  lcd.write("NO");

  // Cargar la hora actual desde el RTC e indicar que esto suceda de forma automática durante loop()
  // Utilizamos el método RTC.get() de la libreria DS1307RTC. El RTC debe estar conectado como se
  // indica en el texto y debe tener la fecha y hora correctas
  setSyncProvider(RTC.get);
  if (timeStatus() != timeSet)
    Serial.println("Fallo de RTC");
  else
    Serial.println("Sincronizado con RTC");
    

  // Crear las alarmas y configurar las funciones correspondientes a cada una
  [b]Alarm.alarmRepeat(20, 30, 0, aperturaelectrovalvula);
  Alarm.alarmRepeat(8, 30, 0, aperturaelectrovalvula);[/b]

}

void loop() {

  Serial.println("");
  // Mostrar el reloj en el monitor serial
  Serial.print("Hora: ");
  digitalClockDisplay();
  // Mostrar el reloj en el LCD2004
  LCD1602ClockDisplay();

  // función map para ver porcentajes de humedad suelo en vez de un valor
  int valorHumedad = map(analogRead(sensorPin), 0, 1023, 100, 0);
  int humedad = analogRead(sensorPin);

  // Imprimimos por pantalla los valores de humedad y su porcentaje
  Serial.print("Humedad en porcentaje: ");
  Serial.print(valorHumedad);
  Serial.println("%");

  Serial.print("Humedad en valor: ");
  Serial.println(humedad);

 // Imprimimos en pantalla si se está regando o no.
  Serial.println("Regando: NO"); 
  Serial.println("");
  
 // llamamos a la función humedadporcentaje, pasándole el valorHumedad en porcentaje, para que valore si está por debajo del 10, que mueva los caracteres en el LCD para una correcta visualización
  humedadPorcentaje(valorHumedad);

 // llamamos a la función humedadValor, pasándole la humedad, para que valore si está por debajo del 10, que mueva los caracteres en el LCD para una correcta visualización
  humedadValor(humedad);

  // Esperar 1 segundo y procesar las Alarmas mientras tanto...
  // El metodo Alarm.delay() procesa en el fondo las alarmas y llamara a las funciones indicadas
  Alarm.delay(1000);
  
  lcd.setCursor(0,0);
  lcd.write("Hora:");
  lcd.setCursor(0,1);
  lcd.write("Regando: ");
  lcd.setCursor(0,2);
  lcd.write("Humedad: ");
  lcd.setCursor(9,2);
  lcd.print(humedad);

  digitalWrite(relePin, HIGH);
  lcd.setCursor(9,1);
  lcd.write("NO");
  
}

void aperturaelectrovalvula(){
  
  while(int humedad = analogRead(sensorPin)  > 500)
   { 

   // llamamos a la función humedadporcentaje, pasándole el valorHumedad en porcentaje, para que valore si está por debajo del 10, que mueva los caracteres en el LCD para una correcta visualización    
  int valorHumedad = map(analogRead(sensorPin), 0, 1023, 100, 0);

  // Cogemos la información del sensor de humedad por segunda vez.
  int humedad2 = analogRead(sensorPin);

  // Mostrar el reloj en el monitor serial
   Serial.print("Hora: ");
  digitalClockDisplay();
  
  // Imprimimos por pantalla los valores de humedad y su porcentaje tanto en LCD como en Serial Monitor.
  Serial.print("Humedad en porcentaje: ");
  Serial.print(valorHumedad);
  Serial.println("%");

  Serial.print("Humedad en valor: ");
  Serial.println(humedad2);
  
  lcd.setCursor(9,2);
  lcd.print(humedad2);

  // Ponemos el relé en LOW por lo que se abrirá la electroválvula.
  digitalWrite(relePin, LOW);

  // Imprimimos en el LCD la palabra SI donde pone regando: y antes ponía NO.
  lcd.setCursor(9,1);
  lcd.write("SI");

  // Imprimimos en pantalla si se está regando o no.
  Serial.println("Regando: SI"); 
  Serial.println("");

  // Mostrar el reloj en el LCD2004
  LCD1602ClockDisplay();

  // llamamos a la función humedadValor, pasándole la humedad, para que valore si está por debajo del 10, que mueva los caracteres en el LCD para una correcta visualización
  humedadValor(humedad2);

  // llamamos a la función humedadporcentaje, pasándole el valorHumedad en porcentaje, para que valore si está por debajo del 10, que mueva los caracteres en el LCD para una correcta visualización
  humedadPorcentaje(valorHumedad);

  delay(1000);
   }
}


/**
   Funciones para la impresion del reloj al monitor serial de arduino
*/
void digitalClockDisplay() {
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.println();
}

void LCD1602ClockDisplay(){

lcd.setCursor(6,0);
printDigitsLCDHora(hour() );

lcd.setCursor(8,0);
lcd.print(':');

lcd.setCursor(9,0);
printDigitsLCD(minute());;

lcd.setCursor(11,0);
lcd.print(':');

lcd.setCursor(12,0);
printDigitsLCD(second());
}


// Si los minutos o segundos son inferiores a 10, pone un cero a la izquierda en la pantalla del Monitor Serie.
void printDigits(int digits) {
  Serial.print(":");
  if (digits < 10)
    Serial.print('0');
    Serial.print(digits);
}


// Si los minutos o segundos son inferiores a 10, pone un cero a la izquierda en la pantalla LCD.
void printDigitsLCD(int digits) {
  if (digits < 10)
    lcd.print('0');
    lcd.print(digits);
}

// Si la hora es inferior a 10, pone un cero a la izquierda en la pantalla LCD
void printDigitsLCDHora(int digits) {
  if (digits < 10)
    lcd.print(' ');
    lcd.print(digits);
}


// Si el porcentaje de humedad es inferior a 10, movemos los caracteres para que no se quede el último visualizado en pantalla y parezca un dato incorrecto.
void humedadPorcentaje(int valorHumedad){
      if (valorHumedad < 10){
  lcd.setCursor(15,2);
  lcd.print(' ');
  lcd.setCursor(16,2);
  lcd.print(valorHumedad);
  lcd.setCursor(17,2);
  lcd.print('%');
    }else{
      lcd.setCursor(15,2);
      lcd.print(valorHumedad);
      lcd.setCursor(17,2);
      lcd.print('%');
      }
}

// Si el valor numérico del sensor de humedad es inferior a 1000, ajusta los caractéres para una correcta visualización en el display LCD
void humedadValor(int humedad){
    if(humedad < 1000){
  lcd.setCursor(12,2);
  lcd.print(' ');
      }
}

Gracias.

Ya lo tengo solucionado! sólo había que meter el código en el if, else if y else... independientemente del setup()

Gracias por vuestra ayuda!