Go Down

Topic: ARDUINO UNO, RTC, SD, SIM800L (Read 1 time) previous topic - next topic

Tato84

Oct 05, 2017, 07:22 pm Last Edit: Oct 06, 2017, 02:40 pm by Tato84
Estoy realizando un proyecto usando un Arduino UNO, un modulo RTC, una SD y un SIM800L.

Funcionamiento: el contador se activa por interrupcion y almacena los datos en una SD como la fecha, hora y numero de pulsaciones, la fecha y hora puede programarse mediante la SD en caso de estar desprogramado el rtc, luego los datos almacenados en la SD se envian a un servidor FTP en una hora fijada.

Trabaje en dos partes por una parte un codigo que almacena y hace todo perfecto y por otro un codigo que envia un archivo de la SD al servidor FTP y hace todo perfecto pero al unirlos tengo inconvenientes con la memoria sram, esta usando aproximadamente un 85% y me indica que habra posiblemente inestabilidad, me gustaria compartir el codigo y ver si es posible hacer alguna mejora dado que soy de nivel bajo en programacion e hice el codigo poco a poco con la ayuda de google. Queria usar el Arduino UNO porque es mas facil luego colocar el atmega328 en una placa aparte y usarlo con bateria para bajo consumo, de usar un MEGA 2560 el consumo de bateria seria elevado y no seria viable con dos paneles solares, compre tambien un STM32F103C8T6 pero aun desconozco como usarlo. Agradeceria si pudieran ayudarme indicandome si es posible hacer mejoras que eviten tanto consumo de memoria sram, Saludos.


Codigo para obtener y registrar datos en la sd:


Code: [Select]
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 rtc;

#include <SPI.h>
#include <SD.h>

int year;
int month;
int day;
int hour;
int minute;
int second;
int periodo=60;
int veces;
int min_registro[20],i;
volatile int sensor;
long T0=0;
File myFile;


void add0(byte numero) // imprime 2 dígitos
{
if (numero >= 0 && numero < 10)
{
myFile.print('0');
}
myFile.print(numero, DEC);
}

void alarma_registro () //Crea arreglo con los minutos para
// Registrar en la memoria
{
veces=60/periodo;
for(i=0;i<veces;i++)
{
min_registro[i]=periodo*i;
}
}

void interrupcion_sensor()
   {
       if ( millis() > T0  + 250)
          {   sensor++ ;
              T0 = millis();
          }
    }

void setup()
{
  Serial.begin(9600);
  pinMode(10, OUTPUT);
  attachInterrupt( 0, interrupcion_sensor, FALLING);
  rtc.begin();
   
 if (!SD.begin(10)){
   
 //   Serial.println("Se ha producido un fallo al iniciar la comunicacion");
    return;
  }
//  Serial.println("Se ha iniciado la comunicacion correctamente");

  if (! rtc.isrunning())
  {
  File myFile = SD.open("cfgrtc.txt");
  if (myFile) {
//    Serial.println("abriendo cfgrtc.txt");
    while (myFile.available()) {
      year = myFile.parseInt();
      month = myFile.parseInt();
      day = myFile.parseInt();
      hour = myFile.parseInt();
      minute = myFile.parseInt();
      second = myFile.parseInt();
      myFile.close();
      rtc.adjust(DateTime(year,month,day,hour,minute,second));
//      Serial.println("datos cargados en el rtc  ");
    }
    }
  else {
    // si no abre cfgrtc.txt
//    Serial.println("error abriendo cfgrtc.txt");
  }
  }

  File myFile = SD.open("periodo.txt");
  if (myFile) {
//  Serial.println("abriendo periodo.txt");
  while (myFile.available()) {
      periodo = myFile.parseInt();
      myFile.close();
      alarma_registro ();
  }
  }
  else {
    // si no abre el periodo.txt
//    Serial.println("error abriendo periodo.txt");
  }
       
  }//FIN SETUP


void loop()
{

DateTime now = rtc.now(); // Obtiene la fecha y hora del RTC

for (i=0;i<veces;i++)
{
if((now.minute()==min_registro[i]) && (now.second()==0))  // comparar la hora del RTC con el ciclo de medicion
{
SD.begin(10); // se inicializa SD por si se retiro
delay(20);
myFile = SD.open("log.txt", FILE_WRITE);
if (myFile) // Si el archivo abre escribir la hora
{
myFile.print(now.day());
myFile.print('/');
myFile.print(now.month());
myFile.print('/');
myFile.print(now.year(), DEC);
myFile.print(' ');
myFile.print(' ');
myFile.print(now.hour());
myFile.print(':');
add0(now.minute());
myFile.print(':');
add0(now.second());
myFile.print(' ');
myFile.print(' ');
myFile.print(' ');
myFile.print(sensor);
myFile.println();
myFile.close(); // cerrar archivo log.txt
Serial.println("GUARDO DATOS EN SD");
sensor=0;
}
}
}

delay(1000);
 
} // FIN LOOP*/





