Show Posts
Pages: 1 [2] 3
16  Using Arduino / Project Guidance / Re: Serial filtering program issues - running out of memory. on: July 14, 2013, 12:45:05 pm
I think there's one in HardwareSerial.cpp.
Apart from the "struct" part.

I'm looking at the HardwareSerial.cpp file now, Its hard for me to differentiate the hardware/setup portion from the actual ring buffer/struct portion. Ill be honest, When i look into libraries like this one, i get a little scared no knowing what it all does without learning c/c++ at a low level. Maybe im wrong and this is easier than i seems, but so far, everything i find on Google explaining this topic seems cryptic and vague. I'm sure these ring buffers/struct are built to suit for specific applications. Is there anyone on the forums that have experience with these things that could explain where i need to start.
17  Using Arduino / Project Guidance / Re: Serial filtering program issues - running out of memory. on: July 14, 2013, 11:57:58 am
Is there an example for implementing a ring/circlular buffer on a struct data type, with incoming data from a serial port?
18  Using Arduino / Project Guidance / Re: Serial filtering program issues - running out of memory. on: July 14, 2013, 10:14:47 am
I'm using a Mega 2560 to recieve data on the Serial1 port and filter the data, then send it back out the Serial2 port to a radio transmitter

Given that you seem to be dealing with a significant amount of real-world data that would need to be configured and maintained, and perhaps dealing with messages that are important (must be delivered accurately and reliably), I wonder whether an Arduino-based solution is the best approach. It would be easy to implement the whole solution on a PC with a couple of USB-to-TTL-serial adapters, which gives you effectively unlimited memory and processing power, vastly improved support for storing and managing your configuration data, logging and so on. The sketch you already have would run on a PC as a console application more or less as it is as a starting point, just replacing the Arduino Serial API with the corresponding PC OS serial API.


I actually did this already, and for several reasons including cost/reliability i didnt like the solution. I was considering a raspberry Pi. The arduino is hard to stop, where OS's on raspberry pi or a full Pc arent as stable/reliable. Right now logging isnt a must. Ive tested the current setup with great success, i think the arduino or similar chip would work great.
19  Using Arduino / Project Guidance / Re: Serial filtering program issues - running out of memory. on: July 14, 2013, 09:59:20 am
1000 rooms allows you to store ~ 8 bytes per room.
But then you have no stack space for calling functions, etc.

It would be helpful to understand a brief overview of your project. If you can throw the biggest memory board at it, that might solve your problem for free.

One flaw in your design, however, is that you are unnecessarily setting aside static memory for an unlikely scenario.

ie I am guessing you are setting up some sort of hospital / care facility response system, where patients (or staff) press buttons requesting certain services to be performed and this has to be logged and then a timer tracking response times.

My point being: it is unlikely that you will have 1000 rooms simultaneously requesting assistance. Even if you had half the rooms requesting it, as soon as a response has been handled, you don't need that data any more, and could reuse the memory it occupies fairly simply.

If you can create a basic data structure along the lines of (this is not code, it will not compile, extraneous brackets may be present):

Code:
struct requestType {
    byte room_name_pointer; // pointer to an array of room names
    byte room_floor;    // floor this room appears on
    byte room_number; /// guess ;-)
    byte service_requested; // pointer to an array of possible services
    int request_start_time;  // when we requested the service
(etc)
}

and then a circular buffer similar to what Serial library implements, based on the maximum concurrent requests expected to be current at any one time, +20% to +100%:

requestType request_buffer[200];

As an example, the Serial library can handle megabytes of input, as long as you process it in a timely fashion, despite the fact that the default Serial buffer is only 64 bytes in size.

If you are expecting 120 requests / hour (2 / minute) max, and the longest request response time is 1 hour (just as an example), then you'd only need to store 120 such requests, and for the majority of the time, you'd have less than that in the buffer waiting to be completed.


I seen that on the Arduino forum, but i have no idea how to utilize it. Your guess was almost dead on, it recieves the calls and send them to a paging transmitter . The arrays and timer arent used for checking on the response time, instead its used to re-page the call to different people. 120 calls an hour is actually a light load.  Please explain to me or guide me where I can learn about this data structure.
20  Using Arduino / Project Guidance / Re: Serial filtering program issues - running out of memory. on: July 14, 2013, 05:47:28 am
Please note that in versions of the IDE up to and including 1.0.3, the String library has bugs as discussed here and here.

In particular, the dynamic memory allocation used by the String class may fail and cause random crashes.

I recommend reworking your code to manage without String. Use C-style strings instead (strcpy, strcat, strcmp, etc.), as described here for example.

Alternatively, install the fix described here:  Fixing String Crashes

Preferably upgrade your IDE to version 1.0.4 or above at: http://arduino.cc/en/Main/Software


