Short of 1 Interrupt pin - can I fix this by modifying HardwareSerial libary

Dear all,

In my current project I have all sorts of sensors hooked up to two Arduino's, including a LE Bluetooth Module. I also have serial communication (through wires) between the two Arduino's (I'll call them 'Receiving Arduino' and one 'Transmitting Arduino' referring to the serial communication).

While everything is working separately, I'm short one Interrupt pin for my Bluetooth Module on my 'Receiving Arduino'. I was hoping that for Serial communication, when I don't connect the TX to RX pin from my 'Receiving Arduino' to my 'Transmitting Arduino', TX (on 'Receiving Arduino' ) would become available for my Bluetooth module. Some more information (TX is the pin that is connected to the Ready pin of my BT module)

Whenever I disable Serial data (not calling Serial1.begin), the bluetooth module works, if I do call Serial1.begin, the Arduino seems to occupy the TX pin (even though it's not connected), and my Bluetooth module stops to work. (Switching between the two is not an option, as by disabling the BTLE I will lose connection to my app).

As I'm nearing the end of a project, getting a board with more bluetooth pins is not a possibility.
My question is, if I can somehow tell "#define mySerial Serial1" to not occupy the TX pin.
I've tried altering the HardwareSerial library and importing it as a new one, but failed (honestly, I didn't really know what I was doing).

So to summarize: can I (or preferably someone who knows how to do this) alter the HardwareSerial.h/cpp so that Arduino won't occupy my TX pin for Serial communication? It's probably important to know that I'm calling Serial1 as with the board I'm using, this is necessary

I do think that it's possible right? To alter it so it doesn't occupy the TX pin?
I'm really hoping someone can help me out, as this would be the only way to fix my problem (as it's the only interrupt capable pin I have left, I think ;), or can I target the ICSP pins I have left if they are interruptable? I only have +VCC, GND, RST left ).

Thanks in advance,

Crimson

Any Uno with '328P can have a PCINT on any pin.
Look up PCINT, there have been libraries posted to make them easy to use.

You have missed an important part of the information - what Arduinos are you using? An Uno does not have Serial1.

...R

It might be as simple as disabling the transmitter in the UART control register of whatever processor you're using. Just guessing though.

Oops. That indeed is important information.. Can't believe I didn't mention it. What I'm using are two Flora Arduinos from adafruir (comparable to Lilypads. Pinout diagram: FLORA pinout diagram | Getting Started with FLORA | Adafruit Learning System

So I guess I cannot use the PCINT suggestion.

@jboyton, I was looking for a solution like that, however I have no idea how I can do this. Suggestions are welcome.

My own guess was to somehow hack Serial1.begin so that it doesn't reserve the TX pin and only receives data. Can this be done?

Thanks for your replies so far guys. Really appreciate it!

What a lame board - ATMega32U4, but like half the pins not broken out to anything :-/

The 32u4 has 8 PCINT pins available, see datasheet. You may have to take over ISP pins if no appropriate pins are broken out to the sewable pads that aren't already used.

If you really don't need one of the serial lines, you can kill it (after setting up serial) by unsetting TXEN1 bit from UCSR1B (that's the one you want to axe, right, not RX? it's RXEN1 if RX)

UCSR1B = UCSR1B & ~(1<TXEN1)

(Usart 1 Control and Status Register B)

Thanks for your reply!

The ISP pins I have left are 2, 5 and 6 (Vcc, Reset and Ground), could I use one of them as the interrupt pin for my Bluetooth module (RDY Pin on Bluetooth Module)? How can I target them in my code?

Also, if I were to use the UCSR1B = UCSR1B & ~(1<TXEN1) you describe (this is alien for me btw :wink: ), how would I use that in my code?

Loop through it once? Or do I do this in setup? Call BTLEserial.begin() after?
I'll give things a try.

The code I have so far:

//Serial 1 for communication between Flora's
#define mySerial Serial1

//Include all necessary libraries
#include <SPI.h>
#include <Adafruit_BLE_UART.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_LSM9DS0.h>
#include <Adafruit_Simple_AHRS.h>

//BLUETOOTH SECTION
#define ADAFRUITBLE_REQ 6
#define ADAFRUITBLE_RDY 1     // This should be an interrupt pin
#define ADAFRUITBLE_RST 12

Adafruit_BLE_UART BTLEserial = Adafruit_BLE_UART(ADAFRUITBLE_REQ, ADAFRUITBLE_RDY, ADAFRUITBLE_RST);

//IMU SECTION
// Create LSM9DS0 board instance.
Adafruit_LSM9DS0 lsm(1000);  // Use I2C, ID #1000
// Attitude and Heading Reference System
// Create AHRS algorithm using the LSM9DS0 instance's accelerometer and magnetometer.
Adafruit_Simple_AHRS ahrs(&lsm.getAccel(), &lsm.getMag());

