Teensy 3.2 I2C slave data transfer to Arduino Mega master fails

Status
Not open for further replies.

paynterf

Well-known member
I have a very simple 3-wire (SCL/SDA/GND) connection from an Arduino Mega 2560 to a Teensy 3.2. I can send data from the Mega to the Teensy fine, but no matter what is sent from the Teensy to the Mega, the Mega receives 0xFF. I have verified that the connections are proper, and (with my trusty O'scope) verified that the signal voltage levels are correct. The scope photos below show the SCL line for the master-to-slave case (top) and the slave-to-master case (bottom). In both photos the vertical scale is 1V/cm and the horizontal scale is 20uSec/cm


IMG_2625.jpg

IMG_2626.jpg

I was initially using I2C_Anything to transfer data both ways, but also tried 'bare metal' byte processing by copying the underlying code from I2C_Anything - no change.

Master:

Code:
/*
    Name:       Arduino_I2C_Master_Example.ino
    Created:	3/14/2020 5:32:40 PM
    Author:     FRANKNEWXPS15\Frank
*/

// -------------------------------------------------------------------------------------------
// Basic Master
// -------------------------------------------------------------------------------------------
//
// This creates a simple I2C Master device which when triggered will send/receive a text 
// string to/from a Slave device.  It is intended to pair with a Slave device running the 
// basic_slave sketch.
//
// Pull pin12 input low to send.
// Pull pin11 input low to receive.
//
// This example code is in the public domain.
//
// -------------------------------------------------------------------------------------------

#include "I2Cdev.h" //02/19/19: this includes SBWire.h
#include <I2C_Anything.h>
#include <PrintEx.h> //allows printf-style printout syntax
StreamEx mySerial = Serial; //added 03/18/18 for printf-style printing

// Memory
#define MEM_LEN 256
char databuf[MEM_LEN];
unsigned long count;
float xmtfloat = 1.2344;
const uint8_t slaveAddr = 8;  //uint8_t type reqd here for Wire.requestFrom() call

void setup()
{
	pinMode(LED_BUILTIN, OUTPUT);    // LED
	digitalWrite(LED_BUILTIN, LOW);  // LED off
	pinMode(12, INPUT_PULLUP);       // Control for Send
	pinMode(11, INPUT_PULLUP);       // Control for Receive

									 // Setup for Master mode, pins 18/19, external pullups, 400kHz, 200ms default timeout
	//Wire.begin(I2C_MASTER, 0x00, I2C_PINS_18_19, I2C_PULLUP_EXT, 400000);
	//Wire.begin(I2C_MASTER, 0x00, I2C_PINS_18_19, I2C_PULLUP_INT, 400000);
	//Wire.setDefaultTimeout(200000); // 200ms
	Wire.begin();


	// Data init
	memset(databuf, 0, sizeof(databuf));
	count = 0;

	//Serial.begin(115200);
	unsigned long now = millis();
	Serial.begin(115200); 
	int idx = 0;
	//while (!Serial && (millis() - now) < 3000)
	//{
	//	delay(500);
	//	idx++;
	//}
	//mySerial.printf("Serial available after %lu mSec\n", millis() - now);
	//mySerial.printf("loop idx = %d\n", idx);

	mySerial.printf("I2C_Master Example\n");
	mySerial.printf("\nGround Pin 12 to transmit a float value to the slave\n");
	mySerial.printf("\nGround Pin 11 to request a float value from the slave\n");
	//mySerial.printf("\nInitial transmit float value is %2.4f\n\n",xmtfloat);
	mySerial.printf("\nInitial transmit float value is %1.4f\n\n",xmtfloat);

}

void loop()
{
	count++;
	uint8_t target = 0x66; // target Slave address
	size_t idx;

	// Send string to Slave
	if (digitalRead(12) == LOW)
	{
		digitalWrite(LED_BUILTIN, HIGH);   // LED on

		// Transmit to Slave
		mySerial.printf("Sending to Slave: %2.3f\n", ( xmtfloat * (float)count));
		Wire.beginTransmission(target);   // Slave address
		I2C_writeAnything(xmtfloat * count);
		Wire.endTransmission();           // Transmit to Slave

		digitalWrite(LED_BUILTIN, LOW);    // LED off
		delay(100);                       // Delay to space out tests
	}

	// Read string from Slave
	if (digitalRead(11) == LOW)
	{
		digitalWrite(LED_BUILTIN, HIGH);   // LED on

		Serial.print("Reading from Slave: ");// Print message

		// Read from Slave
		Wire.requestFrom(target, (size_t)MEM_LEN); // Read from Slave (string len unknown, request full buffer)

		//if (Wire.getError())
		//	Serial.print("FAIL\n");
		//else
		//{
			float slave_val = 0;
			mySerial.printf("initial slave_val is %2.3f\n", slave_val);
			//I2C_readAnything(slave_val);

			byte* p = (byte*)&slave_val;
			unsigned int i;
			for (i = 0; i < sizeof slave_val; i++)
			{
				*p = Wire.read();
				Serial.print("i = "); Serial.print(i);
				Serial.print(": received "); Serial.println(*p);
				p++;
			}



			mySerial.printf("Received %2.3f from Slave\n", slave_val);
		//}

		digitalWrite(LED_BUILTIN, LOW);    // LED off
		delay(100);                       // Delay to space out tests
	}

	delay(100);
}

Slave:

Code:
	// -------------------------------------------------------------------------------------------
	// Basic Slave
	// -------------------------------------------------------------------------------------------
	//
	// This creates a simple I2C Slave device which will print whatever text string is sent to it.
	// It will retain the text string in memory and will send it back to a Master device if 
	// requested.  It is intended to pair with a Master device running the basic_master sketch.
	//
	// This example code is in the public domain.
	//
	// -------------------------------------------------------------------------------------------

/*
	03/07/20 Modified to be Teensy-specific, and to use 'I2C_Anything' for I2C communications
*/
#include <i2c_t3.h>
#include <T3_I2C_Anything.h>

// Function prototypes
void receiveEvent(size_t count);
void requestEvent(void);

// Memory
volatile uint8_t received;
volatile float rcvfloat = 0;

//
// Setup
//
void setup()
{
	pinMode(LED_BUILTIN, OUTPUT); // LED

	// Setup for Slave mode, address 0x66, pins 18/19, internal pullups, 400kHz
	//Wire.begin(I2C_SLAVE, 0x66, I2C_PINS_18_19, I2C_PULLUP_INT, 400000);
	//Wire.begin(I2C_SLAVE, 0x66, I2C_PINS_18_19, I2C_PULLUP_INT, 100000);
	Wire.begin(I2C_SLAVE, 0x66, I2C_PINS_18_19, I2C_PULLUP_EXT, 100000);

	// register events
	Wire.onReceive(receiveEvent);
	Wire.onRequest(requestEvent);

	//Serial.begin(115200);
	unsigned long now = millis();
	Serial.begin(1); //rate value ignored
	int idx = 0;
	while (!Serial && (millis() - now) < 3000)
	{
		delay(500);
		idx++;
	}

	Serial.printf("Serial available after %lu mSec\n", millis() - now);
	Serial.printf("I2C Slave Example\n");
}

void loop()
{
	// print received data - this is done in main loop to keep time spent in I2C ISR to minimum
	if (received)
	{
		digitalWrite(LED_BUILTIN, HIGH);
		Serial.printf("Slave received: %f\n", rcvfloat);
		received = 0;
		digitalWrite(LED_BUILTIN, LOW);
	}
}

//
// handle Rx Event (incoming I2C data)
//
void receiveEvent(size_t count)
{
	received = count; // set received flag to count, this triggers print in main loop
	I2C_readAnything(rcvfloat);
}

//
// handle Tx Event (outgoing I2C data)
//
void requestEvent(void)
{
	Serial.printf("Sending %f to Master\n", rcvfloat);

	const byte* p = (const byte*)&rcvfloat;
	unsigned int i;
	for (i = 0; i < sizeof rcvfloat; i++)
		Wire.write(*p++);
	delay(5); //experiment
	//I2C_writeAnything(rcvfloat);
}

Master Serial Output:

Code:
Opening port
Port open
I2C_Master Example

Ground Pin 12 to transmit a float value to the slave

Ground Pin 11 to request a float value from the slave

Initial transmit float value is 1.2344

Sending to Slave: 49.376
Sending to Slave: 50.610
Sending to Slave: 51.845
Sending to Slave: 53.079
Sending to Slave: 54.314
Sending to Slave: 55.548
Sending to Slave: 56.782
Sending to Slave: 58.017
Sending to Slave: 59.251
Sending to Slave: 60.486
Sending to Slave: 61.720
Sending to Slave: 62.954
Sending to Slave: 64.189
Sending to Slave: 65.423
Sending to Slave: 66.658
Reading from Slave: initial slave_val is 0.000
i = 0: received 255
i = 1: received 255
i = 2: received 255
i = 3: received 255
Received nan from Slave
Reading from Slave: initial slave_val is 0.000
i = 0: received 255
i = 1: received 255
i = 2: received 255
i = 3: received 255
Received nan from Slave
Reading from Slave: initial slave_val is 0.000
i = 0: received 255
i = 1: received 255
i = 2: received 255
i = 3: received 255
Received nan from Slave

Slave Serial Output:

Code:
Opening port
Port open
Slave received: 49.375999
Slave received: 50.610401
Slave received: 51.844803
Slave received: 53.079201
Slave received: 54.313602
Slave received: 55.548000
Slave received: 56.782402
Slave received: 58.016800
Slave received: 59.251202
Slave received: 60.485603
Slave received: 61.720001
Slave received: 62.954403
Slave received: 64.188805
Slave received: 65.423203
Slave received: 66.657600
Sending 66.657600 to Master
Sending 66.657600 to Master
Sending 66.657600 to Master
Sending 66.657600 to Master
Sending 66.657600 to Master
Sending 66.657600 to Master
Sending 66.657600 to Master
Sending 66.657600 to Master
Sending 66.657600 to Master
Sending 66.657600 to Master
Sending 66.657600 to Master
Sending 66.657600 to Master
Sending 66.657600 to Master
Sending 66.657600 to Master
Sending 66.657600 to Master

I'm sure it's something simple, but for the life of me I can't see it. Any help would be appreciated.

TIA,

Frank
 
I've been poking around trying to figure out why Slave-to-Master data transfer is failing with my Mega-T3.2 setup with the T3.2 as slave. Wending my way down into the library code, I found this:

Code:
    ------------------------------------------------------------------------------------------------------
    i2c_t3 - I2C library for Teensy 3.x & LC

    - (v11.0) Modified 01Dec18 by Brian (nox771 at gmail.com)

    Full changelog at end of file
    ------------------------------------------------------------------------------------------------------
    Copyright (c) 2013-2018, Brian (nox771 at gmail.com)

    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 
    associated documentation files (the "Software"), to deal in the Software without restriction, 
    including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 
    and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 
    subject to the following conditions:

    The above copyright notice and this permission notice shall be included in all copies or substantial 
    portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 
    LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 
    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    ------------------------------------------------------------------------------------------------------
*/

#if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MKL26Z64__) || \
    defined(__MK64FX512__) || defined(__MK66FX1M0__) // 3.0/3.1-3.2/LC/3.5/3.6

#include "i2c_t3.h"


// ------------------------------------------------------------------------------------------------------
// Static inits
//
#define I2C_STRUCT(a1,f,c1,s,d,c2,flt,ra,smb,a2,slth,sltl,scl,sda) \
    {a1, f, c1, s, d, c2, flt, ra, smb, a2, slth, sltl, {}, 0, 0, {}, 0, 0, I2C_OP_MODE_ISR, I2C_MASTER, scl, sda, I2C_PULLUP_EXT, 100000, \
     I2C_STOP, I2C_WAITING, 0, 0, 0, 0, I2C_DMA_OFF, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, 0, {}, 0, 0 }

struct i2cStruct i2c_t3::i2cData[] =
{
    I2C_STRUCT(&I2C0_A1, &I2C0_F, &I2C0_C1, &I2C0_S, &I2C0_D, &I2C0_C2, &I2C0_FLT, &I2C0_RA, &I2C0_SMB, &I2C0_A2, &I2C0_SLTH, &I2C0_SLTL, 19, 18)

Which looks fine except the entire thing is grayed out, indicating that

Code:
#if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MKL26Z64__) || \
    defined(__MK64FX512__) || defined(__MK66FX1M0__) // 3.0/3.1-3.2/LC/3.5/3.6


Returns false, even though the __MK20DX256__ is clearly defined in i2c_t3.h. If everything in i2c_t3.cpp is grayed out, where is the actual code for all the read/write functionality in i2c_t3.cpp?

Confused in Ohio

Frank
 
Status
Not open for further replies.
Back
Top