I'm currently running 1.0.5 and 1.5.

Consider that storing your booleans

Code:
boolean CallArray[ROOM_COUNT][LEVELS_COUNT];

requires ROOM_COUNT x LEVELS_COUNT bytes (90 x 13 = 1170 bytes) even though in effect you only require 1170 bits (~147 bytes) to do this effectively.

Also, consider you are storing values between 0 and 40 in your pagerArrays, but they are int arrays, requiring 2 bytes per array element. If the values being stored in the pagerarray are <= 255, you can get away with usng byte/char arrays.

So 4 x 90 x 3  x 2 = 2160 bytes, can be halved to 1080 bytes.

If you can use these 2 optimisations,  you could save around (1080 + 1023) = 2100 bytes.


Thanks for explaining it too me, ill try these optimizations first.

When I see things like this (even without understanding the code fully):
Code:
FLASH_STRING_ARRAY(ReplacementArch,
  PSTR("Room 101"),PSTR("Room 102"),PSTR("Room 103"),PSTR("Room 104"),PSTR("Room 105"),
  PSTR("Room 106"),PSTR("Room 107"),PSTR("Room 108"),PSTR("Room 109"),PSTR("Room 110"),
  PSTR("Room 111"),PSTR("Room 112"),PSTR("Room 113"),PSTR("Room 114"),PSTR("Room 115"),
  PSTR("Room 116"),PSTR("Room 117"),PSTR("Room 118"),PSTR("Room 119"),PSTR("Room 120") 
  );

my immediate thought is:
1. take the "Room" out as a constant
2. reduce the room number (currently 3 bytes) to a byte (1 byte).
3. if 1xx is the floor number, take the floor number out as a constant also, and then rooms can definitely be stored in a byte.

This trades off processing time for space, and requires a little more programming (as do my other suggestions).

The reason for this is that in the end each room wont be labeled the same, while most will say "Room" first , 20% or so will be entirely different.  "Public Restroom", "Staff Lounge".....


It's not going to say you memory, but any reason for not doing

Code:
int PagerArray[SOME_CONSTANT][ROOM_COUNT][3] = {
  {0} 
};


?


I assumed anything deeper than 2D was a no-no. Isn't that a 3D array?

Code:
  FLASH_STRING_ARRAY(CallLevels,
  PSTR("CODE PINK"), PSTR("CODE BLUE"), PSTR("FIRE"), PSTR("STAFF EMER"), PSTR("PRIORITY"), PSTR("BATH"), PSTR("ALARM"),
  PSTR("CORDOUT"), PSTR("PERS ATTN"), PSTR("STAFF"), PSTR("NORMAL"), PSTR("NURSE NEEDED"), PSTR("AIDE NEEDED"));

<snip>

  FLASH_STRING_ARRAY(ReplacementCallLevels,
  PSTR("CODE PINK"), PSTR("CODE BLUE"), PSTR("FIRE"), PSTR("STAFF EMER"), PSTR("PRIORITY"), PSTR("Bathroom Assistance Needed."),
  PSTR("ALARM"), PSTR("CORDOUT"), PSTR("PERS ATTN"), PSTR("STAFF"), PSTR("NORMAL"), PSTR("NURSE NEEDED"), PSTR("AIDE NEEDED"));

There's a lot of double up between these two. It seems you could replace the second array with an if for the one entry that does change (BATH) and save some more memory here.

The reason for this is that the incoming data contains text that is matched in CallLevels. Once it is found, the index that is found at is used on the ReplacementCallLevels to build the last message with new text. In the end there will be no duplicates between these two arrays. Example would be the relationship between "BATH" in CallLevels & "Bathroom assistance needed". "BATH" needs to be changed to "Bathroom assistance needed" when it leaves the arduino. 

Even with optimization, does it even seem that the arduino Mega will handle this at 500-1000 rooms? I have the 32bit Due to try it on as a last resort.
21  Using Arduino / Project Guidance / Serial filtering program issues - running out of memory. CONT. on: July 13, 2013, 11:25:10 pm
Additional functions.

Code:
void InitializeSD(){

  Serial << F("Initializing SD card...");

  if (!SD.begin(4)) {
    Serial << F("initialization failed!");
    Serial.println();
    return;
  }
  Serial << F("initialization done.");
  SDCardReady = true;
  Serial.println();




}







void LoadSettingsFromSD(){

  if(SDCardReady){

    myFile = SD.open("SETTINGS.txt");
    Serial << F("Loading Settings.");
    if (myFile) {




      while (myFile.available()) {
        Serial << F(".");


        ShiftType = (int) finder.getValue();
        Serial << F(".");
        Level0 = (int) finder.getValue();
        Serial << F(".");
        Level1 = (int) finder.getValue();
        Serial << F(".");
        Level2 = (int) finder.getValue();
        Serial << F(".");
        CallTimeout = (int) finder.getValue();
        Serial << F(".");       
        myFile.read();
        Serial << F(".");
      }
      // close the file:
      myFile.close();

      Serial << F(" Loaded 100%");
      Serial.println();
    }
    else {
      // if the file didn't open, print an error:
      Serial << F("ERROR - Cannot open! ");
      Serial.println();
    }

  }


}

void DebugSettings(){




  Serial << F("Shift Type = ");
  Serial.println(ShiftType);
  Serial << F("Level 0 = ");
  Serial.println(Level0);
  Serial << F("Level 1 = ");
  Serial.println(Level1);
  Serial << F("Level 2 = ");
  Serial.println(Level2);     
  Serial << F("CallTimeout = ");
  Serial.println(CallTimeout);
  Serial.println();
}



void LoadPagerArray0(){

  if(SDCardReady){
    myFile = SD.open("Shift0.txt");
    if (myFile) {
      Serial << F("Reading ");
      Serial.println("Shift0.txt");

     
      while (myFile.available()) {


        for(int i = 0;i<ROOM_COUNT;i++){
          int Level0 = (int) finder.getValue();
          int Level1 = (int) finder.getValue();
          int Level2 = (int) finder.getValue();

          Serial << F("Line ");
          Serial.print(i+1);
          Serial << F(" : ");
          Serial.print(Level0);
          Serial << F(", ");
          Serial.print(Level1);
          Serial << F(", ");
          Serial.print(Level2);

          PagerArray0[i][0] = Level0;
          PagerArray0[i][1] = Level1;
          PagerArray0[i][2] = Level2;

          Serial << F(" -> PagerArray0[");
          Serial.print(i);
          Serial << F("] = ");
          Serial.print(PagerArray0[i][0]);
          Serial << F(", ");
          Serial.print(PagerArray0[i][1]);
          Serial << F(", ");
          Serial.println(PagerArray0[i][2]);
        }

        myFile.read();
      }
      // close the file:
      myFile.close();
      Serial << F("done.");
      Serial.println();
    }
    else {
      // if the file didn't open, print an error:
      Serial << F("error opening ");
      Serial.println("Shift0.txt");
    }
  }
}

void LoadPagerArray1(){

  if(SDCardReady){


    myFile = SD.open("Shift1.txt");
    if (myFile) {
      Serial << F("Reading ");
      Serial.println("Shift1.txt");

 
      while (myFile.available()) {


        for(int i = 0;i<ROOM_COUNT;i++){
          int Level0 = (int) finder.getValue();
          int Level1 = (int) finder.getValue();
          int Level2 = (int) finder.getValue();

       
          PagerArray0[i][0] = Level0;
          PagerArray0[i][1] = Level1;
          PagerArray0[i][2] = Level2;

         
        }

        myFile.read();
      }
      // close the file:
      myFile.close();
      Serial << F("done.");
      Serial.println();
    }
    else {
      // if the file didn't open, print an error:
      Serial << F("error opening ");
      Serial.println("Shift1.txt");
    }

  }
}


void LoadPagerArray2(){

  if(SDCardReady){

    myFile = SD.open("Shift2.txt");
    if (myFile) {
      Serial << F("Reading ");
      Serial.println("Shift2.txt");

      // read from the file until there's nothing else in it:
      while (myFile.available()) {


        for(int i = 0;i<ROOM_COUNT;i++){
          int Level0 = (int) finder.getValue();
          int Level1 = (int) finder.getValue();
          int Level2 = (int) finder.getValue();

         
          PagerArray0[i][0] = Level0;
          PagerArray0[i][1] = Level1;
          PagerArray0[i][2] = Level2;

     
        }

        myFile.read();
      }
      // close the file:
      myFile.close();
      Serial << F("done.");
      Serial.println();
    }
    else {
      // if the file didn't open, print an error:
      Serial << F("error opening ");
      Serial.println("Shift2.txt");
    }
  }
}



void LoadPagerArray3(){

  if(SDCardReady){

    myFile = SD.open("Shift3.txt");
    if (myFile) {
      Serial << F("Reading ");
      Serial.println("Shift3.txt");

      // read from the file until there's nothing else in it:
      while (myFile.available()) {


        for(int i = 0;i<ROOM_COUNT;i++){
          int Level0 = (int) finder.getValue();
          int Level1 = (int) finder.getValue();
          int Level2 = (int) finder.getValue();


          PagerArray0[i][0] = Level0;
          PagerArray0[i][1] = Level1;
          PagerArray0[i][2] = Level2;


        }

        myFile.read();
      }
      // close the file:
      myFile.close();
      Serial << F("done.");
      Serial.println();
    }
    else {
      // if the file didn't open, print an error:
      Serial << F("error opening ");
      Serial.println("Shift3.txt");
    }
  }
}


22  Using Arduino / Project Guidance / Serial filtering program issues - running out of memory. on: July 13, 2013, 11:23:57 pm
Hi All,

     I'm using a Mega 2560 to recieve data on the Serial1 port and filter the data, then send it back out the Serial2 port to a radio transmitter. I need to use 2d arrays to hold boolean's and int's after certian data is received. I'm also comparing Strings in the program, and using the FLASH/PROGMEM library http://arduiniana.org/libraries/flash/ to store arrays of text for comparison and string output.

     The problem so far is that once i scale the application up, the memory drops, and the mega crashes. Is there a better, more memory efficient way of doing what i need to do? My program crashes at 90 rooms (defined in my code) with 505 bytes available, but i need to step it up to 500-1000 rooms. Do i need to use external storage? Please guide me to a better way of accomplishing this...


Example data sent into Serial1 : "07/04/13  14:44:05    100     NORMAL     CALL PLACED"





Code:
#include <Flash.h>
#include <Streaming.h>
#include <SimpleTimer.h>
#include <TextFinder.h>
#include <SD.h>


#define ROOM_COUNT 90  //MULTIPLIER THAT GROWS ARRAYS SIZE
#define LEVELS_COUNT 13
#define TRIGGERS_COUNT 2


File myFile;
TextFinder finder( myFile );






int ShiftType = 1;
int Level0 = 0;
int Level1 = 20;
int Level2 = 40;
unsigned int CallTimeout = 50; //defualt = 10800


SimpleTimer timer;





int PagerArray0[ROOM_COUNT][3] = {
  {0}  
};

int PagerArray1[ROOM_COUNT][3] = {
  {0}  
};

int PagerArray2[ROOM_COUNT][3] = {
  {0}  
};

int PagerArray3[ROOM_COUNT][3] = {
  {0}  
};



int CurrentShift = 0;
boolean SDCardReady = false;
String SDstring = "";
boolean SDstringComplete = false;


boolean CallArray[ROOM_COUNT][LEVELS_COUNT];
int TimeArray[ROOM_COUNT][LEVELS_COUNT];



String inputString = "";         // a string to hold incoming data
boolean stringComplete = false;

void setup()
{


  // Open serial communications and wait for port to open:
  Serial.begin(9600); // debug port.
  Serial1.begin(9600);
  Serial2.begin(9600);
  inputString.reserve(200);


   InitializeSD();
  LoadSettingsFromSD();
  DebugSettings();
  
  LoadPagerArray0();



  Serial << F("System Ready.") << "\r\n";


  for (int i=0; i<ROOM_COUNT; i++) {
    for (int x=0; x<LEVELS_COUNT; x++) {
      CallArray[i][x] = false;
      }
  }

  timer.setInterval(1000, ScanAndUpdateArrays);

  Serial.print("Available Memory: ");
  Serial.print(availableMemory());
  Serial.println(" bytes");  

}

void loop()
{
  serialEvent();
  serialEvent1();
  timer.run();
}









void serialEvent() {
  while (Serial.available()) {
    char inChar = (char)Serial.read();
    inputString += inChar;

    if (inChar == '\r') {
      stringComplete = true;
    }

    if (stringComplete) {
      inputString.trim();
      
      Finder_Engine(inputString);

      inputString = "";
      stringComplete = false;

      Serial.print("Available Memory: ");
      Serial.print(availableMemory());
      Serial.println(" bytes");
    }
  }
}

void serialEvent1() {
  while (Serial1.available()) {
    char inChar = (char)Serial1.read();
    inputString += inChar;

    if (inChar == '\r') {
      stringComplete = true;
    }

    if (stringComplete) {
      inputString.trim();
      
      Finder_Engine(inputString);

      inputString = "";
      stringComplete = false;

      Serial.print("Available Memory: ");
      Serial.print(availableMemory());
      Serial.println(" bytes");
    }
  }
}

int availableMemory()
{
  int size = 8000;
  byte *buf;
  while ((buf = (byte *) malloc(--size)) == NULL);
  free(buf);
  return size;
}



void Finder_Engine(String s){
  String ArchAddress;
  int RoomIndex = -1;
  String CallText;
  int CallIndex = -1;
  int TriggerIndex = -1;
  boolean CallBool;

  ArchAddress = s.substring(19, 30);
  ArchAddress.trim();

  char Arch[ROOM_COUNT][8]= {
    "101", "102", "103", "104", "105",
    "106", "107", "108", "109", "110",
    "111", "112", "113", "114", "115",
    "116", "117", "118", "119", "120"
  };





  for (int i=0; i<ROOM_COUNT; i++) {
    if (ArchAddress.indexOf(Arch[i]) >=0){
      RoomIndex = i;
    }    
  }


  CallText = s.substring(30);

  FLASH_STRING_ARRAY(CallLevels,
  PSTR("CODE PINK"), PSTR("CODE BLUE"), PSTR("FIRE"), PSTR("STAFF EMER"), PSTR("PRIORITY"), PSTR("BATH"), PSTR("ALARM"),
  PSTR("CORDOUT"), PSTR("PERS ATTN"), PSTR("STAFF"), PSTR("NORMAL"), PSTR("NURSE NEEDED"), PSTR("AIDE NEEDED"));

  for (int i=0; i<CallLevels.count(); i++) {

    char CallLevelsTmp[12];
    CallLevels[i].copy(CallLevelsTmp);
    if (CallText.indexOf(CallLevelsTmp) >=0){  //Call in Call Level Array (Call is Filtered)

      CallIndex = i;
    }
  }


  FLASH_STRING_ARRAY(CallTriggers,
  PSTR("CALL CANCELLED"), PSTR("CALL PLACED"));


  for (int i=0; i<CallTriggers.count(); i++) {

    char CallTriggersTmp[12];
    CallTriggers[i].copy(CallTriggersTmp);  
    if (s.indexOf(CallTriggersTmp) >=0){  //Call in Call Level Array (Call is Filtered)

      TriggerIndex = i;
    }
  }



  if((RoomIndex >=0 ) && (CallIndex >= 0)){ // Values not zero

    if(TriggerIndex == 1){  //if Call Placed

      if(ReturnArray(RoomIndex,CallIndex) == false){    // call not placed Yet
        UpdateArray(RoomIndex,CallIndex,TriggerIndex);  // Place call and page for the first time.
      }
      else {                                          // Call already placed
        UpdateArray(RoomIndex,CallIndex,TriggerIndex);  
      }
    }
    else if(TriggerIndex == 0){  //Call cancelled
      UpdateArray(RoomIndex,CallIndex,TriggerIndex);
    }    
  }
  else {              
    Serial << F("Bad/Ignored Data: ") << s << "\r\n";
  }
}

void UpdateArray(int room,int level, boolean b){
  CallArray[room][level] = b;

  Serial << F("Updating Array: ")<< room  << F(" and Level ") << level << F(" To : ") << b << "\r\n";

}

boolean ReturnArray(int room,int level){
  return CallArray[room][level];
}


void ScanAndUpdateArrays(){
  for (int i=0; i<ROOM_COUNT; i++) {
    for (int x=0; x<LEVELS_COUNT; x++) {

      if(CallArray[i][x] == 1){      

        if(TimeArray[i][x] == Level0){
          BuildPage(0, i,x);
        }

        if(TimeArray[i][x] == Level1){
          BuildPage(1, i,x);
        }

        if(TimeArray[i][x] == Level2){
          BuildPage(2, i,x);
        }

        if(TimeArray[i][x] == CallTimeout){
          
          CallArray[i][x] = 0;
          Serial << F("Boolean Array Timeout Code: ");
          Serial.print(i);
          Serial << F("-");
          Serial.println(x);
            
        }
        ++TimeArray[i][x];
      }
      else {
        TimeArray[i][x] = 0;
      }  
    }
  }
}

void BuildPage(int CodeLevel, int room, int text){
  
FLASH_STRING_ARRAY(ReplacementArch,
  PSTR("Room 101"),PSTR("Room 102"),PSTR("Room 103"),PSTR("Room 104"),PSTR("Room 105"),
  PSTR("Room 106"),PSTR("Room 107"),PSTR("Room 108"),PSTR("Room 109"),PSTR("Room 110"),
  PSTR("Room 111"),PSTR("Room 112"),PSTR("Room 113"),PSTR("Room 114"),PSTR("Room 115"),
  PSTR("Room 116"),PSTR("Room 117"),PSTR("Room 118"),PSTR("Room 119"),PSTR("Room 120")  
  );
  

  char RoomTmp[20];
  ReplacementArch[room].copy(RoomTmp);

  FLASH_STRING_ARRAY(ReplacementCallLevels,
  PSTR("CODE PINK"), PSTR("CODE BLUE"), PSTR("FIRE"), PSTR("STAFF EMER"), PSTR("PRIORITY"), PSTR("Bathroom Assistance Needed."),
  PSTR("ALARM"), PSTR("CORDOUT"), PSTR("PERS ATTN"), PSTR("STAFF"), PSTR("NORMAL"), PSTR("NURSE NEEDED"), PSTR("AIDE NEEDED"));

  char MessageTmp[60];
  ReplacementCallLevels[text].copy(MessageTmp);



  Serial << F("Sending Page # ");
  Serial.print(CodeLevel+1);
   Serial << F(" to: ");
  if(CurrentShift == 0){Serial.print(PagerArray0[room][CodeLevel]);}
  if(CurrentShift == 1){Serial.print(PagerArray1[room][CodeLevel]);}
  if(CurrentShift == 2){Serial.print(PagerArray2[room][CodeLevel]);}
  if(CurrentShift == 3){Serial.print(PagerArray3[room][CodeLevel]);}
  Serial << F(" With Message( ");
  Serial.print(RoomTmp);
  Serial << F(" : ");
  Serial.print(MessageTmp);
  Serial << F(" )");
  Serial.write(13);
  Serial.write(10);
  
  Serial2.write(1);
  Serial2 << F("A5");
  if(CurrentShift == 0){Serial2.print(PagerArray0[room][CodeLevel]);}
  if(CurrentShift == 1){Serial2.print(PagerArray1[room][CodeLevel]);}
  if(CurrentShift == 2){Serial2.print(PagerArray2[room][CodeLevel]);}
  if(CurrentShift == 3){Serial2.print(PagerArray3[room][CodeLevel]);}
  Serial2.write(2);
  Serial2.print(RoomTmp);
  Serial2 << F(" : ");
  Serial2.print(MessageTmp);
  Serial2.write(3);
  Serial2.write(4);
  Serial2.write(13);
  Serial2.write(10);
  

}

