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.