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