Quantcast
Channel: Arduino Forum - Latest topics
Viewing all articles
Browse latest Browse all 15484

I2C Transmission Clock Speed of Start Condition

$
0
0

Hello,

I am trying to connect to a motor driver (MCTA8315A) via I2C using an ATmega328P on a PCB but I keep getting a NAK on transmission of the address (which should be 0x00 by default and I haven't changed it). I connected an oscilloscope to SCL and SDA, and it looks like the microcontroller is holding SCL low for longer than the clock speed of the I2C transmission. Any ideas why this might be?

I am using the sparkfun AVR pocket programmer and MiniCore core to upload programs to the ATmega328P. I am using the programming header to upload the program, but to test I disconnect the programmer and apply 9V to the J1 connector which feeds directly into VM of the motor driver, which supplies power to the microcontroller. I've also confirmed the SDA and SCL pins of the driver and microcontroller are connected and there's no soldering error.

I attached screenshots of my schematic, programming settings for uploading to the ATmega328P, and oscilloscope of SCL and SDA.

Thank you



/**
   Description: Connects to MCTA8315A motor driver and configures driver settings

   Created: 10 MAY 2024
   Updated: 26 MAY 2024

**/



// include libraries
#include <Wire.h>

// define motor driver address and registers
#define MCT8315A_ADDRESS 0x00
#define ISD_CONFIG_ADDRESS 0x00000080

// declare pins
const int LED_PIN = 10;           // ATmega328P pin PB2

// declare and initialize variables and libraries
// time variables
unsigned long current_millis = millis();

// function prototypes
void init_I2C(void);
void init_pins(void);
void init_motor_driver(void);
void blink_LED_x_times(uint8_t num_blinks);



// ********************************************** START PROGRAM ********************************************** //

void setup() {
  delay(100);

  init_pins();
  init_I2C();

//  delay(2000);
  delay(1000);
  // delay 2 seconds before starting program
}

void loop() {

  init_motor_driver();

//  delay(3000);
  delay(1500);
  // delay 3 seconds between loops

}



// ********************************************** FUNCTIONS ********************************************** //

void init_motor_driver(void) {
  // initializes motor driver registers
  
  uint8_t transmission_status;        // stores value returned by Wire.endTransmission(), 0 = success, 1-5 other error messages
  
  Wire.beginTransmission(MCT8315A_ADDRESS);
  transmission_status = Wire.endTransmission();
  if (transmission_status == 0) {
    blink_LED_x_times(8);
  }

  else {
    blink_LED_x_times(transmission_status);
  }
}

void init_I2C(void) {
  Wire.begin();

  // I2C transmission freq = clock / (16 + (2 * TWBR * prescaler)), clock freq = 1 MHz
//  TWBR = 2;        // TWBR (two wire bit rate) register
//  TWSR &= ~(0b11);     // set prescaler in TWSR register to 1
  Wire.setClock(100000);      // set transmission clock speed to 100kHz
}

void init_pins(void) {
  // initializes pins at input/output and pullups
  
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);
}

void blink_LED_x_times(uint8_t num_blinks) {
  // blink LED x number of times
  uint8_t led_state = digitalRead(LED_PIN);
//  const unsigned int led_blink_interval = 250;       // time in ms
  const unsigned int led_blink_interval = 125;       // time in ms
  unsigned long previous_led_flip_time = 0;

  for (uint8_t i = 0; i < num_blinks;) {
    current_millis = millis();
    while (current_millis - previous_led_flip_time < led_blink_interval) {
      current_millis = millis();
//      delay(50);
      delay(25);
    }

    // reached led_blink_interval
    previous_led_flip_time = current_millis;

    if (led_state == LOW) {
      led_state = HIGH;
    } else {
      led_state = LOW;
      i++;    // LED starts LOW, initial state will not be counted
    }
    digitalWrite(LED_PIN, led_state);
  }
}

4 posts - 3 participants

Read full topic


Viewing all articles
Browse latest Browse all 15484

Trending Articles