DFRobot Nova Basic Kit -- Test Report

jwatte's picture

The kind folks at DFRobot sent me a sample of their "Nova Basic Kit" to test out.

The kit consists of a few parts:

1) A small carrier board for the Atmega 32u4 microcontroller (the same controller that powers the Arduino Leonardo)

2) A "shield" that plugs into this small carrier, and provides half-width JST connectors for pigtails to hook up I2C, UART, analog and digital devices. The pigtails have standard 100 mil (2.54 mm) pitch connectors on the ends.

3) A very small LiPo battery cell with a very small antenna-style connector to plug into the carrier board.

4) Actual pigtails to plug into the shield.

All the things in this kit are physically very small! It's the cutest piece of gear I've played with for a long time. The carrier board, and the shield, are each about 20x20 mm in size -- this is less than a square inch! The headers on the carrier board look like 50 mil pitch (1.27 mm) and are tiny as well. The board has a tiny on/off switch along one end, and a micro USB connector for programming (using the Arduino IDE) and charging the LiPo battery.

But it doesn't stop there! The carrier contains a small battery charger/protector/management system, with two status LEDs for charging state. It also contains a 3-axis accelerometer, with 10 bits of resolution along each axis.

As far as microcontrollers on the go goes, this kit is cute and quite clever. The LiPo battery is as tiny as anything else -- it fits between the two sandwiched carrier/shield boards, if you don't squeeze them together too tightly. If you push them all the way in, the sharp pins sticking out the bottom of the boards may puncture the gray LiPo cell pouch, which would be a bad and dangerous thing, so don't do that :-)

As I said, programming the device is easiest done using the Arduino IDE. Download and install version 1.0.5, select the Leonardo board option in the IDE, and start writing code!

Well, that's what it should have been like. Unfortunately, for me, it didn't detect the board correctly (I'm using Arch Linux, and generally program a large number of different microcontrollers.) Switching from Leonardo to Lilypad USB in the Arduino IDE made it recognize the board, but after I had programmed the basic blink sketch into it, the bootloader was somehow destroyed, and it would not be recognized on the USB bus anymore. This ought to be easily fixed by flashing a new bootloader using a regular USBtinyISP programmer -- but there is no ICSP header on this baord! (No doubt because of the tiny size.)

After exchanging some messages with their support on their forums, I found this pinout on their Wiki, which let me hook up the ICSP cable to the appropriate mini-pin header on the carrier board, and flash the latest Leonardo firmware onto the board. After doing that, the board has been stable, so perhaps the firmware that was on the board when I got it wasn't the latest Leonardo, and upgrading to that at the factory would make for a smoother out-of-the-box experience.

Here's a picture of flashing the bootloader again -- note how cramped the jumper wires are in that very tiny connector. I can't get over how adorably cute this little thing is!

So what did I make with this thing?

The small form factor allows it to go in many places -- pockets, bicycles, toys, ... I haven't found a permanent home for it. But, as a way to test out the accelerometer, and to see how long the battery will live, I wrote this sample sketch that works as a vibration detector. When laying still on a stable floor or table, the built-in indicator LED (bright white) is off. When it picks up any vibrations, it will light up. And this thing can be sensitive -- I've tuned it so that it picks up people walking next to the table, but it could be tuned all the way down to picking up typing on the keyboard. Which would mean it would pretty much always be on...

Here's the code. Paste it into the Arduino IDE and off you go! (This code would also work for a Leonardo or other Arduino board that you hook up an I2C accelerometer to compatible with the ADXL345B that appears to be on this board according to the schematics.

Actually, just trying to hold it still so it doesn't blink is a fun game in itself. I had to take it away from my wife when I showed it to her!

All in all, this is a great piece of kit for those looking for a very, very small, full-featured, LiPo battery powered Arduino Leonardo compatible board to go. Just make sure you get the right firmware into it!

#include <Wire.h>
#include <math.h>
 
#define ACCEL_ADDR ((uint8_t)0x53)
#define ACCEL_REG_POWER_CTL 0x2D
#define ACCEL_REG_DATA_FORMAT 0x31
#define ACCEL_REG_DATA_XL 0x32
#define ACCEL_REG_DATA_XH 0x33
#define ACCEL_REG_DATA_YL 0x34
#define ACCEL_REG_DATA_YH 0x35
#define ACCEL_REG_DATA_ZL 0x36
#define ACCEL_REG_DATA_ZH 0x37
 
#define THRESHOLD 4
 
const int ledPin = 13;
unsigned char brightness = 0;
float lastG = 0;
float delta = 0;
 
void accel_write_reg(unsigned char reg, unsigned char val) {
  Wire.beginTransmission(ACCEL_ADDR);
  Wire.write(reg);
  Wire.write(val);
  Wire.endTransmission();
}
 
unsigned char accel_read_regs(unsigned char reg, unsigned char cnt, unsigned char *buf) {
  Wire.beginTransmission(ACCEL_ADDR);
  Wire.write(reg);
  Wire.endTransmission();
  cnt = Wire.requestFrom(ACCEL_ADDR, cnt);
  for (unsigned char i = 0; i != cnt; ++i)
  {
    buf[i] = Wire.read();
  }
  return cnt;
}
 
void setup()
{
  pinMode(ledPin, OUTPUT);
  Wire.begin();
  accel_write_reg(ACCEL_REG_DATA_FORMAT, 0x1);
  accel_write_reg(ACCEL_REG_POWER_CTL, 0x08);
}
 
void loop()
{
  if (brightness > 0)
  {
    brightness -= 1;
  }
  unsigned char buf[6];
  if (accel_read_regs(ACCEL_REG_DATA_XL, 6, buf))
  {
    float x = ((int)buf[1] << 8) | buf[0];
    float y = ((int)buf[3] << 8) | buf[2];
    float z = ((int)buf[5] << 8) | buf[4];
    float dd = sqrt(x*x + y*y + z*z);  //  4G at +/- 511
    delta += fabs(dd - lastG);
    lastG = dd;
    if (delta > THRESHOLD)
    {
      delta -= THRESHOLD;
      unsigned char mb = (dd > 255) ? 255 : (unsigned char)dd;
      if (mb > brightness)
      {
        brightness = mb;
      }
      delta -= mb;
    }
    else
    {
      delta = delta * 0.5f;
      if (fabs(delta) < 0.000001f)
      {
        delta = 0;  //  kill denormals
      }
    }
  }
  analogWrite(ledPin, brightness);
  delayMicroseconds(1000);
}