Question about VirtualWire library

Hello

I have a problem with the function vw_wait_rx_max().
The limit size of time is more than 4.000.000.000 and when I put a delay of max 300.000 it doesn't work.
The arduino doesn't receive message but the function stop before the end of the delay.
Can you help me please? Is there an other solution?

Thank

Post the code, using code tags. See "How to use this forum" for helpful tips.

Always declare variables for use with delay(), millis(), micros() as unsigned long.

Here my code

TFE_v2_emetteur.ino (2.07 KB)

Please read these two posts:

General Guidance and How to use the Forum
and
Read this before posting a programming question ...
You may also find useful information that would answer your question here:
Useful links - check here for reference posts / tutorials

It is important to provide as much of the information that is needed to solve your problem as you can, in your first posts. The forum link above has guidelines for posting in a standard way that makes it easiest for people to provide you with useful answers. Making an effort to do this will greatly increase the number and quality of helpful responses that you get.

In this case, the problem is that you have posted code without using code tags. The code tags make the code look

like this

when posting source code files. It makes it easier to read, and can be copied with a single mouse click. Also, if you don't do it, some of the character sequences in the code can be misinterpred by the forum code as italics or funny emoticons. The "Code: [Select]" feature allows someone to select the entire sketch so it can be easily copied and pasted into the IDE for testing.

If you have already posted without using code tags, open your message and select "modify" from the pull down menu labelled, "More", at the lower right corner of the message. Highlight your code by selecting it (it turns blue), and then click on the "</>" icon at the upper left hand corner. Click on the "Save" button. Code tags can also be inserted manually in the forum text using the code and /code metatags.

Sorry aarg

Thank
the problem should be that my variable is an int

to0n7:
Sorry aarg

That's okay. I make this request not for me, but for the forum helpers in general.

Your code, posted as I requested in reply #1:

#include <VirtualWire.h>


int ThermistorPin = 0;
int tension;
int valeurTableau;
int tempPourEnvoyer;
const bool okR = 1;
const bool okE = 0 ;

float R1 = 10000;
float logR2, R2, T, Tc ;
float c1 = 1.009249522e-03, c2 = 2.378405444e-04, c3 = 2.019202697e-07;



void setup() {

  Serial.begin(9600);
  vw_set_tx_pin(9);
  vw_set_rx_pin(8);
  vw_setup(2000);
  vw_rx_start();


}

void loop() {
  int temp[2001];
  int valeur;
  int msg;

  Serial.println("Attente réception");
  vw_wait_rx();

  if (vw_get_message((byte *) &valeur, sizeof(int))) {

    Serial.println(valeur);
  }

  if (valeur == 10 || valeur == 30 || valeur == 60 || valeur == 120 || valeur == 300)
  { delay(1000);
    while (1){vw_send((byte *)&okR, sizeof(okR));
    vw_wait_tx();
    Serial.println(okR);}

    for (int n = 0; n < 2000; n++)
    {
      tension = analogRead(ThermistorPin);
      R2 = R1 * (1023.0 / (float)tension - 1.0);
      logR2 = log(R2);
      T = (1.0 / (c1 + c2 * logR2 + c3 * logR2 * logR2 * logR2));
      Tc = T - 273.15;
      tempPourEnvoyer = Tc * 100;
      temp[n + 1] = tempPourEnvoyer;
      Serial.println(tempPourEnvoyer);
      Serial.println(valeur * 1000);
      vw_wait_rx_max(valeur * 1000);


      if (vw_get_message((byte *) &msg, sizeof(int)))
      { Serial.println(msg);
        if (msg == 477) //à définir pour collecter
        { Serial.println(okR);
          delay(1000);
          vw_send((byte *) & okR, sizeof(okR));
          vw_wait_tx();
          temp[0] = n;
          for (int a = 0; a < n + 1; a++)
          { valeurTableau = temp[a];
            vw_send((byte *) &valeurTableau, sizeof(valeurTableau));
            vw_wait_tx();
          }
          vw_wait_rx_max(2000);

          if (vw_get_message((byte *) msg, sizeof(int)))
          {
            if (msg = okE)
            { break;
            }

          }

        }

      }
    }
  }





  if (valeur == 1 )//à définir pour collecter
  {
  }


  if (valeur == 0 )//à définir pour reset carte
  {
  }

}

Which Arduino are you using? This single line consumes all of the RAM memory of an Arduino Uno:

  int temp[2001];

I use arduino mega

Why do you even use the vw_wait_rx() function? It isn't used in this RX example:
https://github.com/sparkfun/RF_Links/blob/master/Firmware/Arduino/libraries/VirtualWire/examples/receiver/receiver.pde

It's described this way in the header file:

    /// Block until a message is available
    /// then returns
    extern void vw_wait_rx();

Why do you need to block?

aarg:
Why do you even use the vw_wait_rx() function? It isn't used in this RX example:
https://github.com/sparkfun/RF_Links/blob/master/Firmware/Arduino/libraries/VirtualWire/examples/receiver/receiver.pde

It's described this way in the header file:

    /// Block until a message is available

/// then returns
    extern void vw_wait_rx();




Why do you need to block?

I use vw_wait_rx() like delay function for the temperature but during this delay I can receive messages.

(valeur*1000) will always be less than 32768.

    vw_wait_rx_max(valeur * 1000);

See reply #1.

jremington:
(valeur*1000) will always be less than 32768.

    vw_wait_rx_max(valeur * 1000);

See reply #1.

Thanks jremington I have arlready changed it. Now valeur is an unsigned long. Thank you for you help but now I have an other problem. Even if I don't emit message the function vw_wait_rx_max(...) is activated before the end of the function.

Post the revised code using code tags.

Here my "new" code

#include <VirtualWire.h>

#include <avr/wdt.h>

int ThermistorPin = 0;
int tension;
int valeurTableau;
int tempPourEnvoyer;
const bool okR = 1;
const bool okE = 0 ;

float R1 = 10000;
float logR2, R2, T, Tc ;
float c1 = 1.009249522e-03, c2 = 2.378405444e-04, c3 = 2.019202697e-07;



void setup() {

  Serial.begin(9600);
  vw_set_tx_pin(12);
  vw_set_rx_pin(11);
  vw_setup(2000);
  vw_rx_start();


}

void loop() {
  int temp[2001];
  unsigned long valeur;
  int msg;

  Serial.println("Attente réception");
  vw_wait_rx();

  if (vw_get_message((byte *) &valeur, sizeof(unsigned long))) {

    Serial.println(valeur);
  }

  if (valeur == 10 || valeur == 30 || valeur == 60 || valeur == 120 || valeur == 300)
  {
    vw_send((byte *)&okR, sizeof(okR));
    vw_wait_tx();
    Serial.println(okR);
    unsigned long incrementTemps = valeur * 1000;

    for (int n = 0; n < 2000; n++)
    {
      tension = analogRead(ThermistorPin);
      R2 = R1 * (1023.0 / (float)tension - 1.0);
      logR2 = log(R2);
      T = (1.0 / (c1 + c2 * logR2 + c3 * logR2 * logR2 * logR2));
      Tc = T - 273.15;
      tempPourEnvoyer = Tc * 100;
      temp[n + 1] = tempPourEnvoyer;
      Serial.println(tempPourEnvoyer);
      Serial.println(incrementTemps);
      vw_wait_rx_max(incrementTemps);


      if (vw_get_message((byte *) &msg, sizeof(int)))
      { Serial.println(msg);
        if (msg == 477) //à définir pour collecter
        { Serial.println(okR);
          delay(1000);
          vw_send((byte *) & okR, sizeof(okR));
          vw_wait_tx();
          temp[0] = n;
          for (int a = 0; a < n + 1; a++)
          { valeurTableau = temp[a];
            vw_send((byte *) &valeurTableau, sizeof(valeurTableau));
            vw_wait_tx();
          }
          vw_wait_rx_max(2000);

          if (vw_get_message((byte *) msg, sizeof(int)))
          {
            if (msg = okE)
            { break;
            }

          }

        }

      }
    }
  }





  if (valeur == 1 )//à définir pour collecter
  {
  }


  if (valeur == 0 )//à définir pour reset carte
  {
  }

}

