I2c wire.h and softwareserial.h Conflict

Hi Guys,

I have tested both i2c wire.h master and slave, all good. I have used softwareserial.h for bluetooth also works good.

Now add the two together and its a mess. It appears that they are using the same buffer. My question is am I right and how do I fix this. I have looked at I2c.h but don't know if it uses its own buffer and can not find any documentation or examples on it's use.

Please help, Thanks muchly. Phil

Now add the two together and its a mess.

A place to get Army food? What do you mean by "a mess"?

It appears that they are using the same buffer.

How did you arrive at this conclusion? What buffer do you think they are sharing?

The symptoms you describe are typically caused by a programming error. If you post your sketch perhaps someone will spot an error you missed.

I checked the source code, but the buffer is inside the class.
If they get mixed, you might have too many variables in ram.

Read this before posting a programming question

The I2C library actually has 5 x 32 byte buffers. That's a bit, considering you only have 2048 bytes in total. That's assuming you have a Uno or similar, which you didn't actually say.

The others are probably right about it being a RAM issue, but without seeing your code, it's hard to say.

I'm having a similar issue. I've explained it at this post. But haven't managed to solve it yet. If someone please would suggest me any thing I can try I'd be very grateful.

Kind regards.

I'm having a similar issue

Similar to what? Running out of memory? Failing to post code?

PaulS:
Similar to what? Running out of memory? Failing to post code?

Maybe, if you had entered at the link I provided where everything is explained and code posted, you would have answered me in a different manner. I didn't want to duplicate the post here, but maybe that's what I should have done.

Thank's anyway.

xexijreil:
Maybe, if you had entered at the link I provided where everything is explained and code posted, you would have answered me in a different manner. I didn't want to duplicate the post here, but maybe that's what I should have done.

Thank's anyway.

So you want to barge into another thread, blurt out that you are having the same problem, when the OP has several problems, AND you want us to go to some OTHER thread to help you. And, then you're going to get defensive when I don't. I see. Well, good luck.

PaulS:
So you want to barge into another thread, blurt out that you are having the same problem, when the OP has several problems, AND you want us to go to some OTHER thread to help you. And, then you're going to get defensive when I don't. I see. Well, good luck.

Well, I've done this thinking that it would be the right way to proceed. But everybody makes mistakes, and if I should have posted here the code and duplicate the post then yes, then I've made one, and because of that I beg your pardon. Also, I think there are several ways to speak when someone is wrong, and the way you talked to me it's not the best one. But I understand that there are a lot of people, as I am, who come here knowing barely anything and expect to be helped and see all our problems solved, and that there are little, as you, who help all those who don't know for nothing. So once again, I'm sorry.

I'll post tomorrow the code and the explanation of what I think it's happening.

Kind regards.

So this is the original post in the thread I previously posted:

I’m trying to obtain pressure samples from a MS5611 altimeter (Drotek 10 DOF), and after some issues with the conversion of RawData I finally got it.

The next step is send this data and some other to another micro (I’m using two ATMEGA328 for this) for later processing, to achieve this I’ve tried using the library SoftEasyTransfer. There seems to be no problem when I use

ET.sendData()

, but the data starts to drift when adding

ET.receiveData()

to my program.

I’m using pins 27 and 28 (SCL and SDA) on one of the ATMEGAs to get info from the sensor, and pins 4 and 5 on both ATMEGAs to communicate between them.

I don’t know why this can be. Maybe they share the same buffer? I’m completely lost.

This is the piece of code for ET.receiveData(), you can find it inside the library SoftEasyTransfer:

boolean SoftEasyTransfer::receiveData(){
  
  //start off by looking for the header bytes. If they were already found in a previous call, skip it.
  if(rx_len == 0){
  //this size check may be redundant due to the size check below, but for now I'll leave it the way it is.
    if(_serial->available() >= 3){
 //this will block until a 0x06 is found or buffer size becomes less then 3.
      while(_serial->read() != 0x06) {
 //This will trash any preamble junk in the serial buffer
 //but we need to make sure there is enough in the buffer to process while we trash the rest
 //if the buffer becomes too empty, we will escape and try again on the next call
 if(_serial->available() < 3)
 return false;
 }
      if (_serial->read() == 0x85){
        rx_len = _serial->read();
 //make sure the binary structs on both Arduinos are the same size.
        if(rx_len != size){
          rx_len = 0;
          return false;
        }
      }
    }
  }
  
  
  
  if(rx_len != 0){
    while(_serial->available() && rx_array_inx <= rx_len){
      rx_buffer[rx_array_inx++] = _serial->read();
    }
    
    if(rx_len == (rx_array_inx-1)){
      //seem to have got whole message
      //last uint8_t is CS
      calc_CS = rx_len;
      for (int i = 0; i<rx_len; i++){
        calc_CS^=rx_buffer[i];
      } 
      
      if(calc_CS == rx_buffer[rx_array_inx-1]){//CS good
        memcpy(address,rx_buffer,size);
 rx_len = 0;
 rx_array_inx = 0;
 return true;
 }
        
  else{
  //failed checksum, need to clear this out anyway
 rx_len = 0;
 rx_array_inx = 0;
 return false;
  } 
 
    }
  }
  
  return false;
}

And this is my program for one of the ATMEGA328, the one I call microB (there are some variables and led functions that I haven’t added for simplifying purposes, I’ve checked they don’t interfere):

/*librerías necesarias para sensor MS561101*/
#include <Wire.h>

/*librerías necesarias para intercomunicación con micro A (SOFTSERIAL)*/
#include <SoftEasyTransfer.h>
#include <SoftwareSerial.h>

SoftwareSerial softSerial(2, 3);

