Show Posts
Pages: 1 [2] 3 4 ... 7
16  Using Arduino / General Electronics / Using LM317 in CONSTANT CURRENT mode to power board? on: November 06, 2013, 03:31:26 pm
I have an Uno based circuit with Atmega 328P. Currently the board is powered by 9v through a LM2940CT-5 regulator. I have a sensor connected to A0 and the sensor is powered by the same 5V supply. Using internal 1.1V reference for A0.
I have some drift in the sensor output related to ambient temperature, and it is suggested that one way to minimize this is to use constant current supply to the sensor instead of voltage.

The sensor supply current is 11mA. i could use a LM334 inserted to the supply of the sensor only but i was thinking of replacing the board regulator with an LM317 in constant current mode. This would mean the entire board including processor, Sensor and LCD is being supplied by this constant current regulator. Is this a BAD idea? I am assuming I will measure the current that the entire setup draws right now and then configure the LM317 to output the same current?

Any help would be appreciated.
17  Using Arduino / Microcontrollers / Burn bootloader before setting fuses? on: June 20, 2013, 09:48:54 am
I am using Atmel studio 6.1 and the Avrisp MkII to burn Atmega 328P with Optiboot bootloader. My question is, does it matter if you set the fuses before or after burning the bootloader? The Atmel studio is set to erase device before programming, does this clear the fuse settings?
I use the following fuse settings. L=0XFF H=0XDE Ex=0X05 Lock=0X0F
However, after setting the fuses, if I exit the fuse settings page an return again, the Low and High are correct but the Extended has changed to 0XFD? Also the lockbit has changed to 0XFF?
If I burn the bootloader first and then set the fuses and lockbits, after exiting and reading fuses again fuses are as above but the lock bit reads 0XCF. Why would these change?
I have had a few occasions where after a few days my arduino sketch mysteriously gets corrupted and I have to reload it. I was wondering if it had anything to do with the order of burning bootloader and setting fuses.
I guess that is a few questions.
Any help is appreciated.
18  Community / Products and Services / Re: Send Arduino data to Iphone -HID - Magic MonitorX on: June 03, 2013, 11:17:41 pm
It is only to read right now.
19  Development / Other Hardware Development / My Latest design - UNO-ish with LCD - Share on: April 18, 2013, 10:18:34 pm
This is my latest design roughly based on an Uno...Well at least as far as the Atmega328P. It iuses a FT231X for USB. I have added an ADS1114 16bit A/D Converter to A0 which is selectable via jumper so you can bypass it if needed. A1 and A2 are available. D2 - D6 have a Schmitt Trigger debounce circuit added for button inputs or in my case the keypad. D7 - D12 are available. The USB input is via Mini-B which can power the board and there is a 3.5mm Stereo socket which connects to A0/16 Bit A/D input or you can solder directly to the header..
The regulator is a beefy LM2940 and the board can be set for 5v or 3.3v use by a jumper and changing the regulator and crystal, both through hole.
The LCD mounts directly to the back of the board so no wiring needed (Newhaven NHD-C0216CiZ-FSW-FBW-3V3) COG 16 x 2 Character .
Both the LCD and the A/D are I2C leaving most inputs free.
The power switch is a slide switch and no other wiring except for the DC input.
For a single analog sensor USB application, the board can actually be sliced at the line which leaves a totally functioning USB powered board.

Although this board is for a specific application, I may have a few extras if someone has a short run project that can use it. I also have some of the keypads available if your project can use them. Its not the cheapest game in town but solves a lot of design time and wiring.