Tato84

Codigo para enviar archivo .txt a servidor ftp


Code: [Select]
#include <SD.h>
#include <SPI.h>
#include <SoftwareSerial.h>
SoftwareSerial SIM800L(2, 3); // Declaramos los pines RX(2) y TX(3)


int8_t answer;
int data_size=0;
int aux;
int seconds=0;
int GsmDo=0;
int GPRS_IDLE_TIME=0;
int GsmStatut=0;



void setup(){
  delay(5000);
  Serial.begin(9600);
//  Serial.print("Initializing SD card...");
   pinMode(10, OUTPUT);
  
  if (!SD.begin(10)) {
//    Serial.println("initialization failed!");
    return;
  }
//  Serial.println("initialization done.");
    File myFile = SD.open("prueba.txt", FILE_READ);
    if (myFile)
//      Serial.println("prueba.txt is opened in read mode.");
  
    SIM800L.begin(9600);
    delay(3000);
    
    sendATcommand("AT", "OK", 5000);
    sendATcommand("AT+CSQ", "OK", 5000);
    while( (sendATcommand("AT+CREG?", "+CREG: 0,1", 500) || sendATcommand("AT+CREG?", "+CREG: 0,5", 500)) == 0 );
    // Serial.println("GSM modem working!");
    delay(3000);
    
    sendATcommand("AT+SAPBR=3,1,\"Contype\",\"GPRS\"", "OK", 2000);
    sendATcommand("AT+SAPBR=3,1,\"APN\",\"internet.movistar.ve\"", "OK", 2000);
        
    while (sendATcommand("AT+SAPBR=2,1", "OK", 20000) != 1);
    {
      //Serial.println("Querting Bearer 1...");
    }
    while (sendATcommand("AT+SAPBR=1,1", "OK", 20000) != 1);
    {
      //Serial.println("Opening Bearer 1...");
    }
    delay(1000);
 //   Serial.println("Setting up FTP");
    sendATcommand("AT+FTPCID=1", "OK", 2000);
    sendATcommand("AT+FTPSERV=\"xxxx\"", "OK", 2000);
    sendATcommand("AT+FTPPORT=21", "OK", 2000);
    sendATcommand("AT+FTPUN=\"xxxx\"", "OK", 2000);
    sendATcommand("AT+FTPPW=\"xxxx\"", "OK", 2000);

    sendATcommand("AT+FTPPUTNAME=\"prueba.txt\"", "OK", 2000);
    sendATcommand("AT+FTPPUTPATH=\"/\"", "OK", 2000);
    
    // waits for signal
  if (sendATcommand("AT+FTPPUT=1", "+FTPPUT: 1,1,", 30000) == 1)
            {
                data_size = 0;
                while(SIM800L.available()==0);
                aux = SIM800L.read();
                do{
                    data_size *= 10;
                    data_size += (aux-0x30);
                    while(SIM800L.available()==0);
                    aux = SIM800L.read();                      
                }while(aux != 0x0D);
                myFile = SD.open("prueba.txt");
                String XcomA = "";
                String XcomB = "";
                // archivosize += 1;
                XcomA.concat("AT+FTPPUT=2,");
                XcomA.concat(data_size);
                XcomA.concat("\"");
        
                XcomB.concat("+FTPPUT: 2,");
                XcomB.concat(data_size);
                XcomB.concat("\"");
        
                char XxcomA[XcomA.length()], XxcomB[XcomB.length()];
        
                XcomA.toCharArray(XxcomA,XcomA.length());
                XcomB.toCharArray(XxcomB,XcomB.length());
        
                if (myFile) {
                    int archivosize = myFile.size();
                    while(myFile.available()){
                        //Serial.println(archivosize);
                        
                        while(archivosize >= data_size){
                            if (sendATcommand(XxcomA,XxcomB,3000) == 1){
                            for(int d = 0; d < data_size; d++){
                                SIM800L.write(myFile.read());
                                archivosize -= 1;
                          //      Serial.print("Archive size : ");
                          //      Serial.println(archivosize);
                                }
                            }
                        }
               // Serial.print("El resto : ");
                                //Serial.println(archivosize);
                        String ScomA = "";
                        String ScomB = "";
                        ScomA.concat("AT+FTPPUT=2,");
                        ScomA.concat(archivosize);
                        ScomA.concat("\"");
                
                        ScomB.concat("+FTPPUT: 2,");
                        ScomB.concat(archivosize);
                        ScomB.concat("\"");
                
                        char CcomA[ScomA.length()], CcomB[ScomB.length()];
                
                        ScomA.toCharArray(CcomA,ScomA.length());
                        ScomB.toCharArray(CcomB,ScomB.length());
                        
                        if (sendATcommand(CcomA,CcomB,3000) == 1){
                        for(int t = 0; t < archivosize; t++){
                        SIM800L.write(myFile.read());
                       // Serial.print("Archive size : ");
                       // Serial.println(archivosize);
                        //Serial.println(t);
                        }
                        }
                    }
                      // close the file:
                      myFile.close();
                    }
                    delay(500);
                    if (sendATcommand("AT+FTPPUT=2,0", "+FTPPUT: 1,0", 30000)==1){
                        GPRS_IDLE_TIME = seconds + 10;        
                        GsmDo = 3;
                        GsmStatut = 1;
                    }
                
                }else{
                //Erreur

}}
void loop(){
    
    

}


unsigned char sendATcommand(char* ATcommand, char* expected_answer1, unsigned int timeout)
{

    unsigned char x=0,  answer=0;
    char response[100];
    unsigned long previous;

    memset(response, '\0', 100);    // Initialize the string

    delay(100);

    while( SIM800L.available() > 0) SIM800L.read();    // Clean the input buffer

    SIM800L.println(ATcommand);    // Send the AT command


        x = 0;
    previous = millis();

    // this loop waits for the answer
    do{

        if(SIM800L.available() != 0){    
            response[x] = SIM800L.read();
       //     Serial.print(response[x]);
            x++;
            // check if the desired answer is in the response of the module
            if (strstr(response, expected_answer1) != NULL)    
            {
                answer = 1;
            }
        }
        // Waits for the asnwer with time out
    }
    while((answer == 0) && ((millis() - previous) < timeout));    

    return answer;
}


surbyte

El segundo código me arroja estos datos de salida

Code: [Select]
Device: atmega328p
Program:   14384 bytes (43.9% Full)
(.text + .data + .bootloader)
Data:       1324 bytes (64.6% Full)
(.data + .bss + .noinit)


Yo uso Sublime Text + Platformio +DEVIOT.
son muy similares al IDE.

El IDE al compilar dice

Code: [Select]
El Sketch usa 14.434 bytes (44%) del espacio de almacenamiento de programa. El máximo es 32.256 bytes.
Las variables Globales usan 1.340 bytes (65%) de la memoria dinámica, dejando 708 bytes para las variables locales. El máximo es 2.048 bytes.


Porque hablas de 85% ?

Lucario448

De momento voy a empezar a ver el código para ver qué se le puede mejorar; mientras tanto te recomiendo usar esta librería en vez de la que trae para tarjetas SD.

Esa librería tiene menor "huella" en memoria que la que viene en la IDE.

surbyte

El código tal como esta funciona bien, y no se en que condiciones dice que ocupa 85% de la SRAM.

Tato84

85% cuando uno los dos porque necesito unir los dos, lo puse asi porque primero lo trabaje en dos partes ya colocare el codigo en su totalidad y notaran el 85%.

Tato84

#6
Oct 06, 2017, 07:06 am Last Edit: Oct 06, 2017, 07:17 am by Tato84
Code: [Select]

#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 rtc;

#include <SPI.h>
#include <SD.h>
#include <SoftwareSerial.h>
SoftwareSerial SIM800L(2, 3); // Declaramos los pines RX(2) y TX(3)

int8_t answer;
int data_size=0;
int aux;
int seconds=0;
int GsmDo=0;
int GPRS_IDLE_TIME=0;
int GsmStatut=0;

int year;
int month;
int day;
int hour;
int minute;
int second;
int periodo=60;
int veces;
int min_registro[20],i;
volatile int sensor;
long T0=0;
File myFile;


void add0(byte numero) // imprime 2 dígitos
{
if (numero >= 0 && numero < 10)
{
myFile.print('0');
}
myFile.print(numero, DEC);
}

void alarma_registro () //Crea arreglo con los minutos para
// Registrar en la memoria
{
veces=60/periodo;
for(i=0;i<veces;i++)
{
min_registro[i]=periodo*i;
}
}

void interrupcion_sensor()
  {
      if ( millis() > T0  + 250)
         {   sensor++ ;
             T0 = millis();
         }
   }

void setup()
{
 Serial.begin(9600);
 SIM800L.begin(9600);
 delay(3000);
 
 pinMode(10, OUTPUT);
 attachInterrupt( 0, interrupcion_sensor, FALLING);
 rtc.begin();
   
if (!SD.begin(10)){
   
//   Serial.println("Se ha producido un fallo al iniciar la comunicacion");
   
   return;
 }
 
//  Serial.println("Se ha iniciado la comunicacion correctamente");

 if (! rtc.isrunning())
 {
 File myFile = SD.open("cfgrtc.txt");
 if (myFile) {

  // Serial.println("abriendo cfgrtc.txt");
   
   while (myFile.available()) {
     year = myFile.parseInt();
     month = myFile.parseInt();
     day = myFile.parseInt();
     hour = myFile.parseInt();
     minute = myFile.parseInt();
     second = myFile.parseInt();
     myFile.close();
     rtc.adjust(DateTime(year,month,day,hour,minute,second));
   
     // Serial.println("datos cargados en el rtc  ");
     
   }
   }
 else {
   // si no abre cfgrtc.txt
   //Serial.println("error abriendo cfgrtc.txt");
 }
 }

 
 File myFile = SD.open("periodo.txt");
 if (myFile) {
   
 // Serial.println("abriendo periodo.txt");
 
 while (myFile.available()) {
     periodo = myFile.parseInt();
     myFile.close();
     alarma_registro ();
     
   }
 }
 else {
   // si no abre el periodo.txt
 //  Serial.println("error abriendo periodo.txt");
 }
     
   
 }//FIN SETUP




void loop()
{

DateTime now = rtc.now(); // Obtiene la fecha y hora del RTC

for (i=0;i<veces;i++)
{
if((now.minute()==min_registro[i]) && (now.second()==0))  // comparar la hora del RTC con el ciclo de medicion
{
SD.begin(10); // se inicializa SD por si se retiro
delay(20);
myFile = SD.open("log.txt", FILE_WRITE);
if (myFile) // Si el archivo abre escribir la hora
{
myFile.print(now.day());
myFile.print('/');
myFile.print(now.month());
myFile.print('/');
myFile.print(now.year(), DEC);
myFile.print(' ');
myFile.print(' ');
myFile.print(now.hour());
myFile.print(':');
add0(now.minute());
myFile.print(':');
add0(now.second());
myFile.print(' ');
myFile.print(' ');
myFile.print(' ');
myFile.print(sensor);
myFile.println();
myFile.close(); // cerrar archivo log.txt
Serial.println("GUARDO DATOS EN SD");
sensor=0;

if((now.hour()==0) && (now.minute()==0) && (now.second()==0))
{

   File myFile = SD.open("log.txt", FILE_READ);
   if (myFile)
 //    Serial.println("log.txt is opened in read mode.");
   // GSM function
   //pinMode(onModulePin, OUTPUT);
   
   sendATcommand("AT", "OK", 5000);
   sendATcommand("AT+CSQ", "OK", 5000);
   while( (sendATcommand("AT+CREG?", "+CREG: 0,1", 500) || sendATcommand("AT+CREG?", "+CREG: 0,5", 500)) == 0 );
//   Serial.println("GSM modem working!");
   delay(3000);
   
   sendATcommand("AT+SAPBR=3,1,\"Contype\",\"GPRS\"", "OK", 2000);
   sendATcommand("AT+SAPBR=3,1,\"APN\",\"internet.movistar.ve\"", "OK", 2000);
       
   while (sendATcommand("AT+SAPBR=2,1", "OK", 20000) != 1);
   {
     //    Serial.println("Querting Bearer 1...");
   }
   while (sendATcommand("AT+SAPBR=1,1", "OK", 20000) != 1);
   {
     //    Serial.println("Opening Bearer 1...");
   }
   delay(1000);
   
   //     Serial.println("Setting up FTP");
   
   sendATcommand("AT+FTPCID=1", "OK", 2000);
   sendATcommand("AT+FTPSERV=\"xxxx\"", "OK", 2000);
   sendATcommand("AT+FTPPORT=21", "OK", 2000);
   sendATcommand("AT+FTPUN=\"xxxx\"", "OK", 2000);
   sendATcommand("AT+FTPPW=\"xxxx\"", "OK", 2000);

   sendATcommand("AT+FTPPUTNAME=\"log.txt\"", "OK", 2000);
   sendATcommand("AT+FTPPUTPATH=\"/\"", "OK", 2000);
   
   // waits for signal
 if (sendATcommand("AT+FTPPUT=1", "+FTPPUT: 1,1,", 30000) == 1)
           {
               data_size = 0;
               while(SIM800L.available()==0);
               aux = SIM800L.read();
               do{
                   data_size *= 10;
                   data_size += (aux-0x30);
                   while(SIM800L.available()==0);
                   aux = SIM800L.read();                     
               }while(aux != 0x0D);
               myFile = SD.open("log.txt");
               String XcomA = "";
               String XcomB = "";
               // archivosize += 1;
               XcomA.concat("AT+FTPPUT=2,");
               XcomA.concat(data_size);
               XcomA.concat("\"");
       
               XcomB.concat("+FTPPUT: 2,");
               XcomB.concat(data_size);
               XcomB.concat("\"");
       
               char XxcomA[XcomA.length()], XxcomB[XcomB.length()];
       
               XcomA.toCharArray(XxcomA,XcomA.length());
               XcomB.toCharArray(XxcomB,XcomB.length());
       
               if (myFile) {
                   int archivosize = myFile.size();
                   while(myFile.available()){
   
                       //Serial.println(archivosize);
                       
                       while(archivosize >= data_size){
                           if (sendATcommand(XxcomA,XxcomB,3000) == 1){
                           for(int d = 0; d < data_size; d++){
                               SIM800L.write(myFile.read());
                               archivosize -= 1;
                           
                            //   Serial.print("Archive size : ");
                            //   Serial.println(archivosize);
                           
                               }
                           }
                       }
              // Serial.print("El resto : ");
                               //Serial.println(archivosize);
                       String ScomA = "";
                       String ScomB = "";
                       ScomA.concat("AT+FTPPUT=2,");
                       ScomA.concat(archivosize);
                       ScomA.concat("\"");
               
                       ScomB.concat("+FTPPUT: 2,");
                       ScomB.concat(archivosize);
                       ScomB.concat("\"");
               
                       char CcomA[ScomA.length()], CcomB[ScomB.length()];
               
                       ScomA.toCharArray(CcomA,ScomA.length());
                       ScomB.toCharArray(CcomB,ScomB.length());
                       
                       if (sendATcommand(CcomA,CcomB,3000) == 1){
                       for(int t = 0; t < archivosize; t++){
                       SIM800L.write(myFile.read());
                      // Serial.print("Archive size : ");
                      // Serial.println(archivosize);
                       //Serial.println(t);
                       }
                       }
                   }
                     // close the file:
                     myFile.close();
                   }
                   delay(500);
                   if (sendATcommand("AT+FTPPUT=2,0", "+FTPPUT: 1,0", 30000)==1){
                   
                       //GPRS_IDLE_TIME = seconds + 10;       
                       //GsmDo = 3;
                       //GsmStatut = 1;
                   }
               
               }else{
               //Erreur

}
}
}
}
}
 
} // FIN LOOP*/


Tato84

Code: [Select]

unsigned char sendATcommand(char* ATcommand, char* expected_answer1, unsigned int timeout)
{

   unsigned char x=0,  answer=0;
   char response[100];
   unsigned long previous;

   memset(response, '\0', 100);    // Initialize the string

   delay(100);

   while( SIM800L.available() > 0) SIM800L.read();    // Clean the input buffer

   SIM800L.println(ATcommand);    // Send the AT command


       x = 0;
   previous = millis();

   // this loop waits for the answer
   do{

       if(SIM800L.available() != 0){    
           response[x] = SIM800L.read();
        
         //  Serial.print(response[x]);
        
           x++;
           // check if the desired answer is in the response of the module
           if (strstr(response, expected_answer1) != NULL)    
           {
               answer = 1;
           }
       }
       // Waits for the asnwer with time out
   }
   while((answer == 0) && ((millis() - previous) < timeout));    

   return answer;
}

Tato84

#8
Oct 06, 2017, 05:01 pm Last Edit: Oct 06, 2017, 05:32 pm by Tato84
Segun todos los foros que he leido el uso de memoria sram no debe superar el 70-75% para que funcione de forma estable, he logrado llevarlo alrededor de 76% tan solo eliminando los Serial.print. y quitando la configuracion de RTC y periodo por memoria SD.

Si logro reducir esta parte del codigo creo que podria hacerlo trabajar sin problemas:

Esta parte del codigo la consigui en el foro, permite calcular el tamaño del archivo y asi enviar 1360 byte por sesion que es el limite del SIM800L, hay partes de este codigo que me generan muchas dudas, si alguien puede ayudarme a entenderlo en su totalidad para simplificarlo y poder usarlo para enviar un archivo que tiene alrededor de 12.288 byte se lo agradeceria. :)

Code: [Select]