23  Using Arduino / Programming Questions / Re: Sketch ramdomly halts/freezes... on: September 25, 2012, 07:29:30 am
Since I Added the  freemem() function, my sketch doesn't stop (yet). So thank you. If i should avoid using Strings, whats the best way to parse incoming data from the UDP library?  Char[]?

You are using a lot of stuff, find the freemem function ( on forum/playground ) and verify you have any ram left, then go from there.

Thanks.

Quote
When i run this sketch it works great then it eventually and randomly stops operating ...

Read this before posting a programming question

In particular:

Quote
Hint: The String class tends to gobble up memory. Try to avoid using that, especially in larger programs.


im guessing that this is the Issue:


Quote
Warning: In versions of the Arduino IDE up to 1.0.1 (at least) there is a bug in dynamic memory allocation. This affects both malloc/free and new/delete. In particular it also affects the String class, which uses dynamic memory allocation. This is discussed in this forum thread. That thread mentions a work-around (replacement free() function) until the inbuilt libraries are updated.

 Thank you.
24  Using Arduino / Programming Questions / Sketch ramdomly halts/freezes... on: September 24, 2012, 11:48:51 pm
My setup is a Mega 2560 with Ethernet Shield. My Sketch has 2 buttons that toggle Booleans and also listens for UDP packets, decrypts them, parses them, then based on the text received it can also toggle Booleans. When i run this sketch it works great then it eventually and randomly stops operating, no reactions from the buttons, UDP packets, nothing.

Please give me some insight to what might be happening to my sketch...



Code:
#include <Metro.h>


#include <aes.h>
#include <aes128_dec.h>
#include <aes128_enc.h>
#include <aes192_dec.h>
#include <aes192_enc.h>
#include <aes256_dec.h>
#include <aes256_enc.h>
#include <AESLib.h>
#include <aes_dec.h>
#include <aes_enc.h>
#include <aes_invsbox.h>
#include <aes_keyschedule.h>
#include <aes_sbox.h>
#include <aes_types.h>
#include <bcal-basic.h>
#include <bcal-cbc.h>
#include <bcal-cmac.h>
#include <bcal-ofb.h>
#include <bcal_aes128.h>
#include <bcal_aes192.h>
#include <bcal_aes256.h>
#include <blockcipher_descriptor.h>
#include <gf256mul.h>
#include <keysize_descriptor.h>
#include <memxor.h>

#include <SPI.h>   
#include <Ethernet.h>
#include <EthernetUdp.h>
#include "Wire.h"
#include "BlinkM_funcs.h"/


// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
  0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }; 
IPAddress ip(192, 168, 0, 1);

unsigned int localPort = 8888;      // local port to listen on

// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
char  ReplyBuffer[] = "ack";       // a string to send back

// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

