Yahoo refuse tous les emails du site. Si vous avez une adresse chez un autre prestataire, c'est le moment de l'utiliser ;)

En cas de soucis, n'hésitez pas à aller faire un tour sur la page de contact en bas de page.

Topic "Communiquer sans fil en 433MHz avec la bibliothèque VirtualWire et une carte Arduino / Genuino"

Flux RSS des posts récents dans ce topic ( Flux Atom)


Photo de profil de skywodd

skywodd

Membre

Membre du staff

#180 | Signaler ce message


Dans un précédent article, je vous avais montré comment utiliser un module radio complet, riche en fonctionnalités. Dans ce tutoriel, nous allons voir plus petit et plus low-cost en utilisant de simples modules de communication radio 433MHz à quelques euros pièce. Nous verrons quand et comment utiliser ces modules et comment les mettre en oeuvre avec la bibliothèque Arduino VirtualWire. En bonus, nous verrons comment fabriquer une télécommande sans fil simpliste.

Lire la suite de l'article sur le site

Derniére modification le par skywodd


Pas de photo de profil

fabien

Membre

#281 | Signaler ce message


Bonjour, Merci pour votre article très complet. J'ai un petit problème concernant cette librairie: Je souhaite utiliser un Attiny 85 comme transmetteurs et un arduino nano comme récepteur afin de transmettre des chiffres (float), mais cela ne marche pas, j'ai essayé mon code entre un UNO et un NANO et il fonctionne très bien, vérifié mes branchements une centaine de fois ^^ il n'y a pas de problème… Faut il ajouter une autre librairie sur Attiny ? Comment trouver une solution à ce problème ?

Voici mon code pour Attiny:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#include <VirtualWire.h>

void setup() {

  vw_setup(2000);
  vw_set_tx_pin(1);
}
 
void loop() {

  float valeur = 204;
  
  vw_send((byte *) &valeur, sizeof(valeur)); 
  vw_wait_tx();
}

Et celui du NANO:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <VirtualWire.h>

void setup() {
  Serial.begin(9600);

  vw_setup(2000);
  vw_rx_start(); 

  Serial.println("Go !"); 
}

void loop() {

  float valeur;
  byte taille_message = sizeof(float);

  vw_wait_rx();

  if (vw_get_message((byte *) &valeur, &taille_message)) {

    Serial.println(valeur);
  }
}

Merci infiniment de votre aide !

Edit Skywodd : Ajout des balises code.

Derniére modification le par skywodd


Photo de profil de skywodd

skywodd

Membre

Membre du staff

#283 | Signaler ce message


Bonjour,

Est-ce que tu as tenté d'envoyer un simple caractère pour voir si l’émission fonctionne de base avec l'Attiny ?

N.B. L'appel à la fonction vw_set_tx_pin() devrait être avant vw_setup().


Pas de photo de profil

fabien

Membre

#286 | Signaler ce message


Bonjour,

L'envoi de caractères ne marche pas non plus, même une simple lettre …

Merci


Photo de profil de skywodd

skywodd

Membre

Membre du staff

#287 | Signaler ce message


L'envoi de caractères ne marche pas non plus, même une simple lettre …

par fabien

Tu as un oscilloscope sous la main pour vérifier qu'il y a un signal en sortie de la broche ?

L'appel à vw_set_tx_pin() est bien avant vw_setup() dans ton code ?


Pas de photo de profil

fabien

Membre

#288 | Signaler ce message


L'envoi de caractères ne marche pas non plus, même une simple lettre …

par fabien

Tu as un oscilloscope sous la main pour vérifier qu'il y a un signal en sortie de la broche ?

L'appel à vw_set_tx_pin() est bien avant vw_setup() dans ton code ?

par skywodd

Non pas d'oscilloscope malheureusement, seulement un multimètre… J'ai bien changé le code mais pas plus de resultat…


Photo de profil de mneo31

mneo31

Membre

#307 | Signaler ce message


Bonjour,
moi j'ai un souci avec le transfère de structure.
Coter émetteur aucuns bug, mais coté récepteur au bout de X réception ça plante.
Je m'explique :
J'envoi une structure composer de 4 variables, 3 float et 1 unsigned int.
Au bout d'un moment le récepteur ne met plus a jours les variables correctement.
Je reset l'arduino récepteur et ça repart pour un moment puis bug.
Pour le moment j'ai bricolé un bout de code qui reset l'arduino en cas de bug, mais j'aimerai que ça fonctionne normalement.
Une idée???
Les infos envoyer sont, deux températures (float), pression (float) et un compteur (unsigned int).
Le compteur est la pour géré mon auto reset du récepteur ( il sera supprimé quand le bug sera résolue).

J'ai essayer de passé ma structure en variable volatile, ça met plus de temps avant de planté.
Tout le programme tourne normalement (c'est juste les variables de la structure qui ne ce mette plus a jours).
Un bug de Virtualwire??? je n'ai jamais eu ce problème avec l'envoi/réception de chaines de caractères.
Le programme récepteur affiche simplement sur un LCD 16x2.
Température d'un 18b20 branché sur l'arduino et les valeurs des sondes de l'émetteur (via ma structure décrite plus haut) .

Je précise que ce n'ai pas un problème de signal ou de porté (j'ai testé avec un fil à la place des modules RF et le bug est toujours là ).
J'ai fait le tour de tout, j'ai même vérifier que sur le récepteur il n'y ai pas un problème de ram, via un bout de code qui informe de la taille de la ram disponible à la demande.
Je n'ai plus d'idée. Merci d'avance.

PS pour Virtualwire avec un attiny 85 il faut faire quelque modification dans le .cpp de la librairie .
Au niveau de la configuration du timer utiliser par virtualwire (il y a un bug avec le timer 0, il faut utiliser le timer1 ) et dans le .h pour modifier la taille du buffer utiliser par virtualwire (sinon il prend trop de ram).

Ps: je peut envoyer les codes récepteur et émetteur, idem pour la modification de la librairie de virtualwire pour l'ami fabien.

PS "encore", j'utilise deux arduino uno pour mon couple émetteur et récepteur.

PS "Fabien" question as tu essayé avec un simple fil pour relier l'attiny et l'arduino ?
Quel est la configuration de l'attiny 85 ? (les fusibles, fréquence d'horloge et type d'horloge)

Derniére modification le par mneo31


Photo de profil de skywodd

skywodd

Membre

Membre du staff

#310 | Signaler ce message


Au bout d'un moment le récepteur ne met plus a jours les variables correctement. Je reset l'arduino récepteur et ça repart pour un moment puis bug.

par mneo31

Ce serait possible de voir le code TX et RX ? On dirait bien qu'il y a un bug côté récepteur. J'ai ma petite idée sur son origine (j'ai déjà eu un probléme similaire par le passé).

PS pour Virtualwire avec un attiny 85 il faut faire quelque modification dans le .cpp de la librairie. Au niveau de la configuration du timer utiliser par virtualwire (il y a un bug avec le timer 0, il faut utiliser le timer1 ) et dans le .h pour modifier la taille du buffer utiliser par virtualwire (sinon il prend trop de ram).

par mneo31

Ce serait possible d'avoir un lien vers les modif en questions ? Ce serait un bon sujet d'article ;)


Photo de profil de mneo31

mneo31

Membre

#311 | Signaler ce message


Au bout d'un moment le récepteur ne met plus a jours les variables correctement. Je reset l'arduino récepteur et ça repart pour un moment puis bug.

par mneo31

Ce serait possible de voir le code TX et RX ? On dirait bien qu'il y a un bug côté récepteur. J'ai ma petite idée sur son origine (j'ai déjà eu un probléme similaire par le passé).

PS pour Virtualwire avec un attiny 85 il faut faire quelque modification dans le .cpp de la librairie. Au niveau de la configuration du timer utiliser par virtualwire (il y a un bug avec le timer 0, il faut utiliser le timer1 ) et dans le .h pour modifier la taille du buffer utiliser par virtualwire (sinon il prend trop de ram).

par mneo31

Ce serait possible d'avoir un lien vers les modif en questions ? Ce serait un bon sujet d'article ;)

par skywodd

Le TX

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include <SPI.h>
#include <Dhcp.h>
#include <Dns.h>
#include <Ethernet.h>
#include <EthernetClient.h>
#include <EthernetServer.h>
#include <EthernetUdp.h>

#include "Timer.h"
Timer t;
/*
Cayenne Ethernet Example

This sketch connects to the Cayenne server using an Arduino Ethernet Shield W5100
and runs the main communication loop.

The Cayenne Library is required to run this sketch. If you have not already done so you can install it from the Arduino IDE Library Manager.

Steps:
1. Set the token variable to match the Arduino token from the Dashboard.
2. Compile and upload this sketch.

For Cayenne Dashboard widgets using digital or analog pins this sketch will automatically
send data on those pins to the Cayenne server. If the widgets use Virtual Pins, data
should be sent to those pins using virtualWrites. Examples for sending and receiving
Virtual Pin data are under the Basics folder.
*/

//#define CAYENNE_DEBUG         // Uncomment to show debug messages
#define CAYENNE_PRINT Serial  // Comment this out to disable prints and save space
#include <CayenneEthernet.h>
#define W5200_CS  10 // pin EN W5200
#define SDCARD_CS 4 //pin EN SDCARD


#include <OneWire.h>
#include <DallasTemperature.h>
#include <VirtualWire.h>

#include <Wire.h>
#include <BMP085.h>

// Cayenne authentication token. This should be obtained from the Cayenne Dashboard.
char token[] = "MON TOKEN";
byte arduino_mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress arduino_ip(192, 168, 1, 177);
IPAddress dns_ip(8, 8, 8, 8);
IPAddress gateway_ip(192, 168, 1, 1);
IPAddress subnet_mask(255, 255, 255, 0);


// Virtual Pin of the DS18B20 widget.
#define VIRTUAL_PIN V0

// Virtual Pins of the BMP180 widget.
#define BAROMETER_PIN V1
#define TEMPERATURE_PIN V2

BMP085 bmp;

// Digital pin the DS18B20 is connected to. Do not use digital pins 0 or 1 since those conflict with the use of Serial.
const int tmpPin = 17;

OneWire oneWire(tmpPin);
DallasTemperature sensors(&oneWire);

typedef struct {
  float realTemperature; //temperature BMP180
  float realPressure; //Pression BMP180
  float temp; //Termperature 18b20
  unsigned int count; //variable compteur pour auto reset du recepteur (a supprimer quand bug résolue)
} Mastructure;

Mastructure ms;
byte taille_ms = sizeof(Mastructure);

void setup()
{
  Serial.begin(9600);
  vw_setup(2000);//vitesse 2000bps
  vw_set_tx_pin(7);//DATA TX
  pinMode(5, OUTPUT); //GND TX
  pinMode(6, OUTPUT); //VCC TX
  pinMode(7, OUTPUT); //DATA TX
  digitalWrite(5, LOW); //GND TX
  digitalWrite(6, HIGH); //VCC TX


  pinMode(SDCARD_CS, OUTPUT); //AUSSI VCC TX
  pinMode(W5200_CS, OUTPUT);
  pinMode(15, OUTPUT);//GND 18B20
  pinMode(16, OUTPUT);//VCC 18B20
  digitalWrite(15, 0);
  digitalWrite(16, 1);
  digitalWrite(W5200_CS, HIGH); // init W5200
  digitalWrite(SDCARD_CS, HIGH); // Deselect the SD card
  Cayenne.begin(token, arduino_ip, dns_ip, gateway_ip, subnet_mask, arduino_mac);
  bmp.begin(BMP085_ULTRA_HIGH_RES);
  bmp.setSoftwareOversampling(1);

  sensors.begin();
  sensors.setResolution(12);

  t.every(20000, envoi); //timer pour envoi périodique 433 (n'utilise pas de timer hardware)
  ms.count = 0;
}

void loop()
{
  Cayenne.run();
  t.update();
}

// This function is called when the Cayenne widget requests data for the Virtual Pin.
CAYENNE_OUT(BAROMETER_PIN)
{
  ms.realPressure = bmp.readFloatPressure();
  Cayenne.virtualWrite(BAROMETER_PIN,  ms.realPressure / 100); // diviser par 100 pour avoir une sortie hPa

}

// This function is called when the Cayenne widget requests data for the temperature's Virtual Pin.
CAYENNE_OUT(TEMPERATURE_PIN)
{

  ms.realTemperature = bmp.readFloatTemperature();
  // Send the value to Cayenne in Celsius.
  Cayenne.celsiusWrite(TEMPERATURE_PIN, ms.realTemperature);

}
CAYENNE_OUT(VIRTUAL_PIN)
{
  // Send the command to get temperatures.
  sensors.requestTemperatures();
  ms.temp = sensors.getTempCByIndex(0);
  // This command writes the temperature in Celsius to the Virtual Pin.
  Cayenne.celsiusWrite(VIRTUAL_PIN, ms.temp);
  // To send the temperature in Fahrenheit use the corresponding code below.
  //Cayenne.fahrenheitWrite(VIRTUAL_PIN, sensors.getTempFByIndex(0));
}

void envoi() {
  ms.count++; 
  vw_send((uint8_t *) &ms, sizeof(ms));
  vw_wait_tx(); // Wait until the whole message is gone
  
  //debug
  Serial.print(F("Pression = "));
  Serial.println(ms.realPressure / 100);
  Serial.print(F("Temperature BMP180 = "));
  Serial.println(ms.realTemperature);
  Serial.print(F("Temperature 18B20 = "));
  Serial.println(ms.temp);
  Serial.print(F("ms.count = "));
  Serial.println(ms.count);
  Serial.print(F("----------"));
  Serial.print(millis() / 1000);
  Serial.println(F(" Seconds----------"));
}



Le code du RX :

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#include <avr/wdt.h> //pour l'auto reset
#include <DFR_Key.h>

#include <LiquidCrystal.h>
#include <VirtualWire.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 17  //DATA DS (module 17 , TO92 16)

#include "Timer.h"
Timer t;

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DFR_Key keypad;

typedef struct {
  float realTemperature;//tempertature bmp180
  float realPressure;//perssion bmp180
  float temp;//temperature 18b20
  unsigned int count;//compteur pour auto reset
} Mastructure;

Mastructure ms;
byte taille_ms = sizeof(Mastructure);

byte mess = 0;//(variable pour l'affichage alternatif sur la ligne 0 du LCD)

unsigned int verifcount = 0;//compteur local pour auto reset

long oldtime = 0;//variable pour les boutons (temporisation lumiere lcd)
byte erreur = 0;//nombre d'erreur de reception (via count et verficount)

// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
void setup() {

  Serial.begin(9600);
  lcd.begin(16, 2);              // start the library
  lcd.setCursor(0, 0);
  sensors.begin();
  sensors.setResolution(12);
  vw_setup(2000);//vitesse 2000bps
  pinMode(10, OUTPUT); // light LCD
  vw_set_tx_pin(11); // data RX
  vw_set_ptt_pin(13);
  pinMode(15, OUTPUT); //gnd ds
  pinMode(16, OUTPUT); // vcc ds  (pour module)
  pinMode(12, OUTPUT); //vcc rx
  pinMode(2, OUTPUT); //gnd rx
  pinMode(3, INPUT); //data rx
  pinMode(18, INPUT_PULLUP); //entrée LDR (A4)
  pinMode(19, OUTPUT); // masse LDR  (A5)
  digitalWrite(19, LOW);
  digitalWrite(12, 1); // vcc rx
  digitalWrite(2, 0); //gnd rx
  digitalWrite(15, 0); //gnd ds18b20
  digitalWrite(16, 1);// vcc ds18b20 (pour module)
  digitalWrite(10, 1);// light LCD

  keypad.setRate(10);

  vw_rx_start();
  //delay(2000);
  oldtime = millis();
  oldtime += 5000;
  t.every(2000, LCD);//timer pour affichage alternatif sur la ligne 0
}

void LCD() {//alterne l'affichage sur la ligne 0 et raffraichie la ligne1 (une fois sur deux)
  sensors.requestTemperatures();//demande la température du 18b20 local
  if (mess == 0) { //affiche la température du 18b20 local
    lcd.setCursor(0, 0);
    lcd.print(sensors.getTempCByIndex(0));
    lcd.write(0xdf);//affiche le symbole °
    lcd.print(F("C"));
    lcd.print(F(":DS"));
    lcd.print(ms.count);
    lcd.print(F("   "));
    mess = 1;
  } else if (mess == 1) {// affiche la préssion du bmp180 externe (433)
    lcd.setCursor(0, 0);
    lcd.print(F("   "));
    lcd.print(ms.realPressure / 100);
    lcd.print(F("hPa   "));
    mess = 0;
    lcd.setCursor(0, 1);//affiche la température du 18b20 et du bmp180 externe (433)
    lcd.print(ms.temp);
    lcd.write(0xdf);
    lcd.print(F("C "));
    lcd.print(ms.realTemperature);
    lcd.write(0xdf);
    lcd.print(F("C"));
  }
}


void loop() {
  t.update();
  recev();

  if (keypad.getKey() > 0) { //détection jour/nuit et forçage éclairage lcd pendant 5sec quand appuis sur un bouton
    digitalWrite(10, 1);
    oldtime = millis();
    oldtime += 5000;
  }// fin if

  if ((analogRead(4) < 300) ) digitalWrite(10, 1);
  else if (oldtime < millis()) digitalWrite(10, 0);

}



void recev() {//message reçu ??? si oui le copie dans ma structure et l'affiche sur le lcd

  if (vw_get_message((byte*) &ms, &taille_ms)) // Non-blocking
  {
    verifcount++;//variable mise a jour pour l'auto reset (si 433 bug)
    Serial.print(F("sizeof(Mastructure) = "));
    Serial.println(sizeof(Mastructure));
    lcd.setCursor(0, 1);
    lcd.print(ms.temp);
    lcd.write(0xdf);
    lcd.print(F("C "));
    lcd.print(ms.realTemperature);
    lcd.write(0xdf);
    lcd.print(F("C"));

    //debug
    Serial.print(F(" ms.realTemperature = "));
    Serial.println(ms.realTemperature);
    Serial.print(F(" ms.realPressure/100 = "));
    Serial.println(ms.realPressure / 100);
    Serial.print(F(" ms.temp = "));
    Serial.println(ms.temp);
    Serial.print(F("ms.count = "));
    Serial.println(ms.count);
    Serial.print(F("----------"));
    Serial.print(millis() / 1000);
    Serial.println(F(" Seconds----------"));
    //Serial.print(F("FREE RAM = "));
    //Serial.println(freeRam());

    if (verifcount == 0) verifcount = ms.count; //si variable à 0 alors on vient de boot on synchronise les deux compteurs
    if (verifcount != ms.count) {//si variable local et distant différente
      lcd.setCursor(0, 1);
      lcd.print(F("ERREUR ERREUR"));//on affiche erreur sur la ligne 1 du lcd
      verifcount = ms.count;//on synchronise les compteurs
      erreur++;//on incrémente la variable erreur
      vw_rx_stop();//on stop la reception
      delay(2000);//on attend 2sec
      vw_rx_start();//on relance la reception    (NB,de stopé et relancé la reception, parfois ça marche mais pas toujours)
    }
  }
  if (erreur == 3) {//Si on a atteind 3 erreur de reception alors on reboot (reset) via le watchdog
    MCUSR = 0; // reboot logiciel
    wdt_disable(); // reboot logiciel
    wdt_enable(WDTO_15MS); //reboot logiciel
  }
}
/* //bout de code pour voir la ram libre au moment ou l'on appel la fonction
int freeRam () {
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}*/



