Teensy LC and Wire1

Status
Not open for further replies.

alexandros

Well-known member
I need to use a Teensy LC as an I2C slave for a Raspberry Pi, which at the same time will act as an I2C master in order to control Adafruit's quad DAC, MCP4728.
Teensy LC has two I2C busses, where the first bus is at pins 18 and 19, and the second at pins 22 and 23, right? I'm trying to access the second bus with Wire1 but I get this error:
Code:
'Wire1' was not declared in this scope

Here's my code:
Code:
#include <Adafruit_MCP4728.h>
#include <Wire.h>

Adafruit_MCP4728 mcp;

byte inBytes[12];

void setup(void) {
  Wire1.begin(0x0A);
  Wire1.onReceive(receiveEvent);

  mcp.begin();

  Serial.begin(115200);
  while (!Serial);
}

void loop() {
}

void receiveEvent(int howMany) {
  int index = 0;
  int val;
  while (Wire1.available()) {
    inBytes[index++] = Wire1.read();
  }
  switch (howMany) {
    case 3:
      val = inBytes[1] + (inBytes[2] * 128);
      mcp.setChannelValue(inBytes[0], val);
      Serial.print("channel "); Serial.print(inBytes[0]);
      Serial.print(", val: "); Serial.println(val);
      break;
    case 6:
      val = inBytes[1] + (inBytes[2] * 128);
      mcp.setChannelValue(inBytes[0], val);
      Serial.print("channel "); Serial.print(inBytes[0]);
      Serial.print(", val: "); Serial.println(val);
      val = inBytes[4] + (inBytes[5] * 128);
      mcp.setChannelValue(inBytes[3], val);
      Serial.print("channel "); Serial.print(inBytes[3]);
      Serial.print(", val: "); Serial.println(val);
      break;
    case 9:
      val = inBytes[1] + (inBytes[2] * 128);
      mcp.setChannelValue(inBytes[0], val);
      Serial.print("channel "); Serial.print(inBytes[0]);
      Serial.print(", val: "); Serial.println(val);
      val = inBytes[4] + (inBytes[5] * 128);
      mcp.setChannelValue(inBytes[3], val);
      Serial.print("channel "); Serial.print(inBytes[3]);
      Serial.print(", val: "); Serial.println(val);
      val = inBytes[7] + (inBytes[8] * 128);
      mcp.setChannelValue(inBytes[6], val);
      Serial.print("channel "); Serial.print(inBytes[6]);
      Serial.print(", val: "); Serial.println(val);
      break;
    case 12:
      val = inBytes[1] + (inBytes[2] * 128);
      mcp.setChannelValue(inBytes[0], val);
      Serial.print("channel "); Serial.print(inBytes[0]);
      Serial.print(", val: "); Serial.println(val);
      val = inBytes[4] + (inBytes[5] * 128);
      mcp.setChannelValue(inBytes[3], val);
      Serial.print("channel "); Serial.print(inBytes[3]);
      Serial.print(", val: "); Serial.println(val);
      val = inBytes[7] + (inBytes[8] * 128);
      mcp.setChannelValue(inBytes[6], val);
      Serial.print("channel "); Serial.print(inBytes[6]);
      Serial.print(", val: "); Serial.println(val);
      val = inBytes[10] + (inBytes[11] * 128);
      mcp.setChannelValue(inBytes[9], val);
      Serial.print("channel "); Serial.print(inBytes[9]);
      Serial.print(", val: "); Serial.println(val);
      break;
    default:
      break;
  }
}

Any ideas?
 
I need to use a Teensy LC as an I2C slave for a Raspberry Pi, which at the same time will act as an I2C master in order to control Adafruit's quad DAC, MCP4728.
Teensy LC has two I2C busses, where the first bus is at pins 18 and 19, and the second at pins 22 and 23, right? I'm trying to access the second bus with Wire1 but I get this error:
Code:
'Wire1' was not declared in this scope
...

Any ideas?

Yes. ;)

Since LC has little memory and it is thought that few use Wire1, by default it is not created on the LC.

Fix:

Go edit in the wire library, the WireKinetis.h

Look at about line see 40-42...

Code:
#if defined(__MKL26Z64__)
#define WIRE_IMPLEMENT_WIRE
//Wire1 consumes precious memory on Teensy LC
//#define WIRE_IMPLEMENT_WIRE1
And uncomment that define for Wire1
 
@Paul and others - I do have a branch of this code which converted this library to new style Arduino library, where there is SRC directory and it creates an archive, which allows me to create all of the objects and then the link phase will only bring in those objects which are necessary. I did find that I needed to muck it up slightly and always include Wire as some libraries use this even though no real reference....

Question is should I make a Pull Request for this? Should I have it leave stub header files? As to direct all stuff into src...
 
Yes. ;)

Since LC has little memory and it is thought that few use Wire1, by default it is not created on the LC.

Fix:

Go edit in the wire library, the WireKinetis.h

Look at about line see 40-42...

Code:
#if defined(__MKL26Z64__)
#define WIRE_IMPLEMENT_WIRE
//Wire1 consumes precious memory on Teensy LC
//#define WIRE_IMPLEMENT_WIRE1
And uncomment that define for Wire1

That did it! I guess the precious memory Wire1 eats up, is only used when calling Wire1, right?
Thanks for the solution!
 
Actually Wrong... It will be eaten in any sketch that uses the Wire library. Which is why I mentioned in the second post I have a version that made Wire library into a newer type library and setup the library properties such that when building it would create an archive file (.a) which is included in the link. When the link is done with an archive. Only those files that resolve any non-resolved symbols will be brought in. So in the library version each WireX object has it's own file, and as such if on T3.6 you don't use Wire3... It wont be created and use up memory... Likewise in this case for Wire1 on LC
 
Status
Not open for further replies.
Back
Top