Virtual Wire library substitute for AVR

Go To Last Post
36 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is there any library available that can be used with avr like ATmega32, ATmega8 etc. like the Virtual Wire library (which can be used only with arduino).

I want to use it for transferring data through 433 Mhz tx and rx.

I like C.

-Thank You

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Depends on your C compiler but Fleury has excellent I2C/TWI library code for avr-gcc.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I2C/TWI is a two wire interface but I need one wire interface to use my RF 433 Mhz Tx and Rx

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you sure (I very quickly looked at it : there were no obvious dependencies on Arduino's specificities) Virtula Wire is designed **only** for Arduini (and MSP430 arduino)can be used only with arduino?: there is a unique (700 lines, some -50%- being conditional) *.cpp file and a unique include file ) : maybe, for a given processor, you might port it..
Virtual Wire for radio is zero (except for testing) wires?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I2C/TWI is a two wire interface but I need one wire interface to use my RF 433 Mhz Tx and Rx

My bad I thought you meant :oops:

Just out of interest then, if it's really this you are talking about:

http://www.pjrc.com/teensy/td_li...

what stops you taking that source (or at least the algorithm) to a non-Arduino environment?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That will be a very big job for me, any other help will be appreciated. Anyway thanks clawson :-)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

That will be a very big job for me

Have a look at the code. It might not be as scary as you might think. It's 600 lines, but heavily commented. So perhaps 300 actual lines of C. Even less when you have thrown out the ARM/Teensy blocks of code.

If the web page is correct, then there are 14 functions to port.

Not that much.

I can't see any C++-specific construct. Have you tried to feed the source file to your C compiler? Might be a pleasant surprise..

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yeah! I have tried that, it's not working because the DigitalWrite function is only for Arduino, I don,t know what else.

OK, I will try my best.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But the digitalWrite function interface is really trivial!

If you look at the innards of it in the Arduino sources, THAT is more complicated. But you do not need to bother with that.

I suppose you will have the VirtualWire code working on a specific port and pin in your app? If so, you "only" need to replace the calls to digitalWrite with standard C manipulation of the port/pin.

There are a total of seven (7) calls to digitalWrite in the VirtualWire source.

I'm not saying that this is done in 15 minutes. But if you take one problem at a time, look at ti, perhaps implement a small test-bench to try out individual problem solutions, dry-run them in the Simulator etc - then you will eventually get to a solution.

Climbing a mountain is done by taking one step after the other.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The latest version is here.

He based his code pretty heavily on the reference code available in an appendix of this PDF. Code is in assembler for AT89C2051, but this document is an important read in understanding the fundamentals. As @clawson said, the Arduino library is pretty well documented, but some concepts are left unexplained.

Funny to see this topic popping up now. I've just finished the first pass at an implementation of the same protocol from the ground up for use in an ATtiny85 project. Not ready for prime time yet, but it is working. It wasn't that difficult to do.

Honestly, the only things in your way are pinMode(), digitalRead(), digitalWrite(), and a timing function like millis(). The first three are dead easy. If you don't know about direct port manipulation via DDRn, PINn, and PORTn, there are plenty of tutorials. Timing isn't even required if you omit vw_wait_rx_max().

JJ

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

VirtualWire is made for Atmega85 also but I don't have one, I am using Atmega8 and Atmega32.
The three functions that you stated joeymorin is really easy, but I am a bit confused at the _timer_calc(speed, (uint8_t)-1, &nticks) function.

https://github.com/digistump/Dig...
this site is using it
https://github.com/m0/Updated-Ar...
but this is not.

Why is it? What it actually does?

Thank You

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
What it actually does?

Let's start with the comment in the source, and then you can tell us where you get lost. OK?

Quote:
// Common function for setting timer ticks @ prescaler values for speed
// Returns prescaler index into {0, 0, 3, 6, 8, 10, 12} array
// and sets nticks to compare-match value if lower than max_ticks
// returns 0 & nticks = 0 on fault

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JimutD wrote:
VirtualWire is made for Atmega85 also but I don't have one, I am using Atmega8 and Atmega32
ATtiny85. There is no ATmega85.

And yes, recent versions of VirtualWire for Arduino support it, but that's not what I meant when I said I implemented it for the '85. I did not implement it for Arduino. I wrote my own implementation of the Virtual Wire protocol that was developed by RFM, and it can be used with any AVR. I just first used it on an '85. This is the same protocol on which Mike McCauley based his Arduino library.

Quote:
I am a bit confused at the _timer_calc(speed, (uint8_t)-1, &nticks) function.

https://github.com/digistump/Dig...
this site is using it
https://github.com/m0/Updated-Ar...
but this is not.

