Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 3 of 3

Thread: Teensy 4.1 I2C slave crashing after data request

  1. #1

    Teensy 4.1 I2C slave crashing after data request

    I have a Teensy 4.1 hooked up to a Raspberry Pi. I have communication working with an example sketch (arduino IDE) and i can request data with the Raspberry pi multiple times without any problem. I'm using this library instead of the default "Wire" because it has a 'slave' function: https://github.com/Richard-Gemmell/teensy4_i2c

    i then put this exact code in my other code project, and a data request from the pi gives the wanted result, but only the first time!
    after that, the I2C slave (Teensy) cannot be found by the raspberry pi and i need to manually reset it by pressing the button before it starts working again.

    I have no idea what can cause this and why, so any help is greatly appreciated.

    Example sketch (Working always):
    Code:
    // Wire Slave Sender
    // by Nicholas Zambetti <http://www.zambetti.com>
    // Modified by Richard Gemmell Oct 2019
    
    // Demonstrates use of the Wire library
    // Sends data as an I2C/TWI slave device
    // Refer to the "Wire Master Reader" example for use with this
    // To use it, connect a master to the Teensy on pins 18 and 19.
    //
    // Consider using the I2CRegisterSlave class instead of Wire to
    // create an I2C slave.
    
    // Created 29 March 2006
    
    // This example code is in the public domain.
    
    #include <Arduino.h>
    #include <i2c_driver.h>
    #include <i2c_driver_wire.h>
    
    void requestEvent();
    
    int led = LED_BUILTIN;
    
    void setup()
    {
      pinMode(led, OUTPUT);
      Wire1.begin(8);        // join i2c bus with address #8
      Wire1.onRequest(requestEvent); // register event
    }
    
    void loop()
    {
      delay(100);
    }
    
    // function that executes whenever data is requested by master
    // this function is registered as an event, see setup()
    void requestEvent()
    {
      uint16_t gotArray[13] = {1,2,3,4,5,6,7,8,9,10,11,12,13};
      digitalWrite(led, HIGH);      // briefly flash the LED
      Wire1.write(gotArray[13]);     // respond with message of 6 bytes
                                    // as expected by master
      digitalWrite(led, LOW);
    }
    Sketch with my other code added but identical I2C code (Working once then crashes):
    Code:
    #include <Arduino.h>
    #include "AdvServo.h"
    #include "FootSensor.h"
    #include "InverseKinematics.h"
    #include "Util.h"
    #include <Servo.h>
    //MANO'S REMOTE STUFF
    #include <SPI.h>
    #include <nRF24L01.h>
    #include <RF24.h>
    RF24 radio(37, 38); // CE, CSN
    const byte address[6] = "00001"; // CHANGE TO A UNIQUE ADDRESS (SAME AS ON THE REMOTE)
    uint16_t gotArray[13];
    // END OF MANO'S REMOTE STUFF
    //I2C STUFF BELOW
    #include <i2c_driver.h>
    #include <i2c_driver_wire.h>
    // END I2C STUFF
    
    using namespace std;
    
    String serialResponse = "";
    char msg0[] = "0,-999.9,-999.9,-999.9"; // general structure for normal position command
    char msg1[] = "0,-999.9,-999.9,-999.9,-999.9,-999.9,-999.9"; // general structure for normal position/speed command
    bool ESTOPPED = false;
    int max_speed = 500; // deg / sec
    
    
    AdvServo BR_Hip, BR_Shoulder, BR_Wrist, BL_Hip, BL_Shoulder, BL_Wrist, FR_Hip, FR_Shoulder, FR_Wrist, FL_Hip, FL_Shoulder, FL_Wrist;
    FootSensor FL_sensor, FR_sensor, BL_sensor, BR_sensor;
    AdvServo * hips[4] = {&FL_Hip, &FR_Hip, &BL_Hip, &BR_Hip};
    AdvServo * shoulders[4] = {&FL_Shoulder, &FR_Shoulder, &BL_Shoulder, &BR_Shoulder};
    AdvServo * wrists[4] = {&FL_Wrist, &FR_Wrist, &BL_Wrist, &BR_Wrist};
    Util util;
    InverseKinematics ik;
    
    void attach_servos() {
      // HIPS
      FL_Hip.init(4, 135, -2);
      FR_Hip.init(11, 135, 0);
      BL_Hip.init(7, 135, 0);
      BR_Hip.init(8, 135, -3);
    
      //SHOULDERS
      FL_Shoulder.init(2, 180, -3);
      FR_Shoulder.init(13, 90, -14);
      BL_Shoulder.init(5, 180, 5); // +
      BR_Shoulder.init(10, 90, 0); // -
    
      //WRISTS
      FL_Wrist.init(3, 0, 2);
      FR_Wrist.init(12, 270, -2);
      BL_Wrist.init(6, 0, 2);
      BR_Wrist.init(9, 270, -1);
    
      //FL_sensor.init(A9, 17);
      //FR_sensor.init(A8, 16);
      //BL_sensor.init(A7, 15);
      //BR_sensor.init(A6, 14);
    
      setLegJointIDS();
    
      delay(1000);
    }
    
    void detach_servos() {
      // HIPS
      FL_Hip.detach();
      FR_Hip.detach();
      BR_Hip.detach();
      BL_Hip.detach();
    
      // SHOULDER
      FL_Shoulder.detach();
      FR_Shoulder.detach();
      BR_Shoulder.detach();
      BL_Shoulder.detach();
    
      // WRIST
      FL_Wrist.detach();
      FR_Wrist.detach();
      BR_Wrist.detach();
      BL_Wrist.detach();
    }
    
    void update_servos(){
      // HIPS
      FL_Hip.update_clk();
      FR_Hip.update_clk();
      BR_Hip.update_clk();
      BL_Hip.update_clk();
    
      // SHOULDER
      FL_Shoulder.update_clk();
      FR_Shoulder.update_clk();
      BR_Shoulder.update_clk();
      BL_Shoulder.update_clk();
    
      // WRIST
      FL_Wrist.update_clk();
      FR_Wrist.update_clk();
      BR_Wrist.update_clk();
      BL_Wrist.update_clk();
    }
    
    void update_sensors() {
      FL_sensor.update_clk();
      FR_sensor.update_clk();
      BL_sensor.update_clk();
      BR_sensor.update_clk();
    }
    
    void setLegJointIDS() {
      // HIPS
      FL_Hip.setType(0, 0);
      FR_Hip.setType(1, 0);
      BL_Hip.setType(2, 0);
      BR_Hip.setType(3, 0);
    
      //SHOULDERS
      FL_Shoulder.setType(0, 1);
      FR_Shoulder.setType(1, 1);
      BL_Shoulder.setType(2, 1);
      BR_Shoulder.setType(3, 1);
    
      //WRISTS
      FL_Wrist.setType(0, 2);
      FR_Wrist.setType(1, 2);
      BL_Wrist.setType(2, 2);
      BR_Wrist.setType(3, 2);
    
    }
    
    void readRemote(){
      while(radio.available()){ 
        radio.read( &gotArray, sizeof(gotArray) ); 
        //Serial.print("Recieved array:\n"); 
        //for (byte i=0; i<13; i++){
          //Serial.print(gotArray[i]);
          //Serial.print(",");
        //}
        //Serial.println("\n");
      }
    }
    
    void requestEvent();
    
    void setup() {
      // SETUP RADIO FOR MANO'S REMOTE
      SPI1.setCS(38);
      SPI1.setMISO(39);
      SPI1.begin();
      //Serial.begin(2000000);
      //Serial.println("starting....");
      radio.begin();
      radio.openReadingPipe(0, address);   //Setting the address at which we will receive the data
      radio.setPALevel(RF24_PA_MAX);       //You can set this as minimum or maximum depending on the distance between the transmitter and receiver.
      radio.setDataRate(RF24_2MBPS);
      radio.startListening();              //This sets the module as receiver
      //END
      //I2C initialization
      Wire1.begin(8);        // join i2c bus with address #8
      Wire1.onRequest(requestEvent); // register event
      // END I2C
    
      Serial1.begin(500000);
      ik.init(8.7, 59, 107, 130); // hip offset 0, hip_offset 1, shoulder length, wrist length
      FL_Hip.init(4, 135, -2);
      FR_Hip.init(11, 135, 0);
      BL_Hip.init(7, 135, 0);
      BR_Hip.init(8, 135, -3);
    
      //SHOULDERS
      FL_Shoulder.init(2, 180, -3);
      FR_Shoulder.init(13, 90, -14);
      BL_Shoulder.init(5, 180, 5); // +
      BR_Shoulder.init(10, 90, 0); // -
    
      //WRISTS
      FL_Wrist.init(3, 0, 2);
      FR_Wrist.init(12, 270, -2);
      BL_Wrist.init(6, 0, 2);
      BR_Wrist.init(9, 270, -1);
    
      FL_sensor.init(A9, 17);
      FR_sensor.init(A8, 16);
      BL_sensor.init(A7, 15);
      BR_sensor.init(A6, 14);
    
      setLegJointIDS();
    
      delay(1000);
      //attach_servos();
    }
    
    void loop() {
      readRemote();
      //MANO'S REMOTE SERVO POWER OFF
      if(gotArray[11]==1){
        detach_servos();
      } //else {
       // attach_servos();
     // }
      
      if(!ESTOPPED){
        update_servos();
      } else {
        detach_servos();
      }
        
      //update_sensors();
      if (Serial1.available()) {
        serialResponse = Serial1.readStringUntil('\r\n');
        // Convert from String Object to String.
        char buf[sizeof(msg0)];
        serialResponse.toCharArray(buf, sizeof(buf));
        char *ptr = buf;
        char *str;
        int index = 0;
        int leg = -1; //0=FL, 1=FR, 2=BL, 3=BR
        double x = -9999;
        double y = -9999;
        double z = -9999;
        while ((str = strtok_r(ptr, ",", &ptr)) != NULL) { // delimiter is the dash
          if(strcmp(str, "e") == 0 || strcmp(str, "E") == 0) {
            ESTOPPED = true;
          }
    
          if(index == 0) {
            util.upper(str);
            if(strcmp(str, "0") == 0){
              leg = 0;
            }
            if(strcmp(str, "1") == 0){
              leg = 1;
            }
            if(strcmp(str, "2") == 0){
              leg = 2;
            }
            if(strcmp(str, "3") == 0){
              leg = 3;
            }
          }
          if(index == 1) {
            x = atof(str);
          }
          if(index == 2) {
            y = atof(str);
          }
          if(index == 3) {
            z = atof(str);
          }
          index++;
        }
    
        //COMPLETE MESSAGE CHECK
        if(leg != -9999 || x != -9999 || y != -9999 || z != -9999){
          Serial.println("complete message");
          double *p;
          p = ik.run(leg, x, y, z);
    
          double temp_hip = util.toDegrees(*p);
    
          if(leg == 1 || leg == 2){
            temp_hip *= -1;
          }
    
          double hip_angle = util.angleConversion(leg, 0, temp_hip);
          double shoulder_angle = util.angleConversion(leg, 1, util.toDegrees(*(p+1)));
          double wrist_angle = util.angleConversion(leg, 2, util.toDegrees(*(p+2)));
    
          double h_dist = abs(hip_angle - (*hips[leg]).getPosition());
          double s_dist = abs(shoulder_angle - (*shoulders[leg]).getPosition());
          double w_dist = abs(wrist_angle - (*wrists[leg]).getPosition());
    
          double scaling_factor = util.max(h_dist, s_dist, w_dist);
    
          h_dist /= scaling_factor;
          s_dist /= scaling_factor;
          w_dist /= scaling_factor;
    
          (*hips[leg]).setPosition(hip_angle, max_speed * h_dist);
          (*shoulders[leg]).setPosition(shoulder_angle, max_speed * s_dist);
          (*wrists[leg]).setPosition(wrist_angle, max_speed * w_dist);
        }
      }
    }
    
    //I2C Data request response
    void requestEvent()
    {
      Wire1.write(gotArray[0]);     // respond with message of 6 bytes
      
    }
    Raspberry pi Python code (Master device):
    Code:
    #!/usr/bin/python
    
    import smbus
    
    bus = smbus.SMBus(1)    # 0 = /dev/i2c-0 (port I2C0), 1 = /dev/i2c-1 (port I2C1)
    
    #DEVICE_ADDRESS = 0x15      #7 bit address (will be left shifted to add the read$
    DEVICE_REG_MODE1 = 0x00
    DEVICE_REG_LEDOUT0 = 0x1d
    
    # Read a block of 16 bytes from address 80, offset 0
    count = 0
    while count < 5:
            block = bus.read_i2c_block_data(8, 0, 16)
            # Returned value is a list of 16 bytes
            print(block)
    What i also notice is that when i do a address scan from the pi ($ i2cdetect -y 1) it finishes in about 100ms, but when the teensy crashes that same scan takes about 10 seconds.


    In the end, what i'm trying to do is send an array (uint16 gotArray[13 values]) over i2c to the pi on the pi's request.
    Last edited by Mano1979; 07-14-2020 at 12:43 AM.

  2. #2
    Anyone? i'm really stuck here....

    i noticed that occasionally the so called 'non crashing' sketch, also crashes.

  3. #3
    Here the output from the python script:

    Code:
    pi@raspberrypi:~ $ python3 i2ctest.py
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [104, 101, 108, 108, 111, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    Traceback (most recent call last):
      File "i2ctest.py", line 14, in <module>
        block = bus.read_i2c_block_data(8, 0, 16)
    OSError: [Errno 121] Remote I/O error
    pi@raspberrypi:~ $

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •