Kobold
Tags: robots, attiny84, drv8830
Published: 2014-02-01 10:00:00

---
title: Kobold
tags: robots, attiny84, drv8830
published_at: 20140201T10:00Z
canonical_url: https://ladvien.com/kobold
main_image: https://ladvien.com/images/Kobold_6.jpg
series: Custom PCBs
published: true
---



[Kobold Files](/files/Kobold_Working_1.zip)

{% embed https://www.youtube.com/embed/f5g_sLFr69g %}

Awhile back Sparkfun posted a new product, their [MiniMoto](https://www.sparkfun.com/products/11890) breakout board.  It breaks out the [DRV8830](http://www.ti.com/lit/ds/slvsab2f/slvsab2f.pdf) IC, which is a serially controlled (I2C) H-Bridge.  I thought the chip was nifty.  A few problems though,

1. Sparkfun's breakout was 25x25mm for _one_ bridge.  If I added another and then an Arduino Pro Mini it'd lose smallness.
2. It's $9.95
3. It's not on a purple board :)

So, I set out to make a robot controller with it that was smaller than a Sparkfun breakout.  What I ended up with is a little bitch I refer to a Kobold.

![](https://ladvien.com/images/IMG_0350.jpg)

The board is pretty straightforward.  It has an ATtiny 85 that acts as an I2C Master using the [SoftI2CMaster](http://todbot.com/blog/2010/09/25/softi2cmaster-add-i2c-to-any-arduino-pins/) library.  This allows the Tiny 85 to control two motors using only two pins, leaving three for your pleasure.  

My end goal will be to build a shield for it and hook up a HM-10 to make it a little wireless tethered bot.  This would bring me down to one pin, which I'm sure will be some sort of range finder or feeling sensor.

![](https://ladvien.com/images/Kobold_Board_Close.jpg)

The BOM:

1. [1 x ATtiny 85 SOIC](http://www.mouser.com/Search/ProductDetail.aspx?R=ATTINY85-20SHvirtualkey55650000virtualkey556-ATTINY85-20SH) $1.21
2. [2 x DRV8830 MSOP-10](http://www.mouser.com/ProductDetail/Texas-Instruments/DRV8830DGQ/?qs=sGAEpiMZZMuJc9I8Ed1ELBR0nLBayH7B) $5.10
3. [2 x .33 Ohm 0402](http://www.mouser.com/Search/ProductDetail.aspx?R=SR731ELTER330Fvirtualkey66000000virtualkey660-SR731ELTPR330F) $.86
4. 1 x 1uF 0402
5. 2 x 4.7k Res. 0402
6. [1 x Kobold PCB](http://www.oshpark.com/shared_projectss/NCVym4Uc) $2.50 (for three)

**Total: $9.76**

The board can be programmed with an Arduino ISP:

![](https://ladvien.com/images/Kobold_ISP_Pinout.jpg)

Now, I just need to make a robot with it :)

I'm currently working on a second iteration to correct some problems.  I'll also add a few features, like my pogo-pin programming interface.  The shield I have designed for it will also include a charging circuit and probably a SMD step-up circuit that should convert a LiPo to a nice 5v.  

Anyway, work in progress...just thought I'd share.  

**If anyone is interested in this board, please wait a few iterations. I get worried I'm making blue-smoke with someone else's money.  :)**

Here is the code running in the video:

```cpp
//Sample Code for the Kobold Board.
#define NO_INTERRUPT 1
#define I2C_TIMEOUT 100

#define SDA_PORT PORTB
#define SDA_PIN 4
#define SCL_PORT PORTB
#define SCL_PIN 3
#include <SoftI2CMaster.h>
#include <avr/io.h>

void CPUSlowDown(int fac) {
  // slow down processor by a fac
    CLKPR = _BV(CLKPCE);
    CLKPR = _BV(CLKPS1) | _BV(CLKPS0);
}

boolean writeSpeed(byte addr, int speedx)
{
  //This should clear the fault register.
  byte regValue = 0x08;
  //Clear the fault status, in case there is one.
  if (!i2c_start(addr | I2C_WRITE)) {
    return false;
  }
  if (!i2c_write(0x01)) {  //0x01 = We want to write.
    return false;
  }
  if (!i2c_write(regValue)) { //Write the clear bye for fault register.
    return false;
  }
  i2c_stop();  //Stop transmission.

  //Let's convert the integer given us into a byte.
  regValue = (byte)abs(speedx);     //Convert 0-63 to byte value to set speed.
  if (regValue > 63) regValue = 63; // Cap the value at 63.
  regValue = regValue<<2;           // Left shift to make room for bits 1:0
  if (speedx < 0) regValue |= 0x01;  // Set bits 1:0 based on sign of input.
  else           regValue |= 0x02;   //A negative number for reverse and positive for forward.

  //Now, let's move this sucker.
  //Sets the i2c slave address
  if (!i2c_start(addr | I2C_WRITE)) {
    return false;
  }
  //0x00 = We want to write something.
  if (!i2c_write(0x00)) {
    return false;
  }
  //Writes the byte which had been converted from an integer that was passed this function.  Annnnd! The motor moves!
  if (!i2c_write(regValue)) {
    return false;
  }
  i2c_stop();
  return true;
}

boolean writeStop(byte addr)
{
  if (!i2c_start(addr | I2C_WRITE)) {
    return false;
  }
  if (!i2c_write(0x00)) {
    return false;
  }
  if (!i2c_write(0x00)) {
    return false;
  }
  i2c_stop();
  return true;
}

//------------------------------------------------------------------------------
void setup(void) {
#if I2C_CPUFREQ == (F_CPU/8)
  CPUSlowDown();
#endif
}

void loop(void){

  for (int i = 0; i <= 3; i++){
  delay(100);
  if (!writeSpeed(0xC0, 10));
  if (!writeSpeed(0xCE, 10));
  delay(1000);
  if (!writeStop(0xC0) );
  if (!writeStop(0xCE) );
  delay(1000);  
  if (!writeSpeed(0xC0, -10));
  if (!writeSpeed(0xCE, -10));
  delay(1000);  
  if (!writeStop(0xC0) );
  if (!writeStop(0xCE) );
  delay(100);  
  }
   for (int i = 0; i <= 3; i++){
       delay(100);
  if (!writeSpeed(0xC0, 14));
  if (!writeSpeed(0xCE, 34));
  delay(1000);
  if (!writeStop(0xC0) );
  if (!writeStop(0xCE) );
  delay(1000);  
  if (!writeSpeed(0xC0, -14));
  if (!writeSpeed(0xCE, -34));
  delay(1000);  
  if (!writeStop(0xC0) );
  if (!writeStop(0xCE) );
  delay(100);  
   }
}
```