The first link is to version 1.14 (although it says 1.9, the author hasn't been good about updating the version string in his source code), by which point support for multiple devices had been added. The timing configuration was abstracted into a few different pieces as a result, with conditional compilation based on device.

The second link is from version 1.4 which didn't have support for as many devices. The timing configuration is more straightforward and is done entirely within vw_setup().

The result is the same in each case, so examine the source at the second link, it's probably easier to understand.

Let's get rid of the conditional compilation statement, and look at the code just for the 168/328:

// Speed is in bits per sec RF rate
void vw_setup(uint16_t speed)
{
    // Calculate the OCR1A overflow count based on the required bit speed
    // and CPU clock rate
    uint16_t ocr1a = (F_CPU / 8UL) / speed;

    // Set up timer1 for a tick every 62.50 microseconds
    // for 2000 bits per sec
    TCCR1A = 0;
    TCCR1B = _BV(WGM12) | _BV(CS10);
    // Caution: special procedures for setting 16 bit regs
    OCR1A = ocr1a;
    // Enable interrupt
    TIMSK1 |= _BV(OCIE1A);

    // Set up digital IO pins
    pinMode(vw_tx_pin, OUTPUT);
    pinMode(vw_rx_pin, INPUT);
    pinMode(vw_ptt_pin, OUTPUT);
    digitalWrite(vw_ptt_pin, vw_ptt_inverted);
}

Should be a lot easier to see the forest.

You can see that the timer is configured to roll over and trigger an interrupt at 8 times the baud rate. In version 1.14 and later, _timer_calc() is used to handle different devices that have 8-bit timers with different prescaler capabilities.

Since both devices you're trying to write for (the mega8 and mega32) have 16-bit timers, it might be better to just modify an earlier version like 1.4 to get what you need.

The author used to have links to all the previous versions. You can still get them, but you have to manually specify the link in your browser. Versions range from 1.0 through 1.20. Simply compose the correct link based on http://www.airspayce.com/mikem/a... where 'x' completes the version you're interested in.

A version history is available at the end of the main page.

JJ

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have modified the code to this but it is still not working it is compiling but it is not transmitting anything, I just connected an LED to the transmitting pin and never seen it blinking.

// VirtualWire.c
//
// Virtual Wire implementation for Arduino
// See the README file in this directory fdor documentation
//
// Changes:
// 2008-05-25: fixed a bug that could prevent messages with certain
//  bytes sequences being received (false message start detected)
//
// Author: Mike McCauley (mikem@open.com.au)
// Copyright (C) 2008 Mike McCauley
// $Id: VirtualWire.cpp,v 1.4 2009/03/31 20:49:41 mikem Exp mikem $

// Maximum number of bytes in a message, counting the byte count and FCS
#define VW_MAX_MESSAGE_LEN 30

// The maximum payload length
#define VW_MAX_PAYLOAD VW_MAX_MESSAGE_LEN-3

// The size of the receiver ramp. Ramp wraps modulu this number
#define VW_RX_RAMP_LEN 160

// Number of samples per bit
#define VW_RX_SAMPLES_PER_BIT 8

// Ramp adjustment parameters
// Standard is if a transition occurs before VW_RAMP_TRANSITION (80) in the ramp,
// the ramp is retarded by adding VW_RAMP_INC_RETARD (11)
// else by adding VW_RAMP_INC_ADVANCE (29)
// If there is no transition it is adjusted by VW_RAMP_INC (20)
#define VW_RAMP_INC (VW_RX_RAMP_LEN/VW_RX_SAMPLES_PER_BIT)
#define VW_RAMP_TRANSITION VW_RX_RAMP_LEN/2
#define VW_RAMP_ADJUST 9
#define VW_RAMP_INC_RETARD (VW_RAMP_INC-VW_RAMP_ADJUST)
#define VW_RAMP_INC_ADVANCE (VW_RAMP_INC+VW_RAMP_ADJUST)

// Outgoing message bits grouped as 6-bit words
// 36 alternating 1/0 bits, followed by 12 bits of start symbol
// Followed immediately by the 4-6 bit encoded byte count, 
// message buffer and 2 byte FCS
// Each byte from the byte count on is translated into 2x6-bit words
// Caution, each symbol is transmitted LSBit first, 
// but each byte is transmitted high nybble first
#define VW_HEADER_LEN 8

#define INPUT 0
#define OUTPUT 1

#define true 1
#define false 0



static uint8_t vw_tx_buf[(VW_MAX_MESSAGE_LEN * 2) + VW_HEADER_LEN] 
     = {0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x38, 0x2c};

// Number of symbols in vw_tx_buf to be sent;
static uint8_t vw_tx_len = 0;

// Index of the next symbol to send. Ranges from 0 to vw_tx_len
static uint8_t vw_tx_index = 0;

// Bit number of next bit to send
static uint8_t vw_tx_bit = 0;

// Sample number for the transmitter. Runs 0 to 7 during one bit interval
static uint8_t vw_tx_sample = 0;

// Flag to indicated the transmitter is active
static volatile uint8_t vw_tx_enabled = 0;

// Total number of messages sent
static uint16_t vw_tx_msg_count = 0;

// The digital IO pin number of the press to talk, enables the transmitter hardware
static uint8_t vw_ptt_pin = 10;
static uint8_t vw_ptt_inverted = 0;

// The digital IO pin number of the receiver data
static uint8_t vw_rx_pin = 11;

// The digital IO pin number of the transmitter data
static uint8_t vw_tx_pin = 12;

// Current receiver sample
static uint8_t vw_rx_sample = 0;

// Last receiver sample
static uint8_t vw_rx_last_sample = 0;

// PLL ramp, varies between 0 and VW_RX_RAMP_LEN-1 (159) over 
// VW_RX_SAMPLES_PER_BIT (8) samples per nominal bit time. 
// When the PLL is synchronised, bit transitions happen at about the
// 0 mark. 
static uint8_t vw_rx_pll_ramp = 0;

// This is the integrate and dump integral. If there are <5 0 samples in the PLL cycle
// the bit is declared a 0, else a 1
static uint8_t vw_rx_integrator = 0;

// Flag indictate if we have seen the start symbol of a new message and are
// in the processes of reading and decoding it
static uint8_t vw_rx_active = 0;

// Flag to indicate that a new message is available
static volatile uint8_t vw_rx_done = 0;

// Flag to indicate the receiver PLL is to run
static uint8_t vw_rx_enabled = 0;

// Last 12 bits received, so we can look for the start symbol
static uint16_t vw_rx_bits = 0;

// How many bits of message we have received. Ranges from 0 to 12
static uint8_t vw_rx_bit_count = 0;

// The incoming message buffer
static uint8_t vw_rx_buf[VW_MAX_MESSAGE_LEN];

// The incoming message expected length
static uint8_t vw_rx_count = 0;

// The incoming message buffer length received so far
static volatile uint8_t vw_rx_len = 0;

// Number of bad messages received and dropped due to bad lengths
static uint8_t vw_rx_bad = 0;

// Number of good messages received
static uint8_t vw_rx_good = 0;


void pinMode(int pin, int status)
{
	if (pin == 11)
	{
		DDRD |= 0<<2;
		//PORTD |= 1<<2;
	}
	if (pin == 12)
	{
		DDRB |= 1<<1;
		PORTB |= 1<<1;
	}
	else;
}

void digitalWrite(int pin, int status)
{
	if (pin == 11 && status == 1)
	{
		PORTD = 1<<2;
	}
	if (pin == 11 && status == 0)
	{
		PORTD = 0<<2;
	}
	
	if (pin == 12 && status == 1)
	{
		PORTB |= 1<<1;
	}
	if (pin == 12 && status == 0)
	{
		PORTB |= 0<<1;
	}
	else;
}

int digitalRead(int pin)
{
	if (pin == 11)
	{
		if(bit_is_set(PORTD,2)) return 1;
		if(bit_is_clear(PORTD,2)) return 0;
	}
	if (pin == 12)
	{
		if(bit_is_set(PORTB,1)) return 1;
		if(bit_is_clear(PORTB,1)) return 0;
	}
	else return -2;
}


// 4 bit to 6 bit symbol converter table
// Used to convert the high and low nybbles of the transmitted data
// into 6 bit symbols for transmission. Each 6-bit symbol has 3 1s and 3 0s 
// with at most 2 consecutive identical bits
static uint8_t symbols[] =
{
    0xd,  0xe,  0x13, 0x15, 0x16, 0x19, 0x1a, 0x1c, 
    0x23, 0x25, 0x26, 0x29, 0x2a, 0x2c, 0x32, 0x34
};

// Compute CRC over count bytes.
// This should only be ever called at user level, not interrupt level
uint16_t vw_crc(uint8_t *ptr, uint8_t count)
{
    uint16_t crc = 0xffff;

    while (count-- > 0) 
  crc = _crc_ccitt_update(crc, *ptr++);
    return crc;
}

// Convert a 6 bit encoded symbol into its 4 bit decoded equivalent
uint8_t vw_symbol_6to4(uint8_t symbol)
{
    uint8_t i;
    
    // Linear search :-( Could have a 64 byte reverse lookup table?
    for (i = 0; i < 16; i++)
  if (symbol == symbols[i]) return i;
    return 0; // Not found
}

// Set the output pin number for transmitter data
void vw_set_tx_pin(uint8_t pin)
{
    vw_tx_pin = pin;
}

// Set the pin number for input receiver data
void vw_set_rx_pin(uint8_t pin)
{
    vw_rx_pin = pin;
}

// Set the output pin number for transmitter PTT enable
void vw_set_ptt_pin(uint8_t pin)
{
    vw_ptt_pin = pin;
}

// Set the ptt pin inverted (low to transmit)
void vw_set_ptt_inverted(uint8_t inverted)
{
    vw_ptt_inverted = inverted;
}

// Called 8 times per bit period
// Phase locked loop tries to synchronise with the transmitter so that bit 
// transitions occur at about the time vw_rx_pll_ramp is 0;
// Then the average is computed over each bit period to deduce the bit value
void vw_pll()
{
    // Integrate each sample
    if (vw_rx_sample)
	vw_rx_integrator++;

    if (vw_rx_sample != vw_rx_last_sample)
    {
	// Transition, advance if ramp > 80, retard if < 80
	vw_rx_pll_ramp += ((vw_rx_pll_ramp < VW_RAMP_TRANSITION) 
			   ? VW_RAMP_INC_RETARD 
			   : VW_RAMP_INC_ADVANCE);
	vw_rx_last_sample = vw_rx_sample;
    }
    else
    {
	// No transition
	// Advance ramp by standard 20 (== 160/8 samples)
	vw_rx_pll_ramp += VW_RAMP_INC;
    }
    if (vw_rx_pll_ramp >= VW_RX_RAMP_LEN)
    {
	// Add this to the 12th bit of vw_rx_bits, LSB first
	// The last 12 bits are kept
	vw_rx_bits >>= 1;

	// Check the integrator to see how many samples in this cycle were high.
	// If < 5 out of 8, then its declared a 0 bit, else a 1;
	if (vw_rx_integrator >= 5)
	    vw_rx_bits |= 0x800;

	vw_rx_pll_ramp -= VW_RX_RAMP_LEN;
	vw_rx_integrator = 0; // Clear the integral for the next cycle

	if (vw_rx_active)
	{
	    // We have the start symbol and now we are collecting message bits,
	    // 6 per symbol, each which has to be decoded to 4 bits
	    if (++vw_rx_bit_count >= 12)
	    {
		// Have 12 bits of encoded message == 1 byte encoded
		// Decode as 2 lots of 6 bits into 2 lots of 4 bits
		// The 6 lsbits are the high nybble
		uint8_t this_byte = 
		    (vw_symbol_6to4(vw_rx_bits & 0x3f)) << 4 
		    | vw_symbol_6to4(vw_rx_bits >> 6);

		// The first decoded byte is the byte count of the following message
		// the count includes the byte count and the 2 trailing FCS bytes
		// REVISIT: may also include the ACK flag at 0x40
		if (vw_rx_len == 0)
		{
		    // The first byte is the byte count
		    // Check it for sensibility. It cant be less than 4, since it
		    // includes the bytes count itself and the 2 byte FCS
		    vw_rx_count = this_byte;
		    if (vw_rx_count < 4 || vw_rx_count > VW_MAX_MESSAGE_LEN)
		    {
			// Stupid message length, drop the whole thing
			vw_rx_active = false;
			vw_rx_bad++;
                        return;
		    }
		}
		vw_rx_buf[vw_rx_len++] = this_byte;

		if (vw_rx_len >= vw_rx_count)
		{
		    // Got all the bytes now
		    vw_rx_active = false;
		    vw_rx_good++;
		    vw_rx_done = true; // Better come get it before the next one starts
		}
		vw_rx_bit_count = 0;
	    }
	}
	// Not in a message, see if we have a start symbol
	else if (vw_rx_bits == 0xb38)
	{
	    // Have start symbol, start collecting message
	    vw_rx_active = true;
	    vw_rx_bit_count = 0;
	    vw_rx_len = 0;
	    vw_rx_done = false; // Too bad if you missed the last message
	}
    }
}

// Speed is in bits per sec RF rate
void vw_setup(uint16_t speed)
{
    // Calculate the OCR1A overflow count based on the required bit speed
    // and CPU clock rate
    uint16_t ocr1a = (F_CPU / 8UL) / speed;

//#ifndef TEST
    // Set up timer1 for a tick every 62.50 microseconds 
    // for 2000 bits per sec
    TCCR1A = 0;
    TCCR1B = _BV(WGM12) | _BV(CS10);
    // Caution: special procedures for setting 16 bit regs
    OCR1A = ocr1a;
    // Enable interrupt
//#ifdef TIMSK1
    // atmega168
    //TIMSK1 |= _BV(OCIE1A);
//#else
    // others
    TIMSK |= _BV(OCIE1A);
//#endif

    // Set up digital IO pins
    pinMode(vw_tx_pin, OUTPUT);
    pinMode(vw_rx_pin, INPUT);
    pinMode(vw_ptt_pin, OUTPUT);
    digitalWrite(vw_ptt_pin, vw_ptt_inverted);
}

// Start the transmitter, call when the tx buffer is ready to go and vw_tx_len is
// set to the total number of symbols to send
void vw_tx_start()
{
    vw_tx_index = 0;
    vw_tx_bit = 0;
    vw_tx_sample = 0;

    // Disable the receiver PLL
    vw_rx_enabled = false;

    // Enable the transmitter hardware
    digitalWrite(vw_ptt_pin, true ^ vw_ptt_inverted);

    // Next tick interrupt will send the first bit
    vw_tx_enabled = true;
}

// Stop the transmitter, call when all bits are sent
void vw_tx_stop()
{
    // Disable the transmitter hardware
    digitalWrite(vw_ptt_pin, false ^ vw_ptt_inverted);
    digitalWrite(vw_tx_pin, false);

    // No more ticks for the transmitter
    vw_tx_enabled = false;

    // Enable the receiver PLL
    vw_rx_enabled = true;
}

// Enable the receiver. When a message becomes available, vw_rx_done flag
// is set, and vw_wait_rx() will return.
void vw_rx_start()
{
    if (!vw_rx_enabled)
    {
	vw_rx_enabled = true;
	vw_rx_active = false; // Never restart a partial message
    }
}

// Disable the receiver
void vw_rx_stop()
{
    vw_rx_enabled = false;
}

// Return true if the transmitter is active
uint8_t vx_tx_active()
{
    return vw_tx_enabled;
}

// 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)
	;
}

// Wait at most max milliseconds for the receiver to receive a message
// Return the truth of whether there is a message
uint8_t vw_wait_rx_max(unsigned long milliseconds)
{
    unsigned long start = millis();

    while (!vw_rx_done && ((millis() - start) < milliseconds))
	;
    return vw_rx_done;
}

// Wait until transmitter is available and encode and queue the message
// into vw_tx_buf
// The message is raw bytes, with no packet structure imposed
// It is transmitted preceded a byte count and followed by 2 FCS bytes
uint8_t vw_send(uint8_t* buf, uint8_t len)
{
    uint8_t i;
    uint8_t index = 0;
    uint16_t crc = 0xffff;
    uint8_t *p = vw_tx_buf + VW_HEADER_LEN; // start of the message area
    uint8_t count = len + 3; // Added byte count and FCS to get total number of bytes

    if (len > VW_MAX_PAYLOAD)
	return false;

    // Wait for transmitter to become available
    vw_wait_tx();

    // Encode the message length
    crc = _crc_ccitt_update(crc, count);
    p[index++] = symbols[count >> 4];
    p[index++] = symbols[count & 0xf];

    // Encode the message into 6 bit symbols. Each byte is converted into 
    // 2 6-bit symbols, high nybble first, low nybble second
    for (i = 0; i < len; i++)
    {
	crc = _crc_ccitt_update(crc, buf[i]);
	p[index++] = symbols[buf[i] >> 4];
	p[index++] = symbols[buf[i] & 0xf];
    }

    // Append the fcs, 16 bits before encoding (4 6-bit symbols after encoding)
    // Caution: VW expects the _ones_complement_ of the CCITT CRC-16 as the FCS
    // VW sends FCS as low byte then hi byte
    crc = ~crc;
    p[index++] = symbols[(crc >> 4)  & 0xf];
    p[index++] = symbols[crc & 0xf];
    p[index++] = symbols[(crc >> 12) & 0xf];
    p[index++] = symbols[(crc >> 8)  & 0xf];

    // Total number of 6-bit symbols to send
    vw_tx_len = index + VW_HEADER_LEN;

    // Start the low level interrupt handler sending symbols
    vw_tx_start();

    return true;
}

