Pages: [1]   Go Down
Author Topic: multiMap() function with 2 data sets - question  (Read 604 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Full Member
***
Karma: 2
Posts: 106
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have a question that has been puzzling me for a while. I have a sensor that can start in 1 of 2 possible positions. Each position will have a different set of values for interpolating an output, using the multiMap() function. Once the loop runs it provides a continuous output of the sensor field, until such time as a button is pressed.
So the question is, how to have 1 piece of code that preselects the correct data arrays and executes, rather than having 2 complete sets of code, each with its own data?
Data arrays in the code are mils[] and anlogin[]
In my code (excuse all the commented print statements, they were for testing), I tried in the main loop to use an if statement based on the value of sampleLow, but the multiMap() function never executes.
I also tried using a SWITCH statement in the fFieldChoice() function and that did not work either.

I know I can add another complete code set with another While statement to the loop(), but wondering what I am doing wrong?
I have left the experimental code commented out, so you can see what I tried.
As-is, the fFieldChoice() only sets the sampleLow and sampleHigh values.
The loop() works as-is but I would have to repeat it to use the other data set if set by sampleLow > 300. There are other conditions to set as well but I need to get something working here first.
Apologies if this is confusing.
Code:
#include <Wire.h>
#include <Adafruit_ADS1015.h>
#include "ST7036.h"
#include "LCD_C0220BiZ.h"

#define CHAR_WIDTH  5
ST7036 lcd = ST7036 ( 2, 16, 0x7C );

Adafruit_ADS1115 ads1115(0x48); // construct an ads1115 at address 0x49
int16_t adc0, adc1, adc2, adc3; 


int _anlogin;
int anlogin;
int _mils;
int adjmilsOutput;
int arraySize;
static int sampleLow = 1024;
static int sampleHigh = 0;
int limitLow;
int limitHigh;
int limitHold;
int milsOutput;
int holdVal;
int swVal;
float metricOutput;

const int numReadings = 50;
int readings[numReadings];      // the readings from the analog input
int index = 0;                  // the index of the current reading
long total = 0;                  // the running total

int rawmilsOutput;
int offSet = 0;
int  sensorReading;
int sensorLevel; // for selecting field size in fFieldChoice
//=============================================================
void fMenu()
{
  Serial.println("This is the Menu Function");

}
//===========================================================================
void setup() {
  // setup serial - diagnostics - port
  Serial.begin(9600);
  ads1115.begin();

  analogReference(INTERNAL);
  pinMode(5, INPUT); // Function Button
  pinMode (6, INPUT); // Left button
  pinMode (7, INPUT); // Right Button
  digitalWrite(A1, HIGH);  // set pullup on analog pin 1
  digitalWrite(A2, HIGH);  // set pullup on analog pin 2
  digitalWrite(A3, HIGH);  // set pullup on analog pin 3
  digitalWrite(A4, HIGH);  // set pullup on analog pin 4
  digitalWrite(A5, HIGH);  // set pullup on analog pin 5

  //welcome message

  Serial.println("Hello");

  Serial.println("Press FUNCTION key to start");

  Serial.println("waiting");
  while (digitalRead (5)== LOW);
  delay (1000);
  fFieldChoice();
  Serial.print("sampleLow=");
  Serial.println(sampleLow);

}
//==============================================================================
void loop()
{
  int anlogin[arraySize];
  int mils[arraySize];

  while (digitalRead (5)== LOW){

    static int holdVal = 1024;

    sensorReading = analogRead(A0);   // Range : 0..1024   
    //Serial.println(sensorReading);


    int adjmilsOutput = map (sensorReading, sampleLow, sampleHigh, limitLow , limitHigh);

    // if (sampleLow < 300){

    //Serial.println("sensorlevel = 1");
    //Serial.println("Big field detected");
    int mils[] = {
      0,    12,  31,  61,  92,   120,  150,  180,  211, 241, 270, 300, 330, 360, 390, 420, 450, 480, 510, 539, 570, 600,  2850          }; //output required
    int anlogin[] = {   
     111  , 134,  183, 262, 334,  391,  445,  489,  531, 564, 591, 616, 639, 659, 676, 692, 706, 718, 728, 738, 747, 755,  858     }; //sampled anlogread
    arraySize = 23;
    limitLow = 111;
    limitHigh = 858;
    limitHold = 755 ;
    /* }
     else
     {
     //  Serial.println("sensorlevel = 2");
     //  Serial.println("Small field detected");
     int mils[] = {
     0,    12,  31,  61,  92,   120,  150,  180,  211, 241, 270, 300, 330, 360, 390, 420, 2300  }; //output required
     int anlogin[] = {
     593,  613,  638, 671, 697,  718,  736,  750,  763, 773, 783, 790, 797, 803, 808, 813,  858 }; //sampled anlogread
     arraySize = 17;
     limitLow = 593;
     limitHigh = 858;
     limitHold = 813;
     }*/
    int milsOutputA = multiMap(adjmilsOutput, anlogin, mils, arraySize);

    Serial.println(milsOutputA);


  }
  fMenu();
}
//===============================================================================
void fCalibrate()
{
  Serial.println("This is the Calibrate Function");

}
//=================================================================================
int multiMap(int adjmilsOutput, int* _anlogin, int* _mils, uint8_t size)
{
  // Serial.println("MultiMap");
  // take care the value is within range
  adjmilsOutput = constrain(adjmilsOutput, _anlogin[0], _anlogin[size-1]);
  // Serial.println(_anlogin[0]);
  if (adjmilsOutput <= _anlogin[0]) return _mils[0];
  //Serial.println("MultiMap2");
  if (adjmilsOutput >= _anlogin[size-1]) return _mils[size-1];
  // Serial.println("MultiMap3");
  // search right interval
  uint8_t pos = 1;  // _in[0] allready tested
  // Serial.println("MultiMap4");
  while(adjmilsOutput > _anlogin[pos]) pos++;
  // Serial.println("MultiMap5");
  // this will handle all exact "points" in the _in array
  if (adjmilsOutput == _anlogin[pos]) return _mils[pos];
  // Serial.println(adjmilsOutput);
  // Serial.println(_anlogin[pos]);
  // interpolate in the right segment for the rest
  return map(adjmilsOutput, _anlogin[pos-1], _anlogin[pos], _mils[pos-1], _mils[pos]);

}
//=================================================================================

//=================================================================================
void fFieldChoice()
{
  // int arraySize;
  //int sampleLow = 1024;
  //int sampleHigh = 0;
  Serial.println("This is the FieldChoice Function");
  delay (200);
  Serial.println("Position sensor and press Function");
  while (digitalRead (5) == LOW);
  Serial.println("Please Wait");
  // measure sensor
  for (int i=0; i<100; i++) {
 
    sensorReading = analogRead(A0);   // Range : 0..1024
    sampleLow = min(sampleLow, sensorReading);
  }
  /*
  //Set up Switch Statement in fFieldChoice.
   if(sensorReading < 3000) {
   sensorLevel = 1;
   }
   else
   {
   sensorLevel = 2;
   }
   
   switch (sensorLevel) {
   case 1:
   {
   Serial.println("sensorlevel = 1");
   Serial.println("Big field detected");
   int mils[] = {
   0,    12,  31,  61,  92,   120,  150,  180,  211, 241, 270, 300, 330, 360, 390, 420, 450, 480, 510, 539, 570, 600,  2850            }; //output required
   int anlogin[] = {   
   111  , 134,  183, 262, 334,  391,  445,  489,  531, 564, 591, 616, 639, 659, 676, 692, 706, 718, 728, 738, 747, 755,  858      }; //sampled anlogread
   arraySize = 23;
   limitLow = 111;
   limitHigh = 858;
   limitHold = 755;
   delay (2000);
   break;
   }
   case 2:
   {
   Serial.println("sensorlevel = 2");
   Serial.println("Small field deteted");
   int mils[] = {
   0,    12,  31,  61,  92,   120,  150,  180,  211, 241, 270, 300, 330, 360, 390, 420, 2300            }; //output required
   int anlogin[] = {
   593,  613,  638, 671, 697,  718,  736,  750,  763, 773, 783, 790, 797, 803, 808, 813,  858        }; //sampled anlogread
   arraySize = 17;
   limitLow = 593;
   limitHigh = 858;
   limitHold = 813;
   delay (2000);
   
   break;
   
   }
   }
   Serial.println("This is end of Switch Function");
   
   */
delay(200);
  Serial.println("Remove sensor and press Function");
  while (digitalRead (5) == LOW);
  Serial.println("Please Wait");
  // measure no sensor
  for (int i=0; i<100; i++) {
 
    sensorReading = analogRead(A0);   // Range : 0..1024
    sampleHigh = max(sampleHigh, sensorReading);
   
  }
  delay(100);
}
//==================================================================================
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 636
Posts: 50279
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Define mils and anlogin as pointers to arrays. In the if/else blocks, change what they point to (to point to arrays mils1 and anlogin1 or mils2 and anlogin2, for instance).
Logged

East Anglia (UK)
Offline Offline
Faraday Member
**
Karma: 118
Posts: 4335
May all of your blinks be without delay()
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Not an answer to your question, Paul has already done that, but the first thing that I would do is to declare the 4 arrays required as global to take them out of the loop() function.  This will make your code much easier to read.
Logged

Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Offline Offline
Full Member
***
Karma: 2
Posts: 106
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks, So I was dreading that option because I barely understand pointers right now and pointers to arrays are even more confusing.
If I understand correctly the declaration int mils[] = { is already an address pointer correct?
I tried to change the multiMap call to
Code:
int milsOutputA = multiMap(adjmilsOutput, &anlogin, &mils, 17);
but that produces an error. In the multiMap function there are references to anlogin and _anlogin which I dont understand.

Any help is appreciated.
Logged

East Anglia (UK)
Offline Offline
Faraday Member
**
Karma: 118
Posts: 4335
May all of your blinks be without delay()
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
In the multiMap function there are references to anlogin and _anlogin
Do you mean in the library files ?  If so, such duplication of variable names with a slight variation is usually because there is a version of the variable that is private to the class in the library and is held for each instance of the class and a second version that is a reference to a variable passed from the calling program.
Logged

Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Offline Offline
Full Member
***
Karma: 2
Posts: 106
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

No, I meant that in the void multiMap() function it references several times int* _anlogin and int* _mils although the arrays are int anlogin[] = { and int mils[] = {
In any case I guess I just dont understand how to do what you suggested, changing them to pointers and then how to insert the calls into the if statements.
If  you wouldnt mind an example, it would be appreciated.
I am trying to understand pointers and have not quite grasped it at this level yet.

Many Thanks
Logged

Seattle, WA USA
Online Online
Brattain Member
*****
Karma: 636
Posts: 50279
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
No, I meant that in the void multiMap() function it references several times int* _anlogin and int* _mils although the arrays are int anlogin[] = { and int mils[] = {
Inside the multiMap() function, the arguments are pointers to the arrays that you passed in, when you made the call.

You could have:
Code:
int anloginOne[] = { 1, 3, 5, 7 };
int millisOne[] = { 2, 4, 6, 8};

int anloginTwo = {100, 200, 300, 400};
int millosTwo = {10, 30, 50, 70};

int *millis = NULL;;
int *anlogin = NULL;

Then, somewhere in your code, you could have:
Code:
if(someCondition)
{
   millis = millisOne;
   anlogin = anloginOne;
}
else
{
   millis = millisTwo;
   anlogin = anloginTwo;
}

Finally, you'd simply call miltiMap() with millis and anlogin. They are pointers, just like the arguments in the function.

Alternatively, you could call multiMap() with anliginOne or anloginTwo and millisOne or millisTwo. There is, as you've seen, very close relationship between pointers and array.
Logged

Pages: [1]   Go Up
Jump to: