Pololu Robotics & Electronics
My account Comments or questions? About Pololu Contact Ordering information Distributors

Multi-m3pi Communication with Wixel


Hello, Côme. I have not tried the address feature of the CC2511 radio, but I have read about it and it seems like a good feature to use. --David


Hi David/Geoff

I am also trying to achieve a similar type of outcome, where as I can use one wixel connected to a PC via USB, to communicate with several other Wixels connected to other devices via UART.

Obviously this will be on a one-to-one basis so the Wixel will need to dynamically change the address to talk to any of the others.

I have read through this post and have been looking at modifying the wireless serial app.

I have dumped in Geoffs complete code that he posted here, including the updated lib file etc.

I then ran this app on the Wixel to try it out.

I communicated between the 2 wixels via ‘HT Comm’. And the wireless conenction worked as expected. i.e. type ‘a’ at one com port and ‘a’ was received at the other, showing that the wireless comms was good.

I assumed that by typing a ‘0’, followed by a new radio channel i.e. ‘6’, that this would change the new channel to channel ‘6’. Instead, it juse sent a ‘6’ accross the radio link.

Is this meant to happen? Have I made the wrong assumption to how this shouuld work? I apologise in advance, as there are a few holes in my C knowledge as I have not had much experience.

Any help would be much appreciated.




I believe typing a ‘0’ will actually send the character itself, not the value zero. You actually need to send a null byte to indicate that you want a channel change, followed by the numerical value representing the channel (i.e., not the character ‘6’, but the actual byte representing 6, 0x06).

As it is, the channel-changing app might be slightly buggy - I’ve written a simpler version that performs much better than the original. I use it in Project Paw Print, and I can provide you with the source code, if you wish.



Ahhh ok. That makes sense.

I have been playing around with it this afternoon and got it to sort of work, but wasn’t ideal.

Yea if you could provide me with the source code that would be really great!



I’ll need you to PM me your email address.



Using the channel changing source code that has been posted on this thread, I have tried to modify the code to use a GPIO pin, instead of using the null byte, as the ‘trigger’ to allow the next byte being sent to be used as the new channel address (if that makes sense).

Below is the change to the usbToRadioService that I have made. I have also ensured that pin14 (the pin I am going to use as a trigger) is set as an input pulled high via internal pullups . Ideally, I would like it so that whenever pin 14 is pulled low for any period of time, the next byte that is received will be used as the new channel address. In a practical sense, a peripheral device will pulse a ‘0’ to this input to say it is ready to recieve the new channel address.

With the code below, this is working as expected (sort of), other than it only works when a byte is sent whilst pin 14 is low. Then the following byte is used as the new channel.

Any reasons to why it only works when a byte is sent and pin 14 is low? I would like it to work so that a byte does not need to be sent at the same time as the pin being low.

void usbToRadioService()
    uint8 signals;
    uint8 receivedByte;			// byte received via USB
    while(!changeChannelSoon && usbComRxAvailable() && radioComTxAvailable())

		receivedByte = usbComRxReceiveByte();

		// are we in a state which accepts a new channel address?
			nextChannel = receivedByte;
			acceptChannelByte = 0;
			changeChannelSoon = 1;
			inputValue = isPinHigh(14);		//reads value of input pin 14 p1_4
			if (inputValue == 0)
					acceptChannelByte = 1;

			else	// normal 'message' byte


    while(radioComRxAvailable() && usbComTxAvailable())

    // Control Signals

    radioComTxControlSignals(usbComRxControlSignals() & 3);

    // Need to switch bits 0 and 1 so that DTR pairs up with DSR.
    signals = radioComRxControlSignals();
    usbComTxControlSignals( ((signals & 1) ? 2 : 0) | ((signals & 2) ? 1 : 0));



Look at your logic - your while-loop will only be entered when there are bytes to transmit via radio. Since your pin is read inside this loop, you’ll actually only ever be able to set acceptChannelByte to 1 when this occurs. You’ll need to restructure your code so that this isn’t the case. It should be a fairly trivial change.



Oh yes. I see. I guess that was pretty obvious!

That’s done and working now. Thanks again for your help!



Thanks again for your help.

I have another quick question…

My current setup is as follows; one Wixel connected to UART and one to USB on my laptop. The Wixel connected to UART is on channel ‘102’. The wixels communicate perfectly when both are on channel 102. I then use the channel changing program (as discussed) to change the channel of the Wixel connected to USB, for example to channel 108. As expected, when I send data between the Wixels, nothing appears at either terminal as the two devices are on seperate channels.

The problem occurs when I change the USB-connected-Wixel back to channel 102. None of the data that I have sent (whilst the 2 devices were on seperate channels) from the USB-connected-Wixel has reached the UART-connected-Wixel - which is what I would like. However, all of the data sent from the UART-connected-Wixel seems to have been stored, and as soon as the 2 devices are on the same channel again, all the data is fired accross to the USB-connected-Wixel.

How come this is happening? I’m not 100% clear where to look in the code to try and resolve this issue.

Any help would be really great.




That’s just how the Wixel’s wireless_serial app (and Geoff’s modified version) work. When you send some bytes to the Wixel’s RX line, they get transferred to the radio TX buffers, which are managed by the radio_link library. The radio_link library will keep the bytes in the radio TX buffers until they have been transmitted to another Wixel and acknowledged. The radio_link library does not ever flush data from those buffers.

However, you could flush the data if you wanted. Maybe Geoff’s modified radio_link library will send a reset packet as the first thing when it changes to a new channel. If that is true, then you could modify the radio_link library further so that it flushes all data in the TX buffers when it receives a reset packet. You would want to add some code to flush the TX buffers right below the comment “// The other Wixel sent a Reset packet, …” in radio_link.c, and the code would be:

Also, you would want to add some code there to flush out the UART’s receive buffer; if the the radio TX buffer has filled up then the part of the code that empties the UART receive buffer will stop running, and it will get filled with old data that you want to discard. This depends on how many bytes you are actually sending while the channels are mismatched.

I have not really thought about this enough to be sure that it would work and be sure it does not have unintended consequences.




Yes, emptying the TX buffer on a channel change was an intentional feature, designed to prevent (unsuccessfully transmitted) data from being sent to the wrong Wixel after the master Wixel changes channel.

If I recall correctly, to undo this effect you’ll need to uncomment the following lines from radioLinkChangeChannel() in radio_link.c.

	// reset TX and RX pointers
	radioLinkRxInterruptIndex = radioLinkRxMainLoopIndex;
	radioLinkTxInterruptIndex = radioLinkTxMainLoopIndex;
	radioLinkTxCurrentPacketTries = 0;

…and I think that will do it.



Hello, Geoff. Actually, alicec63 wants to flush the buffers so that old data does not get through, and she would need to do it on the Wixel whose channel did not change. She would need to flush the radio’s TX buffer and the UART’s RX buffer to really make sure that no old data is used.



Whoops, you’re quite right, David. My mistake.

Sorry, alicec63, I misread your question.