How to use serial interrupt in arduino

Yes , i tried like Robin said. It seems looks OK. but most of the times the previous values not getting changes. That mean it replies the same adc value. but my adc input keeps changing.

i cleared the inChar and inputstring everything.

Is that anything we can do like clearing the serial buffer?

alagappan:
It seems looks OK. but most of the times the previous values not getting changes.

Without seeing your latest code we are blind ...

...R

So really this is nothing to do with serial interrupts? You have a problem with the ADS1115 converter. You may find that the I2C communication speed between your code and the ADS1115 is the problem (plus it would take a little while to do the conversion). You could try increasing the I2C speed.

After Wire.begin(), place:

TWBR = 12;  // I2C speed to 400 kHz (maximum)

and... Adafruit has responded: Adafruit_ADS1015 library conversion delay - adafruit industries
(It doesn't look like live links containing odd punctuation work very well. Here's a link that should at last be copy/pasteable:

http://forums.adafruit.com/viewtopic.php?f=19&t=80633&p=408285#p408285

Basically, the 1115 is a pretty slow ADC, and its default configuration is 128samp/s: about 8ms per conversion.
It CAN go as fast as 860samp/s, or you can set it to do continuous conversions and get the "most recent" result pretty much instantaneously, but you'll have to modify the library to get either of those behaviors.
I2C isn't a very fast interface either, but it shouldn't result in "several milliseconds" of delay.

Thanks, Westfw!

How to use serial interrupt in arduino?

And this is a very good example of a X-Y Problem.

The initial question wandered off into questions about serial interrupts, when it would have been more helpful to disclose that you were having problems reading from the ADS1115 ADC converter in a timely way.

Thanks for all first,

Yes, there was 8ms delay for conversion_delay in adafruit_ads1015.h .

ads1115 operate in oneshot and continuous mode.
in one shot after every sample read at 1.2 ms it goes sleep or idle for 123.8 ms. so next value updated might after 125ms.
now i configured to ads1115 to continuous mode,
Now Can i change conversion_delay deafault value to 2ms?
because now i think there wont be any idle time for 123.8ms. . so max time taken will be around 1.3 to 1.4 ms as data sheet stated.

I am asking because there is default value for conversion delay was 8ms. for other pointer(config) register i configured to achieve both Continuous mode and 475SPS

Thanks for all first,

Yes, there was 8ms delay for conversion_delay in adafruit_ads1015.h .

ads1115 operate in oneshot and continuous mode.
in one shot after every sample read at 1.2 ms it goes sleep or idle for 123.8 ms. so next value updated might after 125ms.
now i configured to ads1115 to continuous mode,
Now Can i change conversion_delay deafault value to 2ms?
because now i think there wont be any idle time for 123.8ms. . so max time taken will be around 1.3 to 1.4 ms as data sheet stated.

I am asking because there is default value for conversion delay was 8ms. for other pointer(config) register i configured to achieve both Continuous mode and 475SPS

Post your configuration code. And more of your other code.
Obviously, if you have the chip configured for more than 125 Samp/s, you shouldn't have to wait 8ms for a conversion complete.
The way I read the datasheet, if you have the chip set to "continuous" mode, you should be able to read the value with zero delay, and you'll get the LAST value that was converted (up to 1/8 s ago, if you're in 125 Samp/s mode.) This sounds like it should be useful for most arduino-like applications; you have at worst a delay of one sample time from the actual value, vs a delay of at least one sample time from the time you ask for a sample in one-shot mode. At the expense of higher power consumption in the realm of "dwarfed by other arduino components anyway."

The one thing that isn't clear is how changing the MUX (channel) value affects things (and I didn't see any info in the datasheet, either.) Does the converter run while you're changing the mux (causing the first reading to be bogus)? Does changing the mux restart a conversion even in continuous mode ? Can you even change the mux while the chip is running in continuous mode? What if the new channel is the same as the old channel? The Adafruit library ALWAYS writes the mux, which seems problematic if you're only reading one channel. At this point, you might want to discard most of the adafruit library and write your own code, using it as "reference material."

I am using Single ended input only, not using differential inputs. So i am not changing anything in MUX.

my configuration cpp file:
here i replaced word adafruit with ivafruit and 1115 with 2224 only, since i have another same I2c ic.

#if ARDUINO >= 100
 #include "Arduino.h"
#else
 #include "WProgram.h"
#endif

#include <Wire.h>

#include "ivafruit_ADS1015.h"

/**************************************************************************/
/*!
    @brief  Abstract away platform differences in Arduino wire library
*/
/**************************************************************************/
static uint8_t i2cread(void) {
  #if ARDUINO >= 100
  return Wire.read();
  #else
  return Wire.receive();
  #endif
}

/**************************************************************************/
/*!
    @brief  Abstract away platform differences in Arduino wire library
*/
/**************************************************************************/
static void i2cwrite(uint8_t x) {
  #if ARDUINO >= 100
  Wire.write((uint8_t)x);
  #else
  Wire.send(x);
  #endif
}

/**************************************************************************/
/*!
    @brief  Writes 16-bits to the specified destination register
*/
/**************************************************************************/
static void writeRegister(uint8_t i2cAddress, uint8_t reg, uint16_t value) {
  Wire.beginTransmission(i2cAddress);
  i2cwrite((uint8_t)reg);
  i2cwrite((uint8_t)(value>>8));
  i2cwrite((uint8_t)(value & 0xFF));
  Wire.endTransmission();
}

/**************************************************************************/
/*!
    @brief  Writes 16-bits to the specified destination register
*/
/**************************************************************************/
static uint16_t readRegister(uint8_t i2cAddress, uint8_t reg) {
  Wire.beginTransmission(i2cAddress);
  i2cwrite(ADS1015_REG_POINTER_CONVERT);
  Wire.endTransmission();
  Wire.requestFrom(i2cAddress, (uint8_t)2);
  return ((i2cread() << 8) | i2cread());
}

/**************************************************************************/
/*!
    @brief  Instantiates a new ADS1015 class w/appropriate properties
*/
/**************************************************************************/
ivafruit_ADS1015::ivafruit_ADS1015(uint8_t i2cAddress)
{
   m_i2cAddress = i2cAddress;
   m_conversionDelay = ADS1015_CONVERSIONDELAY;
   m_bitShift = 4;
   m_PWR = PWR_TWOTHIRDS; /* +/- 6.144V range (limited to VDD +0.3V max!) */
}

/**************************************************************************/
/*!
    @brief  Instantiates a new ADS2224 class w/appropriate properties
*/
/**************************************************************************/
ivafruit_ADS2224::ivafruit_ADS2224(uint8_t i2cAddress)
{
   m_i2cAddress = i2cAddress;
   m_conversionDelay = ADS2224_CONVERSIONDELAY;
   m_bitShift = 0;
   m_PWR = PWR_TWOTHIRDS; /* +/- 6.144V range (limited to VDD +0.3V max!) */
}

/**************************************************************************/
/*!
    @brief  Sets up the HW (reads coefficients values, etc.)
*/
/**************************************************************************/
void ivafruit_ADS1015::begin() {
  Wire.begin();
}

/**************************************************************************/
/*!
    @brief  Sets the PWR and input voltage range
*/
/**************************************************************************/
void ivafruit_ADS1015::setPWR(adsPWR_t PWR)
{
  m_PWR = PWR;
}

/**************************************************************************/
/*!
    @brief  Gets a PWR and input voltage range
*/
/**************************************************************************/
adsPWR_t ivafruit_ADS1015::getPWR()
{
  return m_PWR;
}

/**************************************************************************/
/*!
    @brief  Gets a single-ended ADC reading from the specified channel
*/
/**************************************************************************/
uint16_t ivafruit_ADS1015::readADC_SingleEnded1(uint8_t channel) {
  if (channel > 3)
  {
    return 0;
  }

  // Start with default values
  uint16_t config = ADS1015_REG_CONFIG_CQUE_NONE    | // Disable the comparator (default val)
                    ADS1015_REG_CONFIG_CLAT_NONLAT  | // Non-latching (default val)
                    ADS1015_REG_CONFIG_CPOL_ACTVLOW | // Alert/Rdy active low   (default val)
                    ADS1015_REG_CONFIG_CMODE_TRAD   | // Traditional comparator (default val)
                    ADS1015_REG_CONFIG_DR_3300SPS   | // 1600 samples per second (default)
                    ADS1015_REG_CONFIG_MODE_CONTIN;   // Single-shot mode (default)

  // Set PGA/voltage range
  config |= m_PWR;

  // Set single-ended input channel
  switch (channel)
  {
    case (0):
      config |= ADS1015_REG_CONFIG_MUX_SINGLE_0;
      break;
 }

  // Set 'start single-conversion' bit
  config |= ADS1015_REG_CONFIG_OS_SINGLE;

  // Write config register to the ADC
  writeRegister(m_i2cAddress, ADS1015_REG_POINTER_CONFIG, config);

  // Wait for the conversion to complete
  delay(m_conversionDelay);

  // Read the conversion results
  // Shift 12-bit results right 4 bits for the ADS1015
  return readRegister(m_i2cAddress, ADS1015_REG_POINTER_CONVERT) >> m_bitShift;
}


void ivafruit_ADS1015::startComparator_SingleEnded(uint8_t channel, int16_t threshold)
{
  // Start with default values
  uint16_t config = ADS1015_REG_CONFIG_CQUE_1CONV   | // Comparator enabled and asserts on 1 match
                    ADS1015_REG_CONFIG_CLAT_LATCH   | // Latching mode
                    ADS1015_REG_CONFIG_CPOL_ACTVLOW | // Alert/Rdy active low   (default val)
                    ADS1015_REG_CONFIG_CMODE_TRAD   | // Traditional comparator (default val)
                    ADS1015_REG_CONFIG_DR_1600SPS   | // 1600 samples per second (default)
                    ADS1015_REG_CONFIG_MODE_CONTIN  | // Continuous conversion mode
                    ADS1015_REG_CONFIG_MODE_CONTIN;   // Continuous conversion mode

  // Set PGA/voltage range
  config |= m_PWR;

  // Set single-ended input channel
  switch (channel)
  {
    case (0):
      config |= ADS1015_REG_CONFIG_MUX_SINGLE_0;
      break;
    case (1):
      config |= ADS1015_REG_CONFIG_MUX_SINGLE_1;
      break;
    case (2):
      config |= ADS1015_REG_CONFIG_MUX_SINGLE_2;
      break;
    case (3):
      config |= ADS1015_REG_CONFIG_MUX_SINGLE_3;
      break;
  }

  // Set the high threshold register
  // Shift 12-bit results left 4 bits for the ADS1015
  writeRegister(m_i2cAddress, ADS1015_REG_POINTER_HITHRESH, threshold << m_bitShift);

  // Write config register to the ADC
  writeRegister(m_i2cAddress, ADS1015_REG_POINTER_CONFIG, config);
}


