Ciao a tutti,
Dovrei stampare una frase caricata in modo random da più stringhe
char string1[] = "Frase 1";
char string2[] = "Frase 2";
char string3[] = "Frase 3";
char string4[] = "Frase 4";
Come posso creare il nome della stringa in modo random, per farlo poi stampare?
Avendo frasi da 500 caratteri a stringa quante stringhe posso caricare su arduino uno o mega?
Grazie
No, fai un vettore/array di stringhe e poi in modo random generi quale elemento del vettore stampare.
char* stringa[] = {
"Frase 1",
"Frase 2",
"Frase 3",
"Frase 4"
};
L'indice del vettore va da 0 a n-1 elementi, usi quello per il random
Random calcoli esempio 3 stampi quindi stringa[3]
Così però tutto è in SRAM e Arduino Uno ha solo 2Kb
Dovrai quindi memorizzare le stringhe in memoria FLASH assieme al codice usando PROGMEM
Prima di stampare la frase dovrai copiare dall'array/vettore che sta in flash a una stringa che stà in SRAM e poi stampare.
In allegato pdf da studiare su PROGMEM.
#include <avr/pgmspace.h>
char string_1[] PROGMEM = "String 1";
char string_2[] PROGMEM = "String 2";
char string_3[] PROGMEM = "String 3";
char string_4[] PROGMEM = "String 4";
char string_5[] PROGMEM = "String 5";
PGM_P string_table[] PROGMEM =
{ string_1, string_2, string_3, string_4, string_5
};
char buf[20];
void setup()
{ Serial.begin(9600);
}
void loop()
{ byte x=random(5); // 0-4
strcpy_P(buf, (PGM_P)pgm_read_word(&(string_table[x])));
Serial.println(buf);
}
Compilato con IDE 1.0.6 versione 1.6.x ha nuova toolchain, quindi vedere post sotto di Guglielmo dove dice di aggiungere const.
Progmem.pdf (182 KB)
Risolto con il vettore di array, il problema rimane la memoria, posso memorizzare un massimo di 8 frasi.
Ho provato con progmem e mi da questo errore:
C:\Users\utente\AppData\Local\Temp\arduino_modified_sketch_795762\sketch_jan05a.ino:1:29: fatal error: avr / pgmspace .h: No such file or directory
#include <avr / pgmspace .h>
Non capisco se manca la libreria
gpb01
January 5, 2017, 11:33am
5
NON #include <avr / pgmspace .h> , MA #include <avr/pgmspace .h> ... ovvero SENZA gli spazi !!!!
Fa parte di AVR libc che è sempre inclusa automaticamente. Le funzioni che include <avr/pgmspace.h> le trovi documentate QUI .
Guglielmo
Si, già avevo notato l'errore ora però mi da:
In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:28:0,
from sketch\sketch_jan05a.ino.cpp:1:
sketch_jan05a:5: error: variable 'string_1' must be const in order to be put into read-only section by means of 'attribute ((progmem))'
char string_1[] PROGMEM = "String 1";
^
sketch_jan05a:6: error: variable 'string_2' must be const in order to be put into read-only section by means of 'attribute ((progmem))'
char string_2[] PROGMEM = "String 2";
^
sketch_jan05a:7: error: variable 'string_3' must be const in order to be put into read-only section by means of 'attribute ((progmem))'
char string_3[] PROGMEM = "String 3";
^
sketch_jan05a:8: error: variable 'string_4' must be const in order to be put into read-only section by means of 'attribute ((progmem))'
char string_4[] PROGMEM = "String 4";
^
sketch_jan05a:9: error: variable 'string_5' must be const in order to be put into read-only section by means of 'attribute ((progmem))'
char string_5[] PROGMEM = "String 5";
^
sketch_jan05a:11: error: variable 'string_table' must be const in order to be put into read-only section by means of 'attribute ((progmem))'
PGM_P string_table[] PROGMEM =
^
exit status 1
variable 'string_1' must be const in order to be put into read-only section by means of 'attribute ((progmem))'
gpb01
January 5, 2017, 12:05pm
7
... aggiungi la parolina "const " all inizio delle varie righe ... solo elementi "costanti" (ovvero NON variabili ) possono essere messi in PROGMEM (... ed il compilatore te lo sta anche dicendo ).
Fai una cosa ... studiati bene il documento che ti allego
Guglielmo
Progmem.pdf (182 KB)
Ti ringrazio, sono nuovo e ho solo basi.
Prima di proseguire, dovrei memorizzare 20 - 30 frasi per poi richiamarle, mi consigliate:
Sia come semplicità che come stabilita dello sketch
gpb01
January 5, 2017, 12:53pm
9
Se hai spazio nella memoria "programma", allora PROGMEM è sicuramente la più efficiente.
Dai retta, dedica un po' di tempo a studiare con calma il documento che ti ho allegato al post #6
Guglielmo
Ho adattato il codice senza errori
#include <avr/pgmspace.h>
const char string_1[] PROGMEM = "String 1";
const char string_2[] PROGMEM = "String 2";
const char string_3[] PROGMEM = "String 3";
const char string_4[] PROGMEM = "String 4";
const char string_5[] PROGMEM = "String 5";
const char * MenuItemPointers [] =
{ string_1, string_2, string_3, string_4, string_5
};
char buf[20];
void setup()
{ Serial.begin(9600);
}
void loop()
{
byte x=random(5); // 0-4
strcpy_P(buf, (PGM_P)pgm_read_word(&(MenuItemPointers[x])));
Serial.println(buf);
delay(1000);
}
come println mi da tutti SSSSSSSSSSSSSSSSSSSSSSSSSSSSS
Dove sbaglio?
Anche MenuItemPointer deve usare PROGMEM
Come scritto in pagina 8 del pdf allegato da Guglielmo
#include <avr/pgmspace.h>
// ricorda che PGM_P => const char *
const char string_1[] PROGMEM = "String 1";
const char string_2[] PROGMEM = "String 2";
const char string_3[] PROGMEM = "String 3";
const char string_4[] PROGMEM = "String 4";
const char string_5[] PROGMEM = "String 5";
PGM_P const string_table[] PROGMEM =
{ string_1, string_2, string_3, string_4, string_5
};
char buf[20];
void setup()
{ Serial.begin(9600);
}
void loop()
{ byte x=random(5); // 0-4
strcpy_P(buf, (PGM_P)pgm_read_word(&(string_table[x])));
Serial.println(buf);
}
Versione compilata con IDE 1.6.13
Ok, ora funziona perfettamente!
Ora è sorto un altro problema, aggiungendo un
Serial.println("testo");
Non stampa nè
Serial.println(buf);
Nè
Serial.println("testo");
Posta il codice completo, mica ho capito cosa hai aggiunto.
#include <avr/pgmspace.h>
// ricorda che PGM_P => const char *
const char string_1[] PROGMEM = "String 1";
const char string_2[] PROGMEM = "String 2";
const char string_3[] PROGMEM = "String 3";
const char string_4[] PROGMEM = "String 4";
const char string_5[] PROGMEM = "String 5";
PGM_P const string_table[] PROGMEM =
{ string_1, string_2, string_3, string_4, string_5
};
char buf[20];
void setup()
{ Serial.begin(9600);
}
void loop()
{ byte x=random(5); // 0-4
strcpy_P(buf, (PGM_P)pgm_read_word(&(string_table[x])));
Serial.println(buf);
Serial.println("Testo");
delay(1000);
}
Facendo varie prove sono arrivato a questa conclusione, anche se non capisco il motivo.
Se eseguo:
#include <avr/pgmspace.h>
// ricorda che PGM_P => const char *
const char string_1[] PROGMEM = "String 1";
const char string_2[] PROGMEM = "String 2";
const char string_3[] PROGMEM = "String 3";
const char string_4[] PROGMEM = "String 4";
const char string_5[] PROGMEM = "String 5";
PGM_P const string_table[] PROGMEM =
{ string_1, string_2, string_3, string_4, string_5
};
char buf[20];
void setup()
{ Serial.begin(9600);
}
void loop()
{ byte x=random(5); // 0-4
strcpy_P(buf, (PGM_P)pgm_read_word(&(string_table[x])));
Serial.println(buf);
Serial.println("Testo");
delay(1000);
}
Stampa il testo, ma se la stringa è più lunga
#include <avr/pgmspace.h>
// ricorda che PGM_P => const char *
const char string_1[] PROGMEM = "String 1aaaaaaaaaaaaaa bbbbbbbbbbbbbb ccccccccccccccccc ddddddddddddddd eeeeeeeeeeeeeee ffffffffffffffffff gggggggggggggg hhhhhhhhhhhhhh iiiiiiiiiiiiii llllllllllllll mmmmmmmmmmmmmmm";
const char string_2[] PROGMEM = "String 2aaaaaaaaaaaaaa bbbbbbbbbbbbbb ccccccccccccccccc ddddddddddddddd eeeeeeeeeeeeeee ffffffffffffffffff gggggggggggggg hhhhhhhhhhhhhh iiiiiiiiiiiiii llllllllllllll mmmmmmmmmmmmmmm";
const char string_3[] PROGMEM = "String 3aaaaaaaaaaaaaa bbbbbbbbbbbbbb ccccccccccccccccc ddddddddddddddd eeeeeeeeeeeeeee ffffffffffffffffff gggggggggggggg hhhhhhhhhhhhhh iiiiiiiiiiiiii llllllllllllll mmmmmmmmmmmmmmm";
const char string_4[] PROGMEM = "String 4aaaaaaaaaaaaaa bbbbbbbbbbbbbb ccccccccccccccccc ddddddddddddddd eeeeeeeeeeeeeee ffffffffffffffffff gggggggggggggg hhhhhhhhhhhhhh iiiiiiiiiiiiii llllllllllllll mmmmmmmmmmmmmmm";
const char string_5[] PROGMEM = "String 5aaaaaaaaaaaaaa bbbbbbbbbbbbbb ccccccccccccccccc ddddddddddddddd eeeeeeeeeeeeeee ffffffffffffffffff gggggggggggggg hhhhhhhhhhhhhh iiiiiiiiiiiiii llllllllllllll mmmmmmmmmmmmmmm";
PGM_P const string_table[] PROGMEM =
{ string_1, string_2, string_3, string_4, string_5
};
char buf[20];
void setup()
{ Serial.begin(9600);
}
void loop()
{ byte x=random(5); // 0-4
strcpy_P(buf, (PGM_P)pgm_read_word(&(string_table[x])));
Serial.println(buf);
Serial.println("Testo");
delay(1000);
}
non stampa nulla!
Ho provato anche inserendo una pausa da 10 secondi, per dare il tempo alla seriale di scrivere, ma niente!
Ho risolto impostando una stringa da 200 caratteri
**char buf[200]; ** al posto di char buf[20];
Lavorando con stringhe così lunghe non comporta niente in termini di stabilità?
Scusa, ma è ovvio che non funziona. buf è il tramite in memoria SRAM attraverso cui travasiamo quelle frasi che stanno in memoria FLASH prima di stamparle. Se in FLASH ha frasi da 6 Km è logico che in un buf da 20 non ci stanno !!