Show Posts
Pages: 1 2 [3] 4 5 ... 7
31  Using Arduino / Programming Questions / multiMap() function with 2 data sets - question on: April 03, 2013, 10:37:32 pm
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);
}
//==================================================================================
32  Using Arduino / Programming Questions / Re: ADS1114 convert bi-directional output to positive on: April 03, 2013, 01:56:08 pm
Yup, connecting A1 to GND now gives me a 4000 - 29000 count range for my 0.3 -1.4v input which is the expected 15-bits. This is good for me.
Thanks for your pointers.
Much appreciated.
33  Using Arduino / Programming Questions / Re: ADS1114 convert bi-directional output to positive on: April 01, 2013, 11:32:53 pm
Hmm something must be wrong then, because according to the adafruit library, the default mode is single shot, and my input is only to A0 and GND, so I am not using the differential, and my input range measured with a DVM is +0.3 to +1.4v, but I am getting a -6000 to +6000 output.
Maybe I misunderstand you.
34  Using Arduino / Programming Questions / Re: ADS1114 convert bi-directional output to positive on: April 01, 2013, 09:33:23 am
Great, Thanks
I think the problem with Mapping is that the beginning and end values are not always the same from sensor to sensor.
35  Using Arduino / Programming Questions / ADS1114 convert bi-directional output to positive on: March 31, 2013, 11:53:17 pm
Hi. Another question in my quest to learn.
I am using an ADS1114 16 bit a/d converter and the Adafruit ADS1115 library
https://github.com/adafruit/Adafruit_ADS1X15
although I suppose this is common with many ADC's.
My sensor has a total output from 0.3v to 1.4v so only approx 1v full scale.
The ads1114 is giving me approximately -6000 to 6000 as an output which is about right I guess, 12000 counts for a 1v input.

My question is how do convert the input into a positive ONLY value in the most efficient way for processing time. I know i could just add 7000 to the value and always have it positive but I am sure there is a more efficient way done by the pro's?
36  Using Arduino / Programming Questions / Re: AttachInterrupt? issues on: March 30, 2013, 11:06:35 pm
Thank you John.
Thats what I suspected. So to confirm, the only way to return to a Menu type function that will need to display options and accept inputs will be like what I have done in the main loop() ?
minus the delays of course, those are mainly just for testing the structure.
37  Using Arduino / Programming Questions / AttachInterrupt? issues on: March 30, 2013, 07:14:29 pm
I am setting up the structure for a new application and trying to use the hardware interrupt, but I must be misunderstanding the use case or something else. Basically, after a welcome message the device will detect the sensor filed size and start reading the sensor continuously which it does. I want to use a button to interrupt this and go to a Menu function that may offer choices like calibrate etc.
I can do this with a While statement as shown and it works but this means it polls the button every loop.
If I hit the Interrupt button, everything stops and it just hangs.
I have read that there can be no Print or delays in the interrupt which I removed.
Right now the fMenu() function only calls another function just for testing.
Any help appreciated.
Code:
int  sensorReading;

int sensorLevel;
void fMenu()
{
  // Serial.println("This is the Menu Function");
  //delay (200);
  //Serial.println("waiting");
  // while (digitalRead (5)== HIGH);
  //delay (1000);
  fFieldChoice();
 
}
//===========================================================================
void setup() {
  // setup serial - diagnostics - port
  Serial.begin(9600);
  analogReference(INTERNAL);
  pinMode(5, INPUT);
  pinMode (6, INPUT);
 
  // measure sensor
 for (int i=0; i<10; i++) {
  sensorReading = analogRead(A0);   // Range : 0..1024
 }
 // Button on pin 2, Int0
attachInterrupt(0, fMenu, RISING);

//welcome message

  Serial.println("Hello");
  //Set up Switch Statement in fFieldChoice.
  if(sensorReading < 299) {sensorLevel = 1;}
  else
  {sensorLevel = 2;}
  Serial.println("Press FUNCTION key to start");

  Serial.println("waiting");
  while (digitalRead (5)== LOW);
  delay (1000);
  fFieldChoice();
  }
