Hi,
I am using the Photon to communicate with a Panasonic Grid Eye Sensor over I2C.
I have written a library to get temperature back from sensor but it is currently too slow. I need to read back data at 10Hz so each read needs to take less than 100ms. At the moment each read takes ~304ms but when I comment out the “Wire.endTransmission()” lines the read time is reduced to ~3ms.
I have used other micro controllers in the past reading data over I2C at 500Hz so it seems like it should be possible to read data back much more quickly.
Why does the “Wire.endTransmission()” line take so long as each time it is only sending one int?
Is there anything I can do to speed up the library?
EDIT:
I am using the latest 0.4.6 firmware.
I have tested the sensor with an mBed LCP1768 and it is able to read at 10Hz.
The sensor is connected to the I2C pins on the Photon with 4K7 pull up resistors.
The class is below:
//GridEye.cpp
#include "GridEye.h"
GridEye::GridEye()
{
Wire.setSpeed(CLOCK_SPEED_400KHZ);
Wire.begin();
delay(100);
initialReset();
setFPS(true);
}
bool GridEye::writePacket(int addr, int data)
{
Wire.beginTransmission(ADDRESS);
Wire.write(addr);
Wire.write(data);
return Wire.endTransmission(true) == 0;
}
std::vector<byte> GridEye::readPacket(int addr, int datalength)
{
std::vector<byte> data;
if(datalength <= 32)
{
Wire.beginTransmission(ADDRESS);
Wire.write(addr);
Wire.endTransmission(false);
Wire.requestFrom(ADDRESS, datalength, true);
while(Wire.available()) data.push_back(Wire.read());
}
else
{
int dataRead = 0;
while((datalength - dataRead) > 32)
{
Wire.beginTransmission(ADDRESS);
Wire.write(addr + dataRead);
Wire.endTransmission(false);
Wire.requestFrom(ADDRESS, 32, false);
while(Wire.available()) data.push_back(Wire.read());
dataRead += 32;
}
Wire.beginTransmission(ADDRESS);
Wire.write(addr + dataRead);
Wire.endTransmission(false);
Wire.requestFrom(ADDRESS, (datalength - dataRead), true);
while(Wire.available()) data.push_back(Wire.read());
}
return data;
}
std::vector<float> GridEye::readTemperatures()
{
std::vector<byte> rawData = readPacket(0x80, 128);
std::vector<float> data;
for(int i=0; i < 64; i++) data.push_back((rawData[(2*i)+1] << 8) | rawData[2*i]);
return data;
}
float GridEye::readCalibrationTemperature()
{
std::vector<byte> rawData = readPacket(0x0E, 2);
float temperature = (((rawData[1] << 8) | rawData[0]) * 0.0625);
return temperature;
}
bool GridEye::setFPS(bool fps_set_10)
{
int data = !fps_set_10;
return writePacket(0x02, data);
}
bool GridEye::initialReset()
{
int data = 0x3F;
return writePacket(0x01, data);
}
The main code is below:
// This #include statement was automatically added by the Particle IDE.
#include "GridEye.h"
GridEye* _gridEye;
void setup()
{
Serial.begin(115200);
_gridEye = new GridEye();
}
void loop()
{
Serial.print("Grid-EYE:\r\n");
unsigned long start = millis();
std::vector<float> temps = _gridEye->readTemperatures();
unsigned long end = millis();
Serial.println("Time:" + String(end - start));
for(int i=0; i < temps.size(); i++)
{
Serial.print(String(temps[i]));
Serial.print(" ");
if((i+1)%8 == 0) Serial.print("\r\n");
}
delay(100);
}
Thanks in advance.
Joe