// This is the interrupt service routine called when timer1 overflows
// Its job is to output the next bit from the transmitter (every 8 calls)
// and to call the PLL code if the receiver is enabled
//ISR(SIG_OUTPUT_COMPARE1A)
//SIGNAL(TIMER1_COMPA_vect)
ISR(TIMER1_COMPA_vect)
{
    vw_rx_sample = digitalRead(vw_rx_pin);

    // Do transmitter stuff first to reduce transmitter bit jitter due 
    // to variable receiver processing
    if (vw_tx_enabled && vw_tx_sample++ == 0)
    {
        // Send next bit
	// Symbols are sent LSB first
        // Finished sending the whole message? (after waiting one bit period 
	// since the last bit)
        if (vw_tx_index >= vw_tx_len)
	{
	    vw_tx_stop();
	    vw_tx_msg_count++;
	}
        else
        {
	    digitalWrite(vw_tx_pin, vw_tx_buf[vw_tx_index] & (1 << vw_tx_bit++));
	    if (vw_tx_bit >= 6)
	    {
	        vw_tx_bit = 0;
                vw_tx_index++;
	    }
        }
    }
    if (vw_tx_sample > 7)
	vw_tx_sample = 0;

    if (vw_rx_enabled)
	vw_pll();
}

// Return true if there is a message available
uint8_t vw_have_message()
{
    return vw_rx_done;
}

// Get the last message received (without byte count or FCS)
// Copy at most *len bytes, set *len to the actual number copied
// Return true if there is a message and the FCS is OK
uint8_t vw_get_message(uint8_t* buf, uint8_t* len)
{
    uint8_t rxlen;

    // Message available?
    if (!vw_rx_done)
	return false;

    // Wait until vw_rx_done is set before reading vw_rx_len
    // then remove bytecount and FCS
    rxlen = vw_rx_len - 3;

    // Copy message (good or bad)
    if (*len > rxlen)
	*len = rxlen;
    memcpy(buf, vw_rx_buf + 1, *len);

    vw_rx_done = false; // OK, got that message thanks

    // Check the FCS, return goodness
    return (vw_crc(vw_rx_buf, vw_rx_len) == 0xf0b8); // FCS OK?
}

and this is the header file

// VirtualWire.h
//
// Virtual Wire implementation for Arduino
// See the README file in this directory fdor documentation
// 
// Author: Mike McCauley (mikem@open.com.au)
// Copyright (C) 2008 Mike McCauley
// $Id: VirtualWire.h,v 1.3 2009/03/30 00:07:24 mikem Exp $



#include 
#include 
#include 
#include "VirtualWire.c"
/*#if ARDUINO < 100
#include 
#else
#include 
#endif*/

// These defs cause trouble on some versions of Arduino
#undef abs
#undef double
#undef round


// Cant really do this as a real C++ class, since we need to have 
// an ISR

    // Set the digital IO pin to be for transmit data
    // Defaults to 12
    void vw_set_tx_pin(uint8_t pin);

    // Set the digital IO pin to be for receive data
    // Defaults to 11
    void vw_set_rx_pin(uint8_t pin);

    // Set the digital IO pin to enable the transmitter (press to talk)
    // Defaults to 10
    void vw_set_ptt_pin(uint8_t pin);

    // By default the PTT pin goes high when the transmitter is enabled.
    // This flag forces it low when the transmitter is enabled.
    void vw_set_ptt_inverted(uint8_t inverted);

    // Initialise the VirtualWire software, to operate at speed bits per second
    // Call this one in your setup() after any vw_set_* calls
    // Must call vw_rx_start() before you will get any messages
    void vw_setup(uint16_t speed);

    // Start the Phase Locked Loop listening to the receiver
    // Must do this before you can receive any messages
    // When a message is available (good checksum or not), vw_have_message();
    // will return true.
    void vw_rx_start();

    // Stop the Phase Locked Loop listening to the receiver
    // No messages will be received until vw_rx_start() is called again
    // Saves interrupt processing cycles
    void vw_rx_stop();

    // Return true if the transmitter is active
    uint8_t vx_tx_active();

    // Block until the transmitter is idle
    void vw_wait_tx();

    // Block until a message is available
    void vw_wait_rx();
    // or for a max time
    uint8_t vw_wait_rx_max(unsigned long milliseconds);

    // Send a message with the given length. Returns almost immediately,
    // and message will be sent at the right timing by interrupts
    // Returns true if the message was accepted for transmissions
    // Returns false if the message is too long (>VW_MAX_MESSAGE_LEN - 3)
    uint8_t vw_send(uint8_t* buf, uint8_t len);

    // Returns true if an unread message is available
    uint8_t vw_have_message();

    // If a message is available (good checksum or not), copies
    // up to *len octets to buf.
    // Returns true if there was a message and the checksum was good
    uint8_t vw_get_message(uint8_t* buf, uint8_t* len);
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

These:

    DDRD |= 0<<2;
.
.
.
    PORTD = 0<<2;
.
.
.
    PORTB |= 0<<1;

... do nothing. Shifting 0 by any amount is still zero.

Your implementation of pinMode() and friends won't work. It looks like you're just implementing them for the default VirtualWire RX and TX pins, and mapping them to your own choices for ports/pins, which I assume are PD2 for RX and PB1 for TX...? This is going to be hard to maintain. Why not look at the Arduino source? Start with wiring_digital.c.

For this very specific case, this should work:

void pinMode(int pin, int mode) {
  switch (pin) {
    case 11:
      if (mode) {
        DDRD |= (1<<PD2);
      }
      else {
        DDRD &= ~(1<<PD2);
      }
      break;
    case 12:
      if (mode) {
        DDRB |= (1<<PB1);
      }
      else {
        DDRB &= ~(1<<PB1);
      }
      break;
  }
}

void digitalWrite(int pin, int level) {
  switch (pin) {
    case 11:
      if (level) {
        PORTD = (1<<PD2);
      }
      else {
        PORTD = ~(1<<PD2);
      }
      break;
    case 12:
      if (level) {
        PORTB = (1<<PB1);
      }
      else {
        PORTB = ~(1<<PB1);
      }
      break;
  }
}

int digitalRead(int pin) {
  switch (pin) {
    case 11:
      return !!(PIND & (1<<PD2));
      break;
    case 12:
      return !!(PINB & (1<<PB1));
      break;
  }
}

Untested, and bear in mind that this is not a general-purpose solution.

Arduino have come up with their own routines to map their pin numbering onto the ports and bits of the AVR. There is no need for you to adhere to that. I sometimes use macros similar to these:

// Required by macros below
#define concatenate(a, b) __concatenate(a, b)
#define __concatenate(a, b) a ## b

// Similar to Arduino's digitalWrite() function
#define write_port(port, bit, val)                                            \
  do { if (val) { concatenate(PORT, port) |=  (1<<bit); }                     \
       else     { concatenate(PORT, port) &= ~(1<<bit); } } while(0)

// Similar to Arduino's pinMode() function
#define write_ddr(port, bit, val)                                             \
  do { if (val) { concatenate(DDR, port) |=  (1<<bit); }                      \
       else     { concatenate(DDR, port) &= ~(1<<bit); } } while(0)

// Similar to Arduino's digitalRead() function
#define read_pin(port, bit) !!(concatenate(PIN, port) & (1<<bit))

You use them like this:

// Set PD2 as an input
write_ddr(D, 2, 0);

// Set PB1 as an output
write_ddr(B, 1, 1);

// Read input PD2 and place it into variable foo
foo = read_pin(D, 2);

// Write 0 to output pin PB2
write_port(B, 2, 0);

These macros also let me define my own macros for pins:

#define LED_PORT D
#define LED_BIT 0
#define BUTTON_PORT B
#define BUTTON_BIT 5

