ATtiny & virtual wire pour telecommande

Bonjour tout le monde !!

J'ai grace a vos conseil pu me debrouiller pour trouver ce dont j'avais besoin dans la jungle arduino, tout est dans une belle petite boite, mais pour mettre en oeuvre je suis bloqué.

J'aimerais faire une telecommande RF a l'aide d'un ATtiny et un emmeteur RF qui envoie un ordre a mon aduino qui recois l'ordre et qui actione un mecanisme. Pour cela j'ai la librairire virtual wire.

comment donner des ordres différents ? (mis a part afficher je ne comprend pas comment allummer tel ou tel pin grace a une commande RF)

Voila, si il y a une bouée pour me sauver de cette noyade de codes, merci !!!

Bonjour,

En moyen simple mais pas franchement optimisé est d'utiliser strcmp() et d'envoyer les ordres sous forme de texte.
Exemple : [Tutoriel] Arduino et émetteur/récepteur 433MHz (VirtualWire) | Skyduino - Le DIY à la française

Merci skyduino, tu me sauve la vie =) et par rapport a ton tutoriel sur le RF, si je veux juste déclencher un type d'action j'utilise la commande vw_wait_rx ca marche ? j'attend que le recepteur recoive un message (peut importe lequel) et j'active mon mecanisme apres ? ca marcherais ? sinon le buf c'est comme une variable ? le programme peut il lire dedans et en fonction du mot dedans il deroule mon mecanisme ? parce que j'auris bien fait un truc du genre telecommande somfy, on appraire la telecommande et roule ma poule !

messkid:
j'attend que le recepteur recoive un message (peut importe lequel) et j'active mon mecanisme apres ? ca marcherais ?

Si tu as qu'une seule et unique commande et que tu veut pas vérifier sa validité ça marcherait oui.

messkid:
sinon le buf c'est comme une variable ? le programme peut il lire dedans et en fonction du mot dedans il deroule mon mecanisme ? parce que j'auris bien fait un truc du genre telecommande somfy, on appraire la telecommande et roule ma poule !

C'est un tableau d'octets (byte), à toi de faire rentrer dedans ce que tu veut (des char, des int, des struct, ...).
Regarde dans les commentaires de mon article tu as des exemples de commande par texte.

Donc en gros si ma telecommande envoie "active" je peux dire a l'arduino d'activer le mecanisme uniquement si il recois le mot "active" ! C'est nickel ca merci beaucoup !

et ce composant est compatible virtual wire ? http://arduino.cc/en/uploads/Hacking/Atmega168PinMap2.png

En parlant de transmission radio, que pensez-vous des composants ht12d et ht12e et du cta88 ?

messkid:
Donc en gros si ma telecommande envoie "active" je peux dire a l'arduino d'activer le mecanisme uniquement si il recois le mot "active" ! C'est nickel ca merci beaucoup !

C'est le principe d'une télécommande :wink:

messkid:
et ce composant est compatible virtual wire ? http://arduino.cc/en/uploads/Hacking/Atmega168PinMap2.png

Oui, ATmega168 (Arduino decim...) = ATmega328 (Arduino UNO) avec deux fois moins de mémoire.

Nickel, par contre je n'arrive pas a lire les info sans avoir le COM, puis-je envoyer le message recu dans une variable afin de le comparer ou pas ?

Enfin j'aimerais comparer le message recu sans utiliser le serial, et ca ne marche pas ..

Avec un code pour comprendre d’où vient ton erreur ce serait mieux :wink:

Suis-je bete ..

Donc voila j'ai un ATtiny 85 en emission et j'aimerais juste un ATmega en reception. Pour l'instant les essais se font avec 2 arduino UNO.

J'aimerais recevoir le mot (rotation) , et le mettre dans une variable afin de le comparer et lancer la fonction associée (c'est surtout pour eviter les parasites car a terme j'en aimerais plusieurs qui fonctionnent indépendement).

Donc voila mes codes (c'est pas ecore bien organisé) et plagiés de ton site =)

Pour les essais je met juste un petit interrupteur au niveau de la broche DATA , et j'appuis quand je veux envoyer (+ simple).

RECEPTION :

#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

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
Serial.println("debut de la reception"); // Petit message de bienvenue

}

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.write(buf*);*

  • Serial.println("");*
    _ if(strcmp("rotation", (char*)buf) == 0)_
    {
  • vw_rx_stop;*
  • digitalWrite(2, LOW);*
    delay (1000);
    digitalWrite (2, HIGH);
    vw_rx_start;
    }

}}}
-------------------------------------------------------------
EMISSION :
#include <VirtualWire.h> // inclusion de la librairie VirtualWire
const char *msg = "rotation"; // Tableau qui contient notre message
void setup() // Fonction setup()
{

  • vw_setup(2000); // initialisation de la librairie VirtualWire à 2000 bauds (note: je n'utilise pas la broche PTT)*
    }
    void loop() // Fonction loop()
    {
    vw_send((uint8_t *)msg, strlen(msg)); // On envoie le message
  • vw_wait_tx(); // On attend la fin de l'envoi*
  • delay(1000); // Et on attend 1s pour pas flooder*
    }

