virtual wire and puredata

hello everyone … i am working on this project and i am new to c++ language i have two arduinos hooked by the virtual wire library one is sending data (that works great… ) the other one is receiving (of course)…and lauching it into puredata’s analog firmata but then i only get incoming values like 1.939, 34.39, etc. the received values seems to be stable for long periods but never the same… compared to the messages received ( a loop of two different messages every 2 seconds)
i think the error is in my code even if it compiles and the pin#13 show completed loop

ithink it has to do with the convertion of received messages (bytes format) … anybody has a clue…

here is my mix of code

[/* This firmware supports as many analog ports as possible, all analog inputs,
 * four PWM outputs, and two with servo support.
 *
 * This example code is in the public domain.
 */

#include <Firmata.h>
// receiver.pde
//
// Simple example of how to use VirtualWire to receive messages
// Implements a simplex (one-way) receiver with an Rx-B1 module
//
// See VirtualWire.h for detailed API docs
// Author: Mike McCauley (mikem@open.com.au)
// Copyright (C) 2008 Mike McCauley
// $Id: receiver.pde,v 1.3 2009/03/30 00:07:24 mikem Exp $

#include <VirtualWire.h>
#undef int
#undef abs
#undef double
#undef float
#undef round
/*==============================================================================
 * GLOBAL VARIABLES
 *============================================================================*/



/* analog inputs */
char bank = 0; // bitwise array to store pin reporting
 // counter for reading analog pins
/* timer variables */
unsigned long currentMillis;     // store the current value from millis()
unsigned long previousMillis;    // for comparison with currentMillis


/*==============================================================================
 * FUNCTIONS                                                                
 *============================================================================*/



// -----------------------------------------------------------------------------
// sets bits in a bit array (int) to toggle the reporting of the analogIns
void reportAnalogCallback(byte pin, int value)
{
    if(value == 0) {

    }
    else { // everything but 0 enables reporting of that pin

    }
    // TODO: save status to EEPROM here, if changed
}

/*==============================================================================
 * SETUP()
 *============================================================================*/
void setup() 
{
   vw_set_ptt_inverted(true); // Required for DR3100
    vw_setup(2000);       // Bits per sec
vw_set_rx_pin(11);
    vw_rx_start(); 
    Firmata.setFirmwareVersion(0, 2);

    Firmata.attach(REPORT_ANALOG, reportAnalogCallback);

   
    Firmata.begin(57600);
}

/*==============================================================================
 * LOOP()
 *============================================================================*/
void loop() 
{
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;
  
  
  
      
        {
           if (vw_get_message(buf, &buflen)) // Non-blocking 
          
              { 
                 bank = buflen;

              digitalWrite(13, true); 
              
                 while(Firmata.available()){
                 
                Firmata.sendAnalog(4, (buf[bank], DEC));
                 }
   
                delay(1000);
                   digitalWrite(13, false);
                   delay(100);
                  
              }
    }
}
]

oh yeah and how do put a fancy code frame on the post

oh yeah and how do put a fancy code frame on the post

Select all your code, and press the # button on the top line.

My suggestion is to, for now, get rid of all the Firmata stuff. Get the receiver receiving data correctly, and writing it to the serial port, with the Serial Monitor to view it.

Posting the sender code would be useful, too.

here is my sender code

// transmitter.pde
//
// Simple example of how to use VirtualWire to transmit messages
// Implements a simplex (one-way) transmitter with an TX-C1 module
//
// See VirtualWire.h for detailed API docs
// Author: Mike McCauley (mikem@open.com.au)
// Copyright (C) 2008 Mike McCauley
// $Id: transmitter.pde,v 1.3 2009/03/30 00:07:24 mikem Exp $

#include <VirtualWire.h>
#undef int
#undef abs
#undef double
#undef float
#undef round
void setup()
{
    Serial.begin(9600);        // Debugging only
    Serial.println("setup");

    // Initialise the IO and ISR
    vw_set_ptt_inverted(true); // Required for DR3100
    vw_setup(2000);       // Bits per sec
}

void loop()
{
    const char *msg = "A";

    digitalWrite(13, true); // Flash a light to show transmitting
    vw_send((uint8_t *)msg, strlen(msg));
    vw_wait_tx(); // Wait until the whole message is gone
    digitalWrite(13, false);
    delay(1000);
  {
  const char *msg = "B";}
   vw_send((uint8_t *)msg, strlen(msg));
    vw_wait_tx(); // Wait until the whole message is gone
    digitalWrite(13, false);
    delay(1000);}
    }

works fine with serial monitor and the receiver is set to run firmata only when acomplish messages are received…

thanks for the fancy frame thing

i am wandering if there is an arduino serial monitor in puredata that would make things easier I've looked over their website but there so much stuff to learn ... so any clue would be appreciated

This is a problem:

{
  const char *msg = "B";}

It declares a block. In that block, there is a local variable defined. That local variable goes out of scope at the end of the block, which occurs immediately. The compiler will optimize the whole block out of existence.

You might as well help it out and delete it.

here is my segond version of the virtual_wire … now this one compiles and send data properly with the stock virtual wire library…

// transmitter.pde
//
// Simple example of how to use VirtualWire to transmit messages
// Implements a simplex (one-way) transmitter with an TX-C1 module
//
// See VirtualWire.h for detailed API docs
// Author: Mike McCauley (mikem@open.com.au)
// Copyright (C) 2008 Mike McCauley
// $Id: transmitter.pde,v 1.3 2009/03/30 00:07:24 mikem Exp $

#include <VirtualWire.h>
#undef int
#undef abs
#undef double
#undef float
#undef round
void setup()
{
    Serial.begin(9600);        // Debugging only
    Serial.println("setup");

    // Initialise the IO and ISR
    vw_set_ptt_inverted(true); // Required for DR3100
     vw_set_tx_pin(12);
    vw_setup(2000);       // Bits per sec
}

void loop()
{
    const char *msg = "A";

    digitalWrite(13, true); // Flash a light to show transmitting
    vw_send((uint8_t *)msg, strlen(msg));
    vw_wait_tx(); // Wait until the whole message is gone
    digitalWrite(13, false);
    delay(1000);

  const char *mbg = "B";
   vw_send((uint8_t *)mbg, strlen(msg));
    vw_wait_tx(); // Wait until the whole message is gone
    digitalWrite(13, false);
    delay(1000);
    }

here is the stock virtual wire receiver that i want to modify

// receiver.pde
//
// Simple example of how to use VirtualWire to receive messages
// Implements a simplex (one-way) receiver with an Rx-B1 module
//
// See VirtualWire.h for detailed API docs
// Author: Mike McCauley (mikem@open.com.au)
// Copyright (C) 2008 Mike McCauley
// $Id: receiver.pde,v 1.3 2009/03/30 00:07:24 mikem Exp $

#include <VirtualWire.h>
#undef int
#undef abs
#undef double
#undef float
#undef round
void setup()
{
    Serial.begin(9600);      // Debugging only
    Serial.println("setup");

    // Initialise the IO and ISR
    vw_set_ptt_inverted(true); // Required for DR3100
    vw_setup(2000);       // Bits per sec

    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;

        digitalWrite(13, true); // Flash a light to show received good message
      // Message with a good checksum received, dump it.
      Serial.print("Got: ");
      
      for (i = 0; i < buflen; i++)
      {
          Serial.print(buf[i], HEX);
          Serial.print(" ");
      }
      Serial.println("");
        digitalWrite(13, false);
    }
}

from there i want to send the incoming value into pure data

should i use strings (i don’t really understand how it works … anybody have a link for a good tutorial)

i see a light…

the mistake i figured is the message lenth from reciver into puredata

