Skip to content

Latest commit

 

History

History
102 lines (74 loc) · 4.02 KB

README.md

File metadata and controls

102 lines (74 loc) · 4.02 KB

ATTiny85 I²C interface for TB6600

This firmware is based on the attiny85-i2c-pwm made by fooker (https://github.com/fooker/attiny85-i2c-pwm)

The idea is to implement a microcontroller interface (I2C slave) and signal generator to command an TB6600 or similar stepper motor driver.

New micros like ESP8266 don't work very well as signal generators, but provide some other functionalities. So with this code you can use an ATTiny85 as an interface to communicate to the TB6600 and setup some parameters like RPM, direction, etc just writting on function registers via I²C.

Note: For now the firmware supports free-run mode only. Which means you can set the speed and it'll move until you send another command to shut off the timer.

TB6600 pins and info

The TB6600 uses 3 opto-coupled signals to command the stepper motor: pulse (PUL+, PUL-), direction (DIR+, DIR-) and enable (ENA+, ENA-). More information at: https://www.dfrobot.com/wiki/index.php/TB6600_Stepper_Motor_Driver_SKU:_DRI0043

Pins and Wiring

Beside the usual VCC andGND pins, the following pins are used:

  • 2 (PB3) - ENA+
  • 3 (PB4) - DIR+
  • 5 (PB0) - I²C SDA
  • 6 (PB1) - PUL+
  • 7 (PB2) - I²C SCL

The I²C pins utilize the internal pull-ups but external pull-up resistors should be added according to the specifications.

Configuration

The configuration can be done by mondifying config.h accordin to the needs.

  • TWI_ADDRESS - Contains the address of the slave on the I²C bus. This must only contain the leading 7 bit of the address without the R/W flag.
  • ENA_PIN - Port to command the ENA+ signal
  • DIR_PIN - Same for the DIR+ signal
  • PUL_PIN - Same for the PUL+ signal

Registers

To setup the ATTiny85 just write over the I2C the function address (higher nibble) and the data to store (lower nibble) according to this table:

Higher nibble Lower nibble
F[3-0] D[3-0]
F3 F2 F1 F0 D3 D2 D1 D0 Register function
0 0 0 0 X X DIR ENA FUNC_SHAFT: Driver setup signals
0 0 0 1 X X X X FUNC_PRESC: Timer1 prescaler
0 0 1 0 X X X X FUNC_OCRAL: Timer1 counter (Lower nibble)
0 0 1 1 X X X X FUNC_OCRAH: Timer1 counter (Higher nibble)

Function example to set the motor speed in RPM

This is a draft function to represent how to set the ATTiny prescale and counter from a RPM speed value.

#define 	MIN_RPM		0
#define 	MAX_RPM		250

uint16_t	_ppv 	= 800		//800 pulses to make 1 turn

void setRPM(uint16_t rpm) {
  if ( (rpm<MIN_RPM) || (rpm>MAX_RPM) ) return;   // Check the speed range...
  
  uint8_t		_pre;		// prescale value (0 to 15)
  uint8_t		_ocr;		// counter value (0 to 255)

  if (rpm == 0) {
     // Set prescale to 0 to stop the timer
    _pre = 0;
    _ocr = 0;
  } else {
  
    // Calculate the best prescale/counter combination to achieve the desired RPM
    // This is done in two steps, first estimate a prescale value, then use it to
    // calculate the best counter value.
    
    uint16_t comp = (8000000L * 60) / (256 * _ppv * rpm);

    _pre = 1;
    uint16_t k;
    for (k=2; _pre<16; _pre++) {
      if (comp < k) {
        break;
      } else {
        k<<=1;
      }
    }

    _ocr = ((8000000L * 60) / (k * _ppv * rpm)) - 1;
        
    i2c_write(FUNC_PRESC, _pre & 0x0F);          // Set prescale
    i2c_write(FUNC_OCRAL, _ocr & 0x0F);          // Set counter lower nibble
    i2c_write(FUNC_OCRAH, (_ocr >> 4) & 0x0F);   // Set counter higher nibble (Timer enabled now)
    i2c_write(FUNC_SHAFT, 0b0010);               // Clock-wise direction '1' & Enable driver '0'
  }

TODO:

  • Polish the code.
  • Function to move the shaft an specified number of steps. This probably will require to add more function registers in the future.
  • Add an Arduino library to make it work with other micros like esp8266.