
Description
Hi
I'm relatively new to everything here, but I've been spending a lot of time developing some sketches, and, until now, everything's been working fine.
For some reason the attached sketch cannot finish compiling. The little progress bar only gets to about 20%, and the compiler gives an error that starts with "Exception in thread "Thread-4256" java.lang.StackOverflowError", and is followed by hundreds of lines starting with "at java.util.regex.Pattern$".
It looks like this:
Exception in thread "Thread-4256" java.lang.StackOverflowError
at java.util.regex.Pattern$CharProperty.match(Pattern.java:3344)
at java.util.regex.Pattern$Branch.match(Pattern.java:4114)
at java.util.regex.Pattern$GroupHead.match(Pattern.java:4168)
at java.util.regex.Pattern$Loop.match(Pattern.java:4295)
at java.util.regex.Pattern$GroupTail.match(Pattern.java:4227)
at java.util.regex.Pattern$BranchConn.match(Pattern.java:4078)
at java.util.regex.Pattern$CharProperty.match(Pattern.java:3345)
at java.util.regex.Pattern$Branch.match(Pattern.java:4114)
at java.util.regex.Pattern$GroupHead.match(Pattern.java:4168)
at java.util.regex.Pattern$Loop.match(Pattern.java:4295)
... and it goes on and on and.
Please take a look and see if I'm missing something. I lack experience
Please note: a lot of the code is copied from previous sketches.
Oh, and it's still a work in progress, not a polished piece of machinery
Thanks, and forgive the newbie tendencies
Here is the code:
#include <SoftwareSerial.h> // required to send and receive AT commands from the GPRS Shield
#include <Wire.h> // required for I2C communication with the RTC
// pin numbers for RTC
#define DS3231_I2C_ADDRESS 104 // 0x68 // Address for RTC
#define DS3231_TIME_CAL_ADDR 0 // 0x00
#define DS3231_ALARM1_ADDR 7 // 0x07
#define DS3231_ALARM2_ADDR 11 // 0x0B
#define DS3231_CONTROL_ADDR 14 // 0x0E
#define DS3231_STATUS_ADDR 15 // 0x0F
//#define DS3231_AGING_OFFSET_ADDR 16 // 0x10
#define DS3231_TEMPERATURE_ADDR 17 // 0x11
// Declarations for GPRS shield
SoftwareSerial GPRS( 7, 8 ); // A softwareSerial line is defined for the GPRS Shield
byte buffer[ 64 ]; // Buffer is used to transfer data from the GPRS line to the serial line
int count = 0, e = 0, count2 = 0, t = 0, q;
char temp, lastCaller[13] = "blank";
boolean callIncoming = false, done;
// Declarations for RTC
byte time[ 7 ]; // second, minute, hour, dow, day, month, year
byte time_A1[ 5 ]; // second_A1, minute_A1, hour_A1, day_A1, DY/DT
byte time_A2[ 4 ]; // minute_A2, hour_A2, day_A2, DY/DT
byte received[1]; // used to catch bytes sent from the clock
float temperature; // clock temperature is updated every 64 s
// Declarations for RemoteCallLogger
char telescopeNames[6][4];
/*
Code Exclusively for GPRS shield:
*/
//
// Default set of instructions for GPRS Shield power control
//
void setPowerStateTo( int newState )
{
if( newState != 1 && newState != 0 ) { // tests for an invalid state. In this case no change is made to powerstate
Serial.print( "Error: Invalid powerstate. Current powerstate = " );
Serial.print( getPowerState() );
Serial.print( "\n" );
}
else {
if( newState == getPowerState() ) { // if the requested powerstate is already in effect, no action is taken
Serial.print( "Powerstate = " );
Serial.print( newState );
Serial.print( " remains unchanged.\n" );
}
else {
powerUpOrDown(); // This is the only case where the powerstate is changed
Serial.print( "Powerstate changed from " );
Serial.print( 1 - newState );
Serial.print( " to " );
Serial.print( newState );
Serial.print( "\n" );
}
}
delay( 5000 ); // for startup
}
int getPowerState() // returns 0 if GPRS Shield is off, and 1 if GPRS Shield is on. This corresponds to the constant HIGH LOW enumeration
{
int ret;
if ( digitalRead(18) == 0 && digitalRead(19) == 0 ) // tests pins 18 and 19 for activity. See ExFoundImportantPins sketch to find out why
ret = 1;
else
ret = 0;
return ret;
}
void powerUpOrDown() // toggle the power of the shield
{
pinMode( 9, OUTPUT );
digitalWrite( 9, LOW );
delay( 1000 );
digitalWrite( 9, HIGH );
delay( 2000 );
digitalWrite( 9, LOW );
delay( 3000 );
}
//
// End of default power control
//
void clearBufferArray() // gives each element in the buffer array a null value
{
for( int i = 0; i < count; i++ )
buffer[ i ] = NULL;
}
void makeMissedCall( char num[] )
{
int i;
char in[ 18 ] = "ATD";
for( i = 3; i <= 14; i++ ) // AT command string containing telephone number is prepared
in[ i ] = num[ i - 3] ;
in[ 15 ] = ';';
in[ 16 ] = '\r';
in[ 17 ] = '\0';
GPRS.write( in ); // AT command requesting call is sent
delay( 10000 ); // enough time is given for GSM connection, and at least one ring.
GPRS.write( "ATH\r\0" ); // AT command requesting hangup is sent
delay( 1000 );
}
void sendTextMessage( char number[], char messg[] )
{
char temp[ 27 ] = "AT + CMGS = \"";
for( q = 0; q < 12; q++ ) // for-loop is used to prepare the AT command string containing the telephone number
temp[ q + 13 ] = number[ q ];
temp[ 25 ] = '\"';
temp[ 26 ] = '\0';
GPRS.println( "AT+CMGF=1\r" ); // AT command requesting SMS in text mode is sent
delay( 1000 );
GPRS.println( temp ); // AT command containing telephone number is sent
delay( 1000 );
GPRS.println( messg ); //the content of the message
delay( 1000 );
GPRS.println( (char) 26 ); //the ASCII code of the ctrl+z is 26. This character indicates the end of the message.
delay( 1000 );
}
void analise(byte incoming[], int length) // this function receives and analyses all text sent from the GPRS Shield to the serial line. It stores the cell number of the last caller.
{
e = 0; // Counter that represents a letter in the buffer
done = false; // Boolean that prevents unneccessary loop revolutions
while( e < length && !done){ // while e does not surpass the last letter index of the buffer...
temp = char( incoming[e] ); // store the character at index e in a temporary char
switch( temp ){ // inspect temp
case 'R':
{
if( length > e + 3 && !callIncoming ) { // This case responds to "RING"
if(char( incoming[e + 1] ) == 'I'
&& char( incoming[e + 2] ) == 'N'
&& char( incoming[e + 3] ) == 'G'){
GPRS.write("AT+CLCC\r"); // call information is requested
delay(500); // time is given for processing
GPRS.write("ATH\r"); // GPRS shield hangs up
callIncoming = true; // this ensures that a number cannot be stored in any other case than a missed call
done = true; // prevents the further operation of this while loop
}
}
}
break;
case '+':
{
if(char( buffer[ e + 1]) == '2' && length > e + 11 && callIncoming){ // this case responds to "+2", but only if the buffer contains enough characters for a valid cell number
for(t = 0; t < 12; t++) // and only if the callIncoming boolean had been triggered by a previous instance of this function
lastCaller[t] = char( buffer[ e + t ]); // the number of this caller is stored in lastCaller
lastCaller[12] = '\0';
callIncoming = false; // now we are ready for the next call
done = true; // prevents the further operation of this while loop
}
}
break;
case 'l':
Serial.println(lastCaller); // an easy way to test this function. Simply type "l" to see the value of lastCaller (default "blank")
break;
}
e++; // buffer index is incremented
}
}
/*
End of GPRS Shield code
*/
/*
Code exclusively for RTC
*/
byte decToBcd( byte b ) // converts a byte from a decimal format to a binary-coded decimal
{
return ( b / 10 << 4 ) + b % 10;
}
boolean getBit( byte addr, int pos ) // returns a single bit from a determined location in the RTC register
{
byte temp = getByte( addr );
return boolean( (temp >> pos) & B00000001 );
}
void setBit( byte addr, int pos, boolean newBit ) // ensures that a single bit from a determined location in the RTC register is a determined value
{
boolean oldBit = getBit( addr, pos ); // bits' current state is retrieved
byte temp = received[ 0 ]; // complete byte is retrieved. it is still left in received from the previous command
if ( oldBit != newBit ) // change is only made if the bit isnt already the correct value
{
if( newBit ) // if newBit is 1, then old bit must be 0, thus we must add an amount
temp += (B00000001 << pos); // 2 to the power of the bit position is added to the byte
else
temp -= (B00000001 << pos); // 2 to the power of the bit position is subtracted from the byte
}
setByte( addr, temp ); // the register is updated with the new byte
}
byte getByte( byte addr ) // returns a single byte from the given address in the RTC register
{
byte temp;
if( getBytes( addr, 1) ) // If one byte was read from the address:
temp = received[ 0 ]; // get that byte
else temp = -1; // -1 is returned as an error
return temp;
}
boolean getBytes( byte addr, int amount ) // updates the byte array "received" with the given amount of bytes, read from the given address
{ // ^ returns false if reading failed
boolean wireWorked = false;
Wire.beginTransmission( DS3231_I2C_ADDRESS ); // We transmit to the RTC
Wire.write( addr ); // We want to read from the given address
Wire.endTransmission(); // We want to receive, so we stop transmitting
Wire.requestFrom( DS3231_I2C_ADDRESS, amount ); // we request the given amount of bytes from the RTC
if( Wire.available() ){
received[amount]; // prepare the array for the amount of incoming bytes
for( int i = 0; i < amount; i++){
received[ i ] = Wire.read(); // we read the given amount of bytes
}
wireWorked = true; // everything went as planned
}
return wireWorked;
}
void setByte( byte addr, byte newByte ) // writes a given byte to a given address in the RTCs register. convenient
{
setBytes( addr, &newByte, 1); // call the setBytes function with the default amount = 1
}
void setBytes( byte addr, byte newBytes[], int amount ) // writes a given amount of bytes in a sequence starting from a given address
{
Wire.beginTransmission( DS3231_I2C_ADDRESS ); // We transmit to the RTC
Wire.write( addr ); // We want to start writing from the given address
for( int i = 0; i < amount; i++ )
Wire.write( newBytes[ i ] ); // we write each byte in sequence
Wire.endTransmission(); // we're done here
}
void getTime() // reads the current time from the register and updates the byte array containing the current time
{
if( getBytes( DS3231_TIME_CAL_ADDR, 7) ) // if 7 bytes were read in from the time address:
{
for(int i = 0; i < 7; i++) // place each byte in it's place
time[ i ] = received[ i ];
// The following conversions convert the values from binary-coded decimal format to regular binary:
time[ 0 ] = ( ( time[ 0 ] & B01110000 ) >> 4 ) * 10 + ( time[ 0 ] & B00001111 ); // second
time[ 1 ] = ( ( time[ 1 ] & B01110000 ) >> 4 ) * 10 + ( time[ 1 ] & B00001111 ); // minute
time[ 2 ] = ( ( time[ 2 ] & B00110000 ) >> 4 ) * 10 + ( time[ 2 ] & B00001111 ); // hour
time[ 4 ] = ( ( time[ 4 ] & B00110000 ) >> 4 ) * 10 + ( time[ 4 ] & B00001111 ); // day of month
time[ 5 ] = ( ( time[ 5 ] & B00010000 ) >> 4 ) * 10 + ( time[ 5 ] & B00001111 ); // month
time[ 6 ] = ( ( time[ 6 ] & B11110000 ) >> 4 ) * 10 + ( time[ 6 ] & B00001111 ); // year
}
}
void setTime( byte newTime[ 7 ] ) // sets the time in the RTC register to the given values
{
for(int i = 0; i < 7; i++)
newTime[i] = decToBcd(newTime[i]); // the time consists of 7 bytes, each which must be converted to binary-coded decimal
setBytes( DS3231_TIME_CAL_ADDR, newTime, 7 ); // bytes are sent to be written
}
void getRTCTemperature() // reads the temperature from the register and updates the global temperature float
{
//temp registers (11h-12h) get updated automatically every 64s
if( getBytes( DS3231_TEMPERATURE_ADDR, 2 ) ) // if 2 bytes were read from the temperature addresss
{
temperature = ( received[ 0 ] & B01111111 ); // assign the integer part of the integer
temperature += ( ( received[ 1 ] >> 6 ) * 0.25 ); // assign the fractional part of the temperature
}
}
void gprsListen()
{
if( GPRS.available() ) { // If the GPRS Shield is transmitting data to the Stalker...
while( GPRS.available() ) { // While there is still data left...
buffer[ count++ ] = GPRS.read(); // get the next byte of data
if ( count == 64 ) // we only handle a maximum of 64 bytes of data at a time
break;
}
Serial.write( buffer, count ); // Send the data to the serial line
analise( buffer, count );
clearBufferArray(); // clear the buffer
count = 0; // reset counter
}
if (Serial.available()) // if the Stalker is transmitting data....
GPRS.write(Serial.read()); // send the data to the GPRS Shield.
}
void printTime() // updates time, and prints it in a convenient format
{
getTime();
Serial.print( int( time[ 3 ] ) ); // dow
Serial.print( ' ' );
Serial.print( int( time[ 2 ] ) ); // hour
Serial.print( ':' );
Serial.print( int( time[ 1 ] ) ); // minute
Serial.print( ':' );
Serial.print( int( time[ 0 ] ) ); // second
Serial.print( ' ' );
Serial.print( int( time[ 4 ] ) ); // day
Serial.print( '/' );
Serial.print( int( time[ 5 ] ) ); // month
Serial.print( "/20" );
Serial.print( int( time[ 6 ] ) ); // year
Serial.println();
}
/*
End of RTC code
*/
void setup()
{
// GPRS Shield startup code
GPRS.begin( 9600 );
delay(1000);
setPowerStateTo(1);
delay(1000);
// RTC Startup code
Wire.begin();
delay(1000);
Serial.begin(9600);
delay(1000);
}
void loop()
{
gprsListen(); // GPRS Shield listener. Todo: replace w interrupt
getTime(); // Updates the time. Todo: replace w interrupt
}