Pages: [1]   Go Down
Author Topic: Disable I2C interrupts in wire.h  (Read 1428 times)
0 Members and 1 Guest are viewing this topic.
New Jersey
Offline Offline
God Member
*****
Karma: 2
Posts: 517
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have a sketch where my Arduino acts as an I2C slave.  I'm using the wire.h library and I want to know if Wire.h I2C communication uses interrupts.  Another part of my sketch receives wireless data via a cc1101 chip (I'm using a panStamp).  The cc1101 part of the code uses an interrupt and I'm concerned that if I2C uses an interrupt, it may cause problems if I don't disable it.  So, does I2C use interrupt?  If so, how do I disable then re-enable it.  Here's my sketch for reference

Code:
#include "EEPROM.h"   
#include "cc1101.h"   // http://code.google.com/p/panstamp/source/browse/trunk/arduino/libraries/panstamp/cc1101.h
#include <Wire.h>     // for I2C communication with main arduino

// The networkAdress of panStamp sender and receiver must be the same
byte panStampNetworkAdress =   91;  // Network address for all pool panStamps
byte receiverAddress =         99;  // Device address of this panStamp
const byte addrSlaveI2C =      21;  // I2C Slave address of this device
const byte addrLevelSensor =    1;  // panStamp device address for low water sensor
const byte panStampOffline =  255;  // Send this to I2C master in the panStamp Rx address to indicate panStamp is offline
const byte panStampOK      =    0;  // panStamp is successfully transmitting data
const uint32_t panStampTimeout = 600000; // 10 minute timeout for panStamps.  If no connections in 10 minutes, tell master that panStamp is offline

#define I2C_PACKET_LEN 5 // bytes in I2C Packet
byte I2C_Packet[I2C_PACKET_LEN];   // Array to hold data sent over I2C to main Arduino
uint32_t lastRxSuccess;   // miliseconds since last successful receipt of panStamp data.

CCPACKET packet;  // panStamp data http://code.google.com/p/panstamp/source/browse/trunk/arduino/libraries/panstamp/ccpacket.h

// The connection to the hardware chip CC1101 the RF Chip
CC1101 cc1101;  // http://code.google.com/p/panstamp/wiki/CC1101class

// flag indicates wireless packet has been received
boolean packetAvailable = false;       


// Handle interrupt from CC1101 (INT 0)
void cc1101signalsInterrupt(void)
{
  // set the flag that a package is available
  packetAvailable = true;
} // cc1101signalsInterrupt()


void setup()
{
  delay(3000);
  Serial.begin(9600);
  Serial.println(F("Begin panStamp Rx setup()"));

  Wire.begin(addrSlaveI2C);    // Initiate the Wire library and join the I2C bus
  Wire.onRequest(wireRequestEvent); // Register a function to be called when a master requests data from this slave device.
  Serial.println(F("Wire library initialized"));
 
  cc1101.init(); // initialize the RF Chip in panStamp
  cc1101.setSyncWord(&panStampNetworkAdress, false);  // Set network address (pointer), false parameter tells function not to save to EEPROM
  // This receiverAddress needs to match the receiverAddress in the Tx panStamp
  cc1101.setDevAddress(receiverAddress, false);  // false parameter tells function not to save to EEPROM
  cc1101.setRxState(); // Set this panStamp to be a receiver
 
  // Enable wireless reception interrupt
  attachInterrupt(0, cc1101signalsInterrupt, FALLING);
   
}  // end setup()


void loop()
{
 
  // Get data from water level sensor panStamp
  if(packetAvailable)
  {
    // clear the flag
    packetAvailable = false;
   
    // Disable wireless reception interrupt so this code finishes executing without inturruption
    detachInterrupt(0);
   
    if(cc1101.receiveData(&packet) > 0)
    {
      if (packet.crc_ok && packet.length > 1)
      {
        lastRxSuccess = millis(); // Track time of successful receipt of panStamp data from transmitter
       
        // print received data
        Serial.print(packet.data[3]); // Low level
        Serial.print("\t");
        int Vcc = 0;
        Vcc  = packet.data[4] << 8; 
        Vcc |= packet.data[5];
        Serial.print(Vcc); 
        Serial.print("\t");
        Serial.print(millis()/1000);
        Serial.println();
     
        I2C_Packet[0] = addrSlaveI2C;
        // If sketch hasn't received any data from the panStamp in a while then
        // set the panStamp Tx byte to indicate it's offline by setting it to 255
        if ((long)( millis() - lastRxSuccess) > panStampTimeout )   
        { I2C_Packet[1] = panStampOffline; }
        else
        { I2C_Packet[1] = panStampOK; }
        // Copy data from panStamp packet to I2C packet array
        I2C_Packet[2] = packet.data[3];   // Low water level
        I2C_Packet[3] = packet.data[4];   // Battery voltage
        I2C_Packet[4] = packet.data[5];   // Battery voltage

      } // packet is okay
    }  // got packet
   
    // Enable panStamp wireless reception interrupt
    attachInterrupt(0, cc1101signalsInterrupt, FALLING);
  }
 
} // end loop()


// function that executes whenever data is requested by master
void wireRequestEvent()
{
  // Send data to I2C master
  Wire.write(I2C_Packet, I2C_PACKET_LEN);
 
} // end wireRequestEvent()


Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 197
Posts: 12739
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The cc1101 part of the code uses an interrupt and I'm concerned that if I2C uses an interrupt, it may cause problems if I don't disable it.  So, does I2C use interrupt?

Why would that cause a problem?  You are using Serial which is interrupt driven.  Why are you concerned about I2C interrupts but not Serial interrupts?
Logged

New Jersey
Offline Offline
God Member
*****
Karma: 2
Posts: 517
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't know anything about how serial works.  So your saying when I do a Serial.print() it uses interrupts?

My concern is if my sketch is in the  if(cc1101.receiveData(&packet) > 0) section and then an I2C request comes in, the sketch will jump to wireRequestEvent() and potentially mess up reading cc1101 data.  Maybe that's not a problem.  I'm trying to figure out if I have a potential problem or not.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
// flag indicates wireless packet has been received
boolean packetAvailable = false;        


// Handle interrupt from CC1101 (INT 0)
void cc1101signalsInterrupt(void)
{
  // set the flag that a package is available
  packetAvailable = true;
} // cc1101signalsInterrupt()

Variables set by an ISR should be declared volatile.

http://gammon.com.au/interrupts

Quote
So, does I2C use interrupt?  

Yes it does.

Quote
If so, how do I disable then re-enable it.

Why do you want to?

Read the link above, get back to us if you have more questions. Also:


http://gammon.com.au/i2c
Logged

New Jersey
Offline Offline
God Member
*****
Karma: 2
Posts: 517
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks Nick, that's a very good article on interrupts.  Using volatile variables with interrupts was something I didn't know (and lots of other stuff!).  Seems like I'm okay with the I2C they way it is and I don't need to disable anything while the cc1101 is receiving data.
Logged

Pages: [1]   Go Up
Jump to: