Premier: j'ai hérité de ce projet de quelqu'un qui ne pouvait pas le compléter en raison de contraintes de temps.
Le code contient un peu plus de 100 matrices déclarées, chacun contenant un ensemble d'INTS. Les tableaux sont tous uniques. P>
byte seqs[][7] = { {2, 5, 6, 8, 3}, {1, 7}, {6, 10, 9, 11, 7, 8, 3} }
3 Réponses :
Mettre les données dans des tableaux 2D ne sauverra aucun espace.
En ce moment, vous stockez ces valeurs dans votre 2K de SRAM. Changer ces déclarations pour utiliser Mot-clé PROGMEM , alors ils 're stocké où il y a beaucoup em> plus d'espace. p> Utilisation du PROGMEM indique au compilateur de charger ces données dans la partie flash de la mémoire: p> Cependant, les données doivent être accessibles avec un appel de la fonction , vous ne pouvez pas simplement l'utiliser directement. P> for (byte k = 0; k < 5; k++)
{
uint8_t next_led = pgm_read_byte_near( arr_foo + k );
// Do something with next_led
}
De plus, à cette solution ProgMem, vous auriez besoin d'un tableau de plus de 100 pointeurs ou de références à ces petits tableaux et à leur taille.
@Datafiddler - Oui vrai. Peut-être que l'OP pourrait mettre toutes les données d'adresse LED dans une seule matrice linéaire, mais a ensuite un autre tableau de décalage, longueur code> des paires indexées dans ces données pour chaque élément.
Si ces matrices forment un motif de voyants qui doivent être allumés, tandis que les autres sont éteints, vous pouvez stocker l'état de toutes les voyants dans un Si vous ne connaissez pas la notation hexagonale, vous pouvez utiliser le format binaire. P> uint16_t code> et avoir un tableau de ceux-ci dans PROGMEM code>. (Comme dans la réponse de Kingsley)
const PROGMEM uint_16_t patterns[] = {
// BA9876543210 Led Pins
0b000101101100, //foo: 2, 5, 6, 8, 3
0b000010000010, //bar: 1, 7
0b111111001000, //baz: 6, 10, 9, 11, 7, 8, 3
// ...
};
Oui, l'ordre est corrigé. Fondamentalement une séquence peut alléger les LED 2, 4, 9 dans cet ordre, mais une autre séquence pourrait inverser cela, et encore une autre pourrait aller 4, 9, 2 ... même ensemble de voyants, juste un ordre différent. Et certaines séquences n'ont que 2 LED, d'autres ont plus, dont certaines sont répétées. C'est un peu compliqué ...
Pour une telle séquence, le calendrier est crucial et probablement beaucoup plus de mémoire consommant.
Je ne suis pas sûr de comprendre ce que vous voulez dire avec le timing ici. Pourriez-vous élaborer un peu plus?
Si vous avez besoin d'une séquence i>, vous voulez par exemple. Le voyant de première lumière n ° 6, puis le voyant plus tard n ° 10, puis le voyant n ° 9. Ma question concerne "plus tard". Est-il toujours corrigé (par exemple 200 ms après l'autre) ou n'est-ce pas configurable individuellement?
Oh ça. Non, le timing est tous corrigé. Ils disparaîtront tous en succession rapide (avec un court délai entre chacun), puis disparaissent à nouveau.
Pour moi, vos commentaires ont complètement changé votre question complètement. P>
Comme je l'ai lu maintenant, il n'est pas nécessaire de créer un type particulier de données "nom" pour identifier un tableau. Ce que vous voulez semble être juste de passer des matrices différentes autour des arguments de la fonction. P>
Ceci est généralement fait via des pointeurs et il y a deux éléments à noter: P>
Exemple: p>
Si vous souhaitez transmettre un tableau d'éléments de type ou équivalent p> puis appelez cette fonction en passant simplement la variable de tableau et la longueur de la matrice correspondante, comme p> Les données constantes "peuvent être placées dans Ensuite, il y a le problème de, je pourrais toujours manquer de mémoire plus tard
temps comme plus de séquences sont ajoutés. P>
blockQuote> Notez que l'AVR "Arduino" a 32Ko de mémoire flash. Si chaque séquence consomme 15 octets, il pourrait probablement toujours contenir 1000 ou 2000 de ces éléments avec votre programme. P> Alors quoi? Ajoutez une mémoire flash I2C externe et poussez les choses dans
là? N'ayant jamais traité cela, je ne sais pas comment mettre en œuvre
que, dans quel format stocker les valeurs et comment le faire. p>
blockquote> Si vous manquez de flash à un moment donné, vous pouvez toujours recourir à une forme de stockage externe. p> une solution commune est la mémoire flash SPI, qui est facilement disponible dans la méga -Bit gamme. winbond est un fournisseur bien connu. Il suffit de rechercher des modules et des bibliothèques d'Arduino SPI Flash ". P> Une approche plus complexe serait de prendre en charge les cartes SD comme mémoire externe. Mais probablement pas la peine que si vous voulez veux em> pour stocker des gigaoctets de données. P> suis-je correct que l'on doit d'abord écrire un programme qui charge tout le
données en mémoire, téléchargez cela et exécutez-le, puis mettez le programme actuel
Cela va traiter ces données sur le micro contrôleur? P>
BlockQuote> C'est définitivement une façon de le faire. Si votre espace de code le permet, vous pouvez également inclure les routines à écrire dans la mémoire flash externe de votre application, comme une sorte de chargeur de démarrage afin de pouvoir passer en mode "Télécharger des données flash externes" sans refliger le microcontrôleur. p> h2> T code> sur une fonction, vous pouvez déclarer la fonction d'accepter un pointeur sur < code> t code>: p>
progesmem code> pour sauvegarder la RAM, mais, comme d'autres l'ont noté, Les accès en lecture sont un peu plus complexes, nécessitant
pgm_read _... () code> appelle en C ++. (AVR GCC prend en charge
__Flash code> -Qualified
données uniquement en C, pas en C ++.) P>
Droite, je sais qu'il a 32 kb flash, mais ces tableaux sont stockés dans le 2Kb plus petit SRAM ... Donc, soit je le déplace tout dans PROGMEM, ou je trouve une autre solution. Je n'ai rien fait avec de la mémoire externe (que ce soit une mémoire EEPROM ou Flash), mais j'ai déjà utilisé le stockage SD avant et pour ce projet, ce serait surchargé. :)
Pourquoi les tableaux sont-ils stockés dans la RAM? Les données sont-elles connues au moment de la compilation ou change-t-il pendant l'exécution?
Les données ne changeront jamais. Seuls les nouveaux seront ajoutés au fil du temps (comme une fois tous les quelques mois.)
Avoir-ils besoin d'être modifiés ou de lecture seulement? Si je ne me trompe pas entièrement les déclarer comme des matrices comme celle-ci les fera de copier à la RAM, alors que si vous les déclarez simplement les déclarer avec des pointeurs, ils peuvent être dans la ROM et ne pas prendre de précieux petit bélier que vous avez. Je suppose que c'est ce qui manque ici.
Qu'entendez-vous par «séquences»? Je suppose que les octets de ces tableaux sont des chiffres d'épingle. Devraient-ils former un motif de LED, tandis que les autres sont censés être désactivés?
"Et c'est là qu'ils l'ont adopté, disant qu'ils n'ont pas le temps de le comprendre." - Je déteste quand ça arrive...
@Sami: Yep, à court de 1k RAM - ils ne changent pas, une fois que définir les tableaux restent les mêmes, essentiellement pour toujours.
@Datafiddler: Nombre pas de code PIN, mais numéro de LED. Il y a 11 voyants, numérotés de 1 à 11 (logiciel les voit de 0 à 10). L'un des matrices détermine les LED à ce que quelque chose avec quelque chose avec, en séquence, signification d'un par un. Qu'il s'agisse de les décolorer, ou de les éteindre, ou de les flasherner ... Cela fait quelque chose avec cet ensemble spécifique répertorié dans la matrice, dans l'ordre dans lequel ils sont répertoriés.
"Une routine qui, lorsqu'elle est donnée un nom de matrice ..." - Où est-ce que ce tableau Nom i> vient? Est-ce que c'est comme une chaîne d'entrée par certains utilisateurs? Ou avez-vous juste besoin d'une routine que vous pouvez appeler pour différents tableaux?
@JIMMYB, il n'a pas nécessairement besoin d'un nom de tableau, je lisais les notes laissées par la personne précédente. Compte tenu des exemples ci-dessus, je dois être capable de les référencer plus loin dans le programme: Byte Arr_foo [] = {2, 5, 6, 8, 3}; ... Et l'idée, comme écrit, était que l'on réussirait le nom de la matrice à la routine: annuler quelque_fancy_routine (var_foo) {...} ... à quel point la routine recueille ensuite le contenu de var_foo et fait quelque chose avec ces données. Cependant, je suis bien conscient que ce n'est pas possible, mais il semble que la personne précédente ne l'a pas fait et a abandonné en essayant de le comprendre.
Notez qu'il est parfaitement possible de déclarer une fonction comme
annulement quelque_fancy_routine (uint8_t * arrond, uint8_t len) {...} code> puis appelez-le comme
quelque_fancy_routine (arr_foo, 5) code > et
quelque_fancy_routine (arr_bar, 2) code>.
Hein, je n'ai jamais fait de cette façon ... suppose que c'est l'expérience d'expérimentation. Merci @jimmyb!
Voir aussi EN.WIKIBOOKS.ORG/WIKI/C_PROGAMMING/.../a>