Transmettre de l'Arduino -> ATTiny85 via Radiohead (RH_ASK.h)

Miaou,

J’ai conçu 2 petits programmes de test :
EmissionTest pour Arduino UNO

// Emission pour Arduino UNO

// Inclusion de la bibliothèque radio
#include <RH_ASK.h>
#include <SPI.h> // nécessaire à la compilation 

// Définition des variables globales (Cst)
const uint8_t TX = 12;
const uint8_t LED = 4; // Sortie LED

// Création d'un objet driver
RH_ASK driver; // création du driver (TX sur Pin 12 par défaut)


void setup()
{
  // Définition du mode des pin
  pinMode(TX, OUTPUT);
  pinMode(LED, OUTPUT);
  
  digitalWrite(LED, LOW);

  // Initialisation du driver
  if (!driver.init()) {/* faire un truc */};
}

void loop()
{
  // Codage du message
  uint8_t buf[2]; // Buffer de 2 uint8_t (char)
  uint8_t buflen = sizeof(buf); // Taille du buffer 
  buf[1] = 0b00000011; // adresse
  buf[0] = 0b11111111; // consigne

  // Envoi de 2 octets (char)
  digitalWrite(LED, HIGH);

  driver.send((uint8_t *)buf, buflen);
  driver.waitPacketSent();
     
  delay(2000);
  digitalWrite(LED, LOW);  
}

ReceptionTest pour ATTiny85.

// Réception pour ATTiny85

// Inclusion de la bibliothèque radio
#include <RH_ASK.h>
#include <SPI.h> // nécessaire à la compilation 

// Définition des variabbles globales (Cst)
const uint8_t TX = 3; // ATTiny pin PB3 (arduino pin A3), inutilisé ici
const uint8_t RX = 4; // ATTiny pin PB4 (arduino pin A4)
const uint8_t LED = 4; // Sortie LED
const uint8_t PWM0 = 0; // Sortie PWM

// Création d'un objet driver
RH_ASK driver(2000,RX,TX,10,false); // 2000 baud, réception sur pin 4 ATTiny

void setup()
{
  // Définition du mode des pin de l'ATTiny 85
  pinMode(RX, INPUT);
  pinMode(LED, OUTPUT);
  pinMode(PWM0, 0);

  digitalWrite(LED, LOW);
  if (!driver.init()) {/* faire un truc */}; // Initialisation du driver
}

void loop()
{
  // Initialisation des variables locales
  static uint8_t adresse = 0b00000011;

  // Réception et traitement de 2 octets (char)
  uint8_t buf[2]; // Buffer de 2 uint8_t (char)
  uint8_t buflen = sizeof(buf); // Taille du buffer
   if (driver.recv(buf, &buflen)) // Message correctement reçu
  {
    if(adresse == buf[1]) // Vérification de l'adresse
    {
      digitalWrite(LED, HIGH);
      analogWrite(PWM0, buf[0]);
    }
    delay(2000);
    digitalWrite(LED, LOW);
    analogWrite(PWM0, 0);
  } 
}

Je souhaite transmettre via la librairie radiohead (RH_ASK.h), 2 octets (donc 2 uint8_t aka char) mais je coince sur le formatage du message avant envoi qui passe apparemment par de l’adressage via pointeur...
Chaque octet est conçu en binaire ; le premier code une adresse, le second une consigne PWM. Si à la réception du message, l'adresse décodée est la bonne alors la led s'allume 2 seconde puis s'éteint, idem pour le PWM.
Apparemment le pgm compile mais je ne suis jamais sûr de rien avec les * en C(++)…

Vais-je retrouver mes 2 octets à la réception ?
A vous lire,

Le Chat.

Ou ça ?

Pour l’ATTiny avez vous vu ça dans le .h

Je crois qu’il y a aussi une version spéciale pour ATTiny85, cherchez RH_ASKTiny ou un nom comme ça.

Bin là (dans le 1er programme)... ^^

Ah, je pensais que vous aviez des opérations sur des pointeurs quelque part.

votre tableau est défini par

buf est donc implicitement promu en pointeur sur uint8_t, le cast ne devrait pas être nécessaire mais ne mange pas de pain…

Est-ce à dire que du fait de :

uint8_t buf[2];

la ligne :

driver.send((uint8_t *)buf, buflen);

pourrait aussi bien s'écrire :

driver.send(buf, buflen);

:thinking:
Les pointeurs... Je n'ai jamais pu comprendre qu'on en use à chaque fois qu'on peut leur trouver un substitut plus lisible (comme ici des TB par ex)... C'est dû à mon intellect simpliste d'ingé méca. :sweat_smile:

Le Chat.

Oui, puisque buf est de type uint8_t[2], il se "dégrade" automatiquement en uint8_t* lorsqu'il est passé en argument de fonction.

Le cast explicite (uint8_t*) n'est donc pas nécessaire.

si vous voulez plus de détails : lorsqu’on déclare uint8_t buf[2];, buf est un tableau de deux octets. En C++, un tableau n’est pas directement de type pointeur, mais dans beaucoup de contextes, notamment lorsqu’il est passé en argument à une fonction, il se “dégradera” automatiquement en pointeur vers son premier élément. (en Anglais vous verrez le terme "decay") et donc buf est équivalent à &buf[0] (l'adresse du premier élément du tableau qui est donc bien un pointeur (l'adresse) sur un uint8_t puisque c'est le type des éléments du tableau).

Ainsi, si une fonction attend un uint8_t*, on peut passer directement buf et le compilateur fait la conversion implicitement.

Il faut juste retenir que cette dégradation ne se produit pas partout : par exemple, sizeof buf donnera toujours la taille totale du tableau (ici 2), alors que sizeof(uint8_t*) donnerait la taille d’un pointeur (qui serait 2 sur un petit arduino et 4 sur un ESP32 par exemple). C'est parce que sizeof est un opérateur et pas une fonction.