1

I want to have a switch, that when on, will grab an analog number and essentially "freeze" it. Similarly to how STO> works on a TI83. What should I be using? Excuse my lack of technical terms, I'm not sure what to search and therefore do not know what to use. Thank you :)

6
  • Store/freeze it permanently, so it can be retrieved after power off, or just hold it in memory while power remains on? – Mark Smith Feb 14 '17 at 7:35
  • @MarkSmith sorry, should have clarified. Just while power is on. – mpgiii Feb 14 '17 at 15:21
  • Then you don't need to do anything special - that's what variables do. Just read it: int value = analogRead(...);. value now contains the value you read. – Mark Smith Feb 14 '17 at 15:28
  • @MarkSmith but it will continuously read my analog input, which will be changing. I want it so when I press a button it'll grab that number and not keep reading from analog – mpgiii Feb 14 '17 at 15:29
  • Only if you tell it to. Can you think of a way to tell it only to read when the button is pressed? (Can you think of a way to tell it to do anything when a button is pressed?) – Mark Smith Feb 14 '17 at 15:43
1

it will continuously read my analog input.

easy:

  1. have the adc in free running mode and in the isr writes the adc value to a buffer.

  2. watch the state of the button in an isr. if it changes, save the buffer value to something else.

there are simpler ways of doing it but less real time than that. need to watch out for atomicity if a multi-byte value is involved.

0

Only read the analogue pin if the button is pressed.

#define analogPin 0
#define buttPin 3

int analogVal = 0;

void setup() {
  pinMode(buttPin,INPUT);
}

void loop() {
    // You can do stuff here

    // If the button is pressed...
    if (digitalRead(buttPin)
    {
        // ..read the analogue pin
        analogVal = analogRead(analogPin) / 4;
    }

    // You can do stuff here
}
2
  • I'm not using a button, I'm using a switch. I just want when the switch is first turned on it will freeze a number, and when turned off it will unfreeze. – mpgiii Feb 14 '17 at 16:14
  • What do you mean "unfreeze"? Throw the number away? Read continually? – Mark Smith Feb 14 '17 at 17:00
0

My recommendation:

  1. Configure an external interrupt on the raising edges of the input where the button/switch is wired. Note that only pins 2 and 3 of Uno are capable of external interrupts.

  2. Write a very simple ISR that just sets to True a global volatile variable (a flag to signal that the button/switch has been actuated) and does nothing else.

  3. In the loop() check if the flag variable has been changed by the interrupt. If that's the case, then:

    • Debounce/deglitch the button/switch (optional, but highly recommended).
    • Read the analog input of your choice and store its value or do whatever you want to do with it.
    • Reset the flag variable to False so it can be changed the next time the interrupt is fired.
0

Here's a simple way of tracking the switch and managing the bit of state you need to manage:

int analogPin = 0;
int switchPin = 3;
int switched = 0; // the last-known state of the switch
int lastRead = 0; // the last-desired analog sample

void setup() {
  pinMode(switchPin, INPUT_PULLUP); // connect switch to switchPin+GND w/o resistors
}

void loop() {

  if(digitalRead(switchPin)){ // switch on:
    if(!switched){ // switch on, but was unknown
      lastRead = analogRead(analogPin); // the wanted leading-edge value
      switched = 1; // seen it on
    }//end if switch changed?
  }else{ // switch off:
    if(switched) switched = 0;      //  remember that switch is off
    lastRead = analogRead(analogPin); // the latest value
  }


  Serial.println("Value is " + String(lastRead));
  delay(500);
}
0

Read the analog input and store it, continuously. If the switch is off, also write the value to the "freeze" value:

void loop(){
   int value, freeze;

   value = analogRead(ANALOGPIN);
   if( !digitalRead(SWITCHPIN) ){
      freeze = value;   // sw is off, upd freeze value
   }
}

This doesn't take into account possible bouncing of the switch. That may or may not matter depending on the actual rate of sampling the analog input and what you intend to do with the frozen output, as the switch bouncing will be shorter than human perception but long enough (10s of msec, perhaps) for the MCU to notice and react to changes.

-1

You could use EEPROM on the Arduino. For example:

#include <EEPROM.h>

int valAddr = 0;

#define analogPin 0
#define buttPin 3
void setup() {
  pinMode(buttPin,INPUT);
}

void loop() {
  /***
    Need to divide by 4 because analog inputs range from
    0 to 1023 and each byte of the EEPROM can only hold a
    value from 0 to 255.
  ***/
  if(digitalRead(buttPin)){
     int val = analogRead(analogPin) / 4;
     EEPROM.write(valAddr, val);
     //access this value again by using int newvalue = EEPROM.read(valAddr)*4;

  }
}

By using EEPROM your value will be stored in non-volatile memory, meaning it will stay in memory even after a power cycle which is similar to how STO> works.

2
  • 2
    As noted in the EEPROMWrite page at arduino.cc, “The EEPROM memory has a specified life of 100,000 write/erase cycles, so you may need to be careful about how often you write to it.” The above program is not careful. At 3.3 ms per EEPROM write, the above program will finish 100000 writes to valAddr in about 6 minutes if pin 3 is high. – James Waldby - jwpat7 Feb 14 '17 at 6:54
  • Yes, definitely be careful of this. If your button is held down in your application you will have to write code to make sure it only writes once and only registers the button click once (debounce). – Airfield20 Feb 14 '17 at 15:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.