MPR121 (I2C) and softwareSerial (RS485) conflicts

Hy Forum,

I’m building a project involving a capacitive breakout ( https://www.sparkfun.com/products/9695 ) and RS485 transmission of data “sensed” as my computer will be far away from my arduino Uno rev3.
For RS485 transmission I’m using this devices
https://arduino-info.wikispaces.com/RS485-Modules
especially the two at the top of the page.
On one side I have :

  • the capacitive breakout connected to the arduino
  • the rs485 module connected to the same arduino
    On the other side I have :
  • the usb rs485 module connected to a computer

On the arduino side you can see where the devices are connected in the code below.

When I use the arduino + the capacitive breakout it WORKS (with the usual serial of course)
When I use the arduino + the RS485 module it WORKS
When I use the arduino + the capacitive breakout + the rs485 devices, the capacitive breakout works but the rs485 transmission stops working

I have read many things around possible conflicts beetween I2C and softwareSerial or wire and softwareSerial, or possible issues due to a lack of Ram, but I seem not to be concerned as the capacitive part of my code is still working. It’s only the rs485 that seems to have a problem with the mpr121 (or wire library).
I also try to change the RS485 Direction control pin to 8, but it changes nothing.

So…

I’m open to every ideas

here is my code

#include <MPR121.h>
#include <Wire.h>
#include <SoftwareSerial.h>

#define numElectrodes 9

#define SSerialRX        5  //Serial Receive pin
#define SSerialTX        4  //Serial Transmit pin
#define SSerialTxControl 3   //RS485 Direction control
#define RS485Transmit    HIGH
#define RS485Receive     LOW

SoftwareSerial RS485Serial(SSerialRX, SSerialTX); // RX, TX

int freeRam () {
  extern int __heap_start, *__brkval; 
  int v; 
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

void setup()
{
  
  Serial.begin(9600);
  pinMode(13, OUTPUT);  
    
  // Start the built-in serial port
  pinMode(SSerialTxControl, OUTPUT);

  digitalWrite(SSerialTxControl, RS485Transmit);  // Init Transceiver
  
  // Start the software serial port, to another device
  RS485Serial.begin(9600);   // set the data rate 
  
  
 Serial.println("now testing ....");
  // 0x5C is the MPR121 I2C address on the Bare Touch Board
  if(!MPR121.begin(0x5A)){ 
    Serial.println("error setting up MPR121");  
    switch(MPR121.getError()){
      case NO_ERROR:
        Serial.println("no error");
        break;  
      case ADDRESS_UNKNOWN:
        Serial.println("incorrect address");
        break;
      case READBACK_FAIL:
        Serial.println("readback failure");
        break;
      case OVERCURRENT_FLAG:
        Serial.println("overcurrent on REXT pin");
        break;      
      case OUT_OF_RANGE:
        Serial.println("electrode out of range");
        break;
      case NOT_INITED:
        Serial.println("not initialised");
        break;
      default:
        Serial.println("unknown error");
        break;      
    }
    while(1);
  } else Serial.println("success");
  
  MPR121.setInterruptPin(2);

  // this is the touch threshold - setting it low makes it more like a proximity trigger
  // default value is 40 for touch
  MPR121.setTouchThreshold(20);
  
  // this is the release threshold - must ALWAYS be smaller than the touch threshold
  // default value is 20 for touch
  MPR121.setReleaseThreshold(14);  

  // initial data update
  MPR121.updateTouchData();
  
//remaining ram
  Serial.println("\n[memCheck]");
    Serial.println(freeRam());
}

void loop()
{
  
  if(MPR121.touchStatusChanged()){
    MPR121.updateTouchData();
    for(int i=0; i<numElectrodes; i++){
        if(MPR121.isNewTouch(i)){
          Serial.println(i);
          digitalWrite(13,HIGH);
          delay(250);
          digitalWrite(13, LOW);
          digitalWrite(SSerialTxControl, RS485Transmit);  // Init Transceiver
          RS485Serial.println(i); // Send the byte back
          delay(10);
        } else if(MPR121.isNewRelease(i)){
          //Serial.println(i);
      }
    } 
  }
}

can you try getting rid of

          digitalWrite(13,HIGH);
          delay(250);
          digitalWrite(13, LOW);

as well as

delay(10);

delays are known to create issues with timing.

and instead of Serial.begin(9600); do a Serial.begin(115200); (and set your console accordingly)

I would also try to speed up a bit the RS485Serial.begin(9600); and work at 19200 or even 38400 (update receiver accordingly)

You might want to explore using AltSoftSerial Library instead of Software Serial

Thank you J-M-L,

The speed and delay changes does not work

The use of AltSoftSerial library WORKS. I manage to use it at 115200

+1 karma for you ;)