Voila mes programmes, pour le coté émetteur cayennes fait des demandes des valeurs des sondes très régulièrement
(1 à 5 sec entre les demandes). Mais le problème ne vient pas de l'émetteur. (d'après moi).

Je vais faire un autre poste pour virtualwire car pas de lien, j'ai utilisé la doc atmel
de l'attiny 85 pour voir quel registre modifier et comment.
( en comparant a la doc du 328 et du code d'origine de la lib)

Derniére modification le par mneo31


Photo de profil de mneo31

mneo31

Membre

#312 | Signaler ce message


Les modifications pour virtualwire

Déjà il faut savoir que sur un attiny 85 nous n'avons que 2 timers
et non pas 3 comme sur un arduino à base de atmega328.
De plus nous avons moins de flash 8kb pour l'attiny 85 contre 32Kb pour le 328
Nous avons moins de ram 512bytes pour l'attiny 85 contre 2Kb pour le 328.
Et nous pouvons avoir une fréquence CPU différente selon la programmation des fusibles de l'attiny 85.
Moi personnellement j'utilise souvent le mode PLL interne
pour avoir une fréquence CPU à 16Mhz sur l'attiny.
Quand je n'ai pas besoin de puissance de calcule (programme simple sans librairie complexe)
je tourne en 8Mhz interne, voir quand j'ai besoin d'une faible consommation 1Mhz.
Pour la modification de virtualwire, j'en revient a l'histoire des timers.
Par défaut virtualwire utilise le timer 0 ce qui fait "planté" les
fonctions tel que millis(), delay(), mais pas que!
toute les librairies utilisant ces fonctions sont aussi impacté,
parfois ça ne pose pas de problème si les tempos sont modifier
mais souvent ça interfère dans le bon déroulement du programme.
D'autant que si vous utilisé une autre librairie et qu'elle aussi utilise le timer 0. Là c'est la pagaille car seul la librairie initialisé en dernier aura le dernier mot sur le paramétrage du timer 0.

Dans la librairie, j'ai modifier l'utilisation du timer,
afin d'utilisé le timer 1 et non plus le timer 0. La taille du buffer (nombre d'octet pouvant être envoyer ou reçu), à adapter selon vos besoins.
A savoir, plus le buffer est grand, plus il prend de la place dans la ram.
Maintenant les modifications :
la partie dans le .h modifier: //pour la taille du buffer

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// These defs cause trouble on some versions of Arduino
#undef abs
#undef double
#undef round

#ifndef VW_MAX_MESSAGE_LEN 
 #ifdef __AVR_ATtiny85__
  #define VW_MAX_MESSAGE_LEN 20  //80 init for 328p
  #else
/// Maximum number of bytes in a message, counting the byte count and FCS
    #define VW_MAX_MESSAGE_LEN 80  //80 init
    #endif
#endif //VW_MAX_MESSAGE_LEN 

