Toggle switch state

What's up, so i have finally fined tuned most things but I've been stuck on this last part. How do i make it so that the toggle switch whenever it's flipped from A to B the servo changes regardless of what angle it is. Currently whenever it's flipped from A to B it works but to make the servo move again i have to move it A to B then back to A then to B.

N.B. Currently if i leave the switch in B, if i use the IRremote to move the servo to 180 the servo will immediately go back to 0.

#include <IRremote.hpp>
#include <Servo.h>

int IRpin = 2;
int servoPin = 9;
int photoPin = A0;
int toggleSwitchPin = 5;

int servoAngle = 0;
int photoValue = 0;
bool buttonPressed = false; 
bool servoActivated = false;

IRrecv receiver(IRpin);
Servo servo; 
decode_results results; 


unsigned long lastDebounceTime = 0;  
unsigned long debounceDelay = 1500;    
int lastButtonState = HIGH; 

unsigned long lastIRTime = 0;      
unsigned long irTimeout = 1000; 

bool photoSensorEnabled = false; 

int lastServoAngle = -1; 
bool toggleSwitchActivated = false; 

void setup() {
  Serial.begin(9600);
  receiver.enableIRIn(); 
  servo.attach(servoPin);
  pinMode(photoPin, INPUT);
  pinMode(toggleSwitchPin, INPUT_PULLUP); 

  servo.write(servoAngle); 
}

void loop() {
  // Check toggle switch state with debouncing
  int reading = digitalRead(toggleSwitchPin);
  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // Check if the switch is flipped to the LOW position AND it hasn't been activated recently
    if (reading == LOW && !toggleSwitchActivated) { 
      servoAngle = (servoAngle == 0) ? 180 : 0; 
      toggleSwitchActivated = true; 

      servo.write(servoAngle); 
      lastServoAngle = servoAngle;
    }
    // If the switch is flipped back to the HIGH position, reset the activated flag
    else if (reading == HIGH && toggleSwitchActivated) { // Added this condition
      toggleSwitchActivated = false;
    }
  }

  lastButtonState = reading;
  
  // Photosensor control (only if enabled and not already activated)
  if (photoSensorEnabled && !servoActivated) {
    photoValue = analogRead(photoPin);

    if (photoValue < 300) {
      servoAngle = 180;
      servoActivated = true; 
      photoSensorEnabled = false; 
      toggleSwitchActivated = false; // Reset toggle switch flag when photoresistor triggers
    }
  }

  if (receiver.decode()) {
    // Check for IR codes to enable/disable photosensor
    if (receiver.decodedIRData.decodedRawData == 0xB847FF00 || 
        receiver.decodedIRData.decodedRawData == 0xBA45FF00) {
      photoSensorEnabled = true;
      servoActivated = false; 
    }

    // Check for other IR codes (servo control)
    else if (receiver.decodedIRData.decodedRawData == 0xBC43FF00 || 
             receiver.decodedIRData.decodedRawData == 0xF609FF00) {
      servoAngle = 180;
      toggleSwitchActivated = false; 
    }
    else if (receiver.decodedIRData.decodedRawData == 0xBB44FF00 || 
             receiver.decodedIRData.decodedRawData == 0xF807FF00) {
      servoAngle = 0;
      servoActivated = false; 
      toggleSwitchActivated = false; 
    }

    if (millis() - lastIRTime > irTimeout) {
      // Handle timeout (e.g., reset state variables)
    }
    servo.write(servoAngle);
    receiver.resume();
    lastIRTime = millis(); 
  }

  // Only update servo if the angle has changed
  if (servoAngle != lastServoAngle) {
    servo.write(servoAngle);
    lastServoAngle = servoAngle;

    // Reset toggleSwitchActivated if the angle change was not due to the toggle switch
    if (reading != LOW) { 
      toggleSwitchActivated = false;
    }
  }

  delay(200); 
}

Hardware

  • Schematic diagrams are the universal language of electronics.
  • We use schematics to communicate hardware design. All components and connections are illustrated.
  • As always, show us a good schematic of your proposed circuit. Hand drawn schematics are acceptable.
  • Show us several good image views of your actual wiring.
  • Give WEB links to your major components.

Software

  • For readability, place { and } on separate lines by themselves, place each line of code on a separate line.

  • Examining a variable for HIGH/LOW or true/false makes your code very difficult to follow.
    something like this documents your code for you and tells others what is happening.

  • Avoid magic numbers in your sketches.

