Show Posts
Pages: 1 ... 4 5 [6]
76  Forum 2005-2010 (read only) / Development / Problem with arrays of strings on: November 15, 2010, 05:00:11 pm
I'm having a problem manipulating arrays of string. I'm working on an app that needs to send SMS messages, but if the SMS can't be sent (i.e. no network coverage) then the message needs to be saved to an array to be sent later when the coverage is better. If the array of messages gets full, then I need to discard the oldest message, and add a new one to the 'new' end of the array (using 'addMessage' and 'leftShiftArray'). When there is network coverage, the most recent message in the array will be delivered, and the sent message will be removed from the array (using  rightNullArray). All the variables and arrays are global. Code snippets are attached.

All of these code snipets work most of the time, but normally after a few iterations (maybe a dozen) either I spot some corruption in the array contents, or it hangs at the line “sms_list[sms_list_size]=strdup(curr_mess);” in addMessage. I'm not sure if I'm using the 'free' command correctly, the code didn't work at all until I added it, but I've since learnt from other postings on the forum that 'free' should only be used to free memory allocated using 'memalloc'. Any advice would be appreciated.

Kind Regards

Code:

const int sms_len = 160;                            //maximum allowable SMS length
char sms_mess[sms_len+1];                  //full sms message
const int max_sms_list_size = 10;           //number of unsent SMSs that can be stored
char *sms_list[max_sms_list_size+1]; //array of messages, as yet un-transmitted
char curr_mess[sms_len+1];                       //current sms.

void addMessage()
{
  //add a new message to the array. Records will be added as they arrive from left to right.
  //therefore the rightmost fix should always be the most recent
  
  if (sms_list_size == max_sms_list_size)
  {
    //The array of fixes is already at maximum, therefore discard the oldest fix
    //to make room for the newest.
    leftShiftArray();
  }

  //add fix to array
  sms_list[sms_list_size]=strdup(curr_mess);
  sms_list_size++;  //increment the counter that records the number of SMSs waiting to be transmitted.
}

void leftShiftArray()
{
  //shift the entire contents of the SMS array left one element. The leftmost element will be lost and
  //a space will be freed up on the righthand side
  free(sms_list[0]);                     //frees up the memory for the 1st (i.e. leftmost element in the array)
  for (int n=0; n<=sms_list_size-1; n++)
  {
    sms_list[n]=sms_list[n+1];
  }
  sms_list[sms_list_size]=0;             //frees up the pointer to the memory
  sms_list_size--;                       //decrement the counter that records the number of fixes waiting to be transmitted.
  sms_lost++;                            //increment the counter that records those SMS's lost due to lack of buffer space
}


void rightNullArray()
{
  //Set the rightmost element (i.e. the most recent message) of the message array to null. This is only used after a
  //message has been succesfully sent and the space needs to be freed up from the array.

  free(sms_list[sms_list_size-1]); //free up the memory
  sms_list[sms_list_size-1]=0;     //delete/reset the pointer to the memory
  sms_list_size--;                 //decrement the size counter
}

77  Forum 2005-2010 (read only) / Development / Re: Problem porting sketches from Duemilanove to Mega on: November 15, 2010, 02:53:40 pm
Yup - you're right PaulS - I was mis-counting. The basic problem was that I reading from the buffer to infrequently, I guess a character must have been droped here and there. I've upped the frequency and now it works fine.

Thanks for your help
78  Forum 2005-2010 (read only) / Development / Re: Problem porting sketches from Duemilanove to Mega on: November 15, 2010, 06:02:53 am
Yup -  that's it.

Reading from the serial port more frequently so that no more that 20-30 characters are read each time seems to improve the accuracy of the data. Still not sure why it's different with the Mega, but at least the issue is solved.

79  Forum 2005-2010 (read only) / Development / Re: Problem porting sketches from Duemilanove to Mega on: November 15, 2010, 05:17:45 am
just an idea, but does it make any difference how frequently data is read from the GPS? I've just notices that each time the GPS is read between 50 and 150 characters are processed. Could there be some buffering issues here? should I be reading the GPS signal more often and takeing fewer bytes each read?

Regards
80  Forum 2005-2010 (read only) / Development / Problem porting sketches from Duemilanove to Mega on: November 15, 2010, 05:04:25 am
Hi,

I've reached the memory limits of the Duemilanove so have recently ported a GPS sketch to a Mega2560. The sketch is designed to read GPS data from an external GPS device that's transimitting NMEA sentences at a rate of 4800 b/s via a Max232 converter.