data_size = 0;
                while(SIM800L.available()==0);
                aux = SIM800L.read();
                do{
                    data_size *= 10;
                    data_size += (aux-0x30);
                    while(SIM800L.available()==0);
                    aux = SIM800L.read();                     
                }while(aux != 0x0D);
                myFile = SD.open("log.txt");
                String XcomA = "";
                String XcomB = "";
                // archivosize += 1;
                XcomA.concat("AT+FTPPUT=2,");
                XcomA.concat(data_size);
                XcomA.concat("\"");
       
                XcomB.concat("+FTPPUT: 2,");
                XcomB.concat(data_size);
                XcomB.concat("\"");
       
                char XxcomA[XcomA.length()], XxcomB[XcomB.length()];
       
                XcomA.toCharArray(XxcomA,XcomA.length());
                XcomB.toCharArray(XxcomB,XcomB.length());
       
                if (myFile) {
                    int archivosize = myFile.size();
                    while(myFile.available()){
   
                        //Serial.println(archivosize);
                       
                        while(archivosize >= data_size){
                            if (sendATcommand(XxcomA,XxcomB,3000) == 1){
                            for(int d = 0; d < data_size; d++){
                                SIM800L.write(myFile.read());
                                archivosize -= 1;
                             
                             //   Serial.print("Archive size : ");
                             //   Serial.println(archivosize);
                             
                                }
                            }
                        }
               // Serial.print("il reste : ");
                                //Serial.println(archivosize);
                        String ScomA = "";
                        String ScomB = "";
                        ScomA.concat("AT+FTPPUT=2,");
                        ScomA.concat(archivosize);
                        ScomA.concat("\"");
               
                        ScomB.concat("+FTPPUT: 2,");
                        ScomB.concat(archivosize);
                        ScomB.concat("\"");
               
                        char CcomA[ScomA.length()], CcomB[ScomB.length()];
               
                        ScomA.toCharArray(CcomA,ScomA.length());
                        ScomB.toCharArray(CcomB,ScomB.length());
                       
                        if (sendATcommand(CcomA,CcomB,3000) == 1){
                        for(int t = 0; t < archivosize; t++){
                        SIM800L.write(myFile.read());
                       // Serial.print("Archive size : ");
                       // Serial.println(archivosize);
                        //Serial.println(t);
                        }
                        }
                    }
                      // close the file:
                      myFile.close();
                      SD.remove("log.txt");
                    }
               



Otra opcion que manejo seria usar el STM32F103C8T6 para el proyecto, me gustaria saber si amerita grandes cambios o es practicamente lo mismo.


surbyte

#9
Oct 06, 2017, 06:14 pm Last Edit: Oct 06, 2017, 06:34 pm by surbyte
Bien ahora si,

Code: [Select]
El Sketch usa 19.444 bytes (60%) del espacio de almacenamiento de programa. El máximo es 32.256 bytes.
Las variables Globales usan 1.675 bytes (81%) de la memoria dinámica, dejando 373 bytes para las variables locales. El máximo es 2.048 bytes.


Revisando.

Creo que el tramo mas ineficiente es este
Code: [Select]
String XcomA = "";
            String XcomB = "";
            // archivosize += 1;
            XcomA.concat("AT+FTPPUT=2,");
            XcomA.concat(data_size);
            XcomA.concat("\"");

            XcomB.concat("+FTPPUT: 2,");
            XcomB.concat(data_size);
            XcomB.concat("\"");

            char XxcomA[XcomA.length()], XxcomB[XcomB.length()];

            XcomA.toCharArray(XxcomA, XcomA.length());
            XcomB.toCharArray(XxcomB, XcomB.length());

Tato84

#10
Oct 06, 2017, 06:33 pm Last Edit: Oct 06, 2017, 06:39 pm by Tato84
En total las opciones que manejo serian:

1- Lograr reducir el consumo de ram por lo menos a un 70%.

2- Agregar memoria SRAM una 23K256 o 23LC1024 pero se me hace dificil conseguirla y no se si esto me de problemas con el Modulo SD.

3- Comprar un Mega2560 pero consume mas bateria y el core mini no lo consigo.

4- Utilizar el STM32F103C8T6 pero aun no lo domino bien y hay poco soporte.

5- En caso de ser posible utilizar dos atmega328 uno que realice la programacion del RTC usando la SD, guarde los datos en la SD y otro atmega328 que solo se encargue de enviar los datos de la SD al servidor FTP usando el SIM800L.


Lucario448

En eso acabé tratando de optimizar ambos códigos:

Primero:
Code: [Select]
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 rtc;

#include <SdFat.h>
SdFat SD;

char registro[64];
unsigned int periodo = 60;
unsigned int veces;
unsigned int min_registro[20]; // ¿En serio necesitas tantos? Si periodo == 1, entonces necesitarás 60
volatile unsigned int sensor;
unsigned long T0 = 0;

void alarma_registro() //Crea arreglo con los minutos para
// Registrar en la memoria
{
  veces = 60 / periodo;
  for (byte i = 0; i < veces; i++)
  {
    min_registro[i] = periodo * i;
  }
}