//==============================================================================
void loop()
{
  while (digitalRead (6)== LOW){
   sensorReading = analogRead(A0);   // Range : 0..1024   
   Serial.println(sensorReading);
   delay(100);
   }
  fMenu();
}
//===============================================================================
void fCalibrate()
{
   Serial.println("This is the Calibrate Function");
   delay (200);
   
}
//=================================================================================
void MultiMap()
{
    Serial.println("This is the MultiMap Function");
    delay(200);
}
//=================================================================================

//=================================================================================
void fFieldChoice()
{
   Serial.println("This is the FieldChoice Function");
   delay (200);
   
   switch (sensorLevel) {
     case 1:
       Serial.println("sensorlevel = 1");
       Serial.println("Big field detected");
       delay (2000);
       break;
     case 2:
       Serial.println("sensorlevel = 2");
       Serial.println("Small field deteted");
       delay (2000);
       break;
   }
}
//==================================================================================
38  Using Arduino / Networking, Protocols, and Devices / Re: Another I2C question on: March 05, 2013, 10:40:19 pm
I would like to but the sensor is unstable below 4v.
39  Using Arduino / Networking, Protocols, and Devices / Re: Another I2C question on: March 05, 2013, 09:45:59 pm
Thank you. That was going to be my next question. Although the sensor is powered off 5v, the output is only between 0 and 2.5v.
Before using the ADS I was using the internal 1.1v reference to improve reolution a little.
So in this case I would power both off the 3.3V rail? The Atmega328 is still using 5v so that is ok, correct?

Thanks again for your time and input.
40  Using Arduino / Networking, Protocols, and Devices / Another I2C question on: March 05, 2013, 05:00:51 pm
I have 2 devices that will use the I2C bus talking to an UNO. I understand that I need 1 set of Pullup resistors between the SDA/SCL lines and VCC.
My problem is the 2 devices have different supply voltages. One is an LCD display that only has 3.3v supply and the other is ADS1114 A-D converter that will read a sensor powered off 5v, so I intended to use a 5V supply for this part.
Can these 2 communicate on the same I2C bus?
Where do I connect the pullup resistors to? 5v or 3.3v?

Any help would be appreciated.
41  Using Arduino / Networking, Protocols, and Devices / Re: I2C help needed on: March 04, 2013, 02:09:17 am
Thanks Nick.
As usual you are such an asset to this forum.
So it seems my output must be correct then. It sure seems correct as I rotate the magnet.
Does your I2C Scanner find your device?
42  Using Arduino / Networking, Protocols, and Devices / Re: I2C help needed on: March 04, 2013, 01:17:39 am

Quote
So I gather you are getting valid readings, and your question is "why am I getting valid readings?"

Hi Nick. Yes exactly. At least it appears i am getting valid readings. I just dont understand that if the data is contained in 254 and 255, why it only works when I call 255? I am not calling 254 at all but it seems to be getting the data from it.

Here is the HEX output with the bits shifted 6
0, E
0, 34
1, 6C
3, C7
3, F8
5, 153
6, 1B6
9, 242
C, 312
F, 3DD
12, 483
15, 543
16, 5A1
17, 5D6
1A, 699
1B, 6F7
1F, 7C9
23, 8D4
25, 964
28, A29
2A, AA7
2D, B7C
33, CCC
35, D70
39, E46
3D, F4E
41, 1065
45, 1144
4A, 1292
4E, 139F
55, 1575
5E, 17BF
63, 18CA
6C, 1B06
72, 1C93
78, 1E2B
78, 1E2B
78, 1E17
82, 2083
8D, 2378
96, 259B
A1, 2844
AA, 2A82
B0, 2C00
B5, 2D58
BD, 2F40
C8, 322F
D4, 3518
E1, 386C
ED, 3B4A
F3, 3CD7
F4, 3D10
F4, 3D0E
F9, 3E4D
'
Here is the decimal output
0, 18
2, 130
8, 522
15, 975
24, 1582
34, 2237
45, 2936
58, 3723
72, 4640
89, 5730
98, 6315
112, 7223
128, 8231
132, 8470
132, 8471
139, 8936
153, 9849
170, 10894
181, 11597
190, 12190
200, 12846
215, 13766
225, 14435
228, 14642
233, 14968
240, 15399
247, 15836
251, 16116
255, 16347

