How to save a constant updating value

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.

treahuggs:
So i decided to use the accelerometer. They say its accurate up to 45 degrees and its easy to code.

To repeat - using an accelerometer to detect the lean angle on a bike is futile.

I'd also question your logic of waiting for the lean angle to return past the initial 'set point' established when the signal was started. You should expect the signal to start before the turn not during it and you may even be leaning in the opposite direction to the turn signal.

PaulS's suggested approach of using canceling the signal after an interval derived from the road speed is much simpler to implement and likely to work well from the rider's point of view. Solutions based on the steering position should be feasible but will be harder to get working well. Solutions based on accelerometer sensing of lean angles are not feasible.

As i said i am fine using another chip and admitted seeing the flaws in the accelerometer. The project states i have to use angle. This is my main goal, if while testing i see flaws then i can implement fixes and new chips if need be.

I am more then open on suggestions on what kind of chips to use to get the goal of using angles, but can not default to using speed and distance.

treahuggs:
The project states i have to use angle.

If your solution design has be defined for you, that does rather change things. How much of the solution has been specified? I have doubts about the practical usefulness of the solution based on roll angle. What form does your solution need to take? Do you need to show it working on a physical bike? I think you will need to look for a solution using a gyro to detect roll. Depending how well you want this to work you mighty be able to get away with just looking for a change in the roll angle over a short interval, and the gyro will give you that. But you may well find you need to know the absolute roll angle as well, to detect crossing through straight ahead, and to deal with high speed situations where the roll angle and rate of roll are very small. In that case I suspect you'll also need an accelerometer to compensate for drift in the gyro output. Basically, you need to read up on the control algorithms that have been developed for flying drones such as quadrotors. There's been a lot of work done and people have solved the problem quite effectively, but the solution will take a lot of work just to understand let alone get working in your application.

hmm some side notes.
So the angle is from a device (bike) that can turn over (fall)..

Hmm it might be hard to balance something if thats your goal.
There are accellero meters and there are things who precizely measure an angle but no acceleration.
The math to balance is kinda complex dough there was an article recently i tink on "hack a day" website..
Dough, it might perhaps be an idea to not use complex math for it, but train a more general neural net (there is even a neural net example for arduino)
Training dough will require a lot of falling, but eventualy by learning such software will work (hey even you i can walk by using our real neurons).
I remember for (real) long time ago such neural software has been used on targeting rockets, and kept better track under real world conditions (wind, unstable engines etc).
It wont be easy but.. if learning was your goal.. there is a lot one can learn from it.

Yes peter, the project states "Student will research, design, and implement a circuit that will sense the pitch and yaw of a motorcycle and display the readings. The circuit will also automatically turn off the turn signals after a turn is completed. Student will create a PCB layout and will be soldered into a hard case. Then student will develop a mini presentation"

So i have some free room but in any case i need to use angles. I can also implement other chips to compensate for speed but honestly my exp with arduino is not the advanced. I know more about assembly and C++ then arduino (even though arduino and c++ are similar). I am just trying to take this one step at a time to get somewhere, so even if i can just JUST a gyro for rough product that is fine and would work, then i can implement the accel later.

I wish i was skilled enough to be able to read and break apart codes that would work for me.

In all likelihood you are going to need both to accomplish your goal. Either by themselves are inadequate (for different reasons) for tracking angular position. Put the two together though, and they can compensate for their separate inadequacies and provide a decent IMU.

That is why i first bought this MPU 6050 from Sparkfun. https://www.sparkfun.com/products/11028?

Triple Axis Accelerometer & Gyro Breakout - MPU-6050

But the thing is kinda hard for me to code. I was able to KINDA get it working but had to many problems and not enough knowledge, researching and even emailing the chip makers didnt do much help either.

I am willing to try to use that again to get my goals but i would need some help from you guys if you would be so kind.

The MPU-6000/6050 have an integrated IMU processor. All you have to do is read the heading data output on the I2C.

What did you kinda get working? and what problems did you run into?

This should be a good starting point for working with any of the MPU-6050 breakout boards:
http://arduino.cc/playground/Main/MPU-6050

Basically i had it wired up, found code that worked, installed the teapot demo from invensense website (the board controls a teapot on the computer screen). But when i would try to test controlling teapot my mouse on screen would move everywhere plus right and left click everything.

Invensense told me to try the pointer included in their download package and i couldnt figure out how.

I know probably none of that made sense. I will start looking at the link you sent me, out of 20 other links i have for the MPU 6050 i never had the one you sent me. Thank you.

Here is an example.

treahuggs:
Yes peter, the project states "Student will research, design, and implement a circuit that will sense the pitch and yaw of a motorcycle and display the readings. The circuit will also automatically turn off the turn signals after a turn is completed. Student will create a PCB layout and will be soldered into a hard case. Then student will develop a mini presentation"

Nowhere does that mention measuring lean angles. Yaw and pitch could each be measured using a compass or an gyro. A compass would be subject to distortion from ferrous objects and electric fields, a gyro would be subject to gradual drift. I suspect you could make either work and the choice will probably be driven by which is easier to obtain and get working.