Wixel As Transceiver

The Apps test_radio_signal_tx and test_radio_signal_rx when downloaded into 2 separate wixels
work pretty nicely. I was able to transmit my own data and receive them correctly by changing the
codes a little in both Apps.

But when I combined the Apps to make each wixel as transmitter/receiver for the Tx to send
data only when Rx requests, nothing worked.

Is there any App written as Transmitter/Receiver?

Hello, thaque,

Have you seen our Wireless Serial App? In addition to allowing bidirectional communication, it also has a mechanism to ensure that transmitted packets are reliably received by the other Wixel.

The user’s guide for the Wixel also contains a couple other precompiled apps, along with documentation on how to use them.

- Kevin

Kevin,
Correct me if I’m reading the doc wrong.
Doesn’t ‘wireless_serial’ need an external microcontroller to be
hooked up with wixel through serial pins?

I’m trying to avoid another microcontroller, because CC2511 itself is
a microcontroller. Unfortunately it has only around 29K program holding
flash memory. Tx/Rx combined program alone makes a .wxl file of size 20K with
no additional code.

Hello.

The .wxl file size is not equal to the number of bytes that will be written to the Wixel flash: the app file is written in ASCII and has more information than just the program bytes.

The Wireless Serial App is under 9 kB, which leaves more than 22 kB available. I think the Wireless Serial App would be a good starting point for your program.

- Ben

I’ll give transceiver a try first.
This is where I’m stuck.
Rx --> Tx (request packet)
Tx receives correctly, and starts sending actual data (i know from LEDs)
After sending ‘request packet’, Rx goes into receive mode (from Leds)
But receives nothing.

I’m suspecting RFIF (interrupt) or DMA or RFST bits.
Any suggestions would be welcomed.

Hello, Tarik.

What code are you running on your Wixel? The wireless serial app we provide has no receive mode that would be indicated by LEDs so you must have written your own program and loaded it on to the Wixel. Please simplify the code to the simplest possible thing that should work but doesn’t, and post the entire thing here, surrounded by code tags. Since your program is probably based off of the wireless_serial app, it would be helpful if you highlighted (with comments) the lines of code that you changed or added. Also, please provide more detail about how you tested it and what the LEDs did.

I recommend reading the sticky post at the top of this forum for general advice for getting help:

–David

I have combined two files ‘test_radio_signal_tx.c’ and ‘test_radio_signal_rx.c’. I kept all functions of both programs as they were and called them from the main() method.
For this reason the only part one need to know is the main() method. The sequence of operations can be described as this:
a) After power up, Tx goes into receive mode and waits for a request packet.
b) After Tx receives the packet, it goes into transmit mode and start sending actual data.
c) After power up, Rx goes into transmit mode and sends the request packet.
d) After sending the request packet (no ACK is used) Rx goes into receive mode and wait for actual data, which are sent to the PC through USB port.

void main()
{
	uint8 count=0;
	LED_RED(0);
	LED_YELLOW(0);
	   systemInit();
	    usbInit();

	while(1)
	{
	if(TxRx==1)      //transmit if TxRx=1, receive if TxRx=2
	{
		crcErrors = 0;                  //these 4 re-initialization didn't matter
		currentBurstId = 0;
		packetsSent = 0;
		lastBurst = 0;
		perTestTxInit();

    //I used packet[4] data as token between tx and rx
		while(count<100)    //also used, packet[4]==99) for tx
		{
			boardService();
 //         updateLeds();  default LED operations are disabled
			usbComService();
			sendRadioBursts();
			count++;
			LED_YELLOW(1);
		}
    	TxRx=2;
    	count=0;
        LED_YELLOW(0);
        RFST=4;                     //this 2 lines added later
        RFIF = RFIF & (1<<4);       //but made no difference
	}
	if(TxRx==2)
	{
		RcurrentBurstId = 0;   //these 7 re-initialization didn't matter
		packetsReceived = 0;
		rssiSum = 0;           //rssSum and lqiSum are not used in the program but kept here.
		lqiSum = 0;
		crcErrors = 0;
		lastPacketReceivedTime = 0;
		lastBurst = 0;

		perTestRxInit();
		usbInit();
//I used packet[4] data as token between tx and rx
	    while(packet[4]!=99)     //packet[4]!=99) for rx, packet[4]!=88) for tx
	    {
	        boardService();
	        usbComService();
	  //      updateLeds();
	        receiveRadioBursts();
	        reportResults();
	        LED_RED(1);
	    }
	    LED_RED(0);
	    RFST=4;                  //added later with no results
        RFIF = RFIF & (1<<4);	// added later
	    TxRx=2;
	    count=0;
	   }
	  }


}

Note, packet[4]=88 is request packet, packet[4]=99 is data packet.
The LEDs indicate that Tx receives the request packet correctly and goes into transmit mode.
The Rx transmits the request packet and goes into receive mode, but receives nothing because the PC shows no data.
It appears to me Tx/Rx pair operate correctly only once, after that they do not change their modes as they are supposed to.

Any suggestion?

Hello, Tarik.

There are a few problems with your app that could cause trouble:

  1. sendRadioBursts() is a non-blocking function, but it looks like you were hoping to just call it 100 times to have it send 100 packets.
  2. When switching between RX and TX modes, you will probably need to disarm the DMA channel at some point before rearming it. I don’t think you have any code for doing that.
  3. Instead of “RFIF = RFIF & (1<<4);” you probably meant “RFIF = RFIF & ~(1<<4);”

