How to store sensor data using a button? (SOLVED)

Hello...
Using LSM303 Mag/Accel sensor, I´m reading magnetic Norh at the COM port in use.

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_LSM303_U.h>

/* Assign a unique ID to these sensors */
Adafruit_LSM303_Accel_Unified accel = Adafruit_LSM303_Accel_Unified(54321);
Adafruit_LSM303_Mag_Unified mag = Adafruit_LSM303_Mag_Unified(12345);

void setup(void) 
{
  Serial.begin(9600);
  
  /* Initialize the sensor */
  if(!mag.begin())
  {
    /* There was a problem detecting the LSM303 ... check your connections */
    Serial.println("Ooops, no LSM303 detected ... Check your wiring!");
    while(1);
  }
}

void loop(void) 
{
  /* Get a new sensor event */ 
  sensors_event_t event; 
  mag.getEvent(&event);
  
  float Pi = 3.14159;
  
  // Calculate the angle of the vector y,x
  float heading = (atan2(event.magnetic.y,event.magnetic.x) * 180) / Pi;
  
  // Normalize to 0-360
  if (heading < 0)
  {
    heading = 360 + heading;
  }
  Serial.print("Magnetic North: ");
  Serial.println(heading);
  delay(500);
}

I have tested the "button" code to illuminate a led light but... (i´m just a begginer on programing)..
¿How should I "mix" the above code with the "button" code in one sketch, to store any Heading value when I press the button
and keep it for further usage?.
I guess a variable with the value stored should be created but ¿how?
Or... In order to verify that Heading data has been stored, A LED would be used to indicate it. (flashing in normal operation and steady when value has been stored)....

Please post your button code. And the way you have wired the button.

I have Arduino MEGA 2560 and the Button code I use with Led is the next:
(Thanks a lot for your reply)

/*
  Button
 
 Turns on and off a light emitting diode(LED) connected to digital  
 pin 13, when pressing a pushbutton attached to pin 2. 
 
 
 The circuit:
 * LED attached from pin 13 to ground 
 * pushbutton attached to pin 2 from +5V
 * 10K resistor attached to pin 2 from ground
 
 * Note: on most Arduinos there is already an LED on the board
 attached to pin 13.
 
 
 created 2005
 by DojoDave <http://www.0j0.org>
 modified 30 Aug 2011
 by Tom Igoe
 
 This example code is in the public domain.
 
 http://www.arduino.cc/en/Tutorial/Button
 */

// constants won't change. They're used here to 
// set pin numbers:
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);      
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);     
}

void loop(){
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == HIGH) {     
    // turn LED on:    
    digitalWrite(ledPin, HIGH);  
  } 
  else {
    // turn LED off:
    digitalWrite(ledPin, LOW); 
  }
}

groundfungus:
Please post your button code.

@gf:The way he talks of "the" button code I expect he means the standard IDE example http://arduino.cc/en/Tutorial/Button

@op: It should just be a "simple" matter of replacing the digitalWrite that turns the LED on with code to store the heading. I think a more important aspect is actually to describe what you mean by store... where? EEPROM or what?

Basically you would do something like this:

Put the lines above setup() in button code, above setup() in the code you posted
Put the lines from setup() in button code, into setup()of the code you posted
Put the lines fom loop() of the button code, into loop of your code something like this:

...
...
...
 
  // Normalize to 0-360
  if (heading < 0)
  {
    heading = 360 + heading;
  }
  Serial.print("Magnetic North: ");
  Serial.println(heading);
// new lines go here...
 // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == HIGH) {     
    // save the value
    //digitalWrite(ledPin, HIGH);  // <<<<<<<<<<<<<<<<<<< REMOVE THIS LINE
// put lines here to store the value of "heading"
//BUT THE CODE DEPENDS ON WHAT YOU ACTUALLY MEAN BY "STORE"...EEPROM? OR WHAT?
  }
  delay(500);
}

