How to save a constant updating value

Hey guys i have a project ive been working on for months (planned for years) and what it is, is basically a switch is hit, a accelerometer (memsic 2125) reads the degrees, I need to have a value that saves the angle when the switch was pushed, then compare that saved value against the current real readings from the memsic, once the value drops below the real value the switch is turned off.

Without throwing all my messy code at you this is the part that im stuck on. I can display the angles fine and have a button working with the code. But when i hit the button it displays the value alongside the real value, changing with it. How can i store the value when the button is hit so i can compare?

This is not the final code either.

  Serial.print("Y Angle: ");
  Serial.print(Yangle);
val= digitalRead(button); //Read input
if ((val==HIGH){
    Serial.write(0xFE);   //command flag
    Serial.write(192);    //position
    saveY=Yangle;
    Serial.print(saveY);
    delay(150);
  } else if (Yangle <= -10) {
    Serial.write(0xFE);   //command flag
    Serial.write(192);    //position
    Serial.print("<= -10");
    delay(150);
  } else {
    Serial.write(0xFE);   //command flag
    Serial.write(192);    //position
    Serial.print("Please tilt");
    delay(150);
}
}

Its not exactly clear to me what you want to achieve, but i believe maybe an extra variable could help here.
Below i give a sample based on your code, it might not be complete because i'm not sure what you try to do.

Well here is how it can work for you, use another variable in which you track when its OK to use the activate button.
While readkey = false you wont go into the condition where you store your angle data.
Only when both are true you store your data, so when its not true you only check for the condition of readkey, at certain angle become true..

i placed it all in an if construction, perhaps you might consider while too, but not sure if the code had to keep running (e.e so it wont lock inside a loop) below code wont lock / halt inside a function.

// put in setup
Boolean readkey = true;


// put in main...

val = digitalRead(button); //Read input


if ((val==True) ||(readkey==True)) 
 {    // i asume code below is what you want to happen when things are true
   Serial.write(0xFE);   //command flag
    Serial.write(192);    //position
    saveY=Yangle;
    Serial.print(saveY);
    readkey = false;    //ADDED
 }
else
 {  
  if (readkey==false) { //here you can decide when to enable the readkey
                                 if (yourvalue =< ???? ){ readkey = true; Storemyvalue = ?????}                          
                             }
 }

Ok maybe this will help.

When i display Yangle to the LCD it will update with the angle changes
I have saveY to save that value AT THE CERTAIN TIME the button is pushed. Kind of like a screen shot in a movie.

Instead when i push the button saveY displays the same reading(s) as Yangle, always changing.

I need to save it at the exact instance the button is pressed. while in the back ground Yangle is still updating its value constantly.

Did i explain it better?

treahuggs:
Without throwing all my messy code at you this is the part that im stuck on.

You really do need to post a complete sketch that demonstrates the problem - preferably the simplest sketch you can write which demonstrates the problem.