with this code
Code:
#include <Wire.h>

void setup()
{
  Wire.begin();                // join i2c bus (address optional for master)
  Serial.begin(9600);          // start serial communication at 9600bps
}

unsigned int reading = 0;
int reading1 = 0;
void loop()
{
 
 Wire.beginTransmission(66); // transmit to device #66
 Wire.write(byte(255));      // sets register pointer to echo #1 register
 Wire.endTransmission();      // stop transmitting

  // step 4: request reading from sensor
  Wire.requestFrom(66, 2);    // request 2 bytes from slave device #112

  // step 5: receive reading from sensor
  if(2 <= Wire.available())    // if two bytes were received
  {
    reading = Wire.read();  // receive high byte (overwrites previous reading)
    Serial.print(reading);   // print the reading
    Serial.print(", ");
    reading = reading << 6;    // shift high byte to be high 8 bits
    reading |= Wire.read(); // receive low byte as lower 8 bits
    Serial.println(reading);   // print the reading
  }

  delay(300);                  // wait a bit since people have to read the output :)
}
43  Using Arduino / Networking, Protocols, and Devices / Re: I2C help needed on: March 04, 2013, 12:57:00 am

Code:
You may need to be shifting the first byte you read by 8 bits,  not 6 bits,
If i do that then the output goes to 16-bit (0 - 65535) which is clearly incorrect.

Code:
I'm a bit confused about the relationship between the numbers 66 and 112.
As I said above, the 112 is part of the comments from the arduino code example, I changed the address to 66
44  Using Arduino / Networking, Protocols, and Devices / Re: I2C help needed on: March 04, 2013, 12:31:01 am
I really do not know, All i can tell you is that it says not found. If I try the scanner with an LCD I have i see it operates correctly and finds the LCD Address.
On the data sheet is says you can program the address but it only allows 1 time. I have not done this as yet so is it possible that it will not answer an inquiry (Whatever the scanner is sending) but will respond to a write command if the correct default address is used?
45  Using Arduino / Networking, Protocols, and Devices / Re: I2C help needed on: March 03, 2013, 03:24:38 pm
Quote
Is it 66 or 112?
Sorry, the comments were from original code. It is 66 that can communicate with. I have the manual bits set to A1=0 and A2 = 1 so according to the data sheet the defalt address is 10000 plus A2 A1 which is 1000010 = 66 and this works.
I tried the I2C scanner but it does not find any device.

Quote
The datasheet doesn't show the ability to do sequential reads.  I would read the two registers separately:
When I try that code, it seems to be random data that doesnt change logically when I rotate the device.
3543
407
2826
2425
2930
2610
2482
2610
3183
1571
1630
990
1758
1306
656
716
2827
2186
767
53
3891
3699
3571
807
1058
801
736
601
538
730
794
602
538

Using my posted code I get good data smoothly changing as i rotate the device
14
74
76
75
220
579
801
1160
1473
1691
2005
2256
2427
2663
2832
3024
3251
3520
4038
4303
4624
4914
5220
5922
6707
7407
7946
8529
9568
10686
11401
12014
12632
12637
12640
12718
13130
13520
14093
14244
14463
14802
14697
14698
I am just trying to understand why I only get this result when reading register 255 with 2 bytes? How does it get the readings from 254 in there.
Pages: 1 2 [3] 4 5 ... 7