LSM303DLH COMPASS modified example

Hello all building on from my other post
Im modifying the example arduino heading sketch to display an average heading say over two minutes

the code compiles and loads, the output im getting on say a heading of 80` is an average heading of 30
Id expect the av reading to also be around 80.

can any one tell me whats going on here and where im going wrong Im sure its very basic stuff
Ive commented //KenB to indicate what code has been pasted in to the example

#include <Wire.h>
#include <LSM303DLH.h>

LSM303DLH compass;
const int numReadings = 60;  // this value determines the size of the readings array KenB
int readings[numReadings];   // this declares the array to hold the readings from the compass KenB

int index = 0;                  // the index of the current reading  KenB
int total = 0;                  // the running total KenB
int average = 0;                // the average KenB

void setup() {
  Serial.begin(9600);
  // initialize all the readings to 0: KenB
  for (int thisReading = 0; thisReading < numReadings; thisReading++) //KenB
    readings[thisReading] = 0;   //KenB 
  Wire.begin();
  compass.enableDefault();
  
  // Calibration values. Use the Calibrate example program to get the values for
  // your compass.
  compass.m_min.x = -520; compass.m_min.y = -570; compass.m_min.z = -770;
  compass.m_max.x = +540; compass.m_max.y = +500; compass.m_max.z = 180;
}

void loop() {
  compass.read();
  int heading = compass.heading((LSM303DLH::vector){0,-1,0});
  Serial.println(heading);
  delay(1000);
  // subtract the last reading: KenB
    total= total - readings[index];      //  KenB
  // read from the sensor:            // KenB
  readings[index] = (heading);     // KenB
  // add the reading to the total:      // KenB  
  total= total + readings[index];      // KenB
  // advance to the next position in the array:  // KenB
  index = index + 1;                    // KenB

  // if we're at the end of the array... KenB
  if (index >= numReadings)              // KenB
    // ...wrap around to the beginning:  KenB
    index = 0;                          // KenB

  // calculate the average:                 KenB
  average = total / numReadings;        // KenB
  // send it to the computer as ASCII digits  // KenB
  Serial.println(average);        // KenB      
}

many thanks ken

Ive made a slight mod to make it clearer in the display on the serial monitor

and on reexamination of the output it looks like im actually getting the expected out put
the average is matching the heading its just taking some time to update.
Im I missing something here

Hello,

It sounds like you changed something but did not post the updated code. If you want help, you really need to post what the version you are using, and describe precisely what it is doing differently from what you expect.

-Paul

sorry a bout that

heres the updated code Ive made further changes .im using the Arduino version 0022 on arduino uno

ive successfully got a current heading and an average reading with an array which takes about 10 sec to display the up date when i rotate the compass.
which is fine for my needs .taking this further ive declared a second array that contains 60 elements
to get an average over a longer time period
the output to the serial monitor looks like this:
compass heading :
101
average heading : //after movement of the compass about 10 sec after
101

big Average heading : // about 30 sec after it equals compass heading
101
compass heading :
101
avarage heading :
101

big Avarage // about 40 sec after it is greater than compass heading and continues to increment
164

the idea is to have two sampling rates by having two different sized containers but what happens is that
the larger container does not settle at the same heading reading it continues to increment

not sure why or how to proceed

heres the code


#include <Wire.h>
#include <LSM303DLH.h>

LSM303DLH compass;
const int numReadings = 10;  // this value determines the size of the readings array KenB
const int bigReadings = 30;

int readings[numReadings];   // this declares the array to hold the readings from the compass KenB
int bigreadings[bigReadings]; 


int index = 0;                  // the index of the current reading
int bigindex = 0; 
int total = 0;                  // the running total
int bigtotal = 0;  
int average = 0;                  // the average
int bigaverage = 0;  

void setup() {
  Serial.begin(9600);
  // initialize all the readings to 0: KenB
  for (int thisReading = 0; thisReading < numReadings; thisReading++) //KenB
    readings[thisReading] = 0;   //KenB 
//{     
    //for
    //(int bigReading = 0; bigReading < bigReadings; bigReading++)
    
      
     //bigreadings[bigReading] = 0;   //KenB 
    
  Wire.begin();
  compass.enableDefault();
  
  // Calibration values. Use the Calibrate example program to get the values for
  // your compass.
  compass.m_min.x = -520; compass.m_min.y = -570; compass.m_min.z = -770;
  compass.m_max.x = +540; compass.m_max.y = +500; compass.m_max.z = 180;
}
//}
void loop() {
  compass.read();
  int heading = compass.heading((LSM303DLH::vector){0,-1,0});
  Serial.println("heading");
  Serial.println(heading);
  delay(1000);
  
  //.................................
   for
    (int bigReading = 0; bigReading < bigReadings; bigReading++)
    
      
     bigreadings[bigReading] = 0;   //KenB 
  
  
  
  // subtract the last reading: KenB
    total= total - readings[index];        
  // read from the sensor:  
  readings[index] = (heading);
  // add the reading to the total:
  total= total + readings[index];      
  // advance to the next position in the array:  
  index = index + 1;                    

  // if we're at the end of the array...
  if (index >= numReadings)              
    // ...wrap around to the beginning: 
    index = 0;                          

  // calculate the average:
  average = total / numReadings;        
  // send it to the computer as ASCII digits
  Serial.println("av 10 sec"); 
  Serial.println(average);              
  
  //.................................................................
  // subtract the last reading: KenB
    bigtotal= bigtotal - bigreadings[bigindex];        
  // read from the sensor:  
  bigreadings[bigindex] = (heading);
  // add the reading to the total:
  bigtotal= bigtotal + bigreadings[bigindex];      
  // advance to the next position in the array:  
  bigindex = bigindex + 1;                    

  // if we're at the end of the array...
  if (bigindex >= bigReadings)              
    // ...wrap around to the beginning: 
    bigindex = 0;                          

  // calculate the average:
  bigaverage = bigtotal / bigReadings;        
  // send it to the computer as ASCII digits
  Serial.println("big av 30 sec"); 
  Serial.println(bigaverage);              
               
  
  
}

Hello,

It’s really hard to help you, because you are presenting a program that is more complicated than necessary and not telling me exactly what is going wrong.

You should do the following:

  1. Simplify your program by removing every line that is unnecessary to demonstrate the problem. Specifically: remove all commented-out lines of code. If your small average works, remove it. Remove the compass code and replace it with a constant simulated heading of 100. And so on.
  2. If you are still having trouble, post the code again along with the actual output that you get on the serial terminal. Hand-typing something similar to the output is a waste of time and is unlikely to be as useful as the actual output.

-Paul

thanks paul I will do as you suggest
cheers ken