#include <VirtualWire.h>
const char *msg1 = "23574617";
const char *msg2 = "76543210";
char msg3[10];
void setup()
{
Serial.begin(9600);
vw_setup(2000);
}
void loop()
{
vw_send((uint8_t *)msg1, strlen(msg1)+1); // le +1 pour envoyer le '\0' de fin de chaîne si vous voulez
vw_wait_tx();
vw_send((uint8_t *)msg2, strlen(msg2)+1); // le +1 pour envoyer le '\0' de fin de chaîne si vous voulez
vw_wait_tx();
itoa((int) (millis()/1000), msg3, 10); // nombre de secondes depuis le début du sketch
vw_send((uint8_t *)msg3, strlen(msg3)+1); // le +1 pour envoyer le '\0' de fin de chaîne si vous voulez
vw_wait_tx();
Serial.println("Fin de la transmission.");
delay(2000);
}
bien sûr il faut que de l'autre côté il y ait du code qui écoute..
// ==== Recepteur 433 MHz ===============================
//
// Source : http://skyduino.wordpress.com/2011/12/29/tutoriel-arduino-et-emetteurrecepteur-433mhz-virtualwire/
//
//=======================================================
#include <VirtualWire.h> // inclusion de la librairie VirtualWire
uint8_t buf[VW_MAX_MESSAGE_LEN]; // Tableau qui va contenir le message reçu (de taille maximum VW_MAX_MESSAGE_LEN)
uint8_t buflen = VW_MAX_MESSAGE_LEN; // Taille maximum de notre tableau
void setup() // Fonction setup()
{
Serial.begin(9600); // Initialisation du port série pour avoir un retour sur le serial monitor
Serial.println("Tuto VirtualWire"); // Petit message de bienvenue
vw_setup(2000); // initialisation de la librairie VirtualWire à 2000 bauds (note: je n'utilise pas la broche PTT)
vw_rx_start(); // Activation de la partie réception de la librairie VirtualWire
}
void loop() // Fonction loop()
{
if (vw_wait_rx_max(200)) // Si un message est reçu dans les 200ms qui viennent
{
if (vw_get_message(buf, &buflen)) // On copie le message, qu'il soit corrompu ou non
{
Serial.print("RX : ");
for (byte i = 0; i < buflen; i++) // Si il n'est pas corrompu on l'affiche via Serial
//Serial.print(buf[i]); //Conversion ASCII
{Serial.print(buf[i]- '0'); //Conversion ASCII des chiffres 0-9
}
Serial.println("");
}
}
}
Mais je ne sais pas comment il peut lire deux messages différents (et qu'il sache: celui ci c'est le msg un et celui c'est le msg deux). Pouvez vous m'aider ?
Soit vous comptez à chaque tour de boucle 1, 2 ,3 puis 1, 2 ,3 mais c'est pas très robuste si vous ratez un message, soit vous mettez comme premier octet du message envoyé le No ou le type de ce message. Par exemple si vous envoyez 5 valeurs, envoyez
A214
B125
C32
D177
E112
Puis ça recommence
A233
B144
....
Au décodage vous regardez le premier octet et ça vous dit quel message c'est
Quand vous faites vw_get_message(buf, &buflen, si ça ne retourne pas 0 (c'est pour cela qu'il y a le if avant sinon c'est que le message est corrompu) vous avez dans buf le message reçu. Donc vous pouvez faire un switch(cf example) sur le premier caractère du buffer et lire la valeur à partir du second caractère avec la fonction de décodage d'entiers à partir de leur représentation en ASCII atoi (const char * str);
int valA, valB, valC;
// ...
switch(buf[0]) { // on regarde le premier caractère
case 'A':
valA = atoi((const char *) &buf[1]); // &buf[1] est l'adresse en mémoire de la chaîne partir du second caractère, donc le début du nombre entier envoyé
break;
case 'B':
valB = atoi((const char *) &buf[1]);
break;
case 'C':
//... etc
}
Comment dans le code émetteur je dis que msg1 prend la valeur, par exemple, du potentiomètre ?
Ici, je voudrais dire msg1 prend la valeur de A0 et msg2 celle de A1.
#include <VirtualWire.h>
const char *msg1;
const char *msg2;
void setup()
{
pinMode (A0, INPUT);
pinMode (A1, INPUT);
Serial.begin(9600);
vw_setup(2000);
}
void loop()
{
vw_send((uint8_t *)msg1, strlen(msg1)+1); // le +1 pour envoyer le '\0' de fin de chaîne si vous voulez
vw_wait_tx();
vw_send((uint8_t *)msg2, strlen(msg2)+1); // le +1 pour envoyer le '\0' de fin de chaîne si vous voulez
vw_wait_tx();
Serial.println("Fin de la transmission.");
delay(2000);
}
Il faut réserver un peu de mémoire pour msg1 et pour msg2. Comme vous lisez les valeurs sur A0 et A1 vous aurez un chiffre entre 0 et 1023 - donc 4 caractères max. Il faut le '\0' de fin de chaîne et donc comme on a dit un caractère en début de message pour dire si on envoie A0 (A) ou A1 (B).
Donc 1+4+1=6 characteres pour les buffers:
char msg1[6]; // pour lire A0
char msg2[6]; // pour lire A1
Dans les setup() on peut pré-remplir le premier caractère, on l'écrasera jamais
Ensuite dans la boucle il faut lire A0 et A1 et traduire leur valeur en ASCII et la mettre dans le buffer au bon endroit. on pourrait utiliser sprintf pour tout cela mais inclure cette fonction ça rajoute bcp de code et donc prend de la mémoire. Il existe la fonction [
....
itoa(analogRead(A0), &msg1[1], 10); // &msg[1] --> le pointeur à partir du second caractère
itoa(analogRead(A1), &msg2[1], 10); // idem pour le second message
...
Voilà ça devrait le faire (tapé sur mon iPad donc pas testé)
#include <VirtualWire.h>
char msg1[6]; // pour lire A4
char msg2[6]; // pour lire A5
void setup()
{
pinMode (A4, INPUT);
pinMode (A5, INPUT);
Serial.begin(9600);
vw_setup(2000);
msg1[0] = 'A';
msg2[0] = 'B';
}
void loop()
{
itoa(analogRead(A4), &msg1[1], 10); // &msg[1] --> le pointeur à partir du second caractère
itoa(analogRead(A5), &msg2[1], 10); // idem pour le second message
vw_send((uint8_t *)msg1, strlen(msg1)+1); // le +1 pour envoyer le '\0' de fin de chaîne si vous voulez
vw_wait_tx();
vw_send((uint8_t *)msg2, strlen(msg2)+1); // le +1 pour envoyer le '\0' de fin de chaîne si vous voulez
vw_wait_tx();
Serial.println(msg1);
Serial.println(msg2);
Serial.println("Fin de la transmission.");
delay(200);
}
Mais, je crois que celui ci marche. Vois tu une erreur ?
Ben faut bien écouter les messages qui arriven quand même
(Dans mon exemple de code j'avais mis ... pour montrer qu'il y avait du vide avant)
donc vous attendrez de recevoir un message, quand il est la vous remplissez le buffer et ensuite vous allez regarder si c'est A ou B (valC vous sert à rien au fait)
#include <VirtualWire.h>
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
int valA, valB ;
void setup()
{
Serial.begin(9600);
vw_setup(2000);
vw_rx_start();
}
void loop() // Fonction loop()
{
if (vw_wait_rx_max(200)) // Si un message est reçu dans les 200ms qui viennent
{
if (vw_get_message(buf, &buflen)) // On copie le message, qu'il soit corrompu ou non
{
switch(buf[0]) { // on regarde le premier caractère
case 'A':
valA = atoi((const char *) &buf[1]);
break;
case 'B':
valB = atoi((const char *) &buf[1]);
break;
}
}
}
Serial.println(valA);
Serial.println(valB);
delay (100);
}
Et je ne comprends pas pourquoi les valeurs varient entre 0 et 9999 (ou 0 et 100 la première fois que je lance le programme). Pouvez - vous m'expliquer ?
Mais bon - Il ne faut afficher les valeurs que quand vous avez reçu un message et uniquement pour la valeur reçue - sinon les variables ne sont pas initialisées (enfin comme elles sont globales la première fois elles sont à 0)
Mettez le Print de valA ou valB dans leur case respectif avant le break
Sinon
Pas besoin de délai 100ms à la fin, vous risquez de perdre des messages vaut mieux boucler vite
passez le port série à 115200 bauds au lieu de 9600 pour le moment - pas la peine de ralentir inutilement les Serial.print()
Au lieu d'attendre 200ms un message au début utilisez plutôt la fonction vw_have_message() qui est similaire à available() sur le port série
En gros on fait:
Si qque chose de dispo
Si le message est reçu non corrompu
Décoder en fonction de la première lettre
Lire la valeur
Afficher la valeur