I find a solution. I dont if it's the best solution but it works. I use while and millis functions

#include <VirtualWire.h>

#include <avr/wdt.h>

int ThermistorPin = 0;
int tension;
int valeurTableau;
int tempPourEnvoyer;
const bool okR = 1;
const bool okE = 0 ;

float R1 = 10000;
float logR2, R2, T, Tc ;
float c1 = 1.009249522e-03, c2 = 2.378405444e-04, c3 = 2.019202697e-07;



void setup() {

  Serial.begin(9600);
  vw_set_tx_pin(12);
  vw_set_rx_pin(11);
  vw_setup(2000);
  vw_rx_start();


}

void loop() {
  int temp[2001];
  unsigned long valeur;
  int msg = 0;

  Serial.println("Attente réception");
  vw_wait_rx();

  if (vw_get_message((byte *) &valeur, sizeof(unsigned long))) {

    Serial.println(valeur);
  }

  if (valeur == 10 || valeur == 30 || valeur == 60 || valeur == 120 || valeur == 300)
  {
    vw_send((byte *)&okR, sizeof(okR));
    vw_wait_tx();
    Serial.println(okR);
    unsigned long incrementTemps = valeur * 1000;
    unsigned long moment = millis();
    Serial.print("Temps nécessaire avant de commencer le relevé : ");
    Serial.println(moment);

    for (unsigned long n = 0; n < 2000; n++)
    {

      tension = analogRead(ThermistorPin);
      R2 = R1 * (1023.0 / (float)tension - 1.0);
      logR2 = log(R2);
      T = (1.0 / (c1 + c2 * logR2 + c3 * logR2 * logR2 * logR2));
      Tc = T - 273.15;
      tempPourEnvoyer = Tc * 100;
      temp[n + 1] = tempPourEnvoyer;
      Serial.print("Temperature ");
      Serial.print(n);
      Serial.print(" ");
      Serial.println(tempPourEnvoyer);
      Serial.print("Increment : ");
      Serial.println(incrementTemps);
      unsigned long calcul = moment + ((n + 1) * incrementTemps);
      while ( millis() <= calcul || msg == 477)
      { Serial.print("Calcul : ");
        Serial.println(calcul);
        Serial.print("Millis : ");
        Serial.println(millis());
        vw_wait_rx();
        if (vw_get_message((byte *) &msg, sizeof(int)))
        {
          Serial.println(msg);
        }
      }

      if (msg == 477) //à définir pour collecter
      { Serial.println(okR);
        delay(1000);
        vw_send((byte *) & okR, sizeof(okR));
        vw_wait_tx();
        temp[0] = n;
        for (int a = 0; a < n + 1; a++)
        { valeurTableau = temp[a];
          vw_send((byte *) &valeurTableau, sizeof(valeurTableau));
          vw_wait_tx();
        }
        vw_wait_rx_max(2000);

        if (vw_get_message((byte *) msg, sizeof(int)))
        {
          if (msg = okE)
          { break;
          }

        }

      }

    }
  }






  if (valeur == 477)//à définir pour collecter
  {
  }


  if (valeur == 666 )//à définir pour reset carte
  {
  }

}

This sets "msg" to be equal to "okE".

if (msg = okE)

Use "==" for comparisons.

jremington:
This sets "msg" to be equal to "okE".

if (msg = okE)

Use "==" for comparisons.

Ok thank you. And about the solution I use what do you think?

Hello

I use millis in my program and I find that's not very precise. Is it normal that I have imprecision around few seconds? Thanks for your help

#include <VirtualWire.h>
#include <avr/wdt.h>

int ThermistorPin = 0;
int tension;
int valeurTableau;
int tempPourEnvoyer;
const bool okR = 1;
const bool okE = 0 ;

