Can virtual wire and I2C be made to work together?

I’m using Arduino for a dynamics project involving reaction (fly) wheels. For part of the project I need to wirelessly control two motors using PWM.

I’m using two wireless modules (433Mhz and 315Mhz) for transmitting and receiving data, which use the virtual wire library. After some trail and error I found out that I can not use PWM with the virtual wire library. To get around this I’m using a nano to run virtual wire and communicate with the rf modules and a UNO for PWM. However when I try to communicate with I2C between the UNO (which will control the motors) and the NANO (which communicates with the rf modules) it freezes up.

Also, I’m using a second UNO (which I’m calling the ‘hand controller’) to communicate with the opposing rf modules. I attached a few pictures and included the code below. Thanks in advance.

here’s the code for the NANO:
#include <VirtualWire.h>
#include <Wire.h>

uint8_t PDlength = 8;
uint8_t HCDlength = 8;

byte platformData[8] = {101,102,103,104,105,106,107,108};
byte handControllerData[8] = {1,2,3,4,5,6,7,8};

int DATA_RATE = 1000;

void setup()
{
pinMode(13, OUTPUT);
digitalWrite(13,HIGH);

Wire.begin(9);
Wire.onRequest(requestEvent);
delay(20);
Wire.onReceive(receiveEvent);
delay(20);

Serial.begin(9600);
Serial.println(“Serial up”);
delay(20);
vw_set_ptt_inverted(true); // Required for DR3100
vw_set_rx_pin(3);
vw_set_tx_pin(2);
vw_setup(DATA_RATE);
vw_rx_start();
delay(20);
}
void loop()
{
if (vw_get_message(handControllerData, &HCDlength)) {
Serial.print(“hcd:”);
for(int i=0; i<sizeof(handControllerData); i++){
Serial.print(" ");
Serial.print(handControllerData*);*

  • Serial.print(" ");*

  • }*

  • Serial.println();*

  • delay(20);*

  • digitalWrite(13,!digitalRead(13));*
    vw_send((uint8_t *)platformData, sizeof(platformData));

  • vw_wait_tx();*

  • }*
    }
    void requestEvent(){

  • Wire.write(handControllerData, PDlength); *
    }
    void receiveEvent(int howMany)
    {

  • for(int i=0; i<16; i++){*

  • byte c = Wire.read(); // receive byte as a character*

  • Serial.print(" ");*

  • Serial.print(c); // print the character*

  • }*

  • Serial.println();*

  • delay(30);*
    }
    Here’s the code for the UNO:
    #include <Wire.h>
    uint8_t PDlength = 8;
    uint8_t HCDlength = 8;
    //byte platformData[8];
    byte handControllerData[8];
    void setup(){

  • pinMode(8, OUTPUT);*

  • pinMode(9, OUTPUT);*

  • pinMode(10, OUTPUT);*

  • pinMode(11, OUTPUT); *

  • digitalWrite(8, LOW);*

  • digitalWrite(9, LOW);*

  • digitalWrite(10, LOW);*

  • digitalWrite(11, LOW);*

  • Serial.begin(9600);*

  • Serial.println(“Serial up”);*

  • Wire.begin(); // Start I2C Bus as a Slave (Device Number 9)*

  • for(int i=0; i<PDlength; i++){*
    _ platformData = i+1; _
    _
    }
    _
    * for(int i=0; i<HCDlength; i++){*
    _ handControllerData = i+100;
    }

    }
    void loop(){_

* if(handControllerData[0] < 127 && handControllerData[0] > 0) digitalWrite(8, HIGH);*
* if(handControllerData[1] < 127 && handControllerData[1] > 0) digitalWrite(9, HIGH);*
* if(handControllerData[0] >= 127 && handControllerData[0] < 256) digitalWrite(8, LOW);*
* if(handControllerData[1] >= 127 && handControllerData[1] < 256) digitalWrite(9, LOW); *
* int a = handControllerData[0];*
* int b = handControllerData[1];*
_ if(a > 127) a = 2*(a - 127);
if(b > 127) b = 2*(b - 127);
analogWrite(10, 2a);
analogWrite(11, 2b);_

* Wire.requestFrom(9,16);*
* if(Wire.available()){*
* for(int i=0; i<HCDlength; i++){*
_ handControllerData = Wire.read();
Serial.print(handControllerData*);
Serial.print(" ");
}
Serial.println();
}
delay(40);
Wire.beginTransmission(9);
Wire.write(platformData,16);
Wire.endTransmission();
}
2015-02-02 00.08.25.jpg

_
IMG_3157[1]trimmer.jpg*

There are a number of problems, could you fix them all ? and we see from there how to go on.

When you post your sketch, please use the < code > and < / code > tags. It the the button with the scroll and the “<>”.

Remove the delay(20) and delay(30), they are not needed.

The delay(40) in the loop might be too fast. Start with delay(100);

Never use the Serial library inside the requestEvent() or receiveEvent() handlers, and never use a delay in those functions. Please clean up the recieveEvent().

You set the rx pin and the tx pin, but not the ptt pin. The VirtualWire sets the ptt to its default (even if it is not used). So you better use vw_set_ptt_pin() and set it to an unused pin.

The receiveEvent() knows how many bytes are received with the “howMany” parameter. But in the loop you assume that 16 bytes are available. You could use the “howMany”, or ignore the received data if “howMany” is not 16.

In the loop you check for Wire.available(), and then read “HCDlength” number of bytes. You could read bytes as long as Wire.available() returns a value above zero, or you could check Wire.available() just once and used the number of available bytes in the loop. Even better is to use the return value of requestFrom(), since that is the number of bytes that is available.

  int n = Wire.requestFrom(9,16);
  for(int i=0; i<n; i++){

Or check if the number of bytes is correct.

  int n = Wire.requestFrom(9,16);
  if (n == HCDlength) {
    for(int i=0; i<n; i++){

Is using both 433MHz and 315MHz legal in your country ?