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.