Sensor reading works on uno, not on yun. Im out of any hope. Anyone an idea?

Dear community.

This thread is about Arduino Yun and a 8x8 grid thermal sensor that works (until now) on Uno but not on Yun. In the Uno i get datablocks something like below, where each XX.XX is somewhere (usually) between 10.00 and 40.00 degrees. On the Yun i get nothing at all, although the code still seems to run.

XX.XX XX.XX XX.XX XX.XX XX.XX XX.XX XX.XX XX.XX
XX.XX XX.XX XX.XX XX.XX XX.XX XX.XX XX.XX XX.XX
XX.XX XX.XX XX.XX XX.XX XX.XX XX.XX XX.XX XX.XX
XX.XX XX.XX XX.XX XX.XX XX.XX XX.XX XX.XX XX.XX
XX.XX XX.XX XX.XX XX.XX XX.XX XX.XX XX.XX XX.XX
XX.XX XX.XX XX.XX XX.XX XX.XX XX.XX XX.XX XX.XX
XX.XX XX.XX XX.XX XX.XX XX.XX XX.XX XX.XX XX.XX
XX.XX XX.XX XX.XX XX.XX XX.XX XX.XX XX.XX XX.XX

The connection of sensor on Uno and Yun is on A4 and A5, plus 5V / GND and communication is using I2C

Since i have the Yun i found out quite a lot of stuff. I learned how to communicate between arduino and linino side, and learned how to process test data sent from the arduino side to the linino, and use a home made python script to process it.

However, after modifying the arduino sketch to obtain real sensor data instead of example data, i got nothing. The exact same code works perfectly at an Arduino Uno, by the way. (Yes, i selected a different board :wink: ) To not confuse anyone with any redundant code, the code below is a copy of the Grideye Arduino Demonstration Software which shows the minimal stuff needed to obtain the sensor data.. If i get this to work on a yun, im going to celebrate it.

My best bet would be that the register pointer of the Grideye is different between Uno (0x0E) and Yun.
Another option would be that const uint8_t Address as used at the Yun differs from that of the Uno, but that does not seem really logical, does it?

Any other options? I have read quite a bit about the topic of register pointers until now but it does not help me any further.

/* GridEye Arduino Demonstration Software */
/*-----------------------------------------------------------------------------*/
/* This is meant to show the measurement capabilities of the GridEye sensor. */
/* The following code may be used as example. */
/* Further features (e.g. interrupts) are not part of this demonstration. */
#include "twi.h"
#include <TimerOne.h>

// GridEye I2C slave address of the sensor 1101 000, AD_SELECT is connected to GND
// GridEye I2C slave address of the sensor 1101 001, AD_SELECT is connected to VDD
#define AD_SELECT_IS_GND 0b1101000
#define AD_SELECT_IS_VDD 0b1101001
const uint8_t Address = AD_SELECT_IS_VDD;

// set update period in use. GridEye supports 1 Hz and 10 Hz
#define REFRESH_TIME_1HZ 1000000
#define REFRESH_TIME_10HZ 100000
#define BUFFER_LENGTH 128

uint8_t rxBuffer[BUFFER_LENGTH];
uint8_t txBuffer[6];
volatile char trigger;
 
void setup()
{
 // Setup I2C bus, transfer speed is set to 100kHz (in twi.h)
 twi_init();
 // Setup serial terminal connection, baudrate is 115200 b/s
 Serial.begin(115200);
 // Setup timer to fire an event each second
 Timer1.initialize(REFRESH_TIME_1HZ);
 // Attach timer interrupt service routine to the timer event
 Timer1.attachInterrupt(timer);
}


void loop()
{

 register unsigned char i, length;
 register char tmp;
 register int raw;
 register float result;
 
if (trigger)
 {
 // reset trigger
 trigger = 0;
 // set register pointer of GridEye to 0x0E in order to read the thermistor value
 txBuffer[0]=0x0E;
 i = twi_writeTo(Address, txBuffer, 1, 0);
 // perform block read of 2 bytes into rxBuffer
 length = twi_readFrom(Address, rxBuffer, 2);
 // put upper byte into a register variable
 tmp = rxBuffer[1];
 // convert the upper byte of the 12bit signed value into proper 16bit signed
 // format, if value is negative
 if (tmp & 0b00001000) tmp |= 0b11111000;
 // construct the 16bit signed value, shifting the upper byte 8 bits up and adding
 // the lower byte
 raw = (tmp << 8) | rxBuffer[0];
 // calculate actual thermistor temperature in °C
 result = raw * 0.0625;
 // print value to serial terminal
 Serial.print("\tthermistor value:\t");
 Serial.println(result);
 
 // set register pointer of GridEye to 0x80, the first temperature value register
 txBuffer[0]=0x80;
 i = twi_writeTo(Address, txBuffer, 1, 0);
 // perform block read of 128 bytes into rxBuffer
 // only a block read ensures all given pixel data is out of the same frame
 length = twi_readFrom(Address, rxBuffer, 128);
 
 // loop through all pixel temperature data
 for(i=0;i<=length;i++)
 {
 // insert a new line every 8 pixel values
 if (!(i % 16)) Serial.println();
 // put temperature data into register variable
 tmp = rxBuffer[i];
 // if we are processing the upper byte
 if (i % 2)
 {
 // convert the upper byte of the 12 bit signed value into proper 16 bit
 // signed format, if value is negative
 if (tmp & 0b00001000) tmp |= 0b11111000;
 // add the upper byte into 16 bit register by shifting it 8 bits up
 raw |= tmp << 8;
 // calculate actual pixel temperature in °C
 result = raw * 0.25;
 Serial.print("\t");
 
 // if temperature reading is out of specification, don't print it
 if ((result >= -20) && (result <= 100))
 Serial.print(result);
 else
 Serial.print("X.XX");
 }
 // if the lower byte is processed
 else
 {
 // erase raw value by setting it to the lower byte value
 raw = 0xFF & tmp;
 }
 }
 // print new line after each frame
 Serial.println();
 }
 
}

// timer interrupt service routine
void timer()
{
 // set trigger
 trigger |= 1;
}

For some reason i solved it just 5 minutes after posting, although i searched for a solution the whole day:

The YUN has different I2C ports than the Uno. :expressionless: dumb me.

Board I2C / TWI pins
Uno, Ethernet Analog 4 (SDA), Analog 5 (SCL)
Leonardo digital 2 (SDA), digital 3 (SCL)