virtual wire and attiny85

HI All,
I have a project that has attiny85 send a string via a 433MHZ transmitter and at the moment a arduino nano picks up this with the receiver and tests the string like a password, if correct throws relay.

this all works perfect.

Im now wanting to replace the arduino nano with an attiny85 like i did with the transmitter, however there seems to be an issue, the code will no longer compile for board selected attiny85, if i change the board back it compiles fine.... weird

here is the code, I have replaced the string with # for reasons of my own choosing :slight_smile:

#include <VirtualWire.h>

void setup(){    
digitalWrite(3,HIGH); 
vw_set_ptt_inverted(true); // Required for DR3100 
vw_setup(2000);      // Bits per sec
vw_set_rx_pin(2);
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;        
String abc;
for (i = 0; i < buflen; i++)        
{            
abc += buf[i];
abc += " ";
 
}        

if (abc == "## ## ## ##"){
    digitalWrite(3,LOW);
}
   
}}

in the original code if had just if (abc = "## ## ## ##") but changed to == as the compiler did not like it when attiny85 was selected, this leads me to think its an issue with this line but i can not find out what.

please help

also the error i get is

c:/program files (x86)/arduino/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/../../../../avr/lib/avr25/crttn85.o:(.init9+0x2): relocation truncated to fit: R_AVR_13_PCREL against symbol `exit' defined in .fini9 section in c:/program files (x86)/arduino/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/avr25\libgcc.a(_exit.o)

google had no luck helping

A few problems:

  1. "Relocation truncated to fit" usually means you're using too much memory.
  2. Make sure you're using the latest version of the VirtualWire library (at least 1.14+)
  3. Move the "buf" definition out of the loop function and make it static.
  4. While you're at it, make it smaller than 80 characters (VW_MAX_MESSAGE_LEN)
  5. Get rid of the "String abc" variable
  6. Use memcmp or strcmp instead.

That should probably get you there...

Something like this maybe:

#include <VirtualWire.h>

#define PIN_RX          2
#define PIN_RELAY       3
#define BUFFER_LENGTH  15

static uint8_t buf[BUFFER_LENGTH];    
static uint8_t buflen;

static const char SECRET_CODE[] = "## ## ## ##";

void setup()
{
    digitalWrite(PIN_RELAY, HIGH); 
    vw_set_ptt_inverted(true); // Required for DR3100 
    vw_setup(2000);      // Bits per sec
    vw_set_rx_pin(PIN_RX);
    vw_rx_start();       // Start the receiver PLL running
}

void loop()
{
    buflen = BUFFER_LENGTH;
    if (vw_get_message(buf, &buflen)) // Non-blocking    
    {
        if (buflen >= sizeof(SECRET_CODE) && memcmp(SECRET_CODE, buf, sizeof(SECRET_CODE)) == 0)
        {
            digitalWrite(PIN_RELAY, LOW);
        }
    }
}

Hi thank you sooooo much for your reply,

I was about to ask how you ment then you replied again. The code you supplied complies perfect and is about half the size!

thank you so very much, very very much

I will let you know how it goes :slight_smile:

I made a quick update in the code above:
BUFFER_LENGTH should be 15, not 10 since your passcode is longer than 10 characters.

Hi,
I have tried the code and its not working, i think the issue lies in the secret code part.
this is what i have including the real message as received by my original code

#include <VirtualWire.h>

#define PIN_RX          2
#define PIN_RELAY       3
#define BUFFER_LENGTH  30

static uint8_t buf[BUFFER_LENGTH];    
static uint8_t buflen;

static const char SECRET_CODE[] = "66 101 110 115 111 110 49 52";

void setup()
{
    digitalWrite(PIN_RELAY, HIGH); 
    vw_set_ptt_inverted(true); // Required for DR3100 
    vw_setup(2000);      // Bits per sec
    vw_set_rx_pin(PIN_RX);
    vw_rx_start();       // Start the receiver PLL running
}

void loop()
{
    buflen = BUFFER_LENGTH;
    if (vw_get_message(buf, &buflen)) // Non-blocking    
    {
        if (buflen >= sizeof(SECRET_CODE) && memcmp(SECRET_CODE, buf, sizeof(SECRET_CODE)) == 0)
        {
            digitalWrite(PIN_RELAY, LOW);
        }
    }
}

I have tried also removing the space from the secret code as last time i added them in myself and still didnt work, i also tried putting the raw text and that didnt work :frowning:

seeing as attiny has no serial its impossible for me to see what its getting as data, any ideas?

bensonsearch:
I have tried also removing the space from the secret code as last time i added them in myself and still didnt work, i also tried putting the raw text and that didnt work :frowning:

Share the code that is sending the message...

seeing as attiny has no serial its impossible for me to see what its getting as data, any ideas?

I'd do two thinks:

  1. Hook up an LED and test the standard "Blink" example. Make sure the LED blinks on/off at the correct interval. The ATTiny85 fuses may be set wrong and your timing might be off.

  2. Leave the LED hooked up and make it blink once for "message received" and blink twice for "passcode correct"

Thanx for your help.

I have since modyfied the code to blink LED on pin 4 when it gets a message, when it receives it blinks. so I know its receiving a message.

Code now

#include <VirtualWire.h>

#define PIN_RX          2
#define PIN_RELAY       3
#define BUFFER_LENGTH  30

static uint8_t buf[BUFFER_LENGTH];    
static uint8_t buflen;

static const char SECRET_CODE[] = "661011101151111104952";

void setup()
{
    digitalWrite(PIN_RELAY, HIGH); 
    vw_set_ptt_inverted(true); // Required for DR3100 
    vw_setup(2000);      // Bits per sec
    vw_set_rx_pin(PIN_RX);
    vw_rx_start();       // Start the receiver PLL running
}

void loop()
{
    buflen = BUFFER_LENGTH;
    if (vw_get_message(buf, &buflen)) // Non-blocking    
    {
      digitalWrite(4,HIGH);
        if (buflen >= sizeof(SECRET_CODE) && memcmp(SECRET_CODE, buf, sizeof(SECRET_CODE)) == 0)
        
        {
            digitalWrite(PIN_RELAY, LOW);
        }
    }digitalWrite(4,LOW);
}

This is the code to send, this also includes the real password being sent.

#include <VirtualWire.h>

void setup(){    
vw_set_ptt_inverted(true); // Required for DR3100    
vw_setup(2000);      // Bits per sec
vw_set_tx_pin(2);  
}
void loop(){    
const char *msg = "Benson14";  
vw_send((uint8_t *)msg, strlen(msg));   
vw_wait_tx(); // Wait until the whole message is gone 
}

I really dont get it but hopefully you can help :slight_smile:

Change this line to:

static const char SECRET_CODE[] = "Benson14";

int2str:
Change this line to:

static const char SECRET_CODE[] = "Benson14";

I have unfortunately tried this as well with no success :frowning:

when i had my original code the message Benson14 came out with the numbers: 66 101 110 115 111 110 49 52, each group being the individual characters.

I have tried as above and Benson14 and removing the blanks from the above :frowning: i wish i could see what the attiny was receiving

again thanx for all your help

If you google the error message you will find a number of people have had the same problem. This error message means that you have exceeded the program size limit (4 Kbyte). There is a patch for the AVR GCC linker that allows you to use the full 8K byte program size.

You can find a link to the patch on the Cosa install page: Cosa: Installing Cosa

Here is the direct link to the patch: ATTinyCore/PCREL Patch for GCC at master · TCWORLD/ATTinyCore · GitHub

Please note that the above helps with your initial error message (only ;-).

If you are interested there is a Cosa version of Virtual Wire that is fully OOP and allows several configurations. It works on all of the boards that Cosa supports. Ranging from Tiny to Mega and Mighty.

Cheers!

bensonsearch:
also the error i get is

c:/program files (x86)/arduino/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/../../../../avr/lib/avr25/crttn85.o:(.init9+0x2): relocation truncated to fit: R_AVR_13_PCREL against symbol `exit' defined in .fini9 section in c:/program files (x86)/arduino/hardware/tools/avr/bin/../lib/gcc/avr/4.3.2/avr25\libgcc.a(_exit.o)