/*variables para calcular press y temp*/
#define ADDRESS 0x77 // 0x76
#define SAMPLENUM 10

uint32_t D1 = 0;
uint32_t D2 = 0;
int64_t dT = 0;
int32_t TEMP = 0;
int64_t OFF = 0;
int64_t SENS = 0;
int32_t P = 0;
uint16_t C[7];

float temperature;
float pressure;

float sampledPress[SAMPLENUM];
unsigned long contadorPress = 0;
int indice = 0;
float pressRef;
int estado = 0; // 0: parado; 2: subiendo; 1: bajando
boolean moveOK = false;
int limite = 3;
int indiceFor = 0;
float cteFiltro1 = 0.85;

/*Softserial !!!*/
SoftEasyTransfer ET;

struct SERIAL_DATA_STRUCTURE
{
 // microB ---->microA
        // there are 7 variables here
 

 //microA---> microB
        //there are 14 variables here
};

//give a name to the group of data
SERIAL_DATA_STRUCTURE soft_serial_data;

void setup()
{
 /** SETUP PARA MS561101 **/
 // Disable internal pullups, 10Kohms are on the breakout
 PORTC |= (1 << 4);
 PORTC |= (1 << 5);

 Wire.begin();
 delay(100);
 initial(ADDRESS);
 
 /** SETUP PARA SOFTSERIAL **/
 softSerial.begin(57600);
 //start the library, pass in the data details and the name of the serial port.
 ET.begin(details(soft_serial_data), &softSerial);
 

 delay(500);
}

void loop()
{
 assignPress();
 
 assignDataToSend();
 ET.sendData();
 
 if(ET.receiveData()){ 
 //assignReceivedData();
 //delay(1000);
 }
 
}

/** FUNCIONES PARA MS561101 **/
//filtramos el valor obtenido de presión y lo metemos a un registro FIFO
void assignPress()
{
 pressure = pressure*cteFiltro1 + getPress()*(1-cteFiltro1);
 indice = contadorPress%SAMPLENUM;
 sampledPress[indice] = pressure;
 contadorPress++;
}

//cálculos necesarios para obtener una muestra de presión en mbar
float getPress()
{
 D1 = getVal(ADDRESS, 0x48); // Pressure raw
 D2 = getVal(ADDRESS, 0x58);// Temperature raw
 
 dT   = D2 - ((uint64_t)C[5] << 8);
 OFF  = ((int64_t)C[2] << 16) + ((dT * C[4]) >> 7);
 SENS = ((int32_t)C[1] << 15) + ((dT * C[3]) >> 8);

 TEMP = (int64_t)dT * (int64_t)C[6] / 8388608 + 2000;

 if(TEMP < 2000) // if temperature lower than 20 Celsius
 {
 int32_t T1    = 0;
 int64_t OFF1  = 0;
 int64_t SENS1 = 0;

 T1    = pow(dT, 2) / 2147483648;
 OFF1  = 5 * pow((TEMP - 2000), 2) / 2;
 SENS1 = 5 * pow((TEMP - 2000), 2) / 4;
 
 if(TEMP < -1500) // if temperature lower than -15 Celsius
 {
 OFF1  = OFF1 + 7 * pow((TEMP + 1500), 2);
 SENS1 = SENS1 + 11 * pow((TEMP + 1500), 2) / 2;
 }
 
 TEMP -= T1;
 OFF -= OFF1;
 SENS -= SENS1;
 }

 temperature = (float)TEMP / 100;
 
 P  = ((int64_t)D1 * SENS / 2097152 - OFF) / 32768;

 pressure = (float)P / 100;
 
 return pressure;
}

//obtener valores de la prom del IMU
long getVal(int address, byte code)
{
 unsigned long ret = 0;
 Wire.beginTransmission(address);
 Wire.write(code);
 Wire.endTransmission();
 delay(10);
 // start read sequence
 Wire.beginTransmission(address);
 Wire.write((byte) 0x00);
 Wire.endTransmission();
 Wire.beginTransmission(address);
 Wire.requestFrom(address, (int)3);
 if (Wire.available() >= 3)
 {
 ret = Wire.read() * (unsigned long)65536 + Wire.read() * (unsigned long)256 + Wire.read();
 }
 else {
 ret = -1;
 }
 Wire.endTransmission();
 return ret;
}

//cálculo de coeficientes necesarios para las posteriores fórmulas matemáticas mediante las que se consigue muestrear la presión ambiental
void initial(uint8_t address)
{
 Wire.beginTransmission(address);
 Wire.write(0x1E); // reset
 Wire.endTransmission();
 delay(10);

 for (int i=0; i<6  ; i++) {

 Wire.beginTransmission(address);
 Wire.write(0xA2 + (i * 2));
 Wire.endTransmission();

 Wire.beginTransmission(address);
 Wire.requestFrom(address, (uint8_t) 6);
 delay(1);
 if(Wire.available())
 {
 C[i+1] = Wire.read() << 8 | Wire.read();
 }
 else {
 //Serial.println("Error reading PROM 1"); // error reading the PROM or communicating with the device
 }
 }
}

As you can see I haven’t added the functions assignReceivedData() and assignDataToSend(), but this is because I’m actually not using them until I solve the press data problem.

Without adding this:

if(ET.receiveData()){ 
 //assignReceivedData();
 //delay(1000);
 }

to the above program I get very stable samples of press, but if I add those lines, the samples go fast down occasionally and then returns to the stable value which I can’t stand.

In the other thread I’ve been suggested to try directly with softwareSerial instead of using SoftEasyTransfer, and thats what I’m gonna do. I’ll keep the post updated with any news regarding this.