Dans le .cpp :
Le code d'origine pour utiliser le timer 0

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void vw_setup(uint16_t speed)
{
    uint16_t nticks; // number of prescaled ticks needed
    uint8_t prescaler; // Bit values for CS0[2:0]

#ifdef __AVR_ATtiny85__
    // figure out prescaler value and counter match value
    prescaler = vw_timer_calc(speed, (uint8_t)-1, &nticks);
    if (!prescaler)
    {
        return; // fault
    }

    TCCR0A = 0;
    TCCR0A = _BV(WGM01); // Turn on CTC mode / Output Compare pins disconnected

    // convert prescaler index to TCCRnB prescaler bits CS00, CS01, CS02
    TCCR0B = 0;
    TCCR0B = prescaler; // set CS00, CS01, CS02 (other bits not needed)

    // Number of ticks to count before firing interrupt
    OCR0A = uint8_t(nticks);

    // Set mask to fire interrupt when OCF0A bit is set in TIFR0
    TIMSK |= _BV(OCIE0A);

A remplacer par ça : pour utiliser le timer 1

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
void vw_setup(uint16_t speed)
{
    uint16_t nticks; // number of prescaled ticks needed
    uint8_t prescaler; // Bit values for CS0[2:0]

#ifdef __AVR_ATtiny85__
    // figure out prescaler value and counter match value
    prescaler = vw_timer_calc(speed, (uint8_t)-1, &nticks);
    if (!prescaler)
    {
        return; // fault
    }
    PLLCSR = 0; // ck clock not pll clock


    TCCR1 = 0;
    TCCR1 = _BV(CTC1); // Turn on CTC mode / Output Compare pins disconnected

    // convert prescaler index to TCCRnB prescaler bits CS00, CS01, CS02
    //TCCR0B = 0;
   // TCCR0B = prescaler; // set CS00, CS01, CS02 (other bits not needed)
    if (prescaler == 1) {
    TCCR1 = _BV(CS10);
    }
    else if (prescaler == 2) {
    TCCR1 = _BV(CS12);
    }
    else if (prescaler == 3) {
    TCCR1 = _BV(CS10);
    TCCR1 = _BV(CS11);
    TCCR1 = _BV(CS12);
    }
    else if (prescaler == 4) {
    TCCR1 = _BV(CS13);
    TCCR1 = _BV(CS10);
    }
    else if (prescaler == 5) {
    TCCR1 = _BV(CS10);
    TCCR1 = _BV(CS11);
    TCCR1 = _BV(CS13);
    }
    // Number of ticks to count before firing interrupt
    OCR1A = uint8_t(nticks);
    OCR1C = OCR1A;

    // Set mask to fire interrupt when OCF0A bit is set in TIFR0
    TIMSK |= _BV(OCIE1A);



Pour la configuration du timer on ne peut pas copier coller la méthode
utiliser pour le timer 0 sur le timer 1 car les prescalers du timer 0 sont différent
des prescalers du timer 1. Voir doc atmel. Pages 80 et 89/90.
Voila, ne pas hésiter a me contacter si besoin.

Derniére modification le par skywodd


Photo de profil de mneo31

mneo31

Membre

#313 | Signaler ce message


L'envoi de caractères ne marche pas non plus, même une simple lettre …

par fabien

Tu as un oscilloscope sous la main pour vérifier qu'il y a un signal en sortie de la broche ?

L'appel à vw_set_tx_pin() est bien avant vw_setup() dans ton code ?

par skywodd


Non pas d'oscilloscope malheureusement, seulement un multimètre… J'ai bien changé le code mais pas plus de resultat…

par fabien

Je pense a un truc! Dans la loop tu envois en boucle essaie de rajouter un delay(2000); après le vw_wait_tx();
Et pense a notifier la broche RX avec vw_set_rx_pin(broche); sur le récepteur (même si tu utilise la broche par défaut)
Tu devrais rajouter un bout de code dans la loop (faire clignoté une led) pour voir que le programme tourne effectivement.

As tu déjà programmer des attiny pour des programmes plus "simple" genre simplement faire clignoté une led a une fréquence donner? (genre un clignotement par seconde) si oui, as tu vérifier que la fréquence de clignotement programmé dans ton code corresponde bien à celle observé sur ton montage?

Si ça ne correspond pas il faut vérifier quel est l'horloge du attiny (réglage des fusibles).

J'ai eu avec un attiny et virtualwire (mais je ne pense pas que ça soit le cas dans ton programme car très léger) c'est un débordement de la ram (par défaut virtualwire utilise un "buffer" de 80 octets)
Dernier cas, j'avais un conflit avec le timer0 (utiliser par virtualwire et une seconde librairie dans mon code). Idem ce n'ai pas le cas dans ton code.

Si tu connais assez bien l'IDE arduino, tu as du forcément rajouter les fichiers board pour programmer les attiny, il faudrait surement creusé de ce coté là. (réglages des fusibles de l'attiny, core utiliser, variante utiliser ect) si tu manipules bien c'est fichiers dans l'IDE il serai bien de faire toi même une config pour attiny a rajouter dans ta liste de board.

Exemple de ma board maison pour les attiny

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
menu.cpu=Processor
menu.clock=Clock

attiny.name=ATtiny
attiny.bootloader.tool=arduino:avrdude
attiny.bootloader.unlock_bits=0xff
attiny.bootloader.lock_bits=0xff
attiny.build.core=arduino:arduino
attiny.build.board=attiny
attiny.upload.tool=arduino:avrdude

attiny.menu.cpu.attiny45=ATtiny45
attiny.menu.cpu.attiny45.upload.maximum_size=4096
attiny.menu.cpu.attiny45.build.mcu=attiny45
attiny.menu.cpu.attiny45.build.variant=tiny8

attiny.menu.cpu.attiny85=ATtiny85
attiny.menu.cpu.attiny85.upload.maximum_size=8192
attiny.menu.cpu.attiny85.build.mcu=attiny85
attiny.menu.cpu.attiny85.build.variant=tiny8

attiny.menu.cpu.attiny85A=ATtiny85 SPECIAL
attiny.menu.cpu.attiny85A.upload.maximum_size=8192
attiny.menu.cpu.attiny85A.build.mcu=attiny85
attiny.menu.cpu.attiny85A.build.variant=tiny

attiny.menu.cpu.attiny44=ATtiny44
attiny.menu.cpu.attiny44.upload.maximum_size=4096
attiny.menu.cpu.attiny44.build.mcu=attiny44
attiny.menu.cpu.attiny44.build.variant=tiny14

attiny.menu.cpu.attiny84=ATtiny84
attiny.menu.cpu.attiny84.upload.maximum_size=8192
attiny.menu.cpu.attiny84.build.mcu=attiny84
attiny.menu.cpu.attiny84.build.variant=tiny14

attiny.menu.clock.internal1=1 MHz (internal BOD 1.8V)
attiny.menu.clock.internal1.bootloader.low_fuses=0x62
attiny.menu.clock.internal1.bootloader.high_fuses=0xd6
attiny.menu.clock.internal1.bootloader.extended_fuses=0xff
attiny.menu.clock.internal1.build.f_cpu=1000000L

attiny.menu.clock.internal8=8 MHz (internal BOD 2.7V)
attiny.menu.clock.internal8.bootloader.low_fuses=0xe2
attiny.menu.clock.internal8.bootloader.high_fuses=0xd5
attiny.menu.clock.internal8.bootloader.extended_fuses=0xff
attiny.menu.clock.internal8.build.f_cpu=8000000L

attiny.menu.clock.internal8d=8 MHz (internal BOD DISABLED)
attiny.menu.clock.internal8d.bootloader.low_fuses=0xe2
attiny.menu.clock.internal8d.bootloader.high_fuses=0xd7
attiny.menu.clock.internal8d.bootloader.extended_fuses=0xff
attiny.menu.clock.internal8d.build.f_cpu=8000000L

attiny.menu.clock.internal16=16 Mhz PLL (internal BOD 2.7V)
attiny.menu.clock.internal16.bootloader.low_fuses=0xF1
attiny.menu.clock.internal16.bootloader.high_fuses=0xd5
attiny.menu.clock.internal16.bootloader.extended_fuses=0xff
attiny.menu.clock.internal16.build.f_cpu=16000000L

attiny.menu.clock.external8=8 MHz (external)
attiny.menu.clock.external8.bootloader.low_fuses=0xfe
attiny.menu.clock.external8.bootloader.high_fuses=0xdf
attiny.menu.clock.external8.bootloader.extended_fuses=0xff
attiny.menu.clock.external8.build.f_cpu=8000000L

attiny.menu.clock.external16=16 MHz (external)
attiny.menu.clock.external16.bootloader.low_fuses=0xfe
attiny.menu.clock.external16.bootloader.high_fuses=0xdf
attiny.menu.clock.external16.bootloader.extended_fuses=0xff
attiny.menu.clock.external16.build.f_cpu=16000000L

attiny.menu.clock.external20=20 MHz (external)
attiny.menu.clock.external20.bootloader.low_fuses=0xfe
attiny.menu.clock.external20.bootloader.high_fuses=0xdf
attiny.menu.clock.external20.bootloader.extended_fuses=0xff
attiny.menu.clock.external20.build.f_cpu=20000000L


Ce qui me donne dans la sélection du type de carte la possibilité de choisir type de carte attiny
Puis quel attiny (45 85 44 84) (dont un attiny 85 spécial, pour palier a un bug de SoftwareSerial sur l'affectation des broches)
Puis de sélectionné quel horloge je veux . 1Mhz , 8Mhz , 16Mhz , 20Mhz
Interne ou externe et avec différent réglage de BOD selon la fréquence .

Comme ça je sais comment sont configurés les fusibles de mon attiny et j'évites les problèmes du a des fusibles mal configurer.
PS si tu ne manipules pas bien les fichiers board.txt, ne cherche pas a copier coller mon code, car il manque les fichiers .h .cpp et .c lier au fichier board.txt
Mais ça peut peut-être inspiré l'admin du blog alias Skywodd.


Pas de photo de profil

fabien

Membre

#316 | Signaler ce message


Bonjour,

Merci beaucoup pour tes messages, je n'ai pas tout compris mais dans l'ensemble je pense savoir d'où vient le problème.

J'ai déjà programmé sur ATtiny (Led, bouton, potentiomètre…etc) donc ce n'est pas dans la programmation qu'il y a un problème.

J'ai Upload le programme "blink", tout se passe bien, si j'ajoute la librairie <VirtualWire>, ça ne change rien, elle clignote toujours à la bonne fréquence mais si j'ajoute "vw_setup(1000);" la led ne clignote plus à la bonne frequence…

Je vais donc des maintenant modifier le .h et le .cpp comme tu me l'as conseillé et on verra bien…

J'ai eu accès à un oscilloscope cette semaine, il y a bien un signal en sortie qui ressemble de loin à celui en sortie du UNO.

Et petite question: comment savoir à quelle frequence programme le ATtiny ?

Merci beaucoup !


Pas de photo de profil

fabien

Membre

#317 | Signaler ce message


J'ai modifier le .cpp et le .h et… ça ne marche pas, ça ne veux pas compiler…


Pas de photo de profil

fabien

Membre

#319 | Signaler ce message


J'ai remarqué une erreur que j'avais faite dans les modifications, je peux maintenant compiler, mais la led ne clignote plus du tout, elle ne s'allume même plus…


Photo de profil de mneo31

mneo31

Membre

#320 | Signaler ce message


J'ai modifier le .cpp et le .h et… ça ne marche pas, ça ne veux pas compiler…

par fabien

Quels sont les erreurs, lors de la compilation ?

Pour savoir à quel vitesse d'horloge tourne ton attiny85, normalement tu le sais quand tu sélectionnes le type de composant (pense aussi a graver la séquence d'initialisation) qui pour un attiny 85 est en faite la programmation des fusibles ( car il n'y a pas de bootloader ).
Comme expliquer dans mon poste précédent, moi je me suis fait une liste pour les attiny "maison", mais si tu as récupéré une configuration sur le net pour programmer les attiny, il est normalement indiqué la fréquence quand tu le sélectionnes dans ta liste ( je parle de la liste ou tu sélectionnes la carte que tu programmes, arduino uno, arduino nano..ect)
Et vérifie bien que ton arduino RX et ton attiny TX soit bien avec la même vitesse de vw_setup(1000);


Photo de profil de mneo31

mneo31

Membre

#321 | Signaler ce message


J'ai remarqué une erreur que j'avais faite dans les modifications, je peux maintenant compiler, mais la led ne clignote plus du tout, elle ne s'allume même plus…

par fabien

Quel est ton programme de test ?

Peux tu le posté.
Merci


Pas de photo de profil

fabien

Membre

#322 | Signaler ce message


Alors ça marche… dans certain cas:

La transmission fonction uniquement si le ATtiny est programmé avec une clock:8Mhz et ce code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
/**
 * Exemple de code pour la bibliothèque VirtualWire – Client d'envoi de variable
 */
 
#include <VirtualWire.h>

void setup() {

  vw_set_tx_pin(0);
  vw_setup(1000);
}
 
void loop() {
  
  float valeur = 9;
  
  vw_send((byte *) &valeur, sizeof(valeur)); // On envoie le message
  vw_wait_tx(); // On attend la fin de l'envoi
}

L'arduino uno en reception utilise la librairie sans modification:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <VirtualWire.h>

void setup() {
  Serial.begin(9600);
  vw_set_rx_pin(11);
  vw_setup(1000);
  vw_rx_start();

  Serial.println("Go !"); 
}

void loop() {
  float valeur;
  byte taille_message = sizeof(float);
  
  vw_wait_rx();
  if (vw_get_message((byte *) &valeur, &taille_message)) {

    Serial.println(valeur);
  }
  
}

Cependant le test avec la led n'est pas concluant, celui ci ne fonctionne d'avec une clock de 1Mhz et un vw_setup(2000), dans les autres cas, la led clignote très vite, très lentement voir pas du tout.

Voici le code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#include <VirtualWire.h>

void setup() {

  vw_set_tx_pin(1);
  vw_setup(2000);

  pinMode(0, OUTPUT);
}

void loop() {
  digitalWrite(0, HIGH);   
  delay(1000);             
  digitalWrite(0, LOW);    
  delay(1000);            
}

Voila voila, donc la transmission fonctionne mais pas le clignotement de la LED.

Merci

Edit modérateur: modification des balises code pour avoir la coloration syntaxique.

Derniére modification le par skywodd


Photo de profil de mneo31

mneo31

Membre

#323 | Signaler ce message


Alors ça marche… dans certain cas:

La transmission fonction uniquement si le ATtiny est programmé avec une clock:8Mhz et ce code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
/**
 * Exemple de code pour la bibliothèque VirtualWire – Client d'envoi de variable
 */
 
#include <VirtualWire.h>

void setup() {

  vw_set_tx_pin(0);
  vw_setup(1000);
}
 
void loop() {
  
  float valeur = 9;
  
  vw_send((byte *) &valeur, sizeof(valeur)); // On envoie le message
  vw_wait_tx(); // On attend la fin de l'envoi
}

L'arduino uno en reception utilise la librairie sans modification:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <VirtualWire.h>

void setup() {
  Serial.begin(9600);
  vw_set_rx_pin(11);
  vw_setup(1000);
  vw_rx_start();

  Serial.println("Go !"); 
}

void loop() {
  float valeur;
  byte taille_message = sizeof(float);
  
  vw_wait_rx();
  if (vw_get_message((byte *) &valeur, &taille_message)) {

    Serial.println(valeur);
  }
  
}

Cependant le test avec la led n'est pas concluant, celui ci ne fonctionne d'avec une clock de 1Mhz et un vw_setup(2000), dans les autres cas, la led clignote très vite, très lentement voir pas du tout.

Voici le code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#include <VirtualWire.h>

void setup() {

  vw_set_tx_pin(1);
  vw_setup(2000);

  pinMode(0, OUTPUT);
}

void loop() {
  digitalWrite(0, HIGH);   
  delay(1000);             
  digitalWrite(0, LOW);    
  delay(1000);            
}

Voila voila, donc la transmission fonctionne mais pas le clignotement de la LED.

Merci

par fabien

OK
Pour le attiny virtualwire + led, le test est fait avec la version modifier de virtualwire? (pour qu'il utilise le timer 1 et non le timer 0). Et inutile de modifier ou non pour l'arduino , car la lib utilise la modification seulement pour les attiny 85 (dans le .cpp on a un #ifdef __AVR_ATtiny85__) donc la modif ne marche pas pour un arduino ou un autre attiny (comme un 45 par ex).
C'est très étrange que la led ne clignote pas normalement avec virtualwire modifier, car le but est justement de laisser le timer0 pour les fonctions delay millis ect…
Concernant la vitesse d'horloge du attiny, faire les testes avec une horloge à 8Mhz (ou 16Mhz si disponible) en interne. Après il faut la choisir en fonction de ce qu'on programme et si la consommation du attiny est importante ou pas.

+1 pour le test à 1Mhz, ça montre bien que le timer 0 ce trouve modifier (il ne devrait pas pourtant)
Tu programmes bien un attiny 85?

Je ne pense pas que virtualwire fonction avec une clock à 1Mhz (jamais testé perso), normalement il marche pour 8Mhz et 16Mhz (testé et approuvé sur attiny 85).


Photo de profil de skywodd

skywodd

Membre

Membre du staff

#327 | Signaler ce message


Je laisse de côté le forum une seconde et paf, 11 notifications. Je vais avoir du boulot :D

@mneo31: Je ne vois pas d'erreur dans ton code TX, quelques améliorations possibles, mais rien de plus.

Je vois par contre une grosse erreur dans le code du RX ;)

1
2
3
4
5
6
7
8
// Variables globales
Mastructure ms;
byte taille_ms = sizeof(Mastructure);

// Dans la fonction recv()
if (vw_get_message((byte*) &ms, &taille_ms)) {
...
}

La fonction vw_get_message() met à jour la valeur de la variable taille_ms passé en argument pour qu'elle corresponde avec la taille du message reçu (cf article).

Or, si le message est corrompu, celui-ci ne fera pas la bonne taille. Tu me vois venir ? A l'appel suivant, la valeur taille_ms n'est plus à jour. Tu écris donc potentiellement en dehors de la structure et ça plante.

Déplace la déclaration de la variable taille_ms dans le corps de la fonction recv(). Ça devrait résoudre ton probléme.

Je pense a un truc! Dans la loop tu envois en boucle essaie de rajouter un delay(2000); après le vw_wait_tx();

Ce n'est pas un soucis, la fonction vw_wait_tx() s'occupe déjà d'attendre la fin de la transmission avec d'en commencer une nouvelle.

Cependant, un délai supplémentaire serait effectivement le bienvenue pour ne pas bloquer complètement la porteuse 433MHz en envoyant continuellement des messages, mais en soit, ça ne devrait pas être la cause du soucis (au pire c'est un élément aggravant).

Cependant le test avec la led n'est pas concluant, celui ci ne fonctionne d'avec une clock de 1Mhz et un vw_setup(2000), dans les autres cas, la led clignote très vite, très lentement voir pas du tout.

Je suis de l'avis de mneo31, ça sent la modification involontaire du timer 0 lors de l'initialisation de VirtualWire. La LED ne devrait pas s’arrêter de clignoter après un simple appel à vw_setup().

Question bête : tu as relancé l'IDE Arduino après avoir fait la modif ? Les bibliothèques de code ne sont mise à jour qu'au démarrage du logiciel.


Photo de profil de mneo31

mneo31

Membre

#328 | Signaler ce message


Je laisse de côté le forum une seconde et paf, 11 notifications. Je vais avoir du boulot :D

@mneo31: Je ne vois pas d'erreur dans ton code TX, quelques améliorations possibles, mais rien de plus.

Je vois par contre une grosse erreur dans le code du RX ;)

1
2
3
4
5
6
7
8
// Variables globales
Mastructure ms;
byte taille_ms = sizeof(Mastructure);

// Dans la fonction recv()
if (vw_get_message((byte*) &ms, &taille_ms)) {
...
}

La fonction vw_get_message() met à jour la valeur de la variable taille_ms passé en argument pour qu'elle corresponde avec la taille du message reçu (cf article).

Or, si le message est corrompu, celui-ci ne fera pas la bonne taille. Tu me vois venir ? A l'appel suivant, la valeur taille_ms n'est plus à jour. Tu écris donc potentiellement en dehors de la structure et ça plante.

Déplace la déclaration de la variable taille_ms dans le corps de la fonction recv(). Ça devrait résoudre ton probléme.

Je pense a un truc! Dans la loop tu envois en boucle essaie de rajouter un delay(2000); après le vw_wait_tx();

Ce n'est pas un soucis, la fonction vw_wait_tx() s'occupe déjà d'attendre la fin de la transmission avec d'en commencer une nouvelle.

Cependant, un délai supplémentaire serait effectivement le bienvenue pour ne pas bloquer complètement la porteuse 433MHz en envoyant continuellement des messages, mais en soit, ça ne devrait pas être la cause du soucis (au pire c'est un élément aggravant).

Cependant le test avec la led n'est pas concluant, celui ci ne fonctionne d'avec une clock de 1Mhz et un vw_setup(2000), dans les autres cas, la led clignote très vite, très lentement voir pas du tout.

Je suis de l'avis de mneo31, ça sent la modification involontaire du timer 0 lors de l'initialisation de VirtualWire. La LED ne devrait pas s’arrêter de clignoter après un simple appel à vw_setup().

Question bête : tu as relancé l'IDE Arduino après avoir fait la modif ? Les bibliothèques de code ne sont mise à jour qu'au démarrage du logiciel.

par skywodd
@Skywodd:


Je laisse de côté le forum une seconde et paf, 11 notifications. Je vais avoir du boulot :D

Avec moi surtout qui poste souvent des tartines…..

La fonction vw_get_message() met à jour la valeur de la variable taille_ms passé en argument pour qu'elle corresponde avec la taille du message reçu (cf article).

Je vois l'idée et j'y avais pensé, j'ai commencé par faire un serial.print pour vérifier la valeur de taille_ms. Aucun problème, elle ne change pas.
J'ai ensuite fixé la valeur (ici) 3 floats + 1 unsigned int = 4 x 4 = 16.
Idem la variable ne change pas dans le temps, et le bug est toujours présent.

NOTA: j'avais un bug sur le setup du TX vw_set_tx_pin(11); // data RX or c'est vw_set_rx_pin(11); // data RX
j'ai corrigé l'erreur, mais ça n'a rien changer. J'ai mis la main sur un mini librairie (Arduino Easy Transfer) , l'idée est simple, et correspond plus ou moins à mon ajout de compteur pour vérifier la bonne transmission des données (sauf que là on a deux variable fixe et une variable de checksum).
J'ai donc fait un autre test (deux en un) un attiny 85 en TX et un nano en RX.
- l'attiny 85 envoi 4 variables (unsigned int) unit0 unit1 unit2 unit3 il fait un random pour unit0 et unit1 puis unit2 = unit0 - unit1 et unit3 = unit0 + unit2.
Sur le nano il vérifie que le calcule mathématique est bon pour validé les données reçu, et là ! aucun bug !
Donc je ne sais toujours pas de ou ça provient.

Pour le delay(2000) il est inutile cas dans mon TX la fonction void envoi() n'ai appelé qu'une fois toute les 20sec environ. Je vais testé avec un envoi de tableau (vu que dans mon cas actuel, je n'envoi que des floats).

@Fabien:


Pour le attiny 85 j'ai remarqué quelques choses , selon tes fichiers board pour le attiny 85 , il utilise soit le timer0 pour millis delay ect…. soit le timer1 !!!! dans mon cas j'utilise le timer1 ce qui entre en conflit avec virtualwire (si j'utilise en parallèle les fonctions millis, delay…).
Extrait de mon code UserTimer.h dans mes fichiers board pour les attiny :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
*=============================================================================
  Assume there are only two timers.  One for millis and one for everything 
  else.
=============================================================================*/

#if TIMER_TO_USE_FOR_MILLIS == 0
#define TIMER_TO_USE_FOR_USER                     1
#elif TIMER_TO_USE_FOR_MILLIS == 1
#define TIMER_TO_USE_FOR_USER                     0
#else
#error Unexpected condition in UserTimer.h.
#endif


On vois bien que si on ne précise rien il utilise le timer1 pour millis (donc pour delay).
Pour changer le choix du timer utilisé il faut modifier ce bout de code dans le fichier core_build_option.h

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*=============================================================================
  Build options for the ATtiny85 processor
=============================================================================*/

#if defined( __AVR_ATtiny25__ ) || defined( __AVR_ATtiny45__ ) || defined( __AVR_ATtiny85__ )
#define __AVR_ATtinyX5__
#endif

#if defined( __AVR_ATtinyX5__ )

/*
  For various reasons, Timer 1 is a better choice for the millis timer on the
  '85 processor.
*/
#define TIMER_TO_USE_FOR_MILLIS                   1

/*
  If the following is true (non-zero) there will be two phase-correct PWM 
  pins and one fast PWM pin.  If false there will be one phase-correct PWM 
  pin and two fast PWM pins.
*/
#define FAVOR_PHASE_CORRECT_PWM                   1

/*
  Tone goes on whichever timer was not used for millis.
*/
#if TIMER_TO_USE_FOR_MILLIS == 1
#define TIMER_TO_USE_FOR_TONE                     0
#else
#define TIMER_TO_USE_FOR_TONE                     1
#endif

#define HAVE_ADC                                  1

#define DEFAULT_TO_TINY_DEBUG_SERIAL              1

#endif


La ligne

1
#define TIMER_TO_USE_FOR_MILLIS                   1


Tu changes le 1 en 0, mais attention !!! Pour les mêmes raisons qu'il est mieux d'utilisé le timer1 pour virtualWire c'est aussi valable pour millis.
Explication : Le timer0 est (moins précis) que le timer1.
Pourquoi ? Car le timer0 possède moins de choix de prescaler que le timer1.
Prescaler c'est un réglage qui permet de diviser pas X la fréquence d'horloge pour "créé" une horloge spécifique pour le timer. Exemple : tu a une horloge configuré à 8Mhz, et un prescaler réglé à 1024, tu auras donc sur le timer une horloge de 8Mhz / 1024 soit une horloge d'environ 7812Hz.
Pour le timer0 on à le choix entre 1 , 8 , 64 , 256 , 1024
Pour le timer1 on à le choix entre 1 ,2 ,4 ,8 ,16 ,32 ,64 ,128 ,256 ,512 ,1024 ,2048 ,4096 ,8192 ,16384.
Donc forcément on peut "régler" plus précisément le timer1 quand il s'agit de compté un intervalle de temps comme c'est la cas pour virtualWire et Millis.
Donc sache que si tu utilises le timer0 pour millis, tu perdras un peu en précision pour les fonctions rattaché (millis, delay notamment).Ce n'ai pas un drame non plus! ça peut être un problème si tu as besoin d'une bonne précision par exemple pour l'utilisation de capteurs ultrasons pour mesuré une distance, ça marchera, mais ça sera moins précis.
J'ai remarqué un bug sur les attiny, il faut passé la broche utilisé en TX en pinMode(brocheTX,OUTPUT); Car je ne sais pas pourquoi, la librairie ne le fait pas.


NOTE du 16/11/2016 19h50
Je n'ai pas totalement résolut le problème d'envoi de structure, MAIS, j'ai remarqué qu'en fixant la valeur de taille_ms
Voici la ligne de code :

1
  if (vw_get_message((byte*) &ms, &taille_ms)) // Non-blocking 


Donc juste avant le if je défini la valeur de taille_ms et ça ne ce bloque plus.
En revanche j'ai un autre problème, maintenant j'ai par moment des valeurs "farfelu" sur mes variables en réception (Oui oui, module chinois en 433Mhz) quelque soit la distance de 30cm à 15m.
Chose étrange, je n'ai pas plus de bug à 15m qu'a 30cm.
Il faut que je test avec un fil entre les deux arduino à la place des modules 433Mhz. Aux prochaines news….

NOTE : 19/11/2016 18h00
J'ai passé la vitesse de 2000 à 200 bps, encore quelques erreurs de transmission, mais ça va bien mieux (7 erreurs sur 24H) , toujour le problème avec les structures (résolut en partie, maintenant seul la dernière variable de la structure bug de temps en temps).
Je n'ai pas encore testé avec un fil à la place des modules 433Mhz. Affaire à suivre.

NOTE: 22/11/2016 16h35
Remarque :
En trouvant un bug sur la carte nano avec l'utilisation du watchdog pour le reset automatique (il ne marche pas avec le bootloader d'origine) , j'ai donc changer de bootloader pour un optiboot et faire fonctionné mon reset software, et là ! bug avec virtualwire et les structures. J'ai donc de nouveau charger le bootloader d'origine sur la nano. Et quasiment plus de bug avec virtualwire. (je pense que les bugs restant vienne d'un problème de communication entre les modules 433).
Donc en résumé, je pense que le bug initial sur mes UNO vient du bootloader (car sur les UNO avec le bootloader d'origine le reset soft marche)
Et comme sur mes NANO avec le bootloader d'origine je n'ai pas de bug avec virtualwire et les structures (mise a part ceux du au problème de communication entre les modules 433).
Quand j'ai un bug du au module 433, la lib le note dans son compteur d'erreur de réception (ce n'ai pas le cas sur le UNO).
Question : quel parti du bootloader peut faire planté la réception de structure via virtualwire?
Comment créé son bootloader (passé du .c au .hex). Via Atmelstudio? ou possible avec la suite arduino IDE?
Possible de mettre le bootloader du nano sur le UNO et inversement ? (je sais le faire, mais ça va fonctionné ?)
Je pars du principe que ce sont tout les deux des atmega328.

L'idée c'est de me composé un bootloader perso, qui prend le reset software sans faire planté virtualwire et les structures et de le collé dans tout les arduino à base de atmega328 (UNO, NANO). J'attends vos lumières.

NOTE: 22/11/2016 17h27
Je viens de voir que dans l'arduino UNO on charge le bootloader OPTIBOOT.
Donc en faite quand je change le bootloader de ma NANO pour pouvoir utilisé le watchdog reset je vient collé le bootloader de la UNO. J'ai un peu regarder les .C des deux bootloader, ça me pique les yeux !
NOTE: 23/11/2016 14h00
Malgré le bootloader d'origine sur la NANO, j'ai maintenant les mêmes bug que sur la UNO avec les structures.
Je ne comprend pas pourquoi ça avais fonctionné quelques jours sans bug majeur avec la NANO (avant que je change puis remette le bootloader d'origine). Donc le problème doit malgré tout être lié au bootloader (car quand je parle de celui d'origine, je parle de celui qui ce patch quand on sélectionne la board NANO dans l'IDE arduino, je n'avais peu être pas la même version dans ma NANO avant modification ).
J'ai encore une NANO non modifier sous la main, je vais essayer avec voir ce que ça donne. (si quelqu'un sait comment on peu "voir" la version du bootloader installé dans la NANO).

NOTE:14/12/2016 1h30
Test avec la NANO non modifier non concluant ( toujours ce freeze des variables de la structure ) car le programme continu de tourner normalement juste les variables de la structure qui ne ce mette plus à jour ou bout d'un certain temps (très variable selon l'arduino utilisé). Quand je parle d'un "certain temps" cela peu aller de quelques minutes à quelques heures, mais jamais plus de 2 ou 3 heures.

Je vais tacher de modifier mes programmes RX et TX pour utilisé un tableau de float pour voir si ça change quelques choses. Je vous tiens informé quand c'est fait.

Derniére modification le par mneo31


Photo de profil de mneo31

mneo31

Membre

#374 | Signaler ce message


Déjà BONNE ANNEE 2017!!!
Petit récapitulatif.
J'utilise deux arduino (un NANO et un UNO).
Le UNO est en récepteur et le NANO en émetteur.
J'envoi 3 float (température issu d'un ds18b20, température et pression issu d'un BMP180).
Avec l'envoi / réception des 3 float sous forme de structure, j'ai un bug étrange, mon UNO ce bloque (comme quand on est dans un delay ou bloqué dans une boucle while(1)), le fait de reset le UNO le fait repartir un moment, puis bug de nouveau. Et donc obligé de redémarrer le UNO manuellement.
J'avais donc, rajouter une variable unsigned INT dans ma structure de départ pour créé un validateur de transmission, afin de faire reset le UNO de façon logiciel. ( ça marche, mais ce n'ai pas mon but final, je ne veux pas que de façon aléatoire le récepteur reset ).
J'ai essayer divers modification (logiciel et matériel) rien à faire! (voir mes postes précédents).
J'ai donc décidé d'essayer d'envoyer un tableau de float (vu que mon projet actuel ne transmet que des floats).
Et là depuis presque 1 mois ( depuis le 15/12/2016) , ça fonctionne avec l'envoi de tableau…. (hors les problèmes de transmission qui sont du aux modules chinois) en gros virtual wire me compte 5 erreur de transmission par 24H. Mais ça ne plante pas mon récepteur, il ne met juste pas a jours l'affichage sur le LCD jusqu’à ce qu'il reçoive une transmission valide. (normal!)
Donc je n'explique toujours pas pourquoi avec les structure ça ne marche pas correctement !!!
Prochaine étape, essayer d'utilise le remplacent de virtual wire, RadioHead (via RH ASK) et voir ce que cela donne avec les structures.


Je viendrais donner des nouvelles quand j'aurai fait le test.
J'ai également commander des nRF24L01+ qui seront surement utilisé pour le projet final (station météo), mais comme toute commande venant de chine, j'ai encore un mois d'attente avant de pouvoir faire joujou avec.
J'ai aussi pris des ESP8266-01 histoire de faire l'impasse sur l'arduino NANO pour connecter le BMP180.

Car la station météo actuel (qui n'ai pour le moment qu'un thermomètre d’intérieur avec mesure de la pression ) fonctionne comme celà.
Un arduino UNO en émetteur avec un BMP180 + DS18b20 + Shield Ethernet ( pour envoi sur Cayenne ).
Donc pour la sonde Extérieur le plus simple pour le moment sera un ESP8266-01 relier directement en wifi pour envoi sur Cayenne.

Le mini cahier des charges de mon projet.
- Module extérieur auto-alimenté (batterie + photovoltaïque) communication sans fil - Module intérieur sur alimentation (transformateur) communication sans fil + Ecran LCD 16x2

Le module extérieur doit :
Mesuré la pression , la température , l'humidité, la luminosité (Levé du jour/jour/coucher/nuit).
Envoyer les données toutes les X secondes au module intérieur.

Le module intérieur doit:
- Mesurer la température intérieur - Avoir un module horloge RTC ( ou mieux une syncro via un serveur NTP ) - Recevoir est interprété les données du module extérieur.
- Afficher sur le LCD les données (pression, température ext + int, humidité, luminosité)
- Stocker en mémoire (carte SD) les données (pour statistique)
- Avoir un accès HTTP (serveur web) intégré pour consultation via un pc (local ou extérieur)
L'accès HTTP doit affiché les données actuels, affiché des courbes des données enregistrées et pouvoir géré les données de la carte SD (télécharger).
- Important, le module intérieur doit être capable de réécrire sur les anciennes données de la carte SD dans le cas ou cette dernière serai pleine. (comme un enregistreur numérique de vidéo surveillance qui vient écrasé les données les plus anciennes pour enregistré les plus récentes)
Idéalement il faudrait même qu'il puisse compacté les données.
J'explique ( si on envoi des données avec le module extérieur toute les minutes) on aura donc un "bloc" de donnée sur la SD toute les 60 seconds (j'appel un "bloc" un enregistrement d'un relevé de température + pression + humidité + luminosité + température intérieur).
Donc sur la SD il y aura un bloc toutes les 60 seconds.
Quand je parle de compactage de données je veux dire que sur des données qui sont jugé "vielle" on vienne faire la moyenne et que l'on garde un bloc toutes les heures.
Puis pour les données "très vielles" un bloc toute les 4 heures.
Si vous utilisé cayenne, c'est un peu le même principe pour l'affichage des graphes.
Idem pour l'affichage des graphes sur la page web du module, qu'on puisse affiché par minute, heure, jours…. et pouvoir choisir une date précise …
Je ne suis pas contre utilisé un service comme Cayenne pour remplacer la carte SD et le serveur WEB. Car je suis très loin d'avoir ce niveau de programmation dans la tête. (surtout la partie compactage des données, et affichage de graphique via la page web).
Voila l'objectif final.
Cela me servira ensuite pour faire une système domotique complet (alarme, gestion éclairage, store, chauffage, ouverture portail ect…) car les bases seront les mêmes.


En parallèle je suis sur un projet alarme RFID pour garage.
Le projet est fonctionnelle avec un module RC522 (badge mifare 1k) avec plusieurs possibilité.
Version 1 - Enregistrement des codes dans une EEPROM I2C
Version 2 - Enregistrement des codes dans l'EEPROM de l'arduino
Version 3 - Enregistrement du code directement dans le badge Le même projet fonctionnelle avec un module RDM 6300 (badge en 125K, lecture seul)
Version 4 - Stockage dans l'EEPROM de l'arduino des codes
Et je recommence ce projet (avec RDM 6300) car à force de modifier le projet de départ, le code est lourd et je cherche donc a l'optimisé (sauf que je galère alors je repart avec des bases plus simple).
Voila si quelqu'un veux mes .ino (enfin .pde) demander moi en MP.


@Skywodd question, je pense que tu sais créé des librairies pour arduino. As tu fais un tuto sur le site sur le sujet?

Vu que je me suis mis a la lecture de ton tuto pour l'EEPROM ( car quand j'ai commencé mon projet "alarme garage" je ne connaissait que EEPROM.write et EEPROM.read) et donc ton tuto va surement m'être très utile pour optimisé mon code!


Merci de m'avoir lu, j'ai encore posté un pavé.
Promis la prochaine fois j'essayerai de pas trop me dispersé ^^

Derniére modification le par mneo31


Photo de profil de skywodd

skywodd

Membre

Membre du staff

#376 | Signaler ce message


@Skywodd question, je pense que tu sais créé des librairies pour arduino. As tu fais un tuto sur le site sur le sujet?

par mneo31

J'ai pas fait d'article sur le sujet. Pas pour le moment en tout cas ;)

Depuis la version 1.5 du logiciel Arduino, il est nécessaire d'ajouter un fichier JSON pour le gestionnaire de bibliothèques intégré à l'IDE. Il faudrait que je me documente sur le sujet.


Photo de profil de mneo31

mneo31

Membre

#382 | Signaler ce message


Juste une remarque, je reste sur la version IDE 1.6.5 R5 car avec la dernière version ( 1.8.1 ) j'ai plein de bug dans mes programmes lors de la compilation ou alors des programmes qui ce compile bien mais qui ne marche pas.
Idem avec les boards maison pour les attiny, bug comme quoi il ne trouve pas le logiciel pour le téléversement du programme. Bref il faudrait pour bien faire que je fasse place net en supprimant tout de ma version 1.6.5 R5 ( programme, librairie, board) et que je réinstalle tout en commençant par le nouvelle IDE. (Franchement pas envie et comme ma version actuel marche bien, je ne vois l'utilité d'en changer pour le moment)
Je sais lier un .h au programme, mais comment créé une librairie de toute pièce… (.h et .cpp) c'est une autre histoire . ( même si je sais modifier un librairie existante ).
Donc quand tu aura un tuto dessus, n'hésite pas à m'envoyer un MP.
Idem pour le tuto sur la librairie RF24 (qui vient remplacer mirf).


Pas de photo de profil

sebas

Membre

#413 | Signaler ce message


Bonjour

Merci pour ce tutoriel très instructif. En utilisant d’autres sources et une bibliothèque similaire (RH_ASK.h), j’ai pu faire fonctionner un couple émetteur-récepteur RF433MHz avec un arduino nano (émetteur) et un arduino uno (récepteur) en ajoutant une antenne pour avoir une portée de quelques mètres et à travers une vitre.

Ma question va un pas plus loin : comment enregistrer le message reçu par le récepteur sur une carte SD ?

Le projet est le suivant (similaire à celui de mneo31): à l’extérieur, un arduino nano sur pile ou panneau solaire dans une boîte hermétique enregistre la température (au moyen du senseur DHT22) et l’envoie par RF433MHz à un arduino uno branché secteur situé à l’intérieur. Ensuite l’arduino uno affiche les valeurs sur un LCD display et les enregistre sur une carte mémoire SD. Je me suis inspiré de ce modèle (http://www.instructables.com/id/SOLAR-POWERED-ARDUINO-WEATHER-STATION/) mais qui n’inclut pas l’enregistrement sur SD.

Le problème est que le module SD que j’utilise (http://www.ebay.com/itm/New-Micro-SD-Storage-Board-SDHC-Card-Reader-Memory-Shield-Module-for-Arduino-/201654161495?hash=item2ef3865057:g:Z5MAAOSw9eVXVO0r) a obligatoirement besoin des digital pins 10,11,12 et 13 de l’arduino, et que le récepteur 433Mhz utilise aussi le digital pin 11. Ma question : est-il possible de recevoir le message du récepteur sur un autre pin que le 11 ? Existe-il une fonction de WirtualWire qui dit à l’arduino sur quel pin lire les données du récepteur ? Ou alors partager le pin 11 en alternant la réception des messages et l'écriture sur SD (en protégeant les modules par des diodes) ?

Merci d’avance pour votre aide. Cordialement, Seb

Derniére modification le par sebas


Photo de profil de mneo31

mneo31

Membre

#414 | Signaler ce message


Bonjour

Merci pour ce tutoriel très instructif. En utilisant d’autres sources et une bibliothèque similaire (RH_ASK.h), j’ai pu faire fonctionner un couple émetteur-récepteur RF433MHz avec un arduino nano (émetteur) et un arduino uno (récepteur) en ajoutant une antenne pour avoir une portée de quelques mètres et à travers une vitre.

Ma question va un pas plus loin : comment enregistrer le message reçu par le récepteur sur une carte SD ?

Le projet est le suivant (similaire à celui de mneo31): à l’extérieur, un arduino nano sur pile ou panneau solaire dans une boîte hermétique enregistre la température (au moyen du senseur DHT22) et l’envoie par RF433MHz à un arduino uno branché secteur situé à l’intérieur. Ensuite l’arduino uno affiche les valeurs sur un LCD display et les enregistre sur une carte mémoire SD. Je me suis inspiré de ce modèle (http://www.instructables.com/id/SOLAR-POWERED-ARDUINO-WEATHER-STATION/) mais qui n’inclut pas l’enregistrement sur SD.

Le problème est que le module SD que j’utilise (http://www.ebay.com/itm/New-Micro-SD-Storage-Board-SDHC-Card-Reader-Memory-Shield-Module-for-Arduino-/201654161495?hash=item2ef3865057:g:Z5MAAOSw9eVXVO0r) a obligatoirement besoin des digital pins 10,11,12 et 13 de l’arduino, et que le récepteur 433Mhz utilise aussi le digital pin 11. Ma question : est-il possible de recevoir le message du récepteur sur un autre pin que le 11 ? Existe-il une fonction de WirtualWire qui dit à l’arduino sur quel pin lire les données du récepteur ? Ou alors partager le pin 11 en alternant la réception des messages et l'écriture sur SD (en protégeant les modules par des diodes) ?

Merci d’avance pour votre aide. Cordialement, Seb

par sebas


Bonjour sebas.
1er oui il est possible de modifier la pin pour le récepteur. Tu le fait lors de l'appel de

1
RH_ASK driver;

, tu fais

1
RH_ASK driver(2000, 11, 12, 10); // 2000 = vitesse , 11 = pin RX , 12 = pin TX ,10 = pin PTT

Bien entendu tu modifies la valeur du pin RX comme bon tu veux. Dans la ligne que je t'ai donner ce sont les valeurs par défauts.
Pour l'utilisation de la carte SD
Regarde ce code :

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
// --- Programme Arduino --- 
// Trame de code g�n�r�e par le g�n�rateur de code Arduino
// du site www.mon-club-elec.fr 

// Auteur du Programme : X. HINAULT - Tous droits r�serv�s 
// Programme �crit le : 18/02/1012

// ------- Licence du code de ce programme ----- 
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License,
//  or any later version.
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.

// ////////////////////  PRESENTATION DU PROGRAMME //////////////////// 

// -------- Que fait ce programme ? ---------
 /* Ce programme teste le stockage de valeurs issues
de mesures analogiques dans un fichier 
sur carte m�moire micro-SD
Donn�es au format CSV pour utilisation directe
dans un tableur OpenOffice.  */ 

// --- Fonctionnalit�s utilis�es --- 

// Utilise la connexion s�rie vers le PC 
// Utilise la conversion analogique num�rique 10 bits 
// Utilise une carte m�moire micro-SD avec le module Ethernet Arduino 
// Utilise une fonction permettant de connaitre la RAM restant disponible

// -------- Circuit � r�aliser --------- 

// La connexion s�rie vers le PC utilise les broches 0 et 1 (via le c�ble USB) 

// Le module Ethernet est � enficher broche � broche sur la carte Arduino 
// Connecter broche SCLK du module Ethernet sur la broche 13
// Connecter broche MISO du module Ethernet sur la broche 12
// Connecter broche MOSI du module Ethernet sur la broche 11
// Connecter broche Select Ethernet du module Ethernet sur la broche 10
// Connecter broche Select SD Card du module Ethernet sur la broche 4
// Le module Ethernet est compatible avec la carte Mega via le connecteur ICSP

// Broche 14 : Une r�sistance variable de 10 KOhms

// /////////////////////////////// 1. Ent�te d�clarative /////////////////////// 
// A ce niveau sont d�clar�es les librairies incluses, les constantes, les variables, les objets utiles...

// --- D�claration des constantes ---

// --- Inclusion des librairies ---

#include <SD.h> // cr�e automatiquement un objet racine SD repr�sentant la carte m�moire SD

// --- D�claration des constantes utiles ---

// --- D�claration des constantes des broches E/S num�riques ---

const int brocheSDCardSelect=4; // broche utilis�e pour s�lectionner la SD card 

// --- D�claration des constantes des broches analogiques ---

const int analog0= A0; // Constante pour la broche analogique 0

// --- D�claration des variables globales ---

int mesure_brute=0;// Variable pour acquisition r�sultat brut de conversion analogique num�rique
float mesuref=0.0;// Variable pour calcul r�sultat d�cimal de conversion analogique num�rique

int test; // Variable utilis�e pour tester valeur renvoy�e par fonctions SD Card


// --- D�claration des objets utiles pour les fonctionnalit�s utilis�es ---

/*
Sd2Card card; // cr�ation d'un objet Sd2Card
SdVolume volume; // cr�ation d'un objet SdVolume
SdFile root; // cr�ation d'un objet SdFile pour le r�pertoire racine
SdFile file; // cr�ation d'un objet SdFile pour le fichier utilis�
*/

File file; // objet file 
File root; // objet root pour le r�pertoire racine


// ////////////////////////// 2. FONCTION SETUP = Code d'initialisation ////////////////////////// 
// La fonction setup() est ex�cut�e en premier et 1 seule fois, au d�marrage du programme

void setup()   { // debut de la fonction setup()

// --- ici instructions � ex�cuter 1 seule fois au d�marrage du programme --- 

// ------- Initialisation fonctionnalit�s utilis�es -------  

Serial.begin(115200); // initialise connexion s�rie � 115200 bauds
// IMPORTANT : r�gler le terminal c�t� PC avec la m�me valeur de transmission 

//---- initialise l'utilisation de la carte m�moire SD en mode SPI  
pinMode(10, OUTPUT); // met la broche 10 (SS) en sortie (n�cessaire avec module ethernet)
digitalWrite(10, HIGH); // mais d�sactive le  circuit int�gr� W5100 du module ethernet!

  //----- initialisation de la carte SD ----- 
  Serial.println("Initialisation de la SD card...");

  pinMode(10, OUTPUT); // laisser la broche SS en sortie - obligatoire avec librairie SD

  test=SD.begin(brocheSDCardSelect); // initialisation de la carte SD avec broche 4 en tant que CS - renvoie true/false

  if (test!=true) { // si initialisation n'est pas r�ussie
    Serial.println("Echec initialisation!"); // message port S�rie
  }
  else { // si nitialisation r�ussie
    Serial.println("Initialisation reussie !"); // message port S�rie

  //----- affiche le contenu du r�pertoire 

  root = SD.open("/"); // ouvre la SD Card � la racine

  Serial.println("Repertoire racine ouvert !");

  } // fin si initialisation r�ussie

// ------- Broches en sorties num�riques -------  

// ------- Broches en entr�es num�riques -------  

// ------- Activation si besoin du rappel au + (pullup) des broches en entr�es num�riques -------  

// ------- Initialisation des variables utilis�es -------  

} // fin de la fonction setup()
// ********************************************************************************

////////////////////////////////// 3. FONCTION LOOP = Boucle sans fin = coeur du programme //////////////////
// la fonction loop() s'ex�cute sans fin en boucle aussi longtemps que l'Arduino est sous tension

void loop(){ // debut de la fonction loop()

  //---- efface fichier au pr�alable ---
  test=SD.remove("data.txt"); // efface fichier et m�morise r�sultat op�ration  
  if (test) Serial.println("Fichier efface"); // affiche message si fichier bien effac�

  //---- cr�e fichier en �criture --- 
  file = SD.open("data.txt", FILE_WRITE); // ouvre le fichier en �criture
  // NB : le fichier est cr�� si il n'existe pas !

  //---- test si fichier dispo en �criture 
  if (!file) { // si fichier pas dispo 

    Serial.println ("Erreur ouverture fichier !");

  } // fin if

  else { // si le fichier existe et est ouvert 

    Serial.println ("Fichier pret pour ecriture !");

    //----- Ecriture dans le fichier au format CSV ----- 

    // premiere ligne du fichier CSV - entete avec liste des champs
    file.println("NumeroMesure;ValeurBrute;ValeurFloat;Millis");

    Serial.println ("Enregistrement en cours :");

    for (int i=0; i<1000; i++) { // n mesures CAN 

      // acquisition conversion analogique num�rique (100�s env.) sur broche analogique indiqu�e
      mesure_brute= analogRead(A0) ; 

      // calcul tension en Volts
      mesuref=mesure_brute*5.0;
      mesuref=mesuref/1023.0; 

      // valeur premier champ
      file.print(i), file.print(';'); 

      // valeur deuxieme champ
      file.print(mesure_brute), file.print(';'); 

      // valeur troisieme champ
      file.print(mesuref), file.print(';'); 

      // valeur quatrieme champ
      file.print(millis());

      // le dernier champ doit se terminer par un saut de ligne +++
      file.println();

      delay(10); // entre chaque mesure
      if ((i+1)%50) Serial.print("."); else  Serial.println(".");// affiche ligne de 50 points

    } // fin boucle for

    file.close(); // ferme le fichier
    Serial.println("Fin enregistrement !");  
    Serial.println("Fermeture fichier !");  

    Serial.println("Retirez SD-Card et la lire sur le PC !");  


  } // fin else

  while(1); // stoppe loop

} // fin de la fonction loop() - le programme recommence au d�but de la fonction loop sans fin
// ********************************************************************************

Il te montre comment écrire simplement avec une mise en page simple pour exporté vers un tableur.
A ta place j'utiliserai un module RTC sur le récepteur pour pouvoir ajouter à chaque mesure la date et l'heure de la mesure.
Regarde le tuto sur le forum ICI
Il est simple et bien fait. Après tu as aussi des librairies toutes faites pour utiliser les modules RTC.
Je penses qu'avec ces bouts de code tu devrais arrivé facilement à faire ce que tu veux.

Autre remarque, concernant le module émetteur, pourquoi ne pas utilisé un petit attiny 85 ? ça consommera moins qu'un nano et fera parfaitement le job. De plus comme je ne pense pas que tu vas faire une mesure toute les 2 secondes, tu peux mettre le attiny en veille pour économisé la batterie.
Avec un attiny 85 bien programmé et trois piles lithium cd2032 ou une pile 9v 6f22 tu peux faire un émetteur qui tiens plusieurs mois . Bien entendu il faut quelques connaissance en électronique pour mettre au point la partie alimentation, il ne suffi pas de collé un régulateur 5v pour alimenté le attiny ( ça fonctionnerai mais tu n'auras pas une autonomie correcte ).
N'hésite pas à demander si tu as besoin. Et pense a posté tes codes (émetteur et récepteur) que l'on puisse t'aidé au mieux.

NOTE pour skywodd . Un petit tuto pour l'utilisation d'un shield SD est il prévu ?