Memory Flash ATtiny85 con GPS NEO 6M

Hola chicos; buenos días… a ver si alguien me logra destrabar la cabeza.

Tengo este Sketch que lee un GPS NEO 6M con un ATtiny85 (no les recomiendo que lo usen porque está a medio hacer. Si logro terminarlo bien. Ahí lo pondré en la Web completo.

El tema es el siguiente:

Donde a este Sketch yo le agregue “una coma” al compilarlo me larga este mensaje de atención que “nunca lo había visto”

Si quito “la coma” por así decirlo. El mensaje desaparece. Es evidente que estoy trabajando sobre el filo de la cornisa de su memoria.

Ahora bien. Seguiré con la metáfora de la “coma”.

Cuando le agrego “la coma” no veo NADA en el Display LCD1602. Pero cuando lo compilo “sin la coma” alcanzo a ver sobre mi display.

$GPGLL y nada más.

Es en este punto; que asocio el mensaje de memory flash con no lograr ver la coordenada completa.

Entonces quisiera poner el parámetro (-D) que me indica el compilador y ver qué ocurre. Pero NO TENGO IDEA donde debo agregar el (-D) Estuve buscando en el datasheet del ATtiny85 pero nada dice al respecto.

Y creo que debo hacerlo en el Archivo de “programmers.txt” pero no tengo idea en que línea hacerlo tampoco.

Gracias de antemano por cualquier comentario que se les ocurra.

#include <SoftwareSerial.h>
SoftwareSerial miCanal(3,4);

#include <LiquidCrystal_attiny.h>
//#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3f,16,2);

char renglon[9]="ZONAL XI";
char dato=' ';
String kracter,kdena;
int k;

void setup(){
//     Serial.begin(9600);            
     miCanal.begin(9600);
     
     lcd.init();
     lcd.backlight();
     
     pinMode(3,INPUT);  // Tx Bth
     pinMode(4,OUTPUT); // Rx Bth
       lcd.clear();lcd.home();
//       for (int i=0; i<8; i++){lcd.setCursor(i,0); lcd.print(renglon[i]);}
}

void loop(){
Nuevo:
//for (int i=0; i<6; i++){lcd.setCursor(i,1); lcd.print(" ");}
k=0;
kdena="";
Lectura:
     if(miCanal.available()>0){
        dato=miCanal.read();
        delay(10);
        kracter=String(dato);
        kdena+=kracter;
        lcd.setCursor(k,1);
        if (k==0){if(kracter=="$"){lcd.print(String("$")); k++; goto Lectura;}else{goto Nuevo;}}
        if (k==1){if(kracter=="G"){lcd.print(String("G")); k++; goto Lectura;}else{goto Nuevo;}}
        if (k==2){if(kracter=="P"){lcd.print(String("P")); k++; goto Lectura;}else{goto Nuevo;}}
        if (k==3){if(kracter=="G"){lcd.print(String("G")); k++; goto Lectura;}else{goto Nuevo;}}
        if (k==4){if(kracter=="L"){lcd.print(String("L")); k++; goto Lectura;}else{goto Nuevo;}}
        if (k==5){if(kracter=="L"){lcd.print(String("L")); 
           while ((dato!='\r') && (dato!=13)){
                  dato=miCanal.read();
                  kracter=String(dato);
           kdena+=kracter; k++; }
           if ((kdena.indexOf(",S")>-1) && (kdena.indexOf(",W")>-1)){
//               lcd.clear(); lcd.home(); for (int i=0; i<8; i++){lcd.setCursor(i,0); lcd.print(renglon[i]);}
               for (int i=0; i<17; i++){
                    char letra=kdena.charAt(i);lcd.setCursor(i,1); lcd.print(String(letra));
               }
           } }
        }
     }
}

no use la clase String, recuperará mucha memoria ...

Hola jackson; gracias por estar ahí.

Debo serte sincero. Pero me decis que no use la clase String. Entonces te consulto. ¿Cual debería de usar en cambio?; así busco y aprendo. Haciendo un esfuerzo por comprenderte. ¿me estarias diciendo que use un buffer? Si es así. Siempre he evitado usarlo porque "creía" que empleaba más memoria al tener que preveer su longitud. Gracias por tu comentario.

es correcto que debemos asignar la memoria necesaria para la string más grande que deseamos recibir. Con una String, deberá asignar esa cantidad de memoria de todos modos, más la que ocupa la clase String y las instancias temporales al manipular.

Jackson!. Te hice caso y mirá que paso.

char renglon[9]="ZONAL XI";
remplacé por este
char renglon[]={90,79,78,65,76,32,88,73};

al compilarlo me aumento un 10% pero ahora mostró el titulo y $GPG

Lo que antes veía uno o el otro por separado. Creo haberte comprendido. Es cambiar el chip de mi cabeza con la facilidad del String por el ASCII, ¿de eso se trata?
Gracias!

Entonces. Si compredí bien todo vos te refías a esto:
http://diymakers.es/usando-el-puerto-serie-del-arduino/

aquí hay un ejemplo que probablemente se acerque a lo que quieres hacer. Sin String

puede ejecutar esto en el simulador haciendo clic en el botón de flecha verde

puede simular lo que sucede en el puerto serie escribiendo un texto en la parte inferior de la ventana, en el monitor serie.


#include <LiquidCrystal_I2C.h>
#include <SoftwareSerial.h>
SoftwareSerial miCanal(PB3, PB4);      // PB3 <-> Tx , PB4 <-> Rx
const uint8_t address = 0x3F;
const uint8_t cols = 16;
const uint8_t lines = 2;

LiquidCrystal_I2C lcd(address, cols, lines);    // PB2 <-> SCL, PB0 <-> SDA

const char * header = "$GPGLL";
byte headerPos = 0;

enum : uint8_t {START, HEADER, CARGAUTIL} stage = START;
const uint8_t maxCargaUtil = 30;
char cargaUtil[maxCargaUtil + 1];
uint8_t cargaUtilPos = 0;

bool escuchar() {
  bool mensajeRecibido = false;

  if (miCanal.available()) {
    char kracter = miCanal.read();
    switch (stage) {
      case START:
        headerPos = 0;
        cargaUtilPos = 0;
        cargaUtil[0] = '\0';
        lcd.clear();
        stage = HEADER;
        [[gnu::fallthrough]];

      case HEADER:
        if (kracter == header[headerPos]) {
          lcd.write(kracter);
          if (++headerPos == strlen(header)) {
            stage = CARGAUTIL;
            lcd.setCursor(0, 1);
          }
        } else {
          stage = START;
        }
        break;

      case CARGAUTIL:
        if ((kracter == '\r') || (kracter == '\n')) {
          stage = START;
          mensajeRecibido = true;
        } else {
          if (cargaUtilPos < cols) lcd.write(kracter);
          cargaUtil[cargaUtilPos++] = kracter;
          cargaUtil[cargaUtilPos] = '\0';
          if (cargaUtilPos >= maxCargaUtil) cargaUtilPos--;
        }
        break;
    }
  }
  return mensajeRecibido;
}

void setup()
{
  miCanal.begin(9600);
  lcd.init();
  lcd.backlight();
  lcd.clear();
}

void loop() {
  if (escuchar()) {
    miCanal.print(F("carga útil: ["));
    miCanal.print(cargaUtil);
    miCanal.println(F("]"));
  }
}

por cierto, no está probando si hay un carácter para leer antes de leer :cold_face: , por lo que agregará mucha basura a su String si hace eso y llenará la memoria muy rápidamente.

➜ Antes de leer, debe asegurarse de que realmente hay algo para leer.

Hola Jackson

Mientras me tomo el mate amargo (acostumbrado) de la tarde pienso ¿cómo se da las gracias en estos casos?

¿Cómo se dice que no soy el que usa el ^C y ^V?... y luego sale diciendo… miren lo que YO hice!

La ayuda brindada de tu parte, (aunque no lo creas) me pone en la responsabilidad de leer mucho más.

Esta inocente sentencia const char * header = "$GPGLL"; He intentando comprenderla en más de una ocasión. Sé que de acuerdo a la posición del “*” cambia su sentido.

No es lo mismo (char * header) que (char *header) que (*char) hace 40 años atrás teníamos que juntar mucho dinero para comprar un libro de Editorial Ra-ma pero sabíamos que detrás de ese gran esfuerzo salíamos aprendiendo muy bien.

Hoy los libros ya no están (pero esta la web) que en este caso del “*” que destaco. No encontré como aprender a usarlo. Del mismo modo que lo hubiese hecho con un libro.

Pero te prometo que aprenderé a usarlo.

Con el tiempo que has dispensado en mi posteo solo me resta decirte dos cosas.

Mi herramienta de trabajo la tengo hecha con una placa de Arduino NANO y funcionando. Pero desde que conocí a ATtiny85 me he quedado fascinado con él. Attiny85 es el símbolo más claro de lo que es el ser humano cuando no piensa en la guerra.

Para finalizar solo quiero expresarte que mi GPS lo uso en mi trabajo y sirve para ayudar a los demás. Con mejor profesionalismo claro.

Me has ayudado a para mejorar la ayuda a vos y el resto de las personas (que me necesitan en mi jurisdicción). Un cordial y gran abrazo.

No soy el mejor para decirlo pero
char * header es igual que char *header y
*char ?? no se que es solo no dice nada tampoco existe si le pones const *char
En todos los casos hablas de un puntero a caracteres
const char *header define = "$GPGLL";
define un puntero a un array de caracteres fijo de 6 bytes.

7 bytes :slight_smile:

no olvides el carácter nulo final

:slight_smile: :innocent:

Buenos Días… se dan cuenta que no miento. En el índice del libro de ra-ma yo hubiese leído “puntero de caracteres”. Vieron ahí está.

Ahora si apareció “claramente” documentación y videos que lo explican. Pero cuando los ves por todas partes y queres buscarlo para comprender porque lo ponen. La web se transforma en un enemigo que termina confundiéndome más (como en este caso en particular).

En otro orden de cosas, anoche veía línea x línea la lógica del algoritmo de Jackson. Y comenzando a intercambiar líneas y conceptos logré bajar (con un par de cambios) la tasa del 43% al 40% de memoria registrada por el compilador. Lo que me lleva a tomar consciencia de su limitación. 512 bytes de memoria.

Voy a tener que replantear; a partir vuestra enseñanza. Mi nueva versión de posicionamiento geográfico “georeferencial” porque me hace perder mucha comodidad en la manipulación de los datos.

Con respecto al Lector “pasivo” que a lo mejor ha seguido este posteo. Concluyo que deberé hacerlo con un Atmega328p. En lugar de un ATtiny85. Me tomaré mi tiempo y analizaré (lo pretencioso de mi proyecto original) para sacar mi decisión final.

¿Que aprendí detrás de este proyecto y gracias a Uds.?:

Puntero de caracteres

Que la lógica con la que se programa un microcontrolador. No es otra; con la que desarrollábamos en los 80 algoritmos que nos permitían leer 100 Tarjetas Electromagnéticas o perforadas en un modo secuencial he ir ordenándolo en base a nuestra búsqueda (deudores > $1500.-) ordenados alfabéticamente o por domicilio. En “pilas” “archivos”, “registros” y “campos”. En lo que definíamos como “Cortes de Control” para terminar imprimiendo en las “sábanas” dicho listado. Algo que a lo largo del tiempo fue remplazado por los GigaBytes de memoria de nuestros equipos; dejando al lenguaje de programación toda la tarea con un simple comando index on, sort to o mySQL. Allá voy… volveré a los 80 con mucho gusto.

Pero también aprendí la grandeza de este pequeño microcontrolador cuando logré una comunicación Bluetooth y conectar mi LCD1602/04. Claro quedó para mí. Que con lo aprendido hoy tendré que reestructurar todo el proyecto en base ya no de lo que quiero obtener si no de la memoria disponible que tengo.

Un cordial saludo.

Pd: mirá estoooo!!!! es un lujo. Ahora sí.
https://www.electrodaddy.com/punteros-y-enlaces-de-arduino/

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.