Teensy3.6 i2c RPi3

Status
Not open for further replies.

MarvinsMom

New member
I'm using a raspberry pi as a master and teensy 3.6 as slave. The SCL and SDA have 4.7 Kohm pull-up resistors to 3.3V. The teensy and RPi are powered through an external 4.9V supply. Their powers and grounds are connected.

In testing, when I power the RPi from its USB-C supply, and then the teensy off of the RPi, the program works and they talk i2c. When I power the RPi and the teensy from the external supply, they no longer talk. I am getting [Errno 5] Input/Output error from the RPi. The RPi is picking up the teensy located at the correct i2c address and it properly sends the SCL but cannot receive the SDA. I can send single bytes back and forth, but not blocks of data.

[Errno 5] Input/Output data normally means bad hardware or connections, but since the system is able to send single bytes back and forth, I do not think this is the issue. It seems the raspberry pi is improperly reading the SDA? Does it have something to do with my voltage logic?

All I am doing is telling the teensy I want to read 4 bytes, and then having the teensy send back 4 bytes to the pi.
 
First, check if you have a recent version of Teensyduino. In Arduino, click Help > About. 1.53 is the latest.

https://www.pjrc.com/teensy/td_download.html

Version 1.46 fixed a problem where Teensy 3.6 could fail to boot when using external power which turns on too slowly (a "soft start" circuit or huge capacitor in the power supply).

You might also add some code to blink the LED while waiting, so you can visually confirm Teensy 3.6 really is running and waiting for incoming communication.

Beyond that, I'm afraid I don't have much more to suggest without being able to see the code and wiring.
 
I have version 1.53 of Teensyduino. I added a blinking LED to confirm the Teensy 3.6 is waiting for the communication.

I am able to send blocks of data to the raspberry pi (just sending integers), but when I add an encoder, I get the [Errno 5] Input/Output error. In testing, the teensy reads the encoder data correctly and creates uint8_t databuffer to send to the pi.
 
Just a blind guess since I can't see any code here, but we know you're using I2C slave mode. Keep your onRequest function as simple as possible, since it gets called from interrupt context. Best to read only bytes from a buffer and do nothing other that transmit the data. Don't call other libraries or do any "real" work, as that's just asking for all sorts of interrupt context trouble.

If you're using the Encoder library, maybe add this before you include Encoder.h

Code:
#define ENCODER_DO_NOT_USE_INTERRUPTS

That will for Encoder to use the lower performance polling mode, but it also removes the complexity of interrupts.

I'm afraid that's all the blind guessing I can do here. I have no idea what you're really doing in the onRequest function or whether you've using Encoder.h or other code. Hopefully you can understand how difficult it is to help when you won't show us what you're really doing.
 
I'm reading a PWM from an encoder. It seems the teensy gets hung on the pulseIn() function. I need to get the dutycycle for multiple PWMs and send them to the raspberry pi. Here's my code:

Code:
#include <i2c_t3.h>

int t = 0;
bool blinking = 0;
#define MEM_LEN 2
uint8_t databuf[MEM_LEN];

void setup() {
  pinMode(13, OUTPUT); // LED
  pinMode(15, INPUT); // Encoder PWM
  Wire.begin(I2C_SLAVE, 0x08, I2C_PINS_18_19, I2C_PULLUP_EXT, 100000); // Setup for slave mode, addr 0x08, pins 18/19, external pullups, 100kHz
  Wire.onRequest(sendData);
}

void loop() {
  if (millis() - t > 100) {
    if (blinking) {digitalWrite(13, LOW); blinking = 0;}
    else {digitalWrite(13, HIGH); blinking = 1;}
    t = millis();
  }
}

void sendData(){
  int hightime = pulseIn(15, HIGH);
  int lowtime = pulseIn(15, LOW);
  float dutycycle = float(hightime) / float(hightime + lowtime);
  int angle = dutycycle * 360;
  databuf[0] = angle;
  databuf[1] = angle >> 8;
  Wire.write(databuf, MEM_LEN);
}
 
Don't call pulseIn() from your sendData() function. Do it in loop() and store the results in databuf[]. Your sendData() function should be as simple as possible because it runs from an interrupt.
 
Status
Not open for further replies.
Back
Top