Passage de valeur a buffer

Bonjour,

Désolé si c'est un question triviale et de niveau de base mais je ne vois pas trop comme faire et surtout l’écrire

J'ai besoin de passer dans un programme des suites de paramètres de longueur variable utilisées dans une fonction.

Pour ce, j'avais l'intention d'utiliser un buffer (déclaré en global) constitué d'un tableau uint8 mais je ne sais pas trop comment le remplir , faire Tableau[0]=Val1; Tableau[1]=Val2; ..... etc me semble idiot et peu pratique .

Y a t"il moyen de remplir le tableau avec une liste de valeurs hexa de longueur variable comme lors de son initialisation en cours de programme ? Cela se fait bien avec des chaines de caractères.

Pointeurs obligatoires ? ..... et comment ?

Y a t’il moyen de remplir le tableau avec une liste de valeurs hexa de longueur variable comme lors de son initialisation en cours de programme ? Cela se fait bien avec des chaines de caractères.

Bonjour,

je ne me suis jamais posé cette question (si j’ai bien compris). Pour moi il faut de toute façon réserver en RAM les emplacements pour la longueur maximale du tableau.
jouer avec des tableaux de différentes longueurs, en espérant économiser de la ram grâce au foisonnement, est un exercice que je me sentirais incapable de maîtriser

le tableau peut être :

  • rempli en cours d’initialisation, exemple :
    volatile byte tab_num = {0,9,3,0,27,0,13,0,15,0,0,23,0,24,0,0} ;
    où l’on définit à la fois le nombre d’éléments et la valeur de chacun

  • modifié en cours d’exécution de programme individuellement :
    tab_num[3] = 4; // il devient 0,9,3,4,27,0,13,0,15,0,23,0,24,0,0

  • ou collectivement :
    do {
    if (stop[ii] > 1) { stop[ii]++; }
    ii++;
    } while (ii <= max_number_of_samples);

Pointeurs obligatoires ?

oui

et comment ?

grosso modo 2 ortographes :

  • simple comme je viens d’utiliser ( le 3 de tab_num[3] et le ii sont des pointeurs
  • utilisation des caractères * et &, je les laisse aux pros

exemple d’écriture (remplissage) dans un buffer :

void write_buffer()
{
	buffer1[buff_wr_p] = send1;
	buffer2[buff_wr_p] = send2;
	if (buff_wr_p == buff_max) {
		buff_wr_p = 0;
	}
	else {
		buff_wr_p++;
		if (buff_wr_p == buff_rd_p) { buff_overflow = 1; }
	 }
}

et de lecture (vidage) du même buffer :

if (buff_rd_p !=  buff_wr_p ) {
	if (buff_overflow == 1) {
		buff_overflow = 2;
	}
	else if (buff_overflow == 2) {
		cli_led[3] = fast_cli;
	}
	else if (!buff_overflow)  {
		usart_tx_rx_d = buffer1[buff_rd_p];
		send_485();
		usart_tx_rx_d = buffer2[buff_rd_p];
		send_485();
	}
}

Bonjour,

Tu peux entre autres initialiser ton tableau avec un autre tableau

  byte tab[10];
  const byte val[]={0,1,2,3,4,5,6,7,8,9};
  for (int i=0; i<min(sizeof tab,sizeof val); i++)
    tab[i]=val[i];

Ou lui affecter des valeurs calculées

  for (int i=0; i<sizeof tab; i++)
    tab[i]=i*i;

Dans tous les cas, il faut faire attention à ne pas écrire en dehors du tableau, ce qui peut générer des bugs difficiles à trouver.

Hello et merci a vous deux pour vos longues réponses.

Primo : Ce que je peux en tirer est que ce je voulais faire n'est apparemment pas possible directement, une chaine de données n'est pas RÉ-initialisable avec une écriture directe.

Secondo : La nuit ayant passé, mon idée de départ n'est pas forcement la plus censée.

Si je reprend le but initial, il est de passer par une liaison série type "SPI" une chaine de commande a un appareil tout en recevant les données en retour. Les chaines de commandes sont donc des constantes et de longueur variable.

Mon idée de départ était de travailler avec deux buffers d'emplacement fixe, un en émission et un en réception pour traitement partiel en cours de transmission ou global a la fin des données reçues. Une fonction s'occupant alors de cela avec les données chargées dans le buffer Em avant son appel.

Si celui celui en réception est obligatoire le premier est idiot. Il suffit juste que je passe a ma fonction de transmission un pointeur sur la chaine de constantes et sa longueur pour travailler directement avec.

Remplir le buffer d’émission situé un emplacement mémoire avec une chaine qui elle sera située ailleurs nécessitera obligatoirement de toute façon une boucle quelle que soit la manière de l’écrire en C.

Un petit mot sur l’usage de sizeof tab

l’opérateur sizeof en C++ a deux écritures possibles:

  1. sizeof( type )
  2. sizeof expression

la forme 1. retourne le nombre de unsigned char utilisés pour représenter un élément de ce type — abusivement on dit le nombre d’octets car dans la plupart des cas les unsigned char sont sur 8 bits (le oct de octets c’est 8 ). Ce nombre de bits est défini dans CHAR_BIT = nombre de bits dans un unsigned char

la forme 2. retourne le nombre de unsigned char utilisés pour représenter l’évaluation de l’expression

en écrivant ce code:

  for (int i=0; i<min(sizeof tab,sizeof val); i++)
    tab[i]=val[i];

Kamill fait donc l’hypothèse que les valeurs dans tab et val tiennent sur un unsigned char (ce qui est le cas vu la définition des tableau sous forme de byte) mais sa boucle ne fonctionnerait pas s’il y avait un type tenant sur plusieurs unsigned char dans le tableau.

par exemple pour const float val[]={0,1,2,3,4,5,6,7,8,9}; alors sizeof val ou sizeof(val) va retourner 20 sur un Arduino Uno mais 40 sur un ESP8266. pour avoir le bon nombre d’éléments d’un tableau il faut prendre la taille totale du tableau divisée par la taille du type, ou pour faire plus simple, la taille totale du tableau divisée par la taille du premier élément du tableau sizeof(val)/sizeof(val[0]) va alors donner 10 éléments dans le tableau, quelle que soit l’architecture matérielle utilisée et vous pouvez utiliser cela comme borne d’itération.

oui, c'est une bonne pratique que j'adopte la plupart du temps (mais pas cette fois :slight_smile: ).