The only software differences between the original sketch and the one now running on the mega is that the original was using the NewSoftSerial library to read the data over ports 2 and three and the new one uses Serial1 on pins 18 and 19 of the Mega. (I've tried serial 2 and 3 too)

Now here's the problem - the orignal sketch indicated that about 95% of NMEA senetences are valid, for my application this was an acceptable figure. However, on the Mega version only about 20% are VALID.

For those not familar with NMEA sentences, the last two characters are checkdigits formed by XORing all the previous bytes in the record, this is what I've been using to confirm the validity of each sentence.

My skteches and library are too large to be included here, does anyone have any suggestions as to what might be wrong?

Finally, I've tried displaying the NMEA records as they arrive, and they all look to the untrained eye to be ok (no weird characters etc, nothing obviously truncated or missing).
81  Forum 2005-2010 (read only) / Interfacing / Re: Hot swapping Arduino SD cards on: January 05, 2011, 12:48:11 pm
Quote
Writing new data without updating the directory that points to it renders the new data invisible and useless

How do I 'update the directory'?

I've been writing to files in the root directory, after writing I close the file and then it appears to be usable. Am a I supposed to be 'updating the directory' to, or does closing the file automatically update the directory?

Regards
82  Forum 2005-2010 (read only) / Interfacing / Hot swapping Arduino SD cards on: January 05, 2011, 12:12:43 pm
I'm working with an SD drive plugged into an Arduino Mega.

Is it Ok to remove and replace the SD card whilst the Arduino is powered up? I know that if put the SD card into a laptop I'm supposed to 'eject' the drive before actually removing it, but this is to do with the caching that the laptop does. I know the arduino isn't caching anything so can a remove and replace the card anytime? Obviously if the card is removed during a read or write operation then this will fail, but will it do any permanent damage to the card?

If I remove the card whilst a file is open (but not being changed) will it corrupt the open file? In practice it doesn't seem to, but maybe I've just been lucky?

Regards
83  Forum 2005-2010 (read only) / Interfacing / Connecting GPS to Arduino - RS232 question on: November 02, 2010, 12:24:41 pm
Hi,

I'm trying to connect an old GPS unit to an Arduino. The GPS has no useful documentation, however it did come with a lead that allowed it to be plugged into the COM1 port on a PC. It's not a USB lead, it's an old 25-way 'D' connector. There's no converter / adapter on the lead, so it's a direct connection from GPS to computer. I assume that the COM1 port on the back of the computer will use RS232 voltage levels? If this is correct then the GPS must also be using RS232 voltage levels? Therefore the GPS must NOT be wired directly to the Arduino?

I assume therefore that I need an RS232 shield such as the one provided by CuteDigi http://www.cutedigi.com/product_info.php?products_id=4329. Judging from the shield schematic it communicates with the Arduino via pins 0 and 1. Since I'm already using these 2 pins for talking to several other devices, I think I can hack the RS232 shield to connect to pins 2 and 3 instead, but if I do this I believe I have to do this in conjunction with using the NewSoftSerial Library?

Finally, I assume that if I were to use a Arduino Mega instead, then I could hack the shield to connect to pins 14 and 15 instead, and wouldn't have to use the NewSoftSerial library?

There's a lot of assumptions here, can anyone confirm which if any are correct?

Regards
84  Forum 2005-2010 (read only) / Interfacing / GSM Shield issues on: October 11, 2010, 03:01:06 pm
Hi,

I've recently got a GSM playground shield from HW kitchen and have been trying to get to know it but have encountered a few problems. I've succesfully run their test sketches to send an SMS and run AT commands. So far so good. Then I started writing my own sketches. My first bit of code simply ran through a number of AT comands to fetch basic information from the GSM module such as IMEI, make, model and serial number. I then tried to call the function to check that the shield is registered to a phone network before sending an SMS that contains the information just pulled from the module. The offending lines are highlighted in the sketch.

Code:
#include "GSM.h"  

#ifndef DEBUG_PRINT
  #error "!!! It is necessary to enable DEBUG_PRINT macro in the GSM.h !!!"
#endif
int n=0;
char atCmd[12];  
char* atMean;
String x;
int sigStrenth;
char disp[180]; //characters to be displayed
char disp2[180]; //characters to be displayed
int freeMem=0;  //available memory
char sms_num[]="0123456789";
int z=0;
long loop_count=0;
byte ret_val2=0;

// definition of instance of GSM class
GSM gsm;

const char* IMEI = "IMEI";
const char* MODEL = "Model";
const char* MAKER = "Maker";
const char* VER = "Version";
const char* STRENGTH = "Sig strength";
const char* REG = "Registered?";
const char* DATE = "Date";
const char* NETOP = "Network";
const char* SERNUM = "Serial Num.";

// sms return variable
char ret_val;

char strOut3[50];   //this will be a trimmed down version of the modem output, so it can be a lot smaller

void setup()
{
  // initialization of serial line
  gsm.InitSerLine(115200);
  
#ifdef DEBUG_PRINT
  gsm.DebugPrint("Starting TestSMS2.pde A\r\n",0);
  // print library version
  sprintf(disp,"Debug Library version <%4d>",gsm.LibVer());
  gsm.DebugPrint(disp,1);
#endif

  //Even before 'Turning On' the module send a reset command. Hopefully this may force it to start behaving itself.
  gsm.SendATCmdWaitResp("ATZ", 2000, 200, "OK", 5);
  
  // turn on GSM module
  gsm.TurnOn();
  // set direction for GPIO pins
  gsm.SetGPIODir(GPIO10, GPIO_DIR_OUT);
  gsm.SetGPIODir(GPIO11, GPIO_DIR_OUT);

}

void loop()
{

  //select a different AT command each time we process the loop
  switch (n)
  {
  case 0:
    strcpy(atCmd,"AT+CGSN");
    atMean = (char*)IMEI;
    break;
  case 1:
    strcpy(atCmd,"AT+CGMM");
    atMean = (char*)MODEL;
    break;
  case 2:
    strcpy(atCmd,"AT+CGMI");
    atMean = (char*)MAKER;
    break;
  case 3:
    strcpy(atCmd,"AT+CGMR");
    atMean = (char*)VER;
    break;
  case 4:
    strcpy(atCmd,"AT+CSQ");
    atMean = (char*)STRENGTH;
    break;
  case 5:
    strcpy(atCmd,"AT+CREG?");
    atMean = (char*)REG;
    break;
  case 6:
    strcpy(atCmd,"AT+COPS?");
    atMean = (char*)NETOP;
    break;
  case 7:
    strcpy(atCmd,"AT+GSN");
    atMean = (char*)SERNUM;
    break;
  case 8:
    strcpy(atCmd,"AT+CCLK?");
    atMean = (char*)DATE;
    n=-1;
    break;
  }
  n++;
  
  //run the AT command against the modem, each time the loop runs a different AT command will be chosen.
  ret_val = gsm.SendATCmdWaitResp(atCmd, 1000, 100, "", 1);
  
  // now we are waiting for response from the GSM module
  // ---------------------------------------------------
  if (ret_val != AT_RESP_ERR_NO_RESP) {
    //Parse the output buffer BEFORE doing any DebugPrint - remember a DebugPrint will alter the output buffer
    parseOutput3();
    
    // ----------------------------------------------------------
    if (strcmp("Sig strength",atMean)==0)
    {
      //if we're checking for signal strength, then need to some further parsing
      sigStrenth=stripSigStrenth();
      
      sprintf(disp,"Request for <%s>, using <%s>, returned value <%d>. ",atMean, atCmd, sigStrenth);
    }
    else
    {
      //result is an array of char, so need to format the output differently
      sprintf(disp,"Request for <%s>, using <%s>, returned value <%s>. ",atMean, atCmd, strOut3);
    }
    
    //Display the results of whatever the previous AT comand was.
    gsm.DebugPrint(disp,1);

//IF THE NEXT THREE LINES ARE ENABLED THE WHOLE SKETCH STOPS WORKING
//    ret_val2=gsm.CheckRegistration();
//    sprintf(disp2,"After checking reg, result is <%i> (1 means registered). ",ret_val2);
//    gsm.DebugPrint(disp2,1);


//IF THE NEXT IF STATEMENT IS UN-COMMENTED THEN THE SKETCH STOPS WORKING
//     //The 1st time round the loop the results of the first command will be SMSed, the
//     //2nd time round the second command will be sent and so on.
//     if ((n==0 && z==0) || (n==1 && z==1) || (n==2 && z==2) || (n==3 && z==3))
//     {
//       gsm.SendATCmdWaitResp("AT+CMGF=1", 500, 20, "OK", 5);  //set modem to text mode
//       gsm.DebugPrint("About to send SMS\r\n",1);
//       ret_val=gsm.SendSMS(sms_num, disp);
//       sprintf(disp,"After sending SMS, result is <%i>. (1 means sent ok) ",ret_val);
//       gsm.DebugPrint(disp,1);
//       z++;
//     }
  }
  else {
    // this should not happen
    gsm.DebugPrint("We have received nothing, something is wrong...", 1);

  }
  
  //pause and then try another command
  delay(1000);
  
  loop_count++;
}


void parseOutput3()
{
  strOut3[0]=0;  //empty the array
  
   //strip out any non-printing characters from the command buffer. Keep anything that is printable
   int i=0;
   int y=0;
   while (gsm.comm_buf[i] != 0)  //check all characters until the end
   {
     if ((gsm.comm_buf[i] >= 32) && (gsm.comm_buf[i] <= 126))
     {
        strOut3[y] = char(gsm.comm_buf[i]);
        y++;
     }
     i++;
   }
  
   //if the last characters are "OK", then remove them
   if ( char(strOut3[y-2])=='O' && char(strOut3[y-1])=='K' )
   {
     strOut3[y-2]=0;
   }
   else  
   {
     strOut3[y] =0;  //stick a null terminator on the end
   }
}

int stripSigStrenth()
{
  //Given the modem buffer after requesting the signal strength, try to parse
  //it out of the array. The results normaly look like this... "+CSQ: 13,7"
  //need to extract the integer between the colon and the space.
  char from=':';
  char to=',';
  char strength[3+1];
  bool found1=false;
  bool found2=false;
  int y=0;
  int i=0;
  int sigStren=0;
  
   while (strOut3[i] != 0)  //check all characters until the end
   {
     //look for the end character
     if (char(strOut3[i]) == to)
     {
       found2=true;
     }

     //any character between the start and end is one we're interested in.
     if ((found1==true) && (found2==false))
     {
       //Check that the ascii value of this character is between 48 and 57 - i.e. between numerals 0 and 9
       if ((strOut3[i] >='0') && (strOut3[i] <='9') )
       {
        strength[y] = strOut3[i];
        y++;
       }
     }


     if (y >=49)
     {
       gsm.DebugPrint("Overflow...", 1);
     }
    
     //look for the start character
     if (char(strOut3[i]) == from)
     {
       found1=true;
     }
    
     strength[y] = '\0';  //terminate with a null character
    
     i++;
   }
      
   sigStren=atoi(strength);  //Convert strength to an integer
    
   strength[0]='\0';  //release the memory
   return sigStren;

}

int availableMemory()
{
  int size = 1024; // Use 2048 with ATmega328
  //int size = 2048;
  byte *buf;

  while ((buf = (byte *) malloc(--size)) == NULL)
    ;

  free(buf);

  return size;
}


The offending function call (gsm.CheckRegistration) works fine in the other sketches, but when I enable it in this one the sketch still compiles and loads without problems but won't run (it doesn't just crash when it get's there - the whole sketch hangs on the first line)

I'm using an arduino duemilanove with version 21 software and a GSM playground (hardware version 1.6) with the latest version of their libraries. (I have tried to contact them, but no response so far). The shield will send a SMS when using the example sketches, so I'm assuming it's working ok. My sketch is getting sensible results from the AT commands it invokes so I must be talking to it OK. One of the AT commands I'm sending gets the signal strength, and another gets the network registration, so I know I'm connected with an adeqaute signal.

Any help appreciated.

Regards

Mike.
85  Forum 2005-2010 (read only) / Interfacing / Cheap Arduino GPRS solution on: September 20, 2010, 07:21:58 am
Hi,

I've just completed a prototype Arduino device that uses a GPRS shield to send SMS's. I now need to make about a dozen more identical modules. The problem is cost, most GPRS shields seem to cost in the range $70 - $120 (plus tax and postage). On the other hand I can get a USB host shield for less than $20 and USB GPRS dongle for less than $10 (for example the HUAWEI E1750 USB stick).

What I'd like to do is interface the GPRS dongle straight to the arduino via the USB host shield. Is this feasible? How difficult is it? has anyone done this before? I have no idea how to write a suitable driver, can anyone point me in the right direction?

Cheers
86  Forum 2005-2010 (read only) / Interfacing / Re: Arduino to Mobile phone to SMS on: August 03, 2010, 09:28:54 am
thanks, but I had thought that the AT commands were supposed to conform to some form of international standard? I just want to send SMS's. I'm not interested in interrorgating the phone, checking for new SMS's or looking up phone numbers on the SIM card or doing any other phone specific stuff, I just want to send SMS's, nothing else. I would however like to be able to plug in any phone and use that without having to change code.
87  Forum 2005-2010 (read only) / Interfacing / Arduino to Mobile phone to SMS on: August 03, 2010, 07:32:56 am
I'm (thinking of) starting a new project. I want to interface an Arduino to a mobile phone (not a modem) and use the Arduino to send out SMS messages via the phone. I understand I need to use "AT" commands to do this, but that's the extent of my knowledge so far. Is anyone aware of any published projects that show how to do this? I'd like to see some code examples, or even better a suitable library.

Any help appreciated
88  Forum 2005-2010 (read only) / Interfacing / Interfacing a GPS to Arduino using NewSoftSerial on: August 21, 2010, 05:09:18 am
Hi,

I'm having a trouble using NewSoftSerial to read data from a GPS. I'm using a very basic sketch (attached), but I just get strings of garbage on the screen

I can read the GPS data using hyperterminal without problems, it auto-detects the connections settings as 4800 baud, 8 bit, no parity. The data displayed by hyperterminal is fine, so I know the GPS is working.

Any suggestions appreciated.

Thanks

Mike

#include <NewSoftSerial.h>

NewSoftSerial mySerial =  NewSoftSerial(2, 3);

#define BUFFSIZ 90 // plenty big
char buffer[BUFFSIZ];
char buffidx;

void setup()
{
  Serial.begin(4800);
  mySerial.begin(4800);
  Serial.println("\n\rNewSoftSerial + GPS test");
}
 
void loop()
{
  Serial.print("\n\rread: ");
  readline();
}

void readline(void) {
  char c;
  buffidx = 0; // start at begninning
  while (1) {
      c=mySerial.read();
      if (c == -1)
        continue;
      Serial.print(c);
      if (c == '\n')
        continue;
      if ((buffidx == BUFFSIZ-1) || (c == '\r')) {
        return;
      }
      buffidx++;
  }
}
89  Forum 2005-2010 (read only) / Interfacing / Re: SMS and port monitoring on: August 20, 2010, 11:43:21 am
Ok, I've learn what I'm doing wrong. The arduino and phone are both USB devices (or slaves). Two USB slaves can't talk to each other directly, one has to be a host and the other a slave.

Need to purchase a USB host shield to achieve this.
90  Forum 2005-2010 (read only) / Interfacing / SMS and port monitoring on: August 19, 2010, 03:45:49 am
Hi, I'm attempting to use an Arduino to control a mobile phone send an SMS. The principle seems to be quite simple, 1) send a command to set the phone to SMS mode, 2) set the phone number, 3) send the message. I've managed to write a similar bit of code using C# .Net so I'm reasonably sure that I've got the correct commands and the phone is working. The problem is getting the same commands to work on the arduino.

When I leave the arduino plugged into my PC and monitor it's output the characters it sends seem to be correct, but when I remove the PC and connect it to the phone itself nothing happens.

I have two questions
1)      Any ideas why it's not working?
2)      How can I monitor the communications between the arduino and phone? It seems I can use a split USB lead to connect the arduino to both the phone and PC at the same time, but the serial monitor will only pick up the data from the arduino, not any data coming back from the phone to the arduino.

A code snipet follows........

  //first go.....
  Serial.flush();
  delay(1000);
  Serial.println("");
  Serial.print("AT+CMGF=1");          //set to SMS mode
  Serial.print(13,BYTE);
  Serial.print(10,BYTE);
  
  delay(1000);
  Serial.print("AT+CMGS=\"123456789\"");  //set the phone number (wrapped in double quotes)
  Serial.print(13,BYTE);                    //Carriage return and line feed
  Serial.print(10,BYTE);

  delay(1000);
  Serial.print("hello world");
  Serial.print(26,BYTE);                  //'ctrl+z' or 'SUB'
  delay(500);
  Serial.print(13,BYTE);                  //Carriage return and line feed
  Serial.print(10,BYTE);

  //Second attempt.......
  Serial.flush();
  delay(1000);
  Serial.println("AT+CMGF=1");          //set to SMS mode
  
  delay(1000);
  Serial.println("AT+CMGS=\"123456789\"");  //set the phone number

  delay(1000);
  Serial.print("hello world2");
  Serial.print(26,BYTE);                  //'ctrl+z' or 'SUB'
  Serial.println("");
Pages: 1 ... 4 5 [6]