The purpouse of stored Heading data is using it during program RUN. I mean: No need to store it on the EEPROM since I don´t need it for other RUNS....
It could be stored temporarily, as I pretend to "pick" manually the values using the button. That´s why a temporal storage is the best.
Thanks a lot for your replays

pacheco:
The purpouse of stored Heading data is using it during program RUN. I mean: No need to store it on the EEPROM since I don´t need it for other RUNS....
It could be stored temporarily, as I pretend to "pick" manually the values using the button. That´s why a temporal storage is the best.
Thanks a lot for your replays

try something like this uncompiled/untested:

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_LSM303_U.h>

/* Assign a unique ID to these sensors */
Adafruit_LSM303_Accel_Unified accel = Adafruit_LSM303_Accel_Unified(54321);
Adafruit_LSM303_Mag_Unified mag = Adafruit_LSM303_Mag_Unified(12345);

const int buttonPin = 2;//Your button Pin
int lastButtonState;
float storedHeading;
float lastHeading;
boolean timerExpired;
unsigned long startTime;

void setup(void) 
{
  Serial.begin(9600);
  /* Initialize the sensor */
  if(!mag.begin())
  {
    /* There was a problem detecting the LSM303 ... check your connections */
    Serial.println("Ooops, no LSM303 detected ... Check your wiring!");
    while(1);
  }
}

void loop(void) 
{
  int buttonState = digitalRead(buttonPin)
  if (buttonState == HIGH)
  {
    if (lastButtonState == LOW)
    {
      storedHeading = lastHeading;
      Serial.print(F("Stored Heading = "));
      Serial.println(storedHeading);
    }
  }
  lastButtonState = buttonState;
  //
  //What to do with your storedHeading?
  //
  sensors_event_t event; /* Get a new sensor event */
  mag.getEvent(&event);
  float Pi = 3.14159;
  float heading = (atan2(event.magnetic.y,event.magnetic.x) * 180) / Pi;// Calculate the angle of the vector y,x
  if (heading < 0)// Normalize to 0-360
  {
    heading = 360 + heading;
  }
  if ((heading != oldHeading) && (timerExpired))// update display on a change only
  {
    Serial.print("Magnetic North: ");
    Serial.println(heading);
    startTime = millis();
  }
  lastHeading = heading;
  if (millis() - startTime >= 500UL)
  {
    timerExpired = true;
  }
  else
  {
    timerExpired = false;
  }
}
1 Like

So what do you mean by "store"?... it's already in the variable named "heading".

 float heading = (atan2(event.magnetic.y,event.magnetic.x) * 180) / Pi;

You can use that variable in other parts of your code anytime you like:

foo = heading * bar
//or
foo = theOutsideTemperature + heading / thePriceOfTomatoes

The code that uses "heading" could be in place of the line that turns the LED on, as in the code I posted a few posts earlier.

You'll need to explain a bit more what you mean, if that doesn't help.

Probably I´d better describe the idea (project) I have in mind.
It could be a handy tool for similar projects or (who knows..)...
I´m a single handed sailor on a 26 feet long boat. I had spent a lot of money on commercial auto-pilots that always broke due to excesive wear on mechanical links an/or electrical components. They all use DC motors connected to 12 volts Battey. The truble is that when the associate sensor detects the limits on desired course, full current is applied to the motor reaching peaks of almost 15 AMps. The autopilot vibrates and shakes so strong that rapidly generates malfunctions.
My proyect: Mark an hold a desired course, ---- Compare further LSM303 with stored value,---- Apply the result to an PID controller to damp and "smooth" current applied to motor circuits to reduce the gererated error as the boat goes to the desired course,.... an mainly: reduce frictions, malfunctions and battery saving...
I´m a retired sailor tha used to work with analog computers back in the 70´s an repair computers when they were made of ferrite coils... and never had enough time to read an learn how programs do their job.
Well... sorry for some lacks on my english .. (spanish is my mother language)..
I´m sure that hundreds of sailboat owners know what I´m talking about ..
Thanks again for your help...