byte key[] = {
  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; //must be 16 bytes long...

int CabinetDoor = 22;
int DOOR1_position_Pin = 23;
int DOOR1_lock_Pin = 24;

boolean deadboltSensor, doorSensor, systemCabinetSensor;

boolean ALARM_ARMED = false;
boolean ALARM_FAULT = false;
boolean DOOR1_FAULT = false;
boolean DOOR1_shut = false;
boolean DOOR1_lock = false;
//boolean b3 = false;
//boolean b4 = false;
//boolean b5 = false;



Metro Metro1 = Metro(250);



void setup() {

  pinMode(CabinetDoor, INPUT_PULLUP);
  pinMode(DOOR1_position_Pin, INPUT_PULLUP);
  pinMode(DOOR1_lock_Pin, INPUT_PULLUP);
  //pinMode(25, INPUT_PULLUP);


  // start the Ethernet and UDP:
  Ethernet.begin(mac,ip);
  Udp.begin(localPort);

  Serial.begin(9600);

  BlinkM_begin();
  delay(100); // wait a bit for things to stabilize
  BlinkM_off(0);

  Serial.print ("System Online @ : ");
  Serial.println(Ethernet.localIP());

}

void loop() {
Serial.println("Looping");
  CheckSensors();

 

  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if(packetSize)
  {
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remote = Udp.remoteIP();
    for (int i =0; i < 4; i++)
    {
      Serial.print(remote[i], DEC);
      if (i < 3)
      {
        Serial.print(".");
      }
    }
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // read the packet into packetBufffer
    Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);
    Serial.print("Contents: ");
    Serial.println(packetBuffer);
    aes128_dec_single(key, packetBuffer); // DECRYPTION


    Serial.print("Decrypted: ");
    Serial.println(packetBuffer);

    CheckCommands(packetBuffer);


  }
  CheckSystemStatus();
  delay(10);
}





void CheckCommands(String s){
  int i = s.length();

  if(s.startsWith("cmd:") || s.startsWith("CMD:")){
    Serial.println("FOUND CMFOUND CMD: ");
    int x = s.indexOf(":");
    int x2 = s.indexOf(":",x+1);
    int x3 = s.indexOf(":",x2+1);
    Serial.println(x);
    Serial.println(x2);
    Serial.println(x3);
    String sub = s.substring(x+1,x2);
    String sub2 = s.substring(x2+1,x3);
    String sub3 = s.substring(x3+1);
    sub.trim();
    sub2.trim();
    sub3.trim();
    Serial.print(sub);
    Serial.print("-");
    Serial.print(sub2);
    Serial.print("-");
    Serial.print(sub3);
    Serial.println("|");


    if(sub.indexOf("HOME") >= 0){
      if(sub2.indexOf("ARM") >= 0){
        Serial.println("ARM");
        if(sub3.indexOf("0") >= 0){
          ClearAlarm();
        }
        else if(sub3.indexOf("1") >= 0){
          ALARM_ARMED = true;
          Serial.println("1");
        }
        else {
          Serial.println("ARM LEVEL ELSE: "+ sub3);
        }

        //SendReturnMessage(Boolean2String("A:",ALARM_ARMED,""));
      }
      else if(sub2.indexOf("GET") >= 0){
        Serial.println("GET");
        //SendReturnMessage(Boolean2String("A:",ALARM_ARMED,""));
      }
      else {
        //BAD COMMAND IN SYSTEM LEVEL
        Serial.println("SYSTEM LEVEL ELSE: "+sub2);
      }
    }
    else if(sub.indexOf("DOOR1") >= 0){
      Serial.println("DOOR1-LEVEL");
      if(sub2.indexOf("GET") >= 0){
        Serial.println("GET");
        //SendReturnMessage(MultiBoolean2String("D:",doorSensor, "L:", deadboltSensor,""));
      }
      else if(sub2.indexOf("SET") >= 0){
        Serial.println("SET");

        if(sub3.indexOf("0") >= 0){
          Serial.println("LOW");
          //analogWrite(12, 0);
          //SendReturnMessage("pin 12 - LOW");
        }
        else if(sub3.indexOf("1") >= 0){
          Serial.println("HIGH");
          //analogWrite(12, 255);
          //SendReturnMessage("pin 12 - HIGH");
        }
        else {
          Serial.println("SET LEVEL ELSE: "+ sub3);
        }
      }
      else {
        //BAD COMMAND IN DOOR1 LEVEL
        Serial.println("DOOR1 LEVEL ELSE: "+ sub2);
      }

    }
    else {

      //BAD COMMAND IN TOP LEVEL
      Serial.println("TOP LEVEL ELSE: "+ sub);

    }

    // send a reply, to the IP address and port that sent us the packet we received
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(ReplyBuffer);
    Udp.endPacket();

  }

}



void CheckSensors(){
  doorSensor = digitalRead(DOOR1_position_Pin);
  deadboltSensor = digitalRead(DOOR1_lock_Pin);
  //Serial.println(doorSensor);
  //Serial.println(deadboltSensor);


  if(ALARM_ARMED){
    if(doorSensor || deadboltSensor){
      DOOR1_FAULT = true;
      Serial.println("Door 1 Faulted");
    }
    else {
      //DOOR1_FAULT = false;
    }

    if(DOOR1_FAULT){
      ALARM_FAULT = true;
      Serial.println("Alarm Faulted");

    }
    else {
      //ALARM_FAULT = false;
    }
   

  }
  else {

    // State when not Armed...

  }


}