if ((val==HIGH){

Posting code that doesn't even compile wastes every ones time.

ehm the code idea i presented allowed for defining a moment when the button is active
the push button would only become active again after a specific condition
isnt that what your looking for ?

isnt that what your looking for ?

I'm not looking for anything, but I don't think it's asking too much of you to at least compile code before you post it. There are different numbers of open and close parentheses in that snippet, so the code will NOT compile.

If it won't compile, it certainly won't do anything like OP might have wanted.

Re. Reply #1.
You haven't defined "True", so that wasn't compiled either.

If you haven't compiled or tested something, it is polite to point this out.

To everyone who assumes my code will not compile, you look really ignorant and rude right now as my code def compiles and will fully upload and run on my build.

PGTBOOS- I havent had a chance yet to implement your code into the program yet as i havent been next to the build. I will have a chance today. I thought i would try to better explain at least whenever i had the chance.

Here is full code with me trying to clean it up to an understandable read.

#include <serLCD.h>
#include <SoftwareSerial.h>
#include <LiquidCrystal.h>
#include <math.h>

int oldval=0; //sec value for the button
int state1=0;  //state the button is in
int val = 0; //first value for the button
const int button = 7; //pin for the push button (for testing)

// these constants won't change:
 const int xPin = 2;     // X output of the accelerometer
 const int yPin = 3;     // Y output of the accelerometer
//Button Left And Right pins (for use later)
int right = 4;
int left = 5;
// Set pin to the LCD's rxPin
 int pin = 1;
 serLCD lcd(pin);
 
 int Xraw, Yraw;
double xGForce, yGForce, Xangle, Yangle;
double saveY, saveX, state;
 
void setup() {
   // initialize serial communications:
   Serial.begin(9600);
   // initialize the pins connected to the accelerometer
   // as inputs:
   pinMode(xPin, INPUT);
   pinMode(yPin, INPUT);
   
   Serial.write(0xFE);   //command flag
   Serial.write(0x01);   //clear command.
   delay(10);

 Serial.print("Lets Begin");
 delay(1000);
}

void loop() {
//   lcd.clear();
   Serial.write(0xFE);   //command flag
   Serial.write(0x01);   //clear command.
   delay(10);
   // variables to read the pulse widths:
   int pulseX, pulseY;
   // variables to contain the resulting accelerations
   int accelerationX, accelerationY;
   
   // read pulse from x- and y-axes:
   pulseX = pulseIn(xPin,HIGH);  
   pulseY = pulseIn(yPin,HIGH);
   
   Xraw = pulseIn (xPin, HIGH);
   Xraw = pulseIn (xPin, HIGH);
   Yraw = pulseIn (yPin, HIGH);
   Yraw = pulseIn (yPin, HIGH);

   // Calculate G-force in Milli-g's.

   xGForce = (( Xraw / 10 ) - 500) * 8;
   yGForce = (( Yraw / 10 ) - 500) * 8;

   // Calculate angle (radians) for both -x and -y axis.

   Xangle = asin ( xGForce / 1000.0 );
   Yangle = asin ( yGForce / 1000.0 );

   // Convert radians to degrees.

   Xangle = Xangle * (360 / (2*M_PI));
   Yangle = Yangle * (360 / (2*M_PI));

//save angle when button is pushed, then compare to live reading send a zero once live reading
//is below saved angle
  
  Serial.print("Y Angle: ");
  Serial.print(Yangle);
val= digitalRead(button); //Read input
if ((val==HIGH) && (oldval==LOW)){
    Serial.write(0xFE);   //command flag
    Serial.write(192);    //position
    saveY=Yangle;
    Serial.print(saveY);
    delay(150);
  } else if (Yangle <= -10) {
    Serial.write(0xFE);   //command flag
    Serial.write(192);    //position
    Serial.print("<= -10");
    delay(150);
  } else {
    Serial.write(0xFE);   //command flag
    Serial.write(192);    //position
    Serial.print("Please tilt");
    delay(150);
}
}

To everyone who assumes my code will not compile, you look really ignorant and rude right now

Who are you referring to?

treahuggs:
To everyone who assumes my code will not compile, you look really ignorant and rude right now as my code def compiles and will fully upload and run on my build.

No assumptions have been made. The code you provided in your initial post does not compile, period.
I highly recommend reading the sticky in this forum. The one titled 'Read this before posting a programming question'. Perhaps you already think you know what that post contains. I can assure you though, based on the above comment you've made, you have no idea what that post contains.

No assumptions have been made.

Actually, there was. PGTBOOS assumed that my post about code that did not compile was directed to him. It wasn't. It was directed to OP.

My response to his tirade assumed we were talking about the same person's code. We were not.

treahuggs:

val= digitalRead(button); //Read input

if ((val==HIGH) && (oldval==LOW)){
   Serial.write(0xFE);   //command flag
   Serial.write(192);    //position
   saveY=Yangle;
   Serial.print(saveY);
   delay(150);
 } else
...

I assume this is intended to detect button transitions from unpressed to pressed, is that the idea? If so you would need to update oldval at some point to record that the switch is now pressed - and then update it again when it is released. I recommend separating the logic to detect button transitions from the code to deal with those transitions, this will eliminate the rather messy if/else if structure. I also recommend that you adopt the coding style of putting each { and } on separate lines with matching pairs indented by the same amount, it will make it much easier to visually check that the code structure matches what you intend.

treahuggs:
To everyone who assumes my code will not compile, you look really ignorant and rude right now as my code def compiles and will fully upload and run on my build.

It was not an assumption, it was a fact: the code you originally posted did not compile. Do you think that insulting the people trying to help you is going to encourage them to offer more help?

It was not an assumption, it was a fact: the code you originally posted did not compile. Do you think that insulting the people trying to help you is going to encourage them to offer more help?

The code i posted did (with respect to needing the rest of course) going back through and reading the thread i will admit i made the error of figuring out who PaulS was talking too, which was not me. I am sorry for that, alot of hassle over more then one person getting confused.

To help everyone understand what i need, i will make a video here in a sec and i will tell you the goal of the project.

Goal- My goal with this project is a auto shut off blinker for a motorcycle. I will read the angle of the bike at all times. Then when the user hits the blinker (left or right) i save that instance of angle. Since you have to lean to turn on a motorcycle the angle will only increase.
While the angle is increasing it is compared to the saved angle, once the live angle is less then the saved angle value the blinker is turned off.

That is the bases of the project. I am just not able to save the value for some reason. When ever i save it, the value follows along the live value.

(Is this because i have it in the main and so it is always looping? Testing that idea now with making a new function.)

EDIT: Changed the code up alittle to try to see what is going on. Here is the updated code and the video with updated code will be attached.

#include <serLCD.h>
#include <SoftwareSerial.h>
#include <LiquidCrystal.h>
#include <math.h>

int oldval=0; //sec value for the button
int state1=0;  //state the button is in
int val = 0; //first value for the button
const int button = 7; //pin for the push button (for testing)

// these constants won't change:
 const int xPin = 2;     // X output of the accelerometer
 const int yPin = 3;     // Y output of the accelerometer
//Button Left And Right pins (for use later)
int right = 4;
int left = 5;
// Set pin to the LCD's rxPin
 int pin = 1;
 serLCD lcd(pin);
 
 int Xraw, Yraw;
double xGForce, yGForce, Xangle, Yangle;
double saveY, saveX, state;
 
void setup() {
   // initialize serial communications:
   Serial.begin(9600);
   // initialize the pins connected to the accelerometer
   // as inputs:
   pinMode(xPin, INPUT);
   pinMode(yPin, INPUT);
   
   Serial.write(0xFE);   //command flag
   Serial.write(0x01);   //clear command.
   delay(10);

 Serial.print("Lets Begin");
 delay(1000);
}

void loop() {
//   lcd.clear();
   Serial.write(0xFE);   //command flag
   Serial.write(0x01);   //clear command.
   delay(10);
   // variables to read the pulse widths:
   int pulseX, pulseY;
   // variables to contain the resulting accelerations
   int accelerationX, accelerationY;
   
   // read pulse from x- and y-axes:
   pulseX = pulseIn(xPin,HIGH);  
   pulseY = pulseIn(yPin,HIGH);
   
   Xraw = pulseIn (xPin, HIGH);
   Xraw = pulseIn (xPin, HIGH);
   Yraw = pulseIn (yPin, HIGH);
   Yraw = pulseIn (yPin, HIGH);

   // Calculate G-force in Milli-g's.

   xGForce = (( Xraw / 10 ) - 500) * 8;
   yGForce = (( Yraw / 10 ) - 500) * 8;

   // Calculate angle (radians) for both -x and -y axis.

   Xangle = asin ( xGForce / 1000.0 );
   Yangle = asin ( yGForce / 1000.0 );

   // Convert radians to degrees.

   Xangle = Xangle * (360 / (2*M_PI));
   Yangle = Yangle * (360 / (2*M_PI));

//save angle when button is pushed, then compare to live reading send a zero once live reading
//is below saved angle
  
  Serial.print("Y Angle: ");
  Serial.print(Yangle);
val= digitalRead(button); //Read input
if ((val==HIGH) && (oldval==LOW)){
  test(saveY);
  Serial.print(saveY);
  } else if (Yangle <= -10) {
    Serial.write(0xFE);   //command flag
    Serial.write(192);    //position
    Serial.print(saveY);
    delay(150);
  } else {
    Serial.write(0xFE);   //command flag
    Serial.write(192);    //position
    Serial.print(saveY);
    delay(150);
}
}

int test(int saveY) {
   Serial.write(0xFE);   //command flag
    Serial.write(192);    //position
    saveY=Yangle;
    Serial.print(saveY);
    delay(150);
    return saveY;
}

Only the bottom has been changed. I added a function that i thought would save the value and keep it there till the button is pressed again but i have the same problem as before.

Here is the Youtube link. Testing code - YouTube

I also recommend that you adopt the coding style of putting each { and } on separate lines with matching pairs indented by the same amount,

My 1 cent is hit CTRL-T in the IDE so it nicely formats your code, then copy-paste it here. Other people's code is hard enough to read, misindented code, although syntactically correct, makes the job unnecessarily harder.

Peace :slight_smile:

treahuggs:
The code i posted did (with respect to needing the rest of course)

No, it did not compile. There is absolutely no way that this would compile:
if ((val==HIGH){

treahuggs:
Goal- My goal with this project is a auto shut off blinker for a motorcycle. I will read the angle of the bike at all times.

Well, saving the current angle and comparing against that is easy enough and I'm sure we can fix your sketch to do that correctly. However, I'm afraid that you will find that on a moving bike your method of reading the lean angle using an accelerometer will not work. Ignoring the small transient forces needed to accelerate the bike in roll and yaw, the net acceleration is always in a plane define by the two contact patches and the center of mass. If you have conventional tyres the contact patch does not move significantly relative the rest of the bike and all your accelerometer will see is that the acceleration remains on the center line of the bike.

I think you might have more luck deriving the turn radius from the average steering angle over a short interval, although I think it'll be difficult to get a reliable detection of the bike coming out of a turn at high speed because the steering angles will be so low. Perhaps, if you know the bike is moving fast enough to make turn detection difficult, you could simply cancel the indicators after a set time on the basis that at high speed you rarely need to signal for longer than a few seconds.

Perhaps, if you know the bike is moving fast enough to make turn detection difficult, you could simply cancel the indicators after a set time on the basis that at high speed you rarely need to signal for longer than a few seconds.

And that's exactly what manufacturers that supply self cancelling turn signals do. The turn signals on my trike quit blinking after I make a turn, and it doesn't lean at all.

How long the turn signals blink is really a matter of distance. Sitting at a light, the lights will blink forever. Start moving, after the turn, and they shut off quickly. The distance is determined based on the speed when the signal is activated. Starting blinking at a slow speed, the blinking stops quickly. Start blinking at 70 mph, they blink for a lot longer.

Is this better?

#include <serLCD.h>
#include <SoftwareSerial.h>
#include <LiquidCrystal.h>
#include <math.h>

int oldval=0; //sec value for the button
int state1=0;  //state the button is in
int val = 0; //first value for the button
const int button = 7; //pin for the push button (for testing)

// these constants won't change:
const int xPin = 2;     // X output of the accelerometer
const int yPin = 3;     // Y output of the accelerometer
//Button Left And Right pins (for use later)
int right = 4;
int left = 5;
// Set pin to the LCD's rxPin
int pin = 1;
serLCD lcd(pin);

int Xraw, Yraw;
double xGForce, yGForce, Xangle, Yangle;
double saveY, saveX, state;

void setup() 
{
  // initialize serial communications:
  Serial.begin(9600);
  // initialize the pins connected to the accelerometer
  // as inputs:
  pinMode(xPin, INPUT);
  pinMode(yPin, INPUT);

  Serial.write(0xFE);   //command flag
  Serial.write(0x01);   //clear command.
  delay(10);

  Serial.print("Lets Begin");
  delay(1000);
}

void loop()
{
  //   lcd.clear();
  Serial.write(0xFE);   //command flag
  Serial.write(0x01);   //clear command.
  delay(10);
  // variables to read the pulse widths:
  int pulseX, pulseY;
  // variables to contain the resulting accelerations
  int accelerationX, accelerationY;

  // read pulse from x- and y-axes:
  pulseX = pulseIn(xPin,HIGH);  
  pulseY = pulseIn(yPin,HIGH);

  Xraw = pulseIn (xPin, HIGH);
  Xraw = pulseIn (xPin, HIGH);
  Yraw = pulseIn (yPin, HIGH);
  Yraw = pulseIn (yPin, HIGH);

  // Calculate G-force in Milli-g's.

  xGForce = (( Xraw / 10 ) - 500) * 8;
  yGForce = (( Yraw / 10 ) - 500) * 8;

  // Calculate angle (radians) for both -x and -y axis.

  Xangle = asin ( xGForce / 1000.0 );
  Yangle = asin ( yGForce / 1000.0 );

  // Convert radians to degrees.

  Xangle = Xangle * (360 / (2*M_PI));
  Yangle = Yangle * (360 / (2*M_PI));

  //save angle when button is pushed, then compare to live reading send a zero once live reading
  //is below saved angle

  Serial.print("Y Angle: ");
  Serial.print(Yangle);
  val= digitalRead(button); //Read input
  if ((val==HIGH) && (oldval==LOW))
  {
    test(saveY);
    Serial.print(saveY);
  } 
  else if (Yangle <= -10) 
  {
    Serial.write(0xFE);   //command flag
    Serial.write(192);    //position
    Serial.print(saveY);
    delay(150);
  } 
  else 
  {
    Serial.write(0xFE);   //command flag
    Serial.write(192);    //position
    Serial.print(saveY);
    delay(150);
  }
}

int test(int saveY) 
{
  Serial.write(0xFE);   //command flag
  Serial.write(192);    //position
  saveY=Yangle;
  Serial.print(saveY);
  delay(150);
  return saveY;
}

EDIT: I was at first using the sparkfun MPU 6050 https://www.sparkfun.com/products/11028? but that quickly proved to be much bigger of a beast then i thought.

So i decided to use the accelerometer. They say its accurate up to 45 degrees and its easy to code. Needing this for a class i figured i could refine it as i start using it. But having it flat moving it across the table it does give me wild readings with the accel. Thnk you for pointing that out. I might be able to implement the accel into a new version where i would use the accel to compare speeds for the auto shut off.

What kind of easy programable chip do you guys recommend that i can use for this project? Or has anyone used the MPU 6050 with their arduino project? Also would still be interested in fixing my problem i have so i wont have it later in the future.

Why so many globals?

Is this better?

No, not really.

double saveY, saveX, state;

So, saveY is a global variable.

    test(saveY);

You pass it to this function.

int test(int saveY) 
{
  Serial.write(0xFE);   //command flag
  Serial.write(192);    //position
  saveY=Yangle;

Whereupon you stomp on it.

test() is a lousy name for a function. A function's name should tell the caller EXACTLY what to expect the function to do. digitalRead(), analogWrite(), etc. don't require much thought, and no code reading, to figure out what they do.

What, exactly, is test() supposed to do? If it's intent is to store a value when a switch is pressed, then, it should have "save" somewhere in it's name. The value to be saved should be passed to the function, not where to save the value.