Contact me if interested.
Thanks
20  Using Arduino / Programming Questions / Re: PROGMEM usage on: April 08, 2013, 12:05:09 am
May not be relevant to you but I had much more success using the Flash library http://arduiniana.org/libraries/flash/
It was easy to implement and took me just 1 day to stuff all my strings into flash memory rather than Ram. Works like a charm.
21  Using Arduino / Programming Questions / Re: small function() eats up RAM on: April 06, 2013, 04:54:57 pm
Presto!
I solved it. It seems using the global variable in the fCalibrate function was the issue. Making the function pass the value of a local variable adjusted by the buttons back to the calling function has solved the memory drain.
The explanation why? is up to you pro's.  smiley
22  Using Arduino / Programming Questions / Re: small function() eats up RAM on: April 06, 2013, 03:53:15 pm
last part
Code:
void fCalibrate()
{
  delay (400);
  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;
}
//=================================================================================
int multiMap(int adjmilsOutput, int* _anlogin, int* _mils, uint8_t size)
{

  // take care the value is within range
  adjmilsOutput = constrain(adjmilsOutput, _anlogin[0], _anlogin[size-1]);

  if (adjmilsOutput <= _anlogin[0]) return _mils[0];

  if (adjmilsOutput >= _anlogin[size-1]) return _mils[size-1];

  // search right interval
  uint8_t pos = 1;  // _in[0] allready tested

  while(adjmilsOutput > _anlogin[pos]) pos++;

  // this will handle all exact "points" in the _in array
  if (adjmilsOutput == _anlogin[pos]) return _mils[pos];

  // interpolate in the right segment for the rest
  return map(adjmilsOutput, _anlogin[pos-1], _anlogin[pos], _mils[pos-1], _mils[pos]);

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

//=================================================================================
void fFieldChoice()
{
  sampleLow = 31000;
  sampleHigh = 0;

  lcd.setCursor(0, 0);
  attach_msg.print(lcd);
  lcd.setCursor(1, 0);
  function_msg.print(lcd);

  while (digitalRead (5) == LOW);

  // measure sensor
  for (int i=0; i<100; i++) {
    adc0 = ads1115.readADC_SingleEnded(0);
    sensorReading = adc0;
    sampleLow = min(sampleLow, sensorReading);
  }

  lcd.setCursor(0, 0);
  remove_msg.print(lcd);

  while (digitalRead (5) == LOW);

  // measure sensor
  for (int i=0; i<100; i++) {
    adc0 = ads1115.readADC_SingleEnded(0);
    sensorReading = adc0;
    sampleHigh = max(sampleHigh, sensorReading);
  }

  if ((sampleHigh - sampleLow) <= 3000)
  {
    lcd.setCursor(1, 0);
    lcd.clear ();
    lcd.setCursor(0, 0);
    calibration_msg.print(lcd);
    lcd.setCursor(1, 0);
    failed_msg.print(lcd);
    delay (2000);
    fFieldChoice(); 
    loop();
  }
  else{

    lcd.clear ();
    lcd.setCursor(0, 0);
    calibration_msg.print(lcd);
    lcd.setCursor(1, 0);
    succeed_msg.print(lcd);

    delay (2000);

    if (sampleLow <= 6000)
    { 
      bigBall_msg.print(Serial);
      detected_msg.print(Serial);

      lcd.clear ();
      lcd.setCursor(0, 0);
      bigBall_msg.print(lcd);
      lcd.setCursor(1, 0);
      detected_msg.print(lcd);
      delay (2000);
    } 
    else{
      smallBall_msg.print(Serial);
      detected_msg.print(Serial);

      lcd.clear ();
      lcd.setCursor(0, 0);
      smallBall_msg.print(lcd);
      lcd.setCursor(1, 0);
      detected_msg.print(lcd);
      delay (2000);
    }

    lcd.clear ();
    lcd.setCursor(0, 0);
    replaceBall_msg.print(lcd);
    lcd.setCursor(1, 0);
    function_msg.print(lcd);
  }   

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

}
23  Using Arduino / Programming Questions / Re: small function() eats up RAM on: April 06, 2013, 03:52:37 pm
2nd part
Code:
void loop()
{
  while (sampleLow < 8000){
    while (digitalRead (5)== LOW){

      Serial.println("\n[memCheck]");
      Serial.println(freeRam());

#define arraySize 23
#define limitLow 3700
#define limitHigh 29252
#define limitHold 25615
      //read sensor
      static int holdVal = 31000;
      adc0 = ads1115.readADC_SingleEnded(0);
      sensorReading = adc0;

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

      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[] = {   
        3700,  4330,  6400, 9400, 11440,  13375,  15300,  16620, 17940, 19185, 20000, 20935, 21725, 22375, 23000, 23500,  24000, 24427, 24833, 25205, 25515, 25615, 29252                              }; //sampled anlogread


      int milsOutputA = multiMap(adjmilsOutput, anlogin, mils, arraySize);
      // subtract the last reading:
      total= total - readings[index];         
      // read from the sensor: 
      readings[index] = milsOutputA;
      // add the reading to the total:
      total= total + readings[index];       
      // advance to the next position in the array: 
      index = index + 1;   
      //     Serial.println("total=");
      // if we're at the end of the array...
      if (index >= numReadings)             
        // ...wrap around to the beginning:
        index = 0;                           

      // calculate the average:
      milsOutput = (total / numReadings)+offSet;         

      int swVal = analogRead(A1);  // hold switch on A1

        if(swVal <=250) {       // hold position

        holdVal = min(holdVal,milsOutput);   // the smallest mil value is locked in
      }

      if (swVal >=250) {      // toggled to unhold position
        holdVal = 31000;
      }
      if (holdVal <= milsOutput) {
        milsOutput = holdVal;
      }

      metricOutput = (milsOutput*25.4)/1000;  // convert to milsOutput

      if (adjmilsOutput  > limitHold   )  {
        lcd.clear();
        lcd.setCursor(0, 0);
        range_msg.print(lcd);
        lcd.setCursor(1, 0);
        range_asterisk_msg.print(lcd);
        range_msg_serial.print(Serial);
        delay (200);
      }
      else {
        lcd.setCursor(0, 0);
        if (swVal <=250) {
          lcd.clear();
          delay(10);
          lcd.print("H");
          lcd.print(milsOutput);
          lcd.print(" mil  "); 
          lcd.setCursor(1, 0);
          lcd.print(" ");
          lcd.print(metricOutput);
          lcd.print(" mm ");

          Serial.print("H");
          Serial.print("M");
          Serial.print(metricOutput);
          Serial.print("|");
          Serial.print("I");
          Serial.println(milsOutput);
          //delay(150);

        }

        else    {
          lcd.clear();
          delay(10);
          lcd.setCursor(0, 0);
          lcd.print(" ");
          lcd.print(milsOutput);
          lcd.print(" mil   ");
          lcd.setCursor(1, 0);

          lcd.print(" ");
          lcd.print(metricOutput);
          lcd.print(" mm ");
          //delay(150);
          Serial.print("M");
          Serial.print(metricOutput);
          Serial.print("|");
          Serial.print("I");
          Serial.println(milsOutput);
          // delay(50);
        }

      }
    }
    fMenu();
  }

  while (sampleLow > 8000  ){

    while (digitalRead (5)== LOW){
#define arraySize2 17
#define limitLow2 12800
#define limitHigh2 29252
#define limitHold2 25935

      //Read Sensor
      static int holdVal = 31000;
      adc0 = ads1115.readADC_SingleEnded(0);
      sensorReading = adc0;

      int adjmilsOutput = map (sensorReading, sampleLow, sampleHigh, limitLow2 , limitHigh2);

      int mils[] = {
        0,    12,        31,    61,     92,    120,    150,    180,   211,   241,   270,   300,   330,   360,   390,   420,    2300                               }; //output required
      int anlogin[] = {
        12800,  13740,  15690, 17350, 19028,  20175,  21175,  22083, 22810, 23540, 24000, 24540, 24950, 25320, 25650, 25935,  29252                              }; //sampled anlogread

      int milsOutputA = multiMap(adjmilsOutput, anlogin, mils, arraySize2);

      // subtract the last reading:
      total= total - readings[index];         
      // read from the sensor: 
      readings[index] = milsOutputA;
      // 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:
      milsOutput = (total / numReadings)+offSet;         

      int swVal = analogRead(A1);  // hold switch on digital 7

      if(swVal <=250) {       // hold position

        holdVal = min(holdVal,milsOutput);   // the smallest mil value is locked in
      }

      if (swVal >=250) {      // toggled to unhold position
        holdVal = 31000;
      }
      if (holdVal <= milsOutput) {
        milsOutput = holdVal;
      }

      metricOutput = (milsOutput*25.4)/1000;  // convert to milsOutput

      if (adjmilsOutput  > limitHold2   )  {
        lcd.clear();
        delay(10);
        lcd.setCursor(0, 0);
        range_msg.print(lcd);
        lcd.setCursor(1, 0);
        range_asterisk_msg.print(lcd);
        range_msg_serial.print(Serial);
        delay (200);
      }
      else {
        lcd.clear();
        delay(10);
        lcd.setCursor(0, 0);
        if (swVal <=250) {
          lcd.print("H");
          lcd.print(milsOutput);
          lcd.print(" mil  "); 
          lcd.setCursor(1, 0);
          lcd.print(" ");
          lcd.print(metricOutput);
          lcd.print(" mm ");

          Serial.print("H");
          Serial.print("M");
          Serial.print(metricOutput);
          Serial.print("|");
          Serial.print("I");
          Serial.println(milsOutput);
          //delay(150);
        }

        else    {
          lcd.clear();
          delay(10);
          lcd.setCursor(0, 0);
          lcd.print(" ");
          lcd.print(milsOutput);
          lcd.print(" mil   ");
          lcd.setCursor(1, 0);
          lcd.print(" ");
          lcd.print(metricOutput);
          lcd.print(" mm ");
          //delay(150);
          Serial.print("M");
          Serial.print(metricOutput);
          Serial.print("|");
          Serial.print("I");
          Serial.println(milsOutput);
          // delay(50);
        }
      }
    }
    fMenu();
  }
}
//
24  Using Arduino / Programming Questions / Re: small function() eats up RAM on: April 06, 2013, 03:51:30 pm
Code:
here is the first bit.
[code#include <Wire.h>
#include <Adafruit_ADS1015.h>
#include "ST7036.h"
#include "LCD_C0220BiZ.h"
#include <Flash.h>

FLASH_STRING(start_msg, "  Hello  \n");
FLASH_STRING(function_msg, " Press FUNCTION \n");
FLASH_STRING(adjOffset_msg, " Adjust  Offset \n");
FLASH_STRING(adjOffset_msg_inst, "<2 Dec--Inc 4>");
FLASH_STRING(offsetCurrent_msg, "Offset = ");
FLASH_STRING(offsetAdj_msg_func, "< 2--4 > or FUNC");
FLASH_STRING(starting_msg, "   Starting   \n");
FLASH_STRING(measurement_msg, "  Measurement  \n");
FLASH_STRING(attach_msg, "Attach  Sensor\n");
FLASH_STRING(remove_msg, "Remove  Sensor\n");
FLASH_STRING(wait_msg, "  Please  Wait  \n");
FLASH_STRING(calibration_msg, "  Calibration   \n");
FLASH_STRING(succeed_msg, "   Succeeded    \n");
FLASH_STRING(replaceBall_msg, "Replace Sensor\n");
FLASH_STRING(range_msg, " Out of Range ! \n");
FLASH_STRING(range_msg_serial, "$ Out of Range ! \n");
FLASH_STRING(range_asterisk_msg, "****************\n");
FLASH_STRING(failed_msg, "    Failed      \n");
FLASH_STRING(press2_msg, "Press < 2 Offset\n");
FLASH_STRING(press4_msg, "> 4 Re-Calibrate\n");
FLASH_STRING(smallBall_msg, " Small Sense \n");
FLASH_STRING(bigBall_msg, "  Big Sense  \n");
FLASH_STRING(detected_msg, "    Detected    \n");

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

Adafruit_ADS1115 ads1115(0x48); // construct an ads1115 at address 0x49
int16_t adc0; 

unsigned int adjmilsOutput;

static int sampleLow = 31000;
static int sampleHigh = 0;

int milsOutput;
unsigned int holdVal;
unsigned 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
unsigned long total = 0;                  // the running total

int offSet = 0;
int  sensorReading;

//=============================================================
void fMenu()
{
  lcd.clear ();
  lcd.setCursor(0, 0);
  press2_msg.print(lcd);
  lcd.setCursor(1, 0);
  press4_msg.print(lcd);

  delay (200);

  while (digitalRead (6)== LOW && digitalRead (7) == LOW);
  if (digitalRead (6) == HIGH)
  {
    fCalibrate();
  }
  if (digitalRead (7) == HIGH)
  {
    fFieldChoice();
  }
  delay (1000);
  loop();

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



  lcd.init ();
  delay(250);
  lcd.setContrast(1);

  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
  start_msg.print(Serial);

  lcd.setCursor(0, 0);
  start_msg.print(lcd);
  lcd.setCursor(1, 0);
  function_msg.print(lcd);

  delay (200);

  while (digitalRead (5)== LOW);
  delay (1000);
  fFieldChoice();
}

//===============================================================

int freeRam () {
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}
//
25  Using Arduino / Programming Questions / Re: small function() eats up RAM on: April 06, 2013, 03:48:58 pm
Nick, Bob and Rob
I continue to be humbled by your willingness to assist.
Nick, No I am not using String anywhere.
Bob, No it was doing the same thing but worse when I was using the conventional RAm for strings. The FLASH allowed me to store all strings in Flash.
Rob, I tried to fragment into smaller functions and it had the same result, although I admit I am not sure what you meant by calling the function every 500mS.
The way it works is that the sensor reading is continuously printing. When D5 button is pressed it goes to a Menu function. D6 will take you to fCalibrate. In that function D6 and D7 will decrement and increment offset variable. D5 will return.
It wouldnt allow me to post the entire code so I will post the code following this in 2 posts.
26  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;
}
27  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
28  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
29  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.
30  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.
Pages: 1 [2] 3 4 ... 7