Programming the 3DoT Current Limiter

Table of Contents

Hardware Overview

Current Limiting Circuit

Current allowed to be drawn by devices connected to 5V on the 3DoT board is controlled by the TPS2553 Constant-Current, Current-Limited Power-Distribution Switch. The value of the current limit set by this power switch is set by the resistance between the ILIM pin (5) and ground on said chip. This resistance can be programmed by I2C serial protocol communication with the MCP4017 Digital Rheostat.

The resistance of the MCP4017 is set in 128 steps, from 0Ω + wiper resistance (~100Ω), to 100kΩ. Combining the equation of the resistance of the MCP4017 with the equation for the current limit of the TPS2553 produces the following overall equation for our system:

3DoT current Limit formula

Where N is the number of steps written to the MCP4017 ( 0 < N ≤ 128).

Software Overview

Using the ArxRobot Library

The easiest way to set the 3DoT’s current limit is using the included ArxRobot Ardunio library. Make sure you have a created a 3DoT Robot such as:

ArxRobot ArxRobot;

Then, simply call:

  ArxRobot.setCurrentLimit(N);

Where N is the number of steps 0-128.

Arduino Software Implementation

First, make sure the Arduino I2C library Wire.h is included. You may also find it helpful to define the address of the MCP4017 at this stage:

#include 
#define MCP4017_ADDRESS 0x2F

Initialize the I2C protocol using this library:

Void setup()
{
Wire.begin();
}

Then, target the address of the MCP4017 and write the desired number of steps:

... some code here

Wire.beginTransmission(MCP4017_ADDRESS);
Wire.write(steps); //
Wire.endTransmission();

... some code here

 

C++ Software Implementation

In C++, the process is the same as Arduino, however, we must first write the functions to initialize, connect, write and disconnect to our I2C device.

void TWIInit(void)
{
    /* Set SCL frequency to ~200kHz */
    TWSR = 0x00;
    TWBR = 0x0C;
    /* Enable TWI */
    TWCR = (1<
}

void TWIStart(void)
{
    /* Send START condition */
    TWCR = (1<1<1<
    /* Wait for TWINT Flag set. This indicates that the START condition has been transmitted */
    while(!(TWCR & (1<
}

void TWIStop(void)
{
    TWCR = (1<1<1<
}

void TWIWrite(uint8_t u8data)
{
    /* Load data into TWDR Register. Clear TWINT bit in TWCR to start transmission */
    TWDR = u8data;
    TWCR = (1<1<
    /* Wait for TWINT Flag set. This indicates that the data has been transmitted, and ACK/NACK has been received. */
    while(!(TWCR & (1<
}

Then, we can call them in a similar order. Instead of “beginTransmission”, we call TWISTART to send a start condition, and then Write the MCP4017 address. 

Note: The address we write, this time, is not simply the hex slave address (SLA) of the MCP4017 (0x2F), but this address shifted left once, with an added bit to indicate whether we are reading or writing (+W). Read = 1, Write = 0. This ends up as 0x5E.

Void setCurrentLimit()
{

TWIInit(); // Sets I2C frequency
TWIStart(); // Start transmission
TWIWrite(SLA_W); // Address MCP4017, defined as 0x5E
TWIWrite(steps); // Write desired resistance value to MCP4017
TWIStop();

}

AVR Assembly Implementation

// Configure current limiter
/* Set SCL frequency to ~200kHz */
    ldi r16, 0x00
	sts TWSR, r16
    ldi r16, 0x0C
    sts TWBR, r16
/* Enable TWI */
    ldi r16, (1<<TWEN)
    sts TWCR, r16

/* Send start condition */
    ldi r16, (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)
    sts TWCR, r16

/* Wait for TWINT Flag set.
* This indicates that the START
* condition has been transmitted
*/
wait1:
    lds r16, TWCR
    sbrs r16, TWINT
    rjmp wait1

/* Load slave address + write bit (SLA_W)
 * into TWDR Register.
 * Clear TWINT bit in TWCR to
 * start transmission of address
 */
    ldi r16, 0x5E
    sts TWDR, r16
    ldi r16, (1<<TWINT)|(1<<TWEN)
    sts TWCR, r16
/* Wait for TWINT Flag set. This
 * indicates that the SLA+W has
 * been transmitted, and
 * ACK/NACK has been received.
 */
wait2:
    lds r16, TWCR
    sbrs r16, TWINT
    rjmp wait2
/* Load data to write to TWDR
 * and clear TWINT to start
 * transmission
 */
    ldi r16, 0x3C //STEPS = 60
    sts TWDR, r16
    ldi r16, (1<<TWINT)|(1<<TWEN)
    sts TWCR, r16
wait3:
    lds r16, TWCR
    sbrs r16, TWINT
    rjmp wait3
/* Transmite STOP condition */
    ldi r16, (1<<TWINT)|(1<<TWEN)|(1<<TWSTO)
    sts TWCR, r16
// End configure current limiter