write_ddr(LED_PORT, LED_BIT, 1)
write_ddr(BUTTON_PORT, BUTTON_BIT, 0);

while (1) {
  write(LED_PORT, LED_BIT, read_pin(BUTTON_PORT, BUTTON_BIT));
}

Other members have written their own, widely used macros.

You seem to be missing some of the fundamentals. Notably, proper bit manipulation, and how to access the general purpose I/O pins via DDRn, PORTn, and PINn. Have a look at the tutorials section, there are lots of resources there, including some of the macros used by other members.

JJ

///////////////////////////////////////////////////////////////////////////////

[captcha] CAPTCHA'D!! :evil: [/captcha]

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Still the same problem compiling but not working/transmitting.
I have a strong feeling that it is never entering the interrupt.
Please someone solve this.
I firstly want to do it on a single pin then want generalize it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JimutD wrote:
Still the same problem compiling but not working/transmitting.
I have a strong feeling that it is never entering the interrupt.
Please someone solve this.
How about we help you gather the tools you need to solve it yourself ;)

You've only posted your (slightly) modified library. You haven't posted your own code that uses it. How are we supposed to guess what's going wrong?

As a stab in the dark, I'd guess you haven't enabled global interrupts. Arduino does that for you, but you have to do it yourself with plain C/C++. Have you done so? If not, add:

#include 

... at the top of your source, and this after calling vw_setup():

sei();

If it still doesn't work, post a minimal program that exhibits the problem, and explain what you've done to try to solve that problem.

[edit]

    Ah, looks like you don't have:
    #include 

    ... in the library, either. Without it, the ISR may generate compile-time warnings, but won't otherwise be properly hooked into the vector table. Again, Arduino normally does this for you via:

    #include 

[/edit]

JJ

Why the [phneep!] am I getting captcha'd!?

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, Here's my code.

#define F_CPU 16000000UL

#include 
#include 
#include 
#include "VirtualWire.h"