so i mixed firmata and virtual wire in the following (using int and byte )
in order to match firmata’s send.analog message…

// receiver.pde
//
// Simple example of how to use VirtualWire to receive messages
// Implements a simplex (one-way) receiver with an Rx-B1 module
//
// See VirtualWire.h for detailed API docs
// Author: Mike McCauley (mikem@open.com.au)
// Copyright (C) 2008 Mike McCauley
// $Id: receiver.pde,v 1.3 2009/03/30 00:07:24 mikem Exp $

#include <VirtualWire.h>
/* This firmware supports all analog inputs,

 * This example code is in the public domain.
 */
#undef int
#undef abs
#undef double
#undef float
#undef round

#include <Firmata.h>


int bank = 0; 
int bankII = 0;// bitwise array to store pin reporting
byte pin; // counter for reading analog pins
/* timer variables */
unsigned long currentMillis;     // store the current value from millis()
unsigned long previousMillis;  

/*==============================================================================
 * FUNCTIONS                                                                
 *============================================================================*/
// -----------------------------------------------------------------------------
// sets bits in a bit array (int) to toggle the reporting of the analogIns

void reportAnalogCallback(byte pin, int value)
{
    if(value == 0) {
        bank = bank &~ (1 << pin);
    }
    else { // everything but 0 enables reporting of that pin
        bank = bank | (1 << pin);
    }
    // TODO: save status to EEPROM here, if changed
}


void setup()
{
  Firmata.setFirmwareVersion(0, 2);
    Firmata.attach(REPORT_ANALOG, reportAnalogCallback);


    Firmata.begin(57600);
    Serial.begin(9600);      // Debugging only
    Serial.println("setup");

    // Initialise the IO and ISR
    vw_set_ptt_inverted(true); // Required for DR3100
    vw_setup(2000);       // Bits per sec

    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
    {
        digitalWrite(13, true); // Flash a light to show received good message
      // Message with a good checksum received, dump it.
      
 while(Firmata.available())
        Firmata.processInput();
    currentMillis = millis();
    if(currentMillis - previousMillis > 20)
    {  
        previousMillis += 20;                   // run this every 20ms
        for(pin=0;pin<TOTAL_ANALOG_PINS;pin++)
        {
            if( pin & (1 << pin) ) 
            {
               for (bank = 0; bank < buflen; bank++) 
               {
                 bankII = (buf[bank], DEC); 
                 
                  Firmata.sendAnalog(pin, (bankII));
   
 Serial.print(bankII);
 digitalWrite(13, false);
 }
    }
      }
    }
}

}

but i still get funky readings in the serial monitor even when modifying the baudrate:

Hi Philippe,

I’ve just been trying exactly the same thing myself. Unfortunately, there doesn’t seem to be any sensible way to monitor the serial port directly in puredata - I was trying to find one the other night. The pd comport object gives a much lower level of access ie 1 byte at a time and trying to turn that into a whole line or a pd message isn’t straightforward although somebody’s probably done it.

I would have thought that printing to the serial port as well as using firmata (which I assume communicates on the serial port in a binary non-human readable manner) is creating a conflict which would account for the “funky” readings. You need to do one or the other.

I’m receiving 6 8bit bytes from my remote arduino via VirtualWire and assigning them to (pretending they come from) 6 analog sensors. On the pd side, they show up as floating point numbers and I’m not sure what the conversion is yet!

Don’t take this as an officially endorsed guide to how it should be done - I’ve only just started looking into firmata but here’s my code so far:

#include <VirtualWire.h>
#include <Firmata.h>

void setup()
{
    //Serial.begin(9600);      // Debugging only
    //Serial.println("setup");
    
    Firmata.setFirmwareVersion(0, 1);
    Firmata.begin(57600);

    // Initialise the IO and ISR
    vw_set_ptt_inverted(true); // Required for DR3100
    vw_set_tx_pin(6);
    vw_set_rx_pin(7);
    vw_set_ptt_pin(8);
    vw_setup(5000);       // Bits per sec
    vw_rx_start();       // Start the receiver PLL running
}