void interrupcion_sensor()
{
  if (millis() > T0 + 250)
  { sensor++;
    T0 = millis();
  }
}

void setup()
{
  pinMode(10, OUTPUT);
  attachInterrupt(0, interrupcion_sensor, FALLING);
  rtc.begin();

  if (!SD.begin(10)) {
    return;
  }

  if (!rtc.isrunning())
  {
    File myFile = SD.open("cfgrtc.txt");
    if (myFile) {
      if (myFile.available()) {
        unsigned int year = myFile.parseInt();
        byte month = myFile.parseInt();
        byte day = myFile.parseInt();
        byte hour = myFile.parseInt();
        byte minute = myFile.parseInt();
        byte second = myFile.parseInt();
        rtc.adjust(DateTime(year, month, day, hour, minute, second));
      }
      myFile.close();
    } else {
      // si no abre cfgrtc.txt
    }
  }

  myFile = SD.open("periodo.txt");
  if (myFile) {
    if (myFile.available()) {
      periodo = myFile.parseInt();
      alarma_registro ();
    }
    myFile.close();
  }
  else {
    // si no abre el periodo.txt
  }

}//FIN SETUP


void loop()
{

  DateTime now = rtc.now(); // Obtiene la fecha y hora del RTC

  for (byte i = 0; i < veces; i++)
  {
    if ((now.minute() == min_registro[i]) && (now.second() == 0)) // comparar la hora del RTC con el ciclo de medicion
    {
      SD.begin(10); // se inicializa SD por si se retiro
      delay(20);
      File myFile = SD.open("log.txt", FILE_WRITE);
      if (myFile) // Si el archivo abre escribir la hora
      {
        detachInterrupt(0);
        sprintf(registro, "%d/%d/%d\t%d:%02d:%02d: %d", now.day(), now.month(), now.year(), now.hour(), now.minute(),
                now.second(), sensor);
        myFile.println(registro);
        myFile.close(); // cerrar archivo log.txt
        sensor = 0;
        attachInterrupt(0, interrupcion_sensor, FALLING);
      }
    }
  }

  delay(1000);

} // FIN LOOP*/


Segundo:
Code: [Select]
#include <SdFat.h>
SdFat SD;

unsigned int seconds = 0;
unsigned int GPRS_IDLE_TIME = 0;

char response[100];
char exp[16];
char comA[32];
char comB[32]

void setup() {
  delay(5000);
  Serial.begin(9600); // ¿Ya no necesitas SoftwareSerial? Usa este
  pinMode(10, OUTPUT);

  if (!SD.begin(10)) {
    return;
  }


  Serial.begin(9600);
  delay(3000);

  sendATcommand(F("AT"), F("OK"), 5000);
  sendATcommand(F("AT+CSQ"), F("OK"), 5000);
  while ( (sendATcommand(F("AT+CREG?"), F("+CREG: 0,1"), 500) || sendATcommand(F("AT+CREG?"), F("+CREG: 0,5"), 500)) == 0 );
  delay(3000);

  sendATcommand(F("AT+SAPBR=3,1,\"Contype\",\"GPRS\""), F("OK"), 2000);
  sendATcommand(F("AT+SAPBR=3,1,\"APN\",\"internet.movistar.ve\""), F("OK"), 2000);

  while (!sendATcommand(F("AT+SAPBR=2,1", F("OK")), 20000));
  while (!sendATcommand(F("AT+SAPBR=1,1"), F("OK"), 20000));

  delay(1000);
  sendATcommand(F("AT+FTPCID=1"), F("OK"), 2000);
  sendATcommand(F("AT+FTPSERV=\"xxxx\""), F("OK"), 2000);
  sendATcommand(F("AT+FTPPORT=21"), F("OK"), 2000);
  sendATcommand(F("AT+FTPUN=\"xxxx\""), F("OK"), 2000);
  sendATcommand(F("AT+FTPPW=\"xxxx\""), F("OK"), 2000);

  sendATcommand(F("AT+FTPPUTNAME=\"prueba.txt\""), F("OK"), 2000);
  sendATcommand(F("AT+FTPPUTPATH=\"/\""), F("OK"), 2000);

  // waits for signal
  if (sendATcommand(F("AT+FTPPUT=1"), F("+FTPPUT: 1,1,"), 30000))
  {
    unsigned int data_size = 0;
    while (Serial.available() == 0);
    byte aux = Serial.read();
    do {
      data_size *= 10;
      data_size += (aux - 0x30);
      while (Serial.available() == 0);
      aux = Serial.read();
    } while (aux != 0x0D);
    File myFile = SD.open("prueba.txt");
    sprintf(comA, "AT+FTPPUT=2,%lu\"", data_size);
    sprintf(comB, "+FTPPUT: 2,%lu\"", data_size);

    if (myFile) {
      unsigned long archivosize = myFile.size();
      while (myFile.available()) {

        while (archivosize >= data_size) {
          if (sendATcommand(comA, comB, 3000) == 1) {
            for (; data_size; data_size--) {
              Serial.write(myFile.read());
              archivosize--;
            }
          }
        }
        sprintf(comA, "AT+FTPPUT=2,%lu\"", archivosize);
        sprintf(comB, "+FTPPUT: 2,%lu\"", archivosize);

        if (sendATcommand(comA, comB, 3000) == 1) {
          for ( ; archivosize; archivosize--) {
            Serial.write(myFile.read());
          }
        }
      }
      // close the file:
      myFile.close();
    }
    delay(500);
    if (sendATcommand(F("AT+FTPPUT=2,0"), F("+FTPPUT: 1,0"), 30000)) {
      GPRS_IDLE_TIME = seconds + 10;
    }

  } else {
    //Erreur

  }
}
void loop() {
}


