Author Topic: Software Serial / SoftSerial Event  (Read 13009 times)

fraguada

  • Newbie
  • *
  • Posts: 17
Software Serial / SoftSerial Event
« on: May 26, 2013, 02:12:55 am »
Hello All!
Having a good time working on a project with a bluetooth module.  Proof of concept for transmissions is working well, but I would like the code to be more 'interrupt' driven.  I am using Software Serial (though I could use SoftSerial) to do the communication to/from the bluetooth module.

Currently I am sending a five byte packet to the bluetooth module.  The first byte is the program to run on the digispark.  The rest of the bytes are program arguments.  Last byte signals that the packet is complete.  Serializing / Deserializing is working quite well.

What I would like, if possible, is something like the Arduino Serial Event example.  I understand that for the Arduino Uno, this is possible due to hardware interrupts?  Would it be possible to do something like this for the Software Serial / SoftSerial via the TinyPinChange Library?

I would like the pin change to drive the code rather than the loop.  The idea is to receive a transmission and then loop based on the input.  While looping, if I receive something else, immediately change what is happening.

Any ideas would be appreciated.  In the meantime, I will look at the TinyPinChange library to see if I can get some inspiration!



fraguada

  • Newbie
  • *
  • Posts: 17
Re: Software Serial / SoftSerial Event
« Reply #1 on: May 26, 2013, 04:06:51 am »
Cool!  Seems to work really well! 
Here is some code set up to change the behavior of the on board LED:
Code: [Select]
#include <TinyPinChange.h>
#include <SoftSerial.h>

#define RxD 2
#define TxD 3


SoftSerial mySerial(RxD, TxD);
uint8_t VirtualPortNb;
volatile byte p = 0;

void setup()
{
  TinyPinChange_Init();
  mySerial.begin(38400);

  VirtualPortNb=TinyPinChange_RegisterIsr(RxD, softSerialEvent);
  TinyPinChange_EnablePin(RxD);

  pinMode(1, OUTPUT); //LED on Model A for debugging
}

/* Function called in interruption in case of change on pins */
void softSerialEvent(void)
{
  int inByte;
  uint8_t PortChange;   
  PortChange = TinyPinChange_GetPinEvent(VirtualPortNb);
  if(PortChange & TinyPinChange_PinToMsk(RxD)) /* Check if we have received something */
  {
    while(mySerial.available()){//check if there's any data in the serial buffer
      inByte = mySerial.read();
      if(inByte == 1 || inByte == 2 || inByte == 3)
      {
        p = inByte;
      }
    }
  }
}

void loop()
{
  program(p);
}

void program(byte seq)
{
  switch(seq)
  {

  case 1:
    digitalWrite(1, HIGH);
    delay(100);             
    digitalWrite(1, LOW);
    delay(100);               
    break;

  case 2:
    digitalWrite(1, HIGH);
    delay(500);               
    digitalWrite(1, LOW);
    delay(100);
    digitalWrite(1, HIGH);
    delay(100);
    digitalWrite(1, LOW);
    delay(100);   
    break;

  case 3:
    digitalWrite(1, HIGH);
    delay(500);               
    digitalWrite(1, LOW);
    delay(100);
    digitalWrite(1, HIGH);
    delay(100);
    digitalWrite(1, LOW);
    delay(100);
    digitalWrite(1, HIGH);
    delay(100);
    digitalWrite(1, LOW);
    delay(100);
    break;
 
  default:
    digitalWrite(1, HIGH);
    delay(2000);           
    digitalWrite(1, LOW);
    delay(2000);     
    break;
  }

}

fraguada

  • Newbie
  • *
  • Posts: 17
Re: Software Serial / SoftSerial Event
« Reply #2 on: May 26, 2013, 04:19:31 am »
Well, I suppose I spoke too soon.  It seems that the change to a new program does not happen immediately, just after the current running program is completed.  I guess what I was after is that if I am in case 3, and a new program comes in during this, then go directly to the new case.  What I forgot is to add the call to the program method within the softSerialEvent:

Code: [Select]
/* Function called in interruption in case of change on pins */
void softSerialEvent(void)
{
  int inByte;
  uint8_t PortChange;   
  PortChange = TinyPinChange_GetPinEvent(VirtualPortNb);
  if(PortChange & TinyPinChange_PinToMsk(RxD)) /* Check if we have received something */
  {
    while(mySerial.available()){//check if there's any data in the serial buffer
      inByte = mySerial.read();
      if(inByte == 1 || inByte == 2 || inByte == 3)
      {
        p = inByte;
        program(p);
      }
    }
  }
}

This now interrupts and exposes some issues in the app I am using to send the commands!  I need to throttle them so that I only transmit if the command changes.  Currently it just loops and sends the current command each time, meaning I get a flurry of activity on the RxD pin.
« Last Edit: May 26, 2013, 04:22:09 am by fraguada »