Mindstorms 3rd Party ROBOTC Drivers RobotC
[Home] [Download] [Submit a bug/suggestion] [ROBOTC Forums] [Blog] [Support this project]

common-rs485.h

Go to the documentation of this file.
00001 /*!@addtogroup common_includes
00002  * @{
00003  * @defgroup common-rs485 RS485 functions
00004  * Commonly used RS485-related functions used by drivers
00005  * @{
00006  */
00007 
00008 /*
00009  * $Id: common-rs485.h 133 2013-03-10 15:15:38Z xander $
00010  */
00011 
00012 /** \file common-rs485.h
00013  * \brief Commonly used RS485-related functions used by drivers.
00014  *
00015  * common-rs485.h provides a number of frequently used RS485-related functions that are
00016  * useful for writing drivers.
00017  * License: You may use this code as you wish, provided you give credit where its due.
00018  *
00019  * THIS CODE WILL ONLY WORK WITH ROBOTC VERSION 3.59 AND HIGHER. 
00020 
00021  *
00022  * Changelog:
00023  * - 0.1: Initial release
00024  *
00025  * \author Xander Soldaat (xander_at_botbench.com)
00026  * \date 15 October 2012
00027  * \version 0.1
00028  */
00029 
00030 #pragma systemFile
00031 
00032 #ifndef __RS485_H__
00033 #define __RS485_H__
00034 
00035 #ifndef __TMR_H__
00036 #include "timer.h"
00037 #endif
00038 
00039 int rxTimer;            /*!< timer for receiving timeouts */
00040 //const string newline = "\n";
00041 const ubyte newline[1] = '\n';
00042 
00043 tMassiveArray RS485rxbuffer; /*!< 128 bit array for receiving */
00044 tMassiveArray RS485txbuffer; /*!< 128 bit array for transmission */
00045 
00046 /**
00047  * Write a message to the NXT2WIFI sensor
00048  * @param buf the buffer to be transmitted
00049  * @param len the length of the data to be transmitted
00050  * @return true if no error occured, false if it did
00051  */
00052 bool RS485write(tMassiveArray &buf, ubyte len)
00053 {
00054   TFileIOResult res;
00055 
00056   // Clear the read buffer
00057   if (nxtGetAvailHSBytes() > 0)
00058   {
00059     nxtReadRawHS(&RS485rxbuffer[0], nxtGetAvailHSBytes());
00060     memset(RS485rxbuffer, 0, sizeof(RS485rxbuffer));
00061   }
00062 
00063   // Make sure we're not sending anymore
00064   while (nxtHS_Status != HS_RECEIVING) EndTimeSlice();
00065 
00066 #ifdef __RS485_DEBUG__
00067         writeDebugStream("RS485write: ");
00068         for (ubyte datacounter = 0; datacounter < len; datacounter++)
00069         {
00070           writeDebugStream("%c", buf[datacounter]);
00071           EndTimeSlice();
00072         }
00073 #endif // __RS485_DEBUG__
00074 
00075   res = nxtWriteRawHS(&buf[0], len);
00076   if (res != ioRsltSuccess)
00077     return false;
00078 
00079   while (nxtHS_Status != HS_RECEIVING) EndTimeSlice();
00080   return true;
00081 }
00082 
00083 
00084 /**
00085  * Read a message from the NXT2WIFI. An optional timeout can be specified.
00086  * @param buf the buffer in which to store the received data
00087  * @param len the amount of data received
00088  * @param timeout optional parameter to specify the timeout, defaults to 100ms
00089  * @return true if no error occured, false if it did
00090  */
00091 bool RS485read(tMassiveArray &buf, int &len, int timeout = 100) {
00092         int bytesAvailable = 0;
00093 
00094         memset(buf, 0, sizeof(buf));
00095 
00096         TMRreset(rxTimer);
00097   TMRsetup(rxTimer, timeout);
00098 
00099         while(bytesAvailable == 0 && !TMRisExpired(rxTimer)) {
00100                 bytesAvailable = nxtGetAvailHSBytes();
00101                 wait1Msec(10);
00102         }
00103 
00104         nxtReadRawHS(&buf[0], bytesAvailable);
00105         len = bytesAvailable;
00106 
00107 #ifdef __RS485_DEBUG__
00108         writeDebugStream("RS485read (%d): ", bytesAvailable);
00109         for (int datacounter = 0; datacounter < bytesAvailable; datacounter++)
00110         {
00111           writeDebugStream("%c", buf[datacounter]);
00112           EndTimeSlice();
00113         }
00114         writeDebugStream("\n");
00115 #endif // __RS485_DEBUG__
00116 
00117   return true;
00118 }
00119 
00120 
00121 /**
00122  * Read a very large response from the NXT2WIFI sensor.  This breaks up the
00123  * reads into many smaller chunks to prevent weirdness on the bus.
00124  * @param buf the buffer in which to store the received data
00125  * @param len the amount of data received
00126  * @param timeout optional parameter to specify the timeout, defaults to 100ms
00127  * @return true if no error occured, false if it did
00128  */
00129 bool RS485readLargeResponse(tMassiveArray &buf, int &len, int timeout = 100)
00130 {
00131   const ubyte chunkSize = 10;
00132   int bytesAvailable;
00133         tByteArray tmpBuff;
00134         int bytesleft = len;
00135         int bytesToRead = 0;
00136         int index = 0;
00137         memset(buf, 0, sizeof(buf));
00138 
00139         TMRreset(rxTimer);
00140   TMRsetup(rxTimer, timeout);
00141 
00142 
00143         while ((bytesleft > 0) && !TMRisExpired(rxTimer))
00144         {
00145                 memset(tmpBuff, 0, sizeof(tmpBuff));
00146                 bytesAvailable = nxtGetAvailHSBytes();
00147                 bytesToRead = (bytesAvailable > chunkSize) ? chunkSize: bytesAvailable;
00148                 nxtReadRawHS(&tmpBuff[0], bytesToRead);
00149 
00150                 memcpy(&buf[index], tmpBuff, bytesToRead);
00151                 bytesleft -= bytesToRead;
00152                 index += bytesToRead;
00153                 wait1Msec(5);
00154         }
00155 
00156 #ifdef __RS485_DEBUG__
00157         writeDebugStream("RS485readLargeResponse: ");
00158         for (int datacounter = 0; datacounter < len; datacounter++)
00159         {
00160           writeDebugStream("%c", buf[datacounter]);
00161           EndTimeSlice();
00162         }
00163 #endif // __RS485_DEBUG__
00164         return (nxtGetAvailHSBytes() == 0);
00165 }
00166 
00167 /**
00168  * Append an array of bytes to a tMassiveArray buffer, starts at index in the buffer
00169  * and copies nLength bytes.
00170  * @param buf the buffer to copy to
00171  * @param index the position in buffer where to start appending to
00172  * @param pData the data to be appended to buf
00173  * @param nLength the length of the data to be appended
00174  * @return the new 'tail' position of buf at which to append.
00175  */
00176 int RS485appendToBuff(tMassiveArray &buf, const short index, const ubyte *pData, const short nLength)
00177 {
00178   if (index == 0) memset(buf, 0, sizeof(buf));
00179 
00180   memcpy(&buf[index], pData, nLength);
00181   return index + nLength;
00182 }
00183 
00184 
00185 /**
00186  * Append a string a tMassiveArray buffer, starts at index in the buffer
00187  * @param buf the buffer to copy to
00188  * @param index the position in buffer where to start appending to
00189  * @param pData the string to be appended to buf
00190  * @return the new 'tail' position of buf at which to append.
00191  */
00192 int RS485appendToBuff(tMassiveArray &buf, const short index, string pData)
00193 {
00194   if (index == 0) memset(buf, 0, sizeof(buf));
00195 
00196   memcpy(&buf[index], pData, strlen(pData));
00197   return index + strlen(pData);
00198 }
00199 
00200 
00201 /**
00202  * Append a string a tBigByteArray buffer, starts at index in the buffer
00203  * @param buf the buffer to copy to
00204  * @param index the position in buffer where to start appending to
00205  * @param pData the string to be appended to buf
00206  * @param nLength the length of the data to be appended
00207  * @return the new 'tail' position of buf at which to append.
00208  */
00209 int RS485appendToBuff(tBigByteArray &buf, const short index, const ubyte *pData, const short nLength)
00210 {
00211   if (index == 0) memset(buf, 0, sizeof(buf));
00212 
00213   memcpy(&buf[index], pData, nLength);
00214   return index + nLength;
00215 }
00216 
00217 
00218 /**
00219  * Append a string a tBigByteArray buffer, starts at index in the buffer
00220  * @param buf the buffer to copy to
00221  * @param index the position in buffer where to start appending to
00222  * @param pData the string to be appended to buf
00223  * @return the new 'tail' position of buf at which to append.
00224  */
00225 int RS485appendToBuff(tBigByteArray &buf, const short index, const string pData)
00226 {
00227   if (index == 0) memset(buf, 0, sizeof(buf));
00228 
00229   memcpy(&buf[index], &pData, strlen(pData));
00230   return index + strlen(pData);
00231 }
00232 
00233 
00234 /**
00235  * Initialise the port, setup buffers
00236  */
00237 void RS485initLib(long baudrate=230400) {
00238   nxtEnableHSPort();
00239   nxtHS_Mode = hsRawMode;
00240   nxtSetHSBaudRate(baudrate);
00241   rxTimer = TMRnewTimer();
00242   memset(RS485rxbuffer, 0, sizeof(RS485rxbuffer));
00243   memset(RS485txbuffer, 0, sizeof(RS485txbuffer));
00244 }
00245 
00246 
00247 
00248 void RS485clearRead(bool sendnewline = false)
00249 {
00250   ubyte nDymmyData[] = {13};
00251   if(sendnewline)
00252   {
00253           nxtWriteRawHS(&nDymmyData[0], 1);   // Send the carriage return
00254           wait1Msec(10);
00255         }
00256   while(nxtGetAvailHSBytes()> 0){
00257     nxtReadRawHS(&nDymmyData[0], 1);    // Read the response.  Probably an error.
00258     EndTimeSlice();
00259   }
00260 }
00261 
00262 
00263 bool RS485sendString(string &data)
00264 {
00265   memcpy(RS485txbuffer, data, strlen(data));
00266   return RS485write(RS485txbuffer, strlen(data));
00267 }
00268 
00269 bool RS485sendString(char *data)
00270 {
00271   memcpy(RS485txbuffer, data, strlen(data));
00272   return RS485write(RS485txbuffer, strlen(data));
00273 }
00274 
00275 #endif // __RS485_H__
00276 
00277 /*
00278  * $Id: common-rs485.h 133 2013-03-10 15:15:38Z xander $
00279  */
00280 /* @} */
00281 /* @} */