That's a bug in the linker. Download the latest version of winavr and copy the binary files (in folder 'bin') into your Arduino installation.

i wish i could see what the attiny was receiving

If you use this core

http://code.google.com/p/arduino-tiny/
You can use Serial.print() with the t85
The Output pin will be PB3, and you will need a Serial/USB converter

More on this subject:

http://www.ernstc.dk/arduino/tinycom.html

You could have the LED blink the message it receives in binary or Morse Code or some other pattern so you could tell what it's receiving.

I would start by having it blink the number of characters it received. I suspect a missing null terminator or something similar.

TanHadron:
You could have the LED blink the message it receives in binary or Morse Code or some other pattern so you could tell what it's receiving.

I would start by having it blink the number of characters it received. I suspect a missing null terminator or something similar.

Yep. I do stuff like this all the time.

WS2811 LED strings are good for debugging - you can output a lot of information in binary on 5m of LEDs :slight_smile:

Thank you all for the information, Blinking a message ha, that to me seems hard as i dont know morse code and binary hmmm lol

its still not working and i have no more variations of the password to try so i may need to experiment with some other way :frowning:

i dont really know much about all this but would the compare between uint8_t and char array have anything to do with it? also the fact its static, i assume when we receive a mesage the static variable changes to the message right?

It's possible that your problem is here:

        if (buflen >= sizeof(SECRET_CODE)

The way I calculate it, when the password is "Benson14", sizeof(SECRET_CODE) is 9. The actual message is only 8 characters long. if buflen doesn't include the null terminator, 8 won't be >- 9, and the test will fail. Maybe you should use strlen(SECRET_CODE) or hard code an 8 in there and see if that works.

bensonsearch:
i dont know morse code and binary

Well, there's your problem...

(Morse code I can excuse, but binary? All programmers should be able to read binary.)

i dont know morse code and binary

That's why I recommended using the serial monitor and Serial.print(), like you are used to from the Arduino

Well, that's just a detail. There are ways to get around any of those issues.

  1. Blink it in binary or Morse Code, take a video, and post it where someone who DOES know them can interpret.

  2. Blink the raw numbers, with pauses in between. First, blink the buflen. Then blink out each of the letters in the msg. So what if it takes 110 blinks to blink an 'n'? At least it's SOMETHING.

Trying to debug a problem by staring at the code is sometimes just not going to work. If you can somehow get the machine to tell you what's actually going on in there, you can figure out what's actually wrong, instead of guessing.