If(vw_get_message... fails always, transmitter seems to be functioning

Nano board but also tried Uno

#include <VirtualWire.h>              
byte message[VW_MAX_MESSAGE_LEN]; // a buffer to store the incoming messages
byte messageLength = VW_MAX_MESSAGE_LEN; // the size of the message
int received_number = 0;
int LED = 5;

void setup()
{
  Serial.begin(9600);
  pinMode(LED, OUTPUT);
  Serial.println("Ready...");
  vw_set_rx_pin(3); // pin
  vw_setup(2000); // bps
  vw_rx_start();
}

void loop()
{
  **if (vw_get_message(message, &messageLength)) // non-blocking**
  {
    Serial.print("Potentiometer: ");
    for (int i = 0; i < messageLength; i++)
    {
      //Serial.print(message[i]);
      received_number = message[i];
    }
    Serial.println(received_number);
    analogWrite(LED, received_number);
  }
}

I cannot get the if statement to pass, I have swapped transmitters and receivers to no avail. If I bypass the test I get an output of 36 and 30 for message and messageLength. I truly do not understand what (message, &messageLength) are doing and if anything is being stored where the pointer is pointing to. I have tried other sketches one using RadioHead, a;; with the same results. Any help would be appreciated muchly.
Woodcrafter

Welcome to the forum!

Please post the transmit code. It is impossible to debug the receive code without knowing exactly what is transmitted. However, several fatal errors are obvious.

First, it is absolutely required to reset "messageLength" every pass through loop(), as follows.

 messageLength = VW_MAX_MESSAGE_LEN; // reset size of the message 
 if (vw_get_message(message, &messageLength)) // non-blocking

When reception is successful, "messageLength" will be modified to hold the size of the received message, in bytes.

The following won't work either, but I would have to know what is transmitted in order to recommend a fix.

    for (int i = 0; i < messageLength; i++)
    {
      //Serial.print(message[i]);
      received_number = message[i];
    }
    Serial.println(received_number);

Note: it is best to start with a simple library example, and first understand how it works, rather than cut and paste some random code from the internet. A lot of what you find will be wrong!

1 Like

Thank you for your assistance

Sometimes knowing the purpose helps to understand the solution. I have an antenna on the roof for TV and cannot tell which way it is pointing, so I have developed a circuit that basically will tell me 8 different points every 45 deg or rotation and send the numerical code based on the BCD 4 bit input to the receiver. I am thinking if it is negative it is moving counterclockwise otherwise it is turning clockwise. and I know where it is pointing. I trigger an interrupt at every 45 degrees and read the 4 reed switches for the direction pointing. That all seems to work ok, I am just trying to get the communications working from antenna case to controller case. I learned basic on the TRS 80 and haven't done any real programming in 40 years, so learning Arduino/C++ has been a delightful challenge.
(The distance I will be working with is about 10 meters so I have an antenna on each module).

This is the transmitter code. I used the Electronoobs example for both transmitter and receiver.
I actually have two pieces of information I need to transmit, one is a numerical ASCII value between 1 and 8 and the other is direction clockwise or counterclockwise. I was thinking of transmitting a byte for the numerals and making it negative if it was counterclockwise, otherwise, it would be clockwise.
As I read in the forum, that there may be two bytes in the transmission, but I was unsure if it applied to this. In the demo, everything worked for him, but I have had no luck. I also have rechecked connections over and over.

/* 1byte 433Mhz TRANSMITTER example.
/* Tutorial link: http://electronoobs.com/eng_arduino_tut99.php
 * Code: http://electronoobs.com/eng_arduino_tut99_code1.php
 * Scheamtic: http://electronoobs.com/eng_arduino_tut99_sch1.php
 * Youtube Channel: http://www.youtube/c/electronoobs   
// Arduino          433Mhz Tx
// GND              GND
// 5V               VCC
// D3               Data
*/

#include <VirtualWire.h> //Download it here: http://electronoobs.com/eng_arduino_virtualWire.php
#define size 1
int pot = A0;
byte TX_buffer[size]={0};
byte i;


void setup() 
{
  Serial.begin (9600);
  // virtual wire
  vw_set_tx_pin(3); // pin
  vw_setup(2000); // bps
  for(i=0;i<size;i++)
  {
     TX_buffer[i]=i;
  }
}

void loop()
{ 

  int val = map(analogRead(pot),0,1024,0,255);
 //   Serial.println (val);
  TX_buffer[0] = val;  
  **Serial.println (val);** // added to test for the actual value, and it does change.
  vw_send(TX_buffer, size); 
  vw_wait_tx(); 
  delay(1000); 

  **Serial.println (val);** //see comment above.
  }

Really? Like in the 1970s? :grinning: :grinning_face_with_smiling_eyes:
https://www.youtube.com/watch?v=HvQiVvUv6Co

Really, get all the local stations and I use the internet for ROKU and stream the rest. Don't have to pay for cable TV

I recommend to avoid "electronoob". That is a pretty bad code example.

But the message transmitted is one byte long, with a value ranging from 0 to 255 (thus throwing away most of the accuracy of the ADC measurement).

To receive that message, this should work for loop:

void loop()
{
   messageLength = VW_MAX_MESSAGE_LEN; // reset maximum size of the message 
   if (vw_get_message(message, &messageLength)) // non-blocking
  {
    if (messageLength == 1)  
	{ //got a message of the expected length
      Serial.print("Potentiometer: ");
      received_number = message[0];
      Serial.println(received_number);
      analogWrite(LED, received_number);
    }
  }
}

When you get that working, post again and I'll show you how to send more than one byte of data in one transmission.

Are these 433 MHz units, and if so, do you have the required 17 cm antennas on both transmitter and receiver?

OK, thank you, working on it now.

Yes they are the 433 MHz and I have coiled antennas on both modules and right now they are about 4-5 inches away from each other.
I did not see any activity on the receiver Nano so I added this to the beginning of the loop to see what it was getting
if (runonce == 1){
Serial.print ("MessageLength ");
Serial.println (messageLength);
runonce = 0;
Getting 30 as the value of messageLength. The transmitter value is about 127 right now.
I took out the runonce condition and the length remains 30. It seems that there is no reception. I do not see the Rx LED blinking except at the download of the sketch. Tx LED is continuously lit, which I don't think it should be. I will exchange the Nano in the AM. Again thank you for your assistance.

Hi, @woodcrafter
Welcome to the forum.

Please read the post at the start of any forum , entitled "How to use this Forum".

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

Always post your complete code, using code tags. This tells me nothing useful:

if (runonce == 1){
Serial.print ("MessageLength ");
Serial.println (messageLength);
runonce = 0;

17 cm of straight wire is best, but the coiled antennas are good for a few inches of range.

Please post a clear, focused picture of your breadboard and wiring. You probably have a wiring problem.

This is a better radio tutorial: Using 433MHz RF Modules with Arduino | DroneBot Workshop


8

I assumed that the distance of 4-5 inches was close enough for the coiled antennas and expected to stretch them out when I finished and assembled the system.
I will check out the DroneBot Workshop tutorial. I have looked at so many and none seemed to work that I settled on the simplest to at least get the communications working. :frowning: . I tried a RadioHead library, but I kept getting compile errors from the library.
I am sorry about the runonce code, I had just inserted it into the beginning of the receiver code void loop, to just a test to see what the messageLenth was as a variable value, just a test I expected a value of 1 or 2 but got 30, the runonce was so it did not keep repeating the Serial.print continuously.
I have thought a wiring problem was the culprit on the receiver, but I thought I had rewired it several times to make sure it was right, perhaps another set of eyes will see my error.

Sorry, I can't make sense of the photographs.

I recommend the VirtualWire library. It is much smaller than RadioHead and has no known bugs. Download from the author, here and try the receiver and transmitter examples (rename from .pde to .ino). If they don't work, either your modules are defective or you have a wiring problem.

Check wiring continuity using your multimeter. If you don't have one, now is the time to buy one.

OK, I am using the VirtualWire example for the receiver Code Below:

// transmitter.ino
// Simple example of how to use VirtualWire to transmit messages
// Implements a simplex (one-way) transmitter with an TX-C1 module
//
// See VirtualWire.h for detailed API docs
// Author: Mike McCauley (mikem@airspayce.com)
// Copyright (C) 2008 Mike McCauley
// $Id: transmitter.pde,v 1.3 2009/03/30 00:07:24 mikem Exp $
#include <VirtualWire.h>
void setup()
{
    Serial.begin(9600);   // Debugging only
    Serial.println("setup");
    // Initialise the IO and ISR
    vw_set_ptt_inverted(true); // Required for DR3100
    vw_setup(2000);      // Bits per sec
}
void loop()
{
    const char *msg = "hello";
    digitalWrite(13, true); // Flash a light to show transmitting
    vw_send((uint8_t *)msg, strlen(msg));
    vw_wait_tx(); // Wait until the whole message is gone
    digitalWrite(13, false);
    delay(200);
}
// Simple example of how to use VirtualWire to receive messages
// Implements a simplex (one-way) receiver with an Rx-B1 module
//
// See VirtualWire.h for detailed API docs
// Author: Mike McCauley (mikem@airspayce.com)
// Copyright (C) 2008 Mike McCauley
// $Id: receiver.pde,v 1.3 2009/03/30 00:07:24 mikem Exp $
#include <VirtualWire.h>
void setup()
{
    Serial.begin(9600); // Debugging only
    Serial.println("setup");
    // Initialise the IO and ISR
    vw_set_ptt_inverted(true); // Required for DR3100
    vw_setup(2000);      // Bits per sec
    vw_rx_start();       // Start the receiver PLL running
}
void loop()
{
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;
    if (vw_get_message(buf, &buflen)) // Non-blocking
    {
        int i;
        digitalWrite(13, true); // Flash a light to show received good message
        // Message with a good checksum received, dump it.
        Serial.print("Got: ");
        
        for (i = 0; i < buflen; i++)
        {
            Serial.print(buf[i], HEX);
            Serial.print(" ");
        }
        Serial.println("");
        digitalWrite(13, false);
    }
}

I have swapped out both transmitter and receiver, rewired each, and added straight wire antennas. The old code showed the Tx light flashing, this code does not but it does have the LED at pin 13 flashing.
How would I Serial.print the data in this line of code "vw_send((uint8_t *)msg, strlen(msg));" just to make sure it is actually being sent?
Pin 11 = transmit data and pin12 = receive data

The Led Pin 13 on the receiver never blinks, but it does output the "Setup" message to the Serial.print screen.

This line in the receiver side never passes a trus state it seems "if (vw_get_message(buf, &buflen)) // Non-blocking"
this is true for 3 different Nano's, and 3 different sets of modules two different antenna setups as well. Here is the latest picture of the setup for the VirtualWire sketches with long antennas.

I have two separate configurations on different boards, all Nano's, I have checked and rechecked wiring and code and it always seems that the receiver is not getting the message. I have no idea what to do next. On the previous sketch at least I saw the Tx light flicker, not on this one, just the pin 13 led.

Just to make sure I swapped pins12 for 11 on one and 11 for 12 on the other, not change then I reset the boards,
I have one more pair of Rf devices.
The circuit is simple Vcc, Gnd, and Data, what could go wrong? :frowning: ((

Incidentally, the LED was connected to D4 from the old setup, disregard as it does nothing in this setup

You can verify that the code works by following the advice on the VirtualWire library page.

Disconnect both the transmitter and receiver. Connect a wire from the TX pin on the transmit Arduino to the RX pin on the receiver Arduino, and connect the two Arduino grounds together. Data should flow through the wire instead of the air.

The VirtualWire library was named so because it replaces that wire.

It is very possible that you received one or more nonfunctional radio modules.

For a start, the wiring on the Transmitter module does not look correct. The Vcc lead appears to go to a pin on the the Nano. It should go to the 5v pin. I can't see perfectly, but the data pin on the end looks like it is going to Nano pin 11 RX instead of Nano pin 12 Tx.

A hand drawn schematic of your connections may be better.

I now know that the Nanos are communicating properly, next is to make sure that the Transmitter and Receiver are functioning. I will limit it to just the three wires.

Thank you cattledog. I now know that the Nanos are communicating properly, next is to make sure that the Transmitter and Receiver are functioning. I will limit it to just the three wires each
Working miswired when I exchange Nano and moved it down one pin hole

Working miswired when I exchange Nano and moved it down one pinhole, gnd and 5v were off by one pin to (res and A7).
You said the other day that you would show me how to send two bytes of data. However, since I am only using the 4 least significant bits for my direction values 1-8 can I not just write to any of the top 4 bits on or off and then determine CW or CCW by that bit? If so, I would only need one byte I think. I could just mask the received value for that bit. for instance my value would comprise bits 0 thru 3 and the rotation direction could be bit 4. unless you think two bytes of data would have a benefit.
Again, thanks for all your help and @cattledog too.

Glad you got it working!

You can store 256 different values in one byte. Divide those 8 bits up any way you like!

To put two four bit values (0-15 each) into one byte, you could for example use

byte direction = 7;
byte rotation = 1;
byte data_to_send = (rotation<<4) | direction;

To get them back out of the received byte:

byte direction = value_received & 0x0F;
byte rotation  = value_received >> 4;

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.