// Function to configure the sensors on the LSM9DS0 board.
void configureLSM9DS0(void)
{
  lsm.setupAccel(lsm.LSM9DS0_ACCELRANGE_2G);
  lsm.setupMag(lsm.LSM9DS0_MAGGAIN_2GAUSS);
  lsm.setupGyro(lsm.LSM9DS0_GYROSCALE_245DPS);
}

//CUSTOM VARIABLES
const int ledPin = 7; // the pin that the LED is attached to
int incomingByte;      // a variable to read incoming serial data into
String headingS1;
long startTime;
String firstValue;
String secondValue;


String content = "";
char character;


//SETUP
void setup() {
    //Serial.begin(9600);

     //Initialize BLE board - NRF8001
    BTLEserial.setDeviceName("CERVAPP"); /* 7 characters max! */
    //the order in which the below statements are declared doesn't matter
    BTLEserial.begin();
    mySerial.begin(9600);


     //Initialize IMU board - LSM9DS0
    if(!lsm.begin())
    {
    // Check for errors
    //Serial.print(F("Error"));
    while(1);
    }
    //If all went well, 
    //Setup the sensor gain and integration time.
    configureLSM9DS0();
    
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
}


aci_evt_opcode_t laststatus = ACI_EVT_DISCONNECTED;

void loop() {
  //mySerial.begin(9600); 
  //IF I UNCOMMENT THIS, I WILL GET SERIAL DATA, BUT CANNOT CONNECT TO BTLE
  
  while(mySerial.available()){
        Serial.println("available");
    // read the serial buffer:
  String myString = mySerial.readStringUntil('\n');

  // check length of string
  if (myString.length()>0) {

    myString.trim(); //Strim any whitespace characters
    //just to be sure
    
      int commaIndex = myString.indexOf(',');
      //  Search for the next comma just after the first
      int secondCommaIndex = myString.indexOf(',', commaIndex+1);
      
      //store data
     firstValue = myString.substring(0, commaIndex);
     secondValue = myString.substring(commaIndex+1, secondCommaIndex);
      
    Serial.println(myString);
    //Serial.println(firstValue);
    //Serial.println(secondValue);
    }
    // Send an A to ask for more:
    mySerial.write("A");


  }
       
  //Refresh nRF8001 data
  BTLEserial.pollACI();
  // Refresh IMU data
  sensors_vec_t   orientation;
   //IMU SECTION
  if (ahrs.getOrientation(&orientation))
  {
     
  //The way the sensor on the neck is oriented, it only needs the heading angle
  //Set orientation heading as the heading value for sensor S1 (Neck sensor)
    headingS1 = String(int(orientation.heading));
   
  // Serial.println(headingS1);
  }
  
   //BLUETOOTH SECTION 
  // Ask what is our current status
  aci_evt_opcode_t status = BTLEserial.getState();
  Serial.println(status); // voor debuggen
  // If the status changed....
  if (status != laststatus) {
    // print it out!
    if (status == ACI_EVT_DEVICE_STARTED) {
        Serial.println(F("* Advertising started"));
    }
    if (status == ACI_EVT_CONNECTED) {
        Serial.println(F("* Connected!"));
        startTime = millis();
        
    }
    if (status == ACI_EVT_DISCONNECTED) {
        Serial.println(F("* Disconnected or advertising timed out"));
    }
    // OK set the last status change to this one
    laststatus = status;
  }
  
  //if connected, send data
  if (status == ACI_EVT_CONNECTED) {
        //Build in delay, without actually delaying program
        //Needed time for BTLE to send to Cervicapp witout Pipe Errors
        Serial.println(firstValue);
        Serial.println(secondValue);
        Serial.println(headingS1);
          if((millis()-startTime)>200){
        //check if all data received
     
        sendDataOverBluetooth();
        startTime+=200;
          }
        
  }
  
}
  
void sendDataOverBluetooth(){

  
  int s1value=123;
  int s2value=456;
  int flxvalue=789;
  
  uint8_t sendPackage1[20];
  uint8_t sendPackage2[20];
  uint8_t sendPackage3[20];

  
//just sending dummy data right now;
 
  String s1package = "S1="+String(s1value);
  String s2package = "S2="+String(s2value);
  String flxpackage = "FLX"+String(flxvalue);
  
    //max bytes is 20
    //characters won't be over 20, 
    //so won't need to break m up
  s1package.getBytes(sendPackage1, 20);
  BTLEserial.write(sendPackage1, char(s1package.length()));
  delay(20);
  s2package.getBytes(sendPackage2, 20);
  BTLEserial.write(sendPackage2, char(s2package.length()));
  delay(20);
  flxpackage.getBytes(sendPackage3, 20);  
  BTLEserial.write(sendPackage3, char(flxpackage.length()));
  delay(20);

}