Show Posts
Pages: [1]
1  Using Arduino / Networking, Protocols, and Devices / Re: Float I2c on: January 04, 2013, 06:17:09 pm
That worked. 

I added the following function to I2C_Anything.h

Code:

template <typename T> int I2C_singleWriteAnything (const T& value) {
  int size = sizeof value;
  byte vals[size];
  const byte* p = (const byte*) &value;
  unsigned int i;
  for (i = 0; i < sizeof value; i++) {
    vals[i] = *p++;
  }
 
  Wire.write(vals, size);
  return i;
}

And it works perfectly, even in the onRequest handler. 

Thanks 4.2 zillions!

Eric Rombokas
2  Using Arduino / Networking, Protocols, and Devices / Re: Float I2c on: January 04, 2013, 06:05:45 pm
Thanks for the reply! 

It works correctly using the single call to Wire.write().  If I split it into two calls it fails:

eg
Code:
Wire.write(vals[0]);
Wire.write(vals[1]);

Produces

 Received 2 bytes. 
Received: 172 .
Received: 255 .

Is there something about the Wire library that means only a single write() should be used in an interrupt?  I2C_writeAnything() uses multiple Wire.write() calls in a for-loop, so that would mean it can't be used in an onRequest handler.

Perhaps I could modify it to fill a byte array, then send using a single write() call, like this:

Code:
float someFloat = 1.2;
byte vals[4];

byte * p = (const byte*) someFloat;
unsigned int i;
for (i = 0; i < sizeof someFloat; i++)
  vals[i] = *p++;

Wire.write(vals, 4);


Or something like that?

-Eric




3  Using Arduino / Networking, Protocols, and Devices / Re: Float I2c on: January 04, 2013, 04:32:25 pm
An update.  Sending multiple bytes at all during a requestEvent results in error.

I'm running on two Uno R3 arduinos.  

Master uses requestFrom to ask for bytes.  If I ask for one, it works, but if I ever ask for more than 1, they come back corrupted.

Master code:

Code:
#include <Wire.h>

int numReceived = 0;

void setup()
{
Wire.begin();        // join i2c bus (address optional for master)
Serial.begin(115200);
}

void loop()
{
  numReceived = 0;
  Wire.requestFrom(2, 2);

  while(Wire.available())
  {
  byte c = Wire.read();
  Serial.print("Received: ");
  Serial.print(c);        
  Serial.println(" . ");
  numReceived++;
  }

  delay(500);
  Serial.print(" Received ");
  Serial.print(numReceived);
  Serial.println(" bytes.  ");
}

Slave code:

Code:
#include <Wire.h>

byte val1 = 0;
byte val2 = 1;

void setup()
{
Wire.begin(2);                // join i2c bus with address #2
Wire.onRequest(requestEvent); // register event
}

void loop()
{
delay(100);
}

void requestEvent()
{
  Wire.write(val1);
  Wire.write(val2);
}

Output is :

Received: 1 .
Received: 255 .
 Received 2 bytes. 


What is happening here?

-Eric
4  Using Arduino / Networking, Protocols, and Devices / Re: Float I2c on: January 03, 2013, 06:35:35 pm
I'm having trouble using I2C_Anything with Wire.requestFrom, and any help would be greatly appreciated.

I'd like the master to request data from the slave, but all my floats arrive as nan .  I've tried sending individual bytes and it works.  I'm confident in my wiring because I can get I2C_Anything to work as written in this post.  There's something about how I'm using requestFrom which is breaking something!


Here are the files:

Master, an Uno which uses Wire.requestFrom to ask for the data
Code:
// Eric Rombokas
// Jan 3 2013
// Arduino is i2c master, arduIMU is i2c slave .  arduino dumps requested i2c data to serial
// Using gammon I2C_readAnything.h for translating I2C bytes to other data types

#include <math.h>
#include <Wire.h>
#include "I2C_writeAnything.h"

const int SLAVE_ADDRESS = 10;

volatile float volatileYaw;

void setup() {
  Serial.begin(115200);
  Wire.begin(); // begin with no address specified joins the bus as a master
}

void loop() {
  
  delay(1000);  
  
  if (Wire.requestFrom(SLAVE_ADDRESS, 4, true) == 4) {
    I2C_readAnything(volatileYaw);
    Serial.println(volatileYaw);
  }  
 
 
}


And slave, which uses I2C_writeAnything in its requestEvent()

Code:

// Eric Rombokas
// Jan 3 2013
// ArduIMU runs as an i2c slave, querying freeIMU for yaw, pitch, roll when asked to by the i2c master
// Adapted from Fabio Varesano's FreeIMU_Yaw_pitch_roll RIP
// i2c float/byte stuff adapted from "WanaGo" on arduino forum

#include <ADXL345.h>
#include <bma180.h>
#include <HMC58X3.h>
#include <ITG3200.h>
#include <MS561101BA.h>
#include <I2Cdev.h>
#include <MPU60X0.h>
#include <EEPROM.h>

//#define DEBUG
#include "DebugUtils.h"
#include "CommunicationUtils.h"
#include "FreeIMU.h"
#include "I2C_writeAnything.h"
#include <Wire.h>
#include <SPI.h>
#include <math.h>

volatile float volatileYaw = 42.42;

const int I2CSlaveAddress = 10;

void setup() {
 
  
  Wire.begin(I2CSlaveAddress);
  Wire.onRequest( requestEvent ) ; // declare function handle to be called when i2c master requests
  
}

void loop() {
  

}

// called by onRequest interrupt
void requestEvent() {

  I2C_writeAnything(volatileYaw);
    
}
 

Any ideas?

Thanks,
Eric R

(edited to remove superfluous stuff)
Pages: [1]