Show Posts
Pages: 1 2 [3] 4 5 ... 8
31  Using Arduino / Programming Questions / small function() eats up RAM on: April 06, 2013, 01:28:03 am
I wrote a small function that seems simple. It simply adds an offset value each time a button is pressed. I have 2 buttons, one for increment and 1 for decrement. When the function is called, it displays the current offset (default 0) and then either increments or decrements the global variable offset by 1. this global variable is then simply added to my sensor output reading. When a third button is pressed, it returns to the loop which is constantly printing the sensor value.

Problem is the sketch hangs after executing this function a few times. I have optimised the memory usage by using the Flash library http://arduiniana.org/libraries/flash/ for most strings which is why the print statements may look strange but it works really well.  I used a memory check utility http://jeelabs.org/2011/05/22/atmega-memory-use/
This utility confirms, when my sketch is running, it reports free ram is about 1K (Atmega 328p). Each time the function is run, the memory drops by 200 - 300 bytes, so after 4 or 5 times the sketch hangs.
The answer is probably staring me in the face but the function seems so simple.

Code:
void fCalibrate()
{

  lcd.clear ();
  lcd.setCursor(0, 0);
  adjOffset_msg.print(lcd);   
  lcd.setCursor(1, 0);
    adjOffset_msg_inst.print(lcd);

  do{
 
    if (digitalRead (6) == HIGH)
    {
      offSet = offSet -1;
      lcd.clear ();
      lcd.setCursor(0, 0);
      offsetCurrent_msg.print(lcd);
      lcd.print(offSet);
      lcd.setCursor(1, 0);
       offsetAdj_msg_func.print(lcd);

      delay (500);
    }
    if (digitalRead (7) == HIGH)
    {
      offSet = offSet +1;
      lcd.clear ();
      lcd.setCursor(0, 0);
      offsetCurrent_msg.print(lcd);
      lcd.print(offSet);
      lcd.setCursor(1, 0);
      offsetAdj_msg_func.print(lcd);
      delay (500);
    }

  }
  while (digitalRead (5) == LOW);
  lcd.clear ();
  lcd.setCursor(0, 0);
  starting_msg.print(lcd);
  lcd.setCursor(1, 0);
  measurement_msg.print(lcd);


  delay (1000);
  return;
}
32  Using Arduino / Programming Questions / Does the use of EEPROM free up RAM? on: April 05, 2013, 09:41:56 am
I have a sketch that seems to be running out of RAM using a Atmega 328p, as I have quite a few LCD Print and Serial.Print requirements. There are a few variables that would be useful to be stored in EEPROM so that they are remembered after power off, but my question is that there is 1k EEPROM available which is not being used. If I write a few variables to EEPRON, does this actually free up the same amount of RAM? Or will a susequent amount of RAM now be used in the access of those EEPROM variables?

Can I store text strings used in LCD Print and Serial.print in EEPROM and what are the consequences?
Thanks
33  Using Arduino / Programming Questions / Re: multiMap() function with 2 data sets - question on: April 04, 2013, 03:28:13 pm
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
34  Using Arduino / Programming Questions / Re: multiMap() function with 2 data sets - question on: April 04, 2013, 12:25:32 pm
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.
35  Using Arduino / Programming Questions / Re: Not Displaying decimal information on: April 03, 2013, 10:42:12 pm
He just told you. You need to use float and not int.
36  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);
}
//==================================================================================
37  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.
38  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.
39  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.
40  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?
41  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.
42  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;
   }
}
//==================================================================================
43  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.
44  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.
45  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.
Pages: 1 2 [3] 4 5 ... 8