int main(void)
{
	const char *msg = "hello";
	sei();
	vw_setup(2000);
	
    while(1)
    {
        vw_send((uint8_t *)msg, strlen(msg));
        vw_wait_tx(); // Wait until the whole message is gone
    
        _delay_ms(200); 
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What is the use of _crc_ccitt_update() in C.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

What is the use of _crc_ccitt_update() in C.

It is not a general C function AFAIK, but it is implemented in avrlibc. It is a function that is used to calculate a CRC checksum.

Anyway, tell us what you miss or do not understand in the following documentation: http://www.nongnu.org/avr-libc/u... . (That was the first hit when I Googled "_crc_ccitt_update()". And if you have the avr-gcc/avrlibc tool chain installed on your computer then chances are good that you also have the avrlibc documentation installed locally.)

Before you ask: http://en.wikipedia.org/wiki/Cyc...

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK, then it is redundancy check. I am struck in the code that your first link uses.
I just want to know , if i call

data = _crc_ccitt_update(0xff00,0xff);
data2 = _crc_ccitt_update(0xffff,0xff); 

what will be the value of data and data2

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JimutD wrote:
Ok, Here's my code.

#define F_CPU 16000000UL

#include 
#include 
#include 
#include "VirtualWire.h"

int main(void)
{
	const char *msg = "hello";
	sei();
	vw_setup(2000);
	
    while(1)
    {
        vw_send((uint8_t *)msg, strlen(msg));
        vw_wait_tx(); // Wait until the whole message is gone
    
        _delay_ms(200); 
    }
}

At first glance, this looks fine.

Did you add:

#include 

... to VirtualWire.c like I suggested?

JJ

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JimutD wrote:
OK, then it is redundancy check. I am struck in the code that your first link uses.
I just want to know , if i call

data = _crc_ccitt_update(0xff00,0xff);
data2 = _crc_ccitt_update(0xffff,0xff); 

what will be the value of data and data2

Why does it matter?

This is not relevant to your problem. If you're not seeing activity on the TX pin, you have deeper problems.

JJ

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I just want to know , if i call
Code:
data = _crc_ccitt_update(0xff00,0xff);
data2 = _crc_ccitt_update(0xffff,0xff);

what will be the value of data and data2


I could run it it in e.g. the simulator for you and report the results, but you could also do that and see for yourself.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, I surrendered but came up with my own version. I have prepared only the sender's protocol. But it is having problems, like it is sending correctly the bits first time, by the second round it is not transmitting anything it's just saying high.

Here is my code:

/*
 * RF_Sender.c
 *
 * Created: 10/4/2013 2:45:23 AM
 *  Author: Jem
 */ 

#define F_CPU 16000000UL

#include 
#include 
#include 



int ow_ocr1a;
uint8_t ow_tccr1b,tccr1b;

void ow_Setup(int);
void ow_RegisterEnable(void);
void ow_RegisterDisable(void);
void ow_Send(char);
void ow_Reset(void);
void ow_CreatePacket(uint8_t);
void ow_BitSelector(void);


void ow_Setup(int speed)
{
	sei();
	
	ow_tccr1b = 0b00001111;
	
	ow_ocr1a = (int) F_CPU / speed;
}

void ow_RegisterEnable()
{
	tccr1b = TCCR1B;
	
	TCCR1B = ow_tccr1b;
	TIMSK |= 1<<OCIE1A;
	
	OCR1A = ow_ocr1a;
}

void ow_RegisterDisable()
{
	TCCR1B = tccr1b;
	TIMSK = 0x00;
}

int packet[44] = {1,0, 1,0, 1,0, 1,0, 1,0, 
				  1,0, 1,0, 1,0, 1,0, 1,0,
				  1,0, 1,0,
				  1,0, 1,0, 1,0, 1,0,
				  1,0, 1,0, 1,0, 1,0,
				  1,0, 1,0};
				  
int ow_NextBit = 0;

int ow_BitWritten = 0;

int ow_Busy = 0;

int selection = 0;

void ow_Send(char data)
{
	uint8_t data_to_send;
	
	data_to_send = (uint8_t) data;
	
	ow_Busy = 1;
	
	ow_CreatePacket(data_to_send); 
}

void ow_Reset()
{
	ow_NextBit = 0;

	ow_BitWritten = 0;

	ow_Busy = 0;

	selection = 0;
}

int ow_PacketReadyFlag = 0;

void ow_CreatePacket(uint8_t data)
{
	int index = 24;
	int i;
	
	/*for (i=0;i<8;i++)
	{
		if (bit_is_set(data,i))
		{
			packet
= 1; packet[index+1] = 0; } else { packet
= 0; packet[index+1] = 1; } index += 2; }*/ ow_BitSelector(); ow_PacketReadyFlag = 1; ow_RegisterEnable(); } void ow_BitSelector() { if (selection < 43) { if (ow_BitWritten) { selection++; ow_NextBit = packet[selection]; } else { ow_NextBit = packet[selection]; } } else { ow_PacketReadyFlag = 0; //ow_RegisterDisable(); ow_Reset(); } ow_BitWritten = 0; } ISR(TIMER1_COMPA_vect) { if (ow_PacketReadyFlag) { PORTB = ow_NextBit<<1; ow_BitWritten = 1; ow_BitSelector(); } TCNT1 = 0; } int main(void) { DDRB |= 1<<1; PORTB |= 0<<1; ow_Setup(3000); while(1) { if (ow_Busy == 0) { ow_Send(0b11111111); } //_delay_ms(200); } }

Just ignore some of the commented out codes and some illogical steps, i am using this for only test purposes, running it on a super slow mode so that i could visualize the square wave through an led. It is just sending the bits in the array packet. But the problem stays.

-Please help I need this.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You have:

  PORTB |= 0<<1;

You probably mean:

  PORTB &= ~(1<<1);

You have:

  ow_ocr1a = (int) F_CPU / speed;

This casts F_CPU, which is an unsigned long, as a signed 16-bit int. With F_CPU defined as 16000000, this leaves a value of (16000000 % 65536), which is 9,216, which is then divided by speed. What you probably meant was:

  ow_ocr1a = (int)(F_CPU / speed);

... but since ow_ocr1a is already a 16-bit int, there is no need to do the cast at all.

Also, you should make ow_ocr1a unsigned.

None of that should 'break' your code in the way you've described.

However, this:

  ow_tccr1b = 0b00001111;

Sets TIMER1 to clock on an external pin T1, which happens to be PB1. So the very pin you are wiggling for TX is the same pin that clocks the timer. Surely this isn't what you meant.

I'd guess you meant to select the highest prescaler available (so you can see your LED) which is 1024, but which is selected with CS1[2:0] = 0b101, so:

 ow_tccr1b = 0b00001101;

BTW, please don't use magic numbers like this. It forces us to look at a datasheet to help you. Instead:

  ow_tccr1b = (1<<WGM12) | (1<<CS12) | (1<<CS10);

... is much more informative.

Quote:
Just ignore some of the commented out codes and some illogical steps, i am using this for only test purposes, running it on a super slow mode so that i could visualize the square wave through an led. It is just sending the bits in the array packet. But the problem stays.
In all honesty, your code is a mess. I know you have struggled to modify the VW library for your purposes and have not yet succeeded. However, the code you posted above is frankly not helping you. It is demonstrating that you don't have a clear understanding of how timers and interrupts work. This is where you need to concentrate your efforts. We weren't kidding when we said the library is almost out-of-the-box ready. You simply need to provide a few of your own functions to replace the Arduino code that the stock VW uses.

I strongly suggest you return to VW and address the issues you are having one by one. Post specific questions here. Break the problem down into smaller parts. Understand timers by going through the many timer tutorials available on this site. Ditto for interrupts. Ditto for bit manipulation. Ditto for port I/O.

JJ

[edit]code typo[/edit]

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Wed. Nov 13, 2013 - 02:43 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Just ignore some of the commented out codes and some illogical steps

The easiest way to do that is to ignore your post as a whole. It is up to YOU to make your posts with questions as clear and TO THE POINT as is possible. YOU are responsible for forming the best question possible. It will pay back.

Remember:

1) The quality of the answers you get is highly correlated with the quality of the question you ask, and

2) You are in a competition for attention and help - The more you put into your questions the more attention you get.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As you told joeymorin, I followed your step, just reviewd your previous posts and added the interrrupt header file to VirtualWire h and c file, and it is working fine now.
A million thanks for all your help.
I just love this forum.

I will make it available on github soon with a clean code.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JimutD wrote:
... it is working fine now.
Good news :)

Quote:
I will make it available on github soon with a clean code.
I might suggest that a better place to contribute your changes would be to the VW Google Group, or directly to the author.

JJ

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Could someone please tell me where I can find the github with the virtual wire substitute code? I know this post is old but I'm curios to have a look at it and it doesn't seem to be available on the Virtualwire google group either.

Thanks in advance,

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK, case reopened, I want to make this user friendly. For now the functions like vw_set_rx_pin(), vw_set_tx_pin will not work.
I want to make it work, I want to make the output and input pins changeable.

So I made this adjustments, but they aren't working.

void pinMode(unsigned char port, unsigned char pin, int mode) 
{
	unsigned char ddr;
	
	if(port == PORTA)
	{
		ddr = DDRA;
	}
	if (port == PORTB)
	{
		ddr = DDRB;
	}
	if (port == PORTC)
	{
		ddr = DDRC;
	}
	if (port == PORTD)
	{
		ddr = DDRD;
	}
	
	if (mode)
	{
		ddr |= (1<<pin);
	}
	else
	{
		ddr &= ~(1<<pin);
	}
}

void digitalWrite(unsigned char port, unsigned char pin, int level) 
{
	if (level) 
	{
		port = (1<<pin);
	}
	else 
	{
		port = ~(1<<pin);
	}
}

int digitalRead(unsigned char port, unsigned char pin) 
{
	unsigned char pinn;
	
	if(port == PORTA)
	{
		pinn = PINA;
	}
	if (port == PORTB)
	{
		pinn = PINB;
	}
	if (port == PORTC)
	{
		pinn = PINC;
	}
	if (port == PORTD)
	{
		pinn = PIND;
	}
	
	if (bit_is_set(pinn,pin))
	{
		return 1;
	}
	else if(bit_is_clear(pinn,pin))
	{
		return 0;
	}
}

and this

void vw_set_tx_pin(unsigned char port, unsigned char pin) 
{
	vw_tx_port = port; 
    vw_tx_pin = pin; 
} 

// Set the pin number for input receiver data 
void vw_set_rx_pin(unsigned char port, unsigned char pin) 
{ 
	vw_rx_port = port;
    vw_rx_pin = pin; 
}

and this also

  pinMode(vw_tx_port,vw_tx_pin, OUTPUT); 
    pinMode(vw_rx_port,vw_rx_pin, INPUT); 
    pinMode(vw_ptt_port,vw_ptt_pin, OUTPUT); 
    digitalWrite(vw_ptt_port,vw_ptt_pin, vw_ptt_inverted); 

and everywhere else where those funtions were present.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

but they aren't working.

Not much to go on is it? :?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It is not transmitting anything. I have connected and led for testing purposes, it is not lighting up in any direction.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Of course your code wont work as you expect. PORTA etc are a little special. You want to get the address of it. Considering what you are wanting to do has been discussed and solved many times before, i surprised you haven't done a search to find the answer.

https://www.avrfreaks.net/index.p...

Was top of the list. This should enlighten you.

When you write simple, but critical functions, write some test code for them rather than hope they work and try them as part of a complex application. With the test code you can run it in the simulator and figure out very quickly if it works or not.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

SORRY GUYS, since I am reading on lots of sites to get rid of my problem, I forgot this is an english-based Forum.
Please ignore this post except the attached files.

English text is one post below. (please help nevertheless :-P)

 

 

Hallo Leute,

ich würde diesen Thread gerne wieder aufleben lassen, da meine Frage wohl am ehesten hier rein passt.

Ich habe meine 4 Dateien "Main.c", "VirtualWire.cpp", "VirtualWire_Config.h" sowie "VirtualWire.h" angehängt.

Ich möchte die Virtual Wire LIB auf dem Attiny2313A benutzen. (Quelle: http://www.airspayce.com/mikem/a... )
Da ich keine C++ Kenntnisse habe, habe ich bewusst Virtual Wire und nicht Radiohead gewählt.

Bisher versuche ich in meinem Programm nur ein paar Zeichen zu Senden.
Zu Testzwecken habe ich eine LED am Sendepin angeschlossen, sowie eine LED am PTT-Pin.

 

Ich nutze Atmelstudio 7, mit standard Einstellungen:
Optimization steht auf -O1

 

 

Mein Code compiliert erfolgreich ohne Errors, jedoch passiert nicht was passieren soll:

Die Delay-Funktion macht deutlich größere Delays, als sie soll.
Ich habe das ganze bereits eingrenzen können:
Die Delays werden größer/unpassend, da in der VirtualWire.cpp in Zeile 121 in der Funktion "timerSetup" ein Prescaler gesetzt wird.

Dieser wird für die passende Bitrate der Sendenfunktion berechnet und in "vw_setup" aufgerufen.
"vw_setup()" wird in der main-funktion aufgerufen.

Kommentiere ich die Zeile in der die "timerSetup"-Funktion aufgerufen wirdaus, tut meine blink-Funktion, was sie soll, diese nutze ich um zu testen ob die _delay_ms() richtig funktioniert.

Mein Attiny läuft mit dem internen 8Mhz Oszillator und gesetztem Prescalerwert 8 (standard-shipping einstellungen, keine verändertren Fusebits), daher schreibe ich die cpu-define auf 1Mhz.

Da sich auch die VirtualWire-lib der "delay" Funktion bedient, gehe ich davon aus, dass das Setzen eines Prescalers und damit die Beeinträchtigung des CPU-Clocks berücksichtig sein sollte ?!

An diesem Punkt setzt meine Frage an: Hat jemand mit dieser LIB inzwischen bereits erfolgreich gearbeitet, OHNE die Arduino IDE zu benutzen oder erkennt jemand, wo hier der Fehler liegen könnte ?

Würde mich über Hilfe riesig freuen, da ich bereits seit knapp 2 Wochen rumprobiere und langsam frustriert werde.
Einen schönen 2. Adventsabend wünsche ich!

 

Attachment(s): 

Last Edited: Sun. Dec 10, 2017 - 06:29 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sry guys, forgot to speak english!

So I tried to ask the following:

I'd like to let this thread revive, since my question fits the best in this thread:
I attached my 4 files: "Main.c", "VirtualWire.cpp", "VirtualWire_Config.h" aswell as "VirtualWire.h".

I'd like to use the virtualWire lib on my Attiny2313A. (From this source: http://www.airspayce.com/mikem/a...)
Because I have no sound knowledge to "c++" I chose virtualWire instead of RadioHead.

At the moment I am just trying to send some characters in my program.

For testing purposes I connected a led to the sending pin as well as to the PTT-pin.

 

I am using Atmel Studio 7 as IDE with the default settings:
Optimization is on "-O1".

 

My code compiles without any error but my program does not work.
The delay-function for example becomes way too "slow".
It is because a prescaler for the clk gets set in Line 121 in the "VirtualWire.cpp" file in the called "timerSetup" function.
This prescaler is calculated for the fitting Bit-Rate of the sending function.

the timerSetup is called in the vw_setup(). The vw_setup is called in my main-function.

The attiny runs with the shipped settings: intern 8MHZ oscillator and activated prescaler 8. So I wrote the cpu-define to 1Mhz (1000000UL).

 

I thought, that since the virtualWire lib uses the delay function aswell, the functions within the virtualWire lib would not affect the practicality of the delay function, but it does...

So my question is: Does anybody see where my fault is or did anybody use it with another AVR than the tiny45?
Is it allowed to include a *.cpp file to a c-Project ?
Would be very great, if anybody could help me out, I am searching the internet and the code since nearly two weeks and it is frustrating me..
Thank you very much!

 

 

 

 

 

 

 

 

 

Last Edited: Sun. Dec 10, 2017 - 06:15 PM