The CC2511’s radio is a complicated machine with lots of states (have you seen Figure 54 in the datasheet?) and it needs to be in the right state for it to work. When we add DMA (and interrupts) to the mix, it gets even more complicated to keep everything in the right state. You should probably add debugging code that prints MARCSTATE (and other important variables) to USB when requested. For example, since your receiver is supposed to receive something but is not, you should make sure radio is actually in receive mode by checking that the MARCSTATE is 13,14, or 15 and you should make sure the transmitter actually transmitted something.

However, I think it will be easier for you if you try to use our existing libraries and apps instead of making your own. We have radio libraries that can do two-way communication: radio_queue, radio_link and radio_com (which uses radio_link).

I think the test_radio_link app would be a good starting point for what you want to do (except that it uses ACKs). The test_radio_link app demonstrates how to do two-way packet-based communication between two Wixels. If you send a character ‘a’,‘b’,‘c’,‘d’,‘e’,‘f’ or ‘g’ to one Wixel on its virtual COM port, it will send a packet to the other Wixel, which should tell you that it received the packet by sending a message to its virtual COM port. You should first get the unmodified app working the way you would expect, then slowly add features to the app and test frequently to make sure things are still working.

–David

I have a set of programs I made from the example code that do what you want. They are not completely cleaned up because I am still modifying them for my own purposes, but hey are easy to follow and can be slightly modified for your purposes. I am using one wixel as a master and it stays connected to my PC USB port. Anything you type into a terminal program that is connected to the master is immediately sent to the slave wixel. The slave wixel simply echo’s back anything that is not a pre-defined command. If the slave recognizes a pre-defined command, it executes that command. The only commands I have pre-defined are for setting P1_0 high or low, and a command to read the temperature sensor. The slave executes the command and sends back the port 0 readings. A little cleanup on the responses you would like and your own pre-defined commands is all that is needed to make it yours. Email me at mark_matter@yahoo.com if you would like me to send you copies of the programs. Once I clean them up completely and take out some of my project specific code, I will likely share them on the forum or submit them for the example applications. If you can handle code that is a little unpolished, I think I have what you want.

Thanks David and Lucutis.
Even though Radio_Link.c is also an oneway application, I think I have made it a two-way application. Radio_link.c is easier to use than test_radio_signal_tx/rx.c. But I will still have to figure out how to reset the pointers (I always hated pointers) after one use.
I have another serious question.
There are pins P1_0 to P1_7 and also some pin labeled as P0_x on a Wixel module. They appear as not being used by anything external.
I need 4 pins for Digital Inputs. Which 4 pins would be the best choice?
Which Library should I look into to access those pins?

Lucutis, you get an email from me soon. Thanks again.

The test_radio_link app and the radio_link library it uses allow for two-way communication without modification.

Any of the pins on Port 0 or Port 1 will work as digital inputs. We provide a gpio library to help you use them:
pololu.github.com/wixel-sdk/gpio_8h.html

If you need pull-up or pull-down resistors on your inputs, then don’t use P1_0 or P1_1.

–David

@David
I have made some progress with the system I am trying to build. Now I am having a little problem with the Input Voltage at the Wixel pins. I understand that the pins accept 3.3VDC.

  1. What is the maximum SAFE voltage these pins can handle? Is 5V too high? You can point me to any TI article.

  2. I used 3.3V from the Wixel module for my small external circuit. After a diode drop , voltage at one wixel input pin appears as 2.85V which my software recognize as ‘1’.
    But when 2 or more pins are energized, voltage becomes around 2.0V to 2.3V, which I think is not recognized as ‘1’. Is it my software or 2.0V or 2.3V are too low to be recognized as ‘1’?

  3. Is 4.5V (3 AA Battery) is too much for Wixel input pins? I can use 4 zener diodes of 3.3V before applying to the pins. But I like to avoid the zeners if I can.

The CC2511 datasheet from Texas Instruments is the source for everything we know about Wixel pin voltage tolerance, and it can be found here:
focus.ti.com/lit/ds/symlink/cc2511f32.pdf

According to section 3, “Absolute Maximum Ratings”, you can’t expose any digital pin to voltages outside -0.3 V to VDD+0.3 V. You can get around that by using a voltage divider or by adding a big resistor (10-100kOhms) in series with the Wixel’s pin.

According to section 6.16, “DC Characteristics”, the voltage on an input pin needs to be at least 70% of VDD to be guaranteed to be recognized as a logic 1. If your VDD is 3.3 V, then that limit would be 2.31 V. This might be a conservative limit, and your 2.0 V might reliably register as a 1 in some conditions, but there is no guarantee.

–David

David, can you explain this? I’m running into a situation where I have 8 buttons on the 8 P1 inputs and I’m seeing weird behavior on those two pins. I’m assuming it’s related to this statement of yours. Basically, the buttons are normally open, connected to ground and I’m using the internal pull-ups for all of port 1. When I press and release a button on pins P1_2 - P1_7, the feedback is immediate in my app. If I press a button connected to P1_0 or P1_1, the response is immediate but when I release there is a second of delay before my app realizes it’s been released. I’ve been trying to find an answer to this in the docs, but I haven’t seen it. I think you know the answer. :slight_smile:

I can just use P0 in this case (aside from the fact that it will screw up my easy pin numbering system since they would all be sequential if i stick with just P1) but I’d like to understand this issue.

Thanks for any help,
Rob

Sorry, I think I found the answer in the SDK docs under gpio: P1_0 and P1_1 aren’t connected to internal pullups/pulldowns. I’ll try adding my own pullup resistors.

rob