void loop()
{
    while(Firmata.available()) {
        Firmata.processInput();
    }
  
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;

    if (vw_get_message(buf, &buflen)) // Non-blocking
    {

        //digitalWrite(13, true); // Flash a light to show received good message
      // Message with a good checksum received, dump it.
      //Serial.print("Got: ");
      
      for (int i = 0; i < 6; i++)
      {
          //Serial.print(buf[i], DEC);
          //Serial.print(" ");
            Firmata.sendAnalog(i, (int)buf[i]); 
      }
      //Serial.println("");
        //digitalWrite(13, false);
    }
}

Good luck!

of what i can understand the TX send a char message and the RX receive a char message .... so litereraly we need to convert char message to int(value) between the RX receiving and sending to firmata . ... euh ithink .... ijust don't know how yet

okay so here is my new code

TX

// transmitter.pde
//
// Simple example of how to use VirtualWire to transmit messages
// Implements a simplex (one-way) transmitter with an TX-C1 module
//
// See VirtualWire.h for detailed API docs
// Author: Mike McCauley (mikem@open.com.au)
// Copyright (C) 2008 Mike McCauley
// $Id: transmitter.pde,v 1.3 2009/03/30 00:07:24 mikem Exp $

#include <VirtualWire.h>
#undef int
#undef abs
#undef double
#undef float
#undef round
void setup()
{
    Serial.begin(9600);        // Debugging only
    Serial.println("setup");

    // Initialise the IO and ISR
    vw_set_ptt_inverted(true); // Required for DR3100
     vw_set_tx_pin(12);
    vw_setup(2000);       // Bits per sec
}

void loop()
{
    const char *msg = "A";

    digitalWrite(13, true); // Flash a light to show transmitting
    delay(500);
    vw_send((uint8_t *)msg, strlen(msg));
    vw_wait_tx(); // Wait until the whole message is gone
    digitalWrite(13, false);
    delay(1000);

  const char *mbg = "B";
  delay(500);
   vw_send((uint8_t *)mbg, strlen(mbg));
    vw_wait_tx(); // Wait until the whole message is gone
    digitalWrite(13, false);
    delay(1000);
    }

and RX

#include <Firmata.h>

#include <VirtualWire.h>
#undef int
#undef abs
#undef double
#undef float
#undef round

char bank;//from virtual wire RX
int bankII;//to firmata
const byte analogPin = 4; // select input pin
/* timer variables */
unsigned long currentMillis;     // store the current value from millis()
unsigned long previousMillis;    // for comparison with currentMillis



void setup()
{
     Firmata.setFirmwareVersion(0, 2);
    
    Firmata.begin(57600);

    // Initialise the IO and ISR
    vw_set_ptt_inverted(true); // Required for DR3100
    vw_setup(2000);       // Bits per sec
    vw_set_rx_pin(11);
    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
    {
      

        digitalWrite(13, true); // Flash a light to show received good message
      // Message with a good checksum received, dump it.
      
      int i;

      for (i = 0; i < 2; i++) // reduced from buflen to 2 bytes messages in order to match word() 
      {
          bank = (buf[i], DEC);

      bankII = word(bank);   
      

       Firmata.sendAnalog(analogPin, bankII);
}
delay(500);
        digitalWrite(13, false);
    }
}

still does not work but aparently you can use word() to create an int value from two bytes

… any valuable feedback is appreciated

Yes, data gets sent over the wireless 1 8-bit char at a time, we call the sendAnalog() function which takes an int, ignores the two most significant bits and sends it as two 7-bit bytes to the puredata library which divides it by 1024 and presents it as a float!!!

Sending over the ascii values of "A" and "B", unless I've got it wrong, should show up on pd as 0.0634765625 and 0.064453125.

sends it as two 7-bit bytes