unsigned char sendATcommand(const __FlashStringHelper* ATcommand, const __FlashStringHelper* expected_answer, unsigned int timeout)
{

  unsigned char x = 0,  answer = 0;
  unsigned long previous;
  strcpy_P(exp, reinterpret_cast<PGM_P>(expected_answer));

  delay(100);

  Serial.flush();    // Clean the input buffer
  memset(response, 0, sizeof(response));
  Serial.println(ATcommand);    // Send the AT command
  previous = millis();
  
  // this loop waits for the answer
  do {

    if (Serial.available() != 0) {
      response[x] = Serial.read();
      //     Serial.print(response[x]);
      x++;
      // check if the desired answer is in the response of the module
      if (strstr(response, exp) != NULL)
      {
        answer = 1;
      }
    }
    // Waits for the asnwer with time out
  }
  while ((answer == 0) && ((millis() - previous) < timeout));

  return answer;
}

unsigned char sendATcommand(char* ATcommand, char* expected_answer1, unsigned int timeout)
{

  unsigned char x = 0,  answer = 0;
  unsigned long previous;

  delay(100);

  Serial.flush();    // Clean the input buffer
  memset(response, 0, sizeof(response));
  Serial.println(ATcommand);    // Send the AT command
  previous = millis();

  // this loop waits for the answer
  do {

    if (Serial.available() != 0) {
      response[x] = Serial.read();
      //     Serial.print(response[x]);
      x++;
      // check if the desired answer is in the response of the module
      if (strstr(response, expected_answer1) != NULL)
      {
        answer = 1;
      }
    }
    // Waits for the asnwer with time out
  }
  while ((answer == 0) && ((millis() - previous) < timeout));

  return answer;
}

Si sientes que algo desapareció; posiblemente esté como variable local, global o por contexto del código no se usaba.
Además no los comprendía al 100%; por lo tanto puede que la haya liado o que la optimización no sea plena.

surbyte

Bueno Lucario cayó en el mismo problema que yo al comienzo. El código no era es Lucario sino el siguiente posteado.

Tato84

Muchas gracias Lucario y Surbyte por la ayuda recibida :)

Realmente el codigo 1 no interfiere con el 2 en un sentido, funcionan por separado, pero al final van unidos en un arreglo simple para que a una determinada hora envie el .txt a un servidor como publique luego de haberlos colocado, me falta realizar el arreglo que tambien borre el .txt y me falta el el sleep para que no consuma tanta bateria.

Noto que falto File, el arreglo de las interrupciones en Loop no las comprendo muy bien.

En el periodo lo voy a fijar a 5 para que de la mayor cantidad en 24 horas.
Necesito que quede asi en la SD.

y pongo una condicion que cuando now.minute()= 0,5,10,15,20,25,30,35,40,45,50 registre en memoria el numero de pulsaciones.

Esto se repetira 12 veces:


01/01/2017  00:00:00  1000
01/01/2017  00:05:00  1000
01/01/2017  00:10:00  1000
01/01/2017  00:15:00  1000
01/01/2017  00:20:00  1000
01/01/2017  00:25:00  1000
01/01/2017  00:30:00  1000
01/01/2017  00:35:00  1000
01/01/2017  00:40:00  1000
01/01/2017  00:45:00  1000
01/01/2017  00:50:00  1000
01/01/2017  00:55:00  1000
01/01/2017  01:00:00  1000




surbyte

Mas alla que se puede optimizar porque no miras este hilo STM32F103C8T6 y Arduino IDE de lightcalarmar

Go Up