float R1 = 10000;
float logR2, R2, T, Tc ;
float c1 = 1.009249522e-03, c2 = 2.378405444e-04, c3 = 2.019202697e-07;



void setup() {

  Serial.begin(9600);
  vw_set_tx_pin(12);
  vw_set_rx_pin(11);
  vw_setup(2000);
  vw_rx_start();


}

void loop() {
  int temp[2001];
  unsigned long valeur;
  int msg = 0;

  Serial.println("Attente réception");
  vw_wait_rx();

  if (vw_get_message((byte *) &valeur, sizeof(unsigned long))) {

    Serial.println(valeur);
  }

  if (valeur == 10 || valeur == 30 || valeur == 60 || valeur == 120 || valeur == 300)
  {
    vw_send((byte *)&okR, sizeof(okR));
    vw_wait_tx();
    Serial.println(okR);
    unsigned long incrementTemps = valeur * 1000;
    unsigned long moment = millis();
    Serial.print("Temps nécessaire avant de commencer le relevé : ");
    Serial.println(moment);

    for (unsigned long n = 0; n < 2000; n++)
    {

      tension = analogRead(ThermistorPin);
      R2 = R1 * (1023.0 / (float)tension - 1.0);
      logR2 = log(R2);
      T = (1.0 / (c1 + c2 * logR2 + c3 * logR2 * logR2 * logR2));
      Tc = T - 273.15;
      tempPourEnvoyer = Tc * 100;
      temp[n + 1] = tempPourEnvoyer;
      Serial.print("Temperature ");
      Serial.print(n);
      Serial.print(" ");
      Serial.println(tempPourEnvoyer);
      Serial.print("Increment : ");
      Serial.println(incrementTemps);
      unsigned long calcul = moment + ((n + 1) * incrementTemps);
      while ( millis() <= calcul || msg == 477)
      { Serial.print("Calcul : ");
        Serial.println(calcul);
        Serial.print("Millis : ");
        Serial.println(millis());
        vw_wait_rx();
        if (vw_get_message((byte *) &msg, sizeof(int)))
        {
          Serial.println(msg);
        }
      }

      if (msg == 477) //à définir pour collecter
      { Serial.println(okR);
        delay(1000);
        vw_send((byte *) & okR, sizeof(okR));
        vw_wait_tx();
        temp[0] = n;
        for (int a = 0; a < n + 1; a++)
        { valeurTableau = temp[a];
          vw_send((byte *) &valeurTableau, sizeof(valeurTableau));
          vw_wait_tx();
        }
        vw_wait_rx_max(2000);

        if (vw_get_message((byte *) msg, sizeof(int)))
        {
          if (msg == okE)
          { break;
          }

        }

      }

    }
  }






  if (valeur == 477)//à définir pour collecter
  {
  }


  if (valeur == 666 )//à définir pour reset carte
  {
  }

}

That code does not compile. Are you missing some library that defines as the vx_xxx() functions?

How have you determined things are "off" by several seconds? What is the output you are seeing. It would be helpful to see that as well.

this loop:

      while ( millis() <= calcul || msg == 477)
      { Serial.print("Calcul : ");
        Serial.println(calcul);
        Serial.print("Millis : ");
        Serial.println(millis());
        vw_wait_rx();
        if (vw_get_message((byte *) &msg, sizeof(int)))
        {
          Serial.println(msg);
        }
      }

could be blocking on vw_wait_rx()? same is true for vw_get_message()

Several seconds over what time period? Years or minutes?

In your duplicate thread I told you about using blocking functions that you probably don't need. Take a good look and try to understand why this is not good for you:

// Wait for the transmitter to become available
// Busy-wait loop until the ISR says the message has been sent
void vw_wait_tx()
{
    while (vw_tx_enabled)
	;
}

// Wait for the receiver to get a message
// Busy-wait loop until the ISR says a message is available
// can then call vw_get_message()
void vw_wait_rx()
{
    while (!vw_rx_done)
	;
}