Voltage sensing switch Help..

I am very new to Arduino and am trying to operate a toggle switch using voltage i.e when the voltage rises above 1v turn on the switch and the next time it happens turn off the switch.. I usually solve these problems and learn by using code from other projects and sticking them together, but cant figure this one out? here is the code I am using. Any guidance would be appreciated.

int inPin = 0;         // the number of the input pin
int outPin = 7;       // the number of the output pin

int state = HIGH;      // the current state of the output pin
int reading;           // the current reading from the input pin
int previous = LOW;    // the previous reading from the input pin

// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long time = 0;         // the last time the output pin was toggled
long debounce = 200;   // the debounce time, increase if the output flickers

void setup()
{
  pinMode(inPin, INPUT);
  pinMode(outPin, OUTPUT);
}

void loop()
{
  reading = analogRead(inPin);
  // read the value on analog input
  
  if (reading >= 1) {
    outPin, HIGH;

  }

  else if (reading <= 0) {
    outPin, LOW;

   

  // if the input just went from LOW and HIGH and we've waited long enough
  // to ignore any noise on the circuit, toggle the output pin and remember
  // the time
  if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (state == HIGH)
      state = LOW;
    else
      state = HIGH;

    time = millis();    
  }

  digitalWrite(outPin, state);

  previous = reading;

  }}

Moderator edit:
</mark> <mark>[code]</mark> <mark>

</mark> <mark>[/code]</mark> <mark>
tags added.

analogRead returns a value between 0 and 1023. When analogRead returns 0 the pin is at 0 volts. When analogRead returns 1023 the pin is at VCC volts (usually very close to 5 volts). So, you will need to adjust the comparison...

if ( reading >= ((1 * 1023) / 5) ) {

    outPin, HIGH;

While that is valid C++ syntax it has no side-effects. I suspect you meant this...

digitalWrite( outPin, HIGH );

Thanks Coding badly, I tried that but still not doing what i want it to?
Basically what I have done is hacked into a mobile phone and taken a feed from it, so that when a message is recieved there is a 1.8v spike from the phone and I want this to activate a relay coming from the arduino board and stay on until the next spike and so on.
It may be the case the code I am using is not appropriate for this project?

Aviator1:
Thanks Coding badly

You are welcome.

I tried that but still not doing what i want it to?

I didn't expect it to work. Your code has a few remaining problems. I suggest you reduce your code to the bare minimum that will indicate the spike has been detected and then build it up bit-by-bit until it does what you want.

When you make changes to your code, you need to re-post the new version. The only way those of us on this side of your internet connection can see what you've done is for you show us what you've done.

Basically what I have done is hacked into a mobile phone and taken a feed from it, so that when a message is recieved there is a 1.8v spike from the phone and I want this to activate a relay coming from the arduino board and stay on until the next spike and so on.

In addition to the analog input / phone output, do the Arduino and mobile phone have the grounds connected?

Yes the grounds are connected..
I only understand a very small amount of code at the moment so not sure I can reduce it?

int inPin = 0;         // the number of the input pin
int outPin = 7;       // the number of the output pin

int state = HIGH;      // the current state of the output pin
int reading;           // the current reading from the input pin
int previous = LOW;    // the previous reading from the input pin

// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long time = 0;         // the last time the output pin was toggled
long debounce = 200;   // the debounce time, increase if the output flickers

void setup()
{
  pinMode(inPin, INPUT);
  pinMode(outPin, OUTPUT);
}

void loop()
{
  reading = analogRead(inPin);
  // read the value on analog input
  
  if ( reading >= ((35 * 1023) / 5) ) {

    digitalWrite ( outPin, HIGH);

  }

  else if (reading <= 0) {
    digitalWrite ( outPin, LOW);

   

  // if the input just went from LOW and HIGH and we've waited long enough
  // to ignore any noise on the circuit, toggle the output pin and remember
  // the time
  if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (state == HIGH)
      state = LOW;
    else
      state = HIGH;

    time = millis();    
  }

  digitalWrite(outPin, state);

  previous = reading;

  }}

Moderator edit:
</mark> <mark>[code]</mark> <mark>

</mark> <mark>[/code]</mark> <mark>
tags added.

Hi Aviator1,

You'll find using the # button to wrap CODE tags around your quoted sketch will make it easier to read.

Are you wiring your input to the analog pin 0 (ie on the opposite side of the Arduino to your pin 7 output)?

Geoff

Thanks geoff I was wondering how to do that, yes the input is in the analog pin A0

// original post deleted.

Sometimes it's good to be able to rewind reality. Sorry for that dumb suggestion.

Geoff