Heyyy... You really go fast :fearful: :fearful:...
To JimbozaZA... Sure is Heading what we`re talking about. In order do not confuse with the continuous "Heading" (LSM303), probably a different name is needed..
I forgot to metion that the PID algorithm pretends to generate two PWM signals on Arduino to regulate the H-Bridge circuit..thus the DC motor itself..
An image is a thousand words spell...

pacheco:
I had spent a lot of money on commercial auto-pilots that always broke due to excesive wear on mechanical links an/or electrical components.

I had a sailboat with a Raymarine autopilot (immediately before they became Raymarine). I understand what you are saying about breakages, and I empathize. Mine did give up just before I sold the boat, but it wasn't from overwork - perhaps underuse as I had not used the boat for several months - I presume it was an electronics problem.

However I would be very surprised if you can make a more reliable device - although you may be able to make it cheaper. The environment and the loads on a boat are very challenging. Keep it as simple as possible,

...R

Hi Robin2..
On the project I explained, the only electrical component outside the cabin will be the DC motor+mechanical gear, and a wall mounted pushbutton with blinking/steady Led ( just to indicate ON/STANDBY operation). The LSM303 in clear area far from metal parts and Arduino on a sealed box. I know the rules: The less buttons, the less trouble. (Also, in case of malfunction, power off and go to MANUAL) :smiley:

pacheco,

Did you try reply #4?

Sorry BulldogLowell... not yet (you mean #4 or #5?)...
I´ll play with above solutions tomorrow (It´s 9 pm here. I have to pick my daughter at Las Palmas airport tonight and need some rest)....
I appreciate your advice ( to all of you...). As I mentioned before I´m retired with near 70 years and also I mentionned that my "backgrounds" in programming are form the age of ice... I´ve been working with computers/peripherals in navy an working side by side with programmers.
You probably know yourselves what I´m saying: (some memory stack broken.... OR a mismatch in your code?...).. Well, sometimes this things turn crazy... :sweat_smile:
I´ll post the progress I make. It could be useful to others and that´s important for me.
Believe or not (sure you know this one), the PID algorithm used on Pulse Widht Modulation is implemented on cruise speed control for cars for decades to smooth and maintain desired speed.

Hello...
I have tested the sketch with #5 reply ( BulldogLowell) with button at pin 2 and got the following result-.... (1st pic)---
I wrote ; at the end of line above a run again...
Result: 2nd pic

error.jpg

error-1.jpg

replace this:

int buttonState = digitalRead(buttonPin)

with this:

int buttonState = digitalRead(buttonPin);

missing semicolon

Hi BulldogLowell..
I already did and on the next run I got the 2nd pic on my previous message.
Thanks a lot

change this:

if ((heading != oldHeading) && (timerExpired))// update display on a change only

to this:

if ((heading != lastHeading) && (timerExpired))// update display on a change only

I could not test/compile, I did not have your libraries.

Heyyyyy...
Your´great ... :grin: :grin:
See the Pic down...
I can see the "light" at the end... :fearful:

result.jpg

I Understand that "Stored Heading" is somewhere and "resets" its value, each time I press the button.. ¿OK?..
The next step would be to compare the incoming heaings with the one stored and determine the positive/negative result to work with PID -----> and a PWM to control the H-Bridge...
As I said: "I can see the light at the end of tunnel"..
If you´re interested on libraries I can Link to them any time.( Or send them over e-mail)...
Just in case: I found an interesting idea about a PID sketch for temperature (not for angles)...
Here

great!

you can easily compare the new saved value and calculate the delta from the last... think about a way to do it...

I think there are enough smart guys here interested to help you, so post the links.

setenta años y todavía está aprendiendo, que bueno, ¿verdad?

cheers mate.