Instead, use:

//Examples
#define ENABLED  true
#define DISABLED  false
//
#define CLOCKwise  0xB847FF00
//
#define LEDon  HIGH
#define LEDoff  LOW
//
#define PRESSED  HIGH
#define RELEASED  LOW
//

. . .

else if (reading == PRESSED && toggleSwitchActivated == ENABLED) {



  • When you follow the posting guidelines, volunteers can be more effective.
  • When we have a schematic we can speak the schematic language in helping you.
  • More volunteers will help when you properly post your questions.
1 Like

shouldn't the code that reads the toggleSwitchPin be conditional on toggle SwitchActivated and the angle simply set to 180 if LOW and zero when HIGH?

1 Like

first part says

this means

  • if switches changes from A to B change servo
  • if switches changes from B to A keep servo-position as it is

switch changes from A to B servo-position changes
as your switch is now in position B
shall the change of the switch back to A already change the servo-position again?

sounds like you are not properly setting / resetting some of your variables.

The basic logic seems to be
if switch changes (regardless if the change is A to B or B to A)
change servo-position (regardless of whatever the servo-position is)

Is this a correct description of your wanted functionality?

yeah correct. I want it to be that if i flip the toggle switch, no matter where the servo is it will go to the opposite angle 0 or 180.

no, I want it to be that if i flip the toggle switch, no matter where the servo is it will go to the opposite angle 0 or 180.

whats the best software to use?

This is a way too generalised question to give an answer.

Software that does what?

  • You can neatly draw a schematic with pencil on paper.
1 Like

Your code has two places with

      servo.write(servoAngle); 
      lastServoAngle = servoAngle;

I think is this a bad idea

Your complete code does more than just react on the toggle-switch.

You should give a detailed description of what your code shall do all in all
there is a IR-remote
and there is a light-sensor

Your description of your wanted functionality should define ALL situations that can happen.

At least a part of the devices switch, IR-receiver and photo-sensor influence the same variables this makes it even more important to describe precisely what shall happen in what situation.

You should write down this description in normal words. NOT as code. As your code does not yet work as intended this means you might have a misconception of how the code works.

schematics for arduino

Move the flippy-bit out of the reading==LOW conditional.

You could put the flippy-code in both sides of the conditional, for both the HIGH->LOW edge and the LOW-> HIGH edge, but that would be sloppy. Just move it outside of the if(reading==LOW...){...}else if (reading==HIGH){...} structure so it is in the debounced reading != lastButtonState context. Then it will happen when reading CHANGED, regardless of what it changed to.

1 Like

LOL. I've written all kindsa of bad code, but no one ever called it sloppy.

a7

1 Like

another question:

a toggle-switch as I understand it works this way

let's assume at first switch is in position closed which pulls down => the IO-pin-state = LOW
first pressing down of toggle-switch => switch changes to opened => IO-pin-state = HIGH
toggle switch can be released and stays in position opened

second pressing down of toggle-switch => switch closes => IO-Pin-state = LOW
toggle switch can be released and stays in position closed

third pressing down of toggle-switch => switch changes to opened => IO-pin-state = HIGH
toggle switch can be released and stays in position opened

.....

But You are writing about flipping the switch which sounds like a switch that works this way:

flip to the right => switch is closed IO-pin-state = LOW
flip to the left => switch is opened IO-pin-state = HIGH

now what kind of switch is it?

???

1 Like

or do you mean that after setting the angle due to some IR encoder code that when toggleSwitchAvtivated is enabled, the angle is only changes after the toggle switch is flipped and if the current angle is < 90 it sets it to 180 and if >= 90 it sets it to 0

Ok so basically, I want the servo to control my light switch. Forward and rewind button on the IRremote controls whether the servo goes 180 or 0 degrees respectively. The power button on the IRremote determines when the reading of the photoresistor can be used to control the servo to 180 degrees when it's dark. The toggle switch will work independently of everything else and can control the servo when flipped. The servo will go the opposite angle of whatever position it currently is in when the toggle switch is flipped.

1 Like

so this:

void toggleServo(){
    servo.write(servo.read() == 0 ? 180 : 0); 
}

... called by appropriate state-change change-detection code for when the toggle switch changes state and the IR sends a code.