void CheckSystemStatus(){



  if(ALARM_ARMED){ // ALARM_ARMED = true
    if(ALARM_FAULT){
      if(DOOR1_FAULT){
        if((!doorSensor && deadboltSensor) || (doorSensor && !deadboltSensor)){
          scriptLEDS(2000, 0, 8, 1);
        }
        else if(doorSensor && deadboltSensor){

          scriptLEDS(2000, 0, 3, 1);
        }
        else if(!doorSensor && !deadboltSensor){

          fadeLEDS(0,255,0,0);
        }
      }
      else {

        fadeLEDS(0,255,0,0);
      }
    }
    else {

      //scriptLEDS(1000, 0, 8, 1);
      fadeLEDS(0,0,1,0);
    }
  }
  else { // ALARM_ARMED = false

      if((!doorSensor && deadboltSensor) || (doorSensor && !deadboltSensor)){
      scriptLEDS(2000, 0, 8, 1);
    }
    else if(doorSensor && deadboltSensor){

      scriptLEDS(2000, 0, 3, 1);
    }
    else{

     setLEDS(0,1,0,0);
     

    }
  }


}





void scriptLEDS(int s, int address, int sNumber, int reps){
  Metro1.interval(s);
  if (Metro1.check() == 1) {
    //BlinkM_setFadeSpeed(0x00,0x30);
    BlinkM_playScript(address,sNumber,reps,0x00);
  }

}

void fadeLEDS(int address, int r,  int g, int b){
  BlinkM_fadeToRGB(address,r,g,b);
}

void setLEDS(int address, int r,  int g, int b){
  BlinkM_setRGB(address,r,g,b);
}



void ClearAlarm(){
  ALARM_ARMED = false;
    Serial.println("Alarm Disarmed");

  ALARM_FAULT = false;
  Serial.println("Alarm Fault Cleared");

  DOOR1_FAULT = false;
  Serial.println("Door 1 Fault Cleared");


}



25  Using Arduino / General Electronics / Re: Detect and ignore 5 volts not 12 question. on: August 31, 2011, 06:59:40 pm
Is it possible to use a voltage divider with a relay directly (without Arduino), i need to Minimize the circuit and size of circuit. Thanks for any suggestions.
26  Using Arduino / General Electronics / Re: Detect and ignore 5 volts not 12 question. on: August 31, 2011, 06:38:37 pm
Would a voltage divider put any load on  the lines like a relay?
27  Using Arduino / General Electronics / Detect and ignore 5 volts not 12 question. on: August 31, 2011, 05:37:31 pm
Anyone know of a ciruit, with or with out the Arduino unit, that can detect voltages between 5 and 12 volts, and only output if 12 volts is detected.

Basicly i have a wireless device that has an output that varies in voltages, The manufacturer says it will be floating voltage when idle, and 12volts in alarm. I tested with my meter, 5.5 volts and 12.8 volts. If i attach a 12volt relay directly to the circuit, it holds down the device and wont allow it to operate properly. Im thinking a Transistor is the answer, but im not sure on detecting only 12 volts. Any one have an idea i can try???
28  Using Arduino / Programming Questions / Re: Arduino Stops After Period of time. on: June 10, 2011, 02:07:52 pm
Quote
and the power supply is a wall wort 9v 1000ma hooked up about 60 feet away.
I bet that is the problem, what sort of extra decoupling have you got?

do you think that it would last more than a month with no decoupling????
29  Using Arduino / Programming Questions / Re: Arduino Stops After Period of time. on: June 10, 2011, 05:34:21 am
Quote
and the power supply is a wall wort 9v 1000ma hooked up about 60 feet away.
I bet that is the problem, what sort of extra decoupling have you got?

decoupling???
 well the only thing is that it lasted over a month with hour to hour use, then just locked up... i assumed that since i made the onboard LED a "Heartbeat" and that was what was locked on solid it must not be alternating with this code.

Code:
if(currentMillis - previousLEDmillis > StatusLEDinterval) {
    // save the last time you blinked the LED
    previousLEDmillis = currentMillis;   

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;

    // set the LED with the ledState of the variable:
    digitalWrite(LEDpin, ledState);
  }
30  Using Arduino / Programming Questions / Re: Arduino Stops After Period of time. on: June 09, 2011, 06:24:20 pm
You need to put some debug print statements in to see at what point it stops. It could be that you have intermittent connections on one device or some other hardware glitch.
If it always stops in the same place then it points to that part. If random then you might have a decoupling issue on your power supplies.

The arduino cannot be connected to a computer at this time, and the power supply is a wall wort 9v 1000ma hooked up about 60 feet away.

And the Led i have Coded with the Blink with out delay example, and that is what was solid when i seen that the device was locked up.

I do have a OpenLog device from Sparkfun,(http://www.sparkfun.com/products/9530) if i connected that, how would i get a data stream to a file on it?
Pages: 1 [2] 3