if ( reading >= ((35 * 1023) / 5) ) {

35 ?

void setup()
{
pinMode(inPin, INPUT); // <<< Remove this line
pinMode(outPin, OUTPUT);
}

Do not call pinMode for analog inputs.

O.K done that, still cant seem to get it to work?

Done what?

Deleted the line you suggested and tried using a shorter code..

int inPin = 0;         // the number of the input pin
int outPin = 7;       // the number of the output pin
long time = 0;         // the last time the output pin was toggled
long debounce = 5000;   // the debounce time, increase if the output flickers
int state = HIGH;      // the current state of the output pin
int reading;           // the current reading from the input pin
int previous = LOW;    // the previous reading from the input pin

void setup()
{
  
  pinMode(outPin, OUTPUT);
}

void loop()
{
  reading = analogRead(inPin);
  // read the value on analog input
  
  if ( reading >= ((3 * 1023) / 5) ) {

    digitalWrite ( outPin, HIGH);

  }

  else if (reading <= 0) {
    digitalWrite ( outPin, LOW);

   

  // if the input just went from LOW and HIGH and we've waited long enough
  // to ignore any noise on the circuit, toggle the output pin and remember
  // the time
  if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (state == HIGH)
      state = LOW;
    else
      state = HIGH;

    time = millis();    }
  
  }
  }

Moderator edit:
</mark> <mark>[code]</mark> <mark>

</mark> <mark>[/code]</mark> <mark>
tags added.

This is the third time I've written about your comparison. At this point, I suspect you are not reading my posts.

if ( reading >= (( 3 * 1023) / 5) ) {

Why 3 ? Is there something in Reply #1 you do not understand?

To be honest there is very little I understand at the moment.. I thought that changing the 1 to a 3 would change the value needed to register a signal ( reading >= ((1 * 1023) / 5) ) {
I am now using this code and it is working but only staying on for 5 seconds then turning off again..

int inPin = 0;         // the number of the input pin
int outPin = 7;       // the number of the output pin
long time = 0;         // the last time the output pin was toggled
long debounce = 5000;   // the debounce time, increase if the output flickers
int state = HIGH;      // the current state of the output pin
int reading;           // the current reading from the input pin
int previous = LOW;    // the previous reading from the input pin

void setup()
{
  
  pinMode(outPin, OUTPUT);
}

void loop()
{
  reading = analogRead(inPin);
  // read the value on analog input
  
  if ( reading >= ((1 * 1023) / 5) ) {

    digitalWrite ( outPin, LOW);

  }

  else if (reading <= 0) {
    digitalWrite ( outPin, HIGH);

   

  // if the input just went from LOW and HIGH and we've waited long enough
  // to ignore any noise on the circuit, toggle the output pin and remember
  // the time
  if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (state == HIGH)
      state = LOW;
    else
      state = HIGH;

    time = millis();    }
  
  }
  }

It's doing what you're asking then.

Your sketch is telling it to write your outPin to LOW if it see's the spike, and HIGH if the input is 0V (actually you're testing for values less than 0 too, but that's not going to happen with an analogRead value).

This next block after that is a legacy of when your system was reading a digital pin, and no longer does what the comments say it does

  // if the input just went from LOW and HIGH and we've waited long enough
  // to ignore any noise on the circuit, toggle the output pin and remember
  // the time
  if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (state == HIGH)
      state = LOW;
    else
      state = HIGH;

    time = millis();    }
  
  }

...since reading will never be HIGH, and you don't set previous at any stage now.

If you want to only toggle on high, and only after your 5sec debounce, something like this should do the trick:

int inPin = 0;         // input pin is A0
int outPin = 7;       // the number of the output pin (D7)
long time = 0;         // the last time the output pin was toggled
long debounce = 5000;   // the debounce time, increase if the output flickers
int reading;           // the current reading from the input pin
int previous = LOW;    // the most recent value written to outPin, also the initial state of that LED

void setup() {
  pinMode(outPin, OUTPUT);
  digitalWrite(outPin, previous);  // set initial state
}

void loop() {
  reading = analogRead(inPin);        // read the value on analog input
  
  if ( reading >= ((1 * 1023) / 5) ) {  // greater than 1V
    if (millis() - time > debounce) {  // enough time has transpired to pay attention again
      // toggle the output pin
      if(previous == LOW) 
        previous = HIGH;
      else 
        previous = LOW;
      digitalWrite (outPin, previous);
      time = millis();                        // reset the timer
    }
  } 
}

I didn't see your rationale for having both a state and a previous variable, so did away with one. And you'll notice there's no else component to either of the if statements at this time. The two nested IFs could be combined into a single one with an and (&&) in the logic but this gives you flexibility to do something else if the timer isn't up yet, by adding an else to that if you choose.

I'm hoping this buys me a reprieve from that previous silly post :slight_smile:
Geoff

Thanks Geoff that works like a charm, need to get help on the code, as I said I have only just started Arduino and have a million and one ideas but struggle with them, what would you reccomend the best way to learn? I have just been learning through trail and error and butchering other peoples codes, it has worked some of the time but probably doing it the hard way :smiley:
Thanks again Dean

Hi Dean,

The best way to learn is just what you're doing I think. Plus check out some of the very worthwhile tutorials - Arduino Tutorial Series – JeremyBlum.com - those from Jeremy Blum are worth watching from start to finish, and are organised so you can go back to topics for reference later.

Glad it's going for you now. Cheers ! Geoff