arduino: one library within another

The next issue is a coding problem: referring to one class or library from within another.

In particular, I want to be able refer to the serial library within another library (one which will parse the data received from the serial connection).

The sketch and library work on the assumption that the data received will hold 3 values packaged as follows: [1stvalue; 2ndvalue; 3rdvalue].

The SerialParse library is set-up by including a reference to the existing Serial Communiction:

// Call the serial class
NewSoftSerial mySerial =  NewSoftSerial(rxPin, txPin);

// Call the serial parsing class
SerialParse myParse = SerialParse(&mySerial); 

And then within the sketch the SerialParse library is used as follows:

void loop
{
   if (mySerial.available() > 0) 
   {
      myParse.parseData(&xVal, &yVal, &zVal);
   }
}

By that highlighted line the SerialParse library is inserting the data it receives into the integers xVal, yVal, and zVal. The ‘&’ is used because the sketch is actually passing to the library the physical address of the integer, the library then amends the data at that physical address. This is a workaround necessary because you cannot return an array of values from a library. See the post-script to this post for further info.

The Sketch

The example sketch looks like this:

/* 

Serial parsing library 
    - Calls the SerialParse library
    - If data arrives in the following format: [15;20;5]
      then the library will return the values to the integers
      as follows: xVal=15; yVal=20; zVal=5.
  
Acknowledgements: 
i) The difficult serial parsing bit was came from Nition at the 
Arduino forum.
see http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1203538464/2#2  

ii) The serial library itself came from Mikal Hart at Arduiniana
see http://arduiniana.org/libraries/NewSoftSerial/

iii) BenF at the Arduino Forum on passing refs between sketches and libraries
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1261939396

Created 16 January 2010 by Ben at Cape Ealing

*/

// include the libraries
#include 
#include 

// define the pins on the arduino
#define rxPin 2
#define txPin 3

// 9600kbps data rate
#define dataRate 9600 

// variables for the data
int xVal = 0;
int yVal =0;
int zVal = 0;

// Call the serial class
NewSoftSerial mySerial =  NewSoftSerial(rxPin, txPin);

// Call the serial parsing class
SerialParse myParse = SerialParse(&mySerial); 


// the setup part of the sketch
void setup() 
{ 

// set the data rate for the serial port
mySerial.begin(dataRate);
} 


// the main part of the sketch
void loop() { 

  // read and parse serial data
  if (mySerial.available() > 0) 
  {    
    // the call parseData method
    myParse.parseData(&xVal, &yVal, &zVal);

    // the integers xVal, yVal, zVal now hold the values received
 
    mySerial.print("[Arduino;Bluetooth;capeMirror]");
  } // end if

} // end loop

The Library: header file

/*
  SerialParse.h 
	- Parse data received over serial connection
	- Version 1.0
*/

// ensure this library description is only included once
#ifndef SerialParse_h
#define SerialParse_h

// create shorthand refs for "[" and "]" and ";"
#define leftbracket 0x5b    
#define rightbracket 0x5d   
#define semicolon 0x3b 
#define dataLength 6

// library interface description
class SerialParse {
  public:
 
	// Initialise the class
	SerialParse(NewSoftSerial *serialAddress);

	// Create the parse method
	void parseData(int *xVal, int *yVal, int *zVal);

	// Return the version
	int version(void);

  private:
	// variable to hold a reference to the serial connection
    NewSoftSerial* theSerial;

	// counter for number of bytes read
	int byteIndex;		
	// whether all data has been read
	int allComplete;	
	// arrays for each of the three values received
	char xData[dataLength], yData[dataLength], zData[dataLength];
	// the character being read
	char thisChar;
	// variable to hold whether any partic value is complete
	int xComplete, yComplete, zComplete;
};
#endif

The Library: cpp file

/*
  SerialParse.cpp
	- Parse data received over serial connection
	- Version 1.0
*/

#include "WProgram.h"
#include "NewSoftSerial.h"
#include "SerialParse.h"

/*
 *   Initialise the class
 */
SerialParse::SerialParse(NewSoftSerial* serialAddress)
{
theSerial = serialAddress;
}


/*	
	Parse method 
*/
void SerialParse::parseData(int* xVal, int* yVal, int* zVal)
{

	// reset the variables
	*xVal = 0;
	*yVal = 0;
	*zVal = 0;

	xComplete = false;
    yComplete = false;
    zComplete = false;

	for (int i=0;i<5;i++){
    xData[i] = 0x00;
    yData[i] = 0x00;
    zData[i] = 0x00;
    }	

	// wait for all data to be in
    delay(1500);  

	// Read the serial data
	char thisChar = theSerial->read();

	if (thisChar == leftbracket)
	{
		// read all first data section 
		while (xComplete == false && theSerial->available() > 0)
		{
    		char thisChar = theSerial->read();
				if (thisChar == semicolon)
				{
  					xComplete = true;
					break; 
				}
				else 
				{
					xData[byteIndex] = thisChar;
					byteIndex++;
				}
		}
		byteIndex = 0;

		// read the second data section
		while (yComplete == false && theSerial->available() > 0)
		{
			char thisChar = theSerial->read();
				if (thisChar == semicolon)
				{
					yComplete = true;
					break;
				}
				else 
				{
					yData[byteIndex] = thisChar;
					byteIndex++;
				}
		}
		byteIndex = 0;

		// read the third data section
		while (zComplete == false && theSerial->available() > 0)
		{
			char thisChar = theSerial->read();
   				if (thisChar == rightbracket)
				{
					zComplete = true;
					break;
				}
				else 
				{
					zData[byteIndex] = thisChar;
					byteIndex++;
				}
		}
		byteIndex = 0;
	
	// report back the values
	*xVal = atoi(xData);
	*yVal = atoi(yData);
	*zVal = atoi(zData);
	}
}
/*
  version() returns the version of the library:
*/
int SerialParse::version(void)
{
  return 1;
}

The visual basic code

I ran this code on the laptop to send data over bluetooth.

Module Module1
    Public WithEvents Arduino_SerialPort As IO.Ports.SerialPort
    Public ReceivedDataYet As Boolean

    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    'Connect to Arduino over Bluetooth via the serial port.
    '
    'created by Ben at Cape Ealing
    '17 June 2008
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

    Public Sub Main()

        Dim Arduino_SerialPort As New IO.Ports.SerialPort
        Dim RxChar As Char
        Dim RxMessage As String

        'Empty the variables
        RxChar = ""
        RxMessage = ""

        'First see if the serial port is open, if not open it
        If Arduino_SerialPort.IsOpen = False Then
            With Arduino_SerialPort
                .PortName = "COM7"
                .BaudRate = 9600
                .DataBits = 8
                .Parity = IO.Ports.Parity.None
                .StopBits = IO.Ports.StopBits.One
                .Encoding = System.Text.Encoding.ASCII
                .ReadTimeout = 5000
            End With
            Arduino_SerialPort.Open()
        End If

        Arduino_SerialPort.DiscardInBuffer()
        Arduino_SerialPort.DiscardOutBuffer()

        MsgBox("Opened port.  Now write data.")

        'send the portions of data
        Arduino_SerialPort.Write("[5;10;15]")

        'Wait until the Arduino sends back it's message
        Do Until Arduino_SerialPort.BytesToRead > 0
        Loop

        'Collect the message one byte at a time
        Do
            RxChar = ChrW(Arduino_SerialPort.ReadByte)
            RxMessage = RxMessage & RxChar
        Loop Until RxChar = "]"

        'Display the message
        MsgBox(RxMessage)

    End Sub
End Module

Download

The files can be downloaded here

Ben

post a comment...

you must be logged in to post a comment.