int16_t ivafruit_ADS1015::getLastConversionResults()
{
  // Wait for the conversion to complete
  delay(m_conversionDelay);

  // Read the conversion results
  uint16_t res = readRegister(m_i2cAddress, ADS1015_REG_POINTER_CONVERT) >> m_bitShift;
  if (m_bitShift == 0)
  {
    return (int16_t)res;
  }
  else
  {
    // Shift 12-bit results right 4 bits for the ADS1015,
    // making sure we keep the sign bit intact
    if (res > 0x07FF)
    {
      // negative number - extend the sign to 16th bit
      res |= 0xF000;
    }
    return (int16_t)res;
  }
}

part of my header file: .h

#include <Wire.h>

CONVERSION DELAY (in mS)
-----------------------------------------------------------------------*/
#define ADS1015_CONVERSIONDELAY (1)
#define ADS2224_CONVERSIONDELAY (2)

alagappan:
Yes, there was 8ms delay for conversion_delay in adafruit_ads1015.h .

If your main code wants a value every 50 millisecs how can this be a problem. You can get 6 readings at 8ms each within 50 ms.

Why not just write your Arduino code to get values from the ad1115 as often as it can and save the value to a variable. Then when a request for a value arrives just send the value that is in the variable.

If the call to the ad115 is a blocking call I would be very tempted to just get one reading immediately AFTER I sent a value - as that way the blocking call would be least likely to interfere with anything else.

...R

I think you want to change the readADC_SingleEnded1() function to NOT re-write the configuration register each time. Instead, you should do all that in the/an initialization function (xxxx.begin()?) ...

Yes , Thanks westfw.

I did now the conversion is faster. less than 1 ms. I configured in continuous mode and 3300SPS

inside begin, i am writing config register, not on every readsingleended function, in readsingleended i simply read and return the values.

I have another doubt. How to use serial interrupt instead of polling
because i tried with attachinterrupt(0,ISR,CHANGE);
detachinterrupt(0);

but not worked,
Can anyone tell me 1)how can i handle interrupt instead of polling in arduino?
2) i need to ensure whether my prev value at serial buffer is cleared or not ?
how can i clear Serial tx,rx buffer
will use of function Serial.clear() clears the buffer

1 Like

http://forum.arduino.cc/index.php?topic=348233.msg2402810#msg2402810

alagappan:
I have another doubt. How to use serial interrupt instead of polling
because i tried with attachinterrupt(0,ISR,CHANGE);
detachinterrupt(0);

Have you not read any of the earlier advice you were given ?

...R

Yes , Thanks to Robin andall, I hope my problem solved

hi Robin,

just i wanted to know how to check whether my previous transmitted value in Serial.print function has been cleared. i am not facing any issue.

May i know where i can find these Serial function in installed libraries?. So that i can get to know about how data has been written into Serial transmit register.

In my Arduino 1.5.6 the HardwareSerial code is in the directory
./arduino-1.5.6-r2/hardware/arduino/avr/cores/arduino

...R

alagappan:
Can anyone tell me 1)how can i handle interrupt instead of polling in arduino?
[/quote]
**What do you want to do with the interrupt? Pull a character and put it into a buffer? That is already being done for you. It is one of those things you have to do on other boards but the code is already there happening in the Arduino core. You aren't going to make it happen any faster than it already does. **

Hi Robin

When I am receiving data via Tx,Rx pin from GUI, is this communicating via Softwareserial or HardwareSerial.
Which library i have to look at, either Hardware serial or software serial.

Thanks
Pon

Hi westfw,

How can i know in which speed my I2c communicating. because in datasheet for standard(100khz) and fast mode(400khz) in configuration and signaling it not mentioned any changes. But for setting into high speed mode it needs master to send 00001xxx followed by repeated start slave address + r/w .

Anyway i am not going for High speed mode. Now i want to know whether my ads1115 slave I2C communicate with my master arduino in standard or fast mode. How can i check??

When I am receiving data via Tx,Rx pin from GUI, is this communicating via Softwareserial or HardwareSerial.

That depends on how you are connecting the PC to the Arduino. If you are using an FTDI cable, you have not provided enough information to answer your question. If you are using a USB cable, the HardwareSerial class instance Serial will be reading the data.