Met tes codes entre balises code (icône #), le forum a bouffé une partie des parenthèses :wink:

#include <VirtualWire.h> // inclusion de la librairie VirtualWire

const char *msg = "rotation"; // Tableau qui contient notre message
const int bouton = 2; // Definition de la broche du bouton
int etatbouton; // Creation de la variable etat du bouton

void setup() // Fonction setup()
{
  Serial.begin(9600); // Initialisation du port série pour avoir un retour sur le serial monitor
  pinMode (bouton, INPUT); // Le bouton est une entrée 
  vw_setup(2000);		// initialisation de la librairie VirtualWire à 2000 bauds (note: je n'utilise pas la broche PTT)
}

void loop() // Fonction loop()
{
  etatbouton = digitalRead(bouton);// Lecture de l'etat du bouton
      if (etatbouton == LOW)// si le bouton est enfoncé :
      {  
        vw_send((uint8_t *)msg, strlen(msg)); // On envoie le message 
        vw_wait_tx(); // On attend la fin de l'envoi
        Serial.println("message envoye");
      }
}

et pour la reception :

#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

    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
    Serial.println("debut de la reception"); // Petit message de bienvenue

}

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.write(buf[i]);
			Serial.println("");
   if(strcmp("rotation", (char*)buf) == 0)
 { 
   vw_rx_stop;
   digitalWrite(2, LOW);
 delay (1000);
 digitalWrite (2, HIGH);
 vw_rx_start;
 }
  
}}}

J'ai essayé de virer les serial mais apres le programme ne marche plus. (encore desolé)

Je crois savoir où est l'erreur :wink:
Tu envois strlen(msg) octets, mais ton message fait en mémoire strlen(msg) + 1 octets.
Il ne faut pas oublier le \0 à la fin de la chaine de caractère (pas \0 = pas de fin = bug).

Sinon c'est quoi c'est deux lignes :

vw_rx_stop; // Parenthèses oubliées ?
   digitalWrite(2, LOW);
 delay (1000);
 digitalWrite (2, HIGH);
 vw_rx_start; // Parenthèses oubliées  ?

Je ne comprend pas, j'ai juste à rajouter le /0 à la fin de mon message ?
Ces 2 lignes c'est pour arrêter la réception le temps du programme et la reprendre à la fin, ça marche pas comme ça ?
Et si je veux mettre le message dans une variable je fais comment ?
Merci pour cette réponse en tout cas j'essaie des que j'ai l'ordinateur sous la main !

messkid:
Je ne comprend pas, j'ai juste à rajouter le /0 à la fin de mon message ?

Non le compilateur ajoute automatiquement le \0 à toute les chaines de caractères entre "...".
C'est au niveau du strlen(msg) que tu doit faire strlen(msg) + 1.
strlen() renvoi le nombre de caractères de la chaine mais ne compte pas le \0, du coup tu ne l’envoie pas et côté réception le strcmp() n'as plus de \0 et ne sait donc plus où se situe la fin du message.

messkid:
Ces 2 lignes c'est pour arrêter la réception le temps du programme et la reprendre à la fin, ça marche pas comme ça ?

C'est des fonctions donc les () sont obligatoires sinon tu n'appelles pas la dite fonction.
truc_machin; -> ça fait rien
truc_machin(); -> appelle la fonction truc_machin()

messkid:
Et si je veux mettre le message dans une variable je fais comment ?

Deux choix :

  • soit tu crées une variable de type char[] avec une taille fixe que tu remplis avec strcpy()
  • soit tu utilises un pointeur char* que tu fait pointer vers une chaine de char constante.

Exemple avec la 2ieme solution :

const char* CMD_TOTO = "toto";
const char* CMD_TATE = "tata";

void envoiCommande(const char* cmd) {
  vw_send((uint8_t *) cmd, strlen(cmd) + 1);
  vw_wait_tx();
}

// ... quelque part dans ton code
envoiCommande(CMD_TOTO);

// ... quelque part ailleurs dans ton code
envoiCommande(CMD_TATA);

// ... et bonus avec une variable
char const * ptr; // "char const *" -> pointeur pas constant sur un truc constant
ptr = CMD_TATA;
envoiCommande(ptr);

Quel sauveur =)) je vais me debrouiller pour la suite alors, mais j'ai juste une derniere question : Je peux utiliser juste des AT tiny ou mega en reception, ou j'ai besoin de composants en + (quartz etc..) ?

messkid:
mais j'ai juste une derniere question : Je peux utiliser juste des AT tiny ou mega en reception, ou j'ai besoin de composants en + (quartz etc..) ?

Si tu utilises des ATmega tu auras besoin d'un quartz + condensateurs (x2, généralement de 22pF), de même qu'un bouton + résistance pour le reset, ... (voir montage "arduino breadboard" pour la liste exhaustive).

Pour l'ATtiny un condensateur de 100nF à mettre entre VCC (5v) et GND devrait suffire.
L'oscillateur interne de l'Attiny devrait suffire pour VirtualWire.