do i get this right..... so we need to convert 2 char into two bytes to then convert 2 bytes into an int

ignores the two most significant bits

...... do you have an idea on how i could select witch char to send

i tried this in order to select wich char is assigned to the analog value

   if (vw_get_message(buf, &buflen)) // Non-blocking
    {


        digitalWrite(13, true); // Flash a light to show received good message
      // Message with a good checksum received, dump it.

      
          banka = (buf[1], DEC);
            bankb = (buf[2], DEC);
//bankc = (buf[2], DEC);
//bankd = (buf[3], DEC);
//banke = (buf[4], DEC);
//bankf = (buf[5], DEC);
          bankII = word(banka, bankb);

            analogPin = 4;
    Firmata.sendAnalog(analogPin, bankII);

does not work

ok so i yhink this code is right but in pd i get an error … it says
[arduino]: version_0.5beta8
UNKNOWN_INPUT_COMMAND: 12 0

but here is the code if somebody wants to try it … let me know of the result

TX

#include <VirtualWire.h>
#undef int
#undef abs
#undef double
#undef float
#undef round
void setup()
{
    Serial.begin(9600);        // Debugging only
    Serial.println("setup");

    // Initialise the IO and ISR
    vw_set_ptt_inverted(true); // Required for DR3100
     vw_set_tx_pin(12);
    vw_setup(2000);       // Bits per sec
}

void loop()
{
    const char *msg = "AA";

    digitalWrite(13, true); // Flash a light to show transmitting
    delay(500);
    vw_send((uint8_t *)msg, strlen(msg));
    vw_wait_tx(); // Wait until the whole message is gone
    digitalWrite(13, false);
    delay(1000);

  const char *mbg = "BB";
  delay(500);
   vw_send((uint8_t *)mbg, strlen(mbg));
    vw_wait_tx(); // Wait until the whole message is gone
    digitalWrite(13, false);
    delay(1000);
    }

RX

#include <Firmata.h>
#include <VirtualWire.h>
#undef int
#undef abs
#undef double
#undef float
#undef round
int analogInputsToReport = 0; // bitwise array to store pin reporting
int analogPin = 0; // counter for reading analog pins
/* timer variables */
unsigned long currentMillis;     // store the current value from millis()
unsigned long nextExecuteMillis; 

void reportAnalogCallback(byte pin, int value)
{
     // everything but 0 enables reporting of that pin
        analogInputsToReport = analogInputsToReport | (1 << pin);
    }
    // TODO: save status to EEPROM here, if changed

void setup()
{
   Firmata.setFirmwareVersion(0, 2);
   Firmata.attach(REPORT_ANALOG, reportAnalogCallback);
    // Initialise the IO and ISR
    vw_set_ptt_inverted(true); // Required for DR3100
    vw_setup(2000);       // Bits per sec
    vw_set_rx_pin(11);
    vw_rx_start(); 
    Firmata.begin(57600);  
}

void loop()
{
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;
while(Firmata.available()) {
        Firmata.processInput();
}
    if (vw_get_message(buf, &buflen)) // Non-blocking
    {  digitalWrite(13, true); // Flash a light to show received good message
    
      int bankA = (buf[0], DEC) *4; 
       Firmata.sendAnalog(0, (bankA));
delay(100);
        
      int bankB = (buf[1], DEC) *4; 
       Firmata.sendAnalog(1, (bankB));
delay(100);

int bankC = (buf[2], DEC) *4; 
       Firmata.sendAnalog(2, (bankC));
delay(100);

int bankD = (buf[3], DEC) *4; 
       Firmata.sendAnalog(3, (bankD));
delay(100);

int bankE = (buf[4], DEC) *4; 
       Firmata.sendAnalog(4, (bankE));
delay(100);

int bankF = (buf[5], DEC) *4; 
       Firmata.sendAnalog(5, (bankF));
delay(250);
        digitalWrite(13, false);
    }
}