Example Source Code:
Unicoder ME-210 Arduino Library and Example

ME-210 Unicoder Demo

Description

This example demonstrates communicating with the ME-210 Unicoder encoder using I2C.

The output of the program will look like this:

Unicoder Test
Initialized
vel = 0
ang = 312
dist = 0
...


 

Download

Unicoder/Unicoder.cpp - Arduino library (cpp) source
Unicoder/Unicoder.h - Library header file
Unicoder/examples/Monitor/Monitor.ino - Arduino sketch file

 

Source Code


Unicoder/Unicoder.cpp


/******************************************************************************/
/* ME-210 Unicoder Library for Arduino 0022 - 1.0                             */
/*                                                                            */
/* Copyright 2009-2012, Noetic Design, Inc.                                   */
/*                                                                            */
/******************************************************************************/

#if defined(ARDUINO) && ARDUINO >= 100
  #include <Arduino.h>
#else
  #include <WProgram.h>
#endif
#include <Wire.h>
#include "Unicoder.h"

#define DEBUG 1
#define DEFAULT_TIMEOUT 500

Unicoder::Unicoder()
{
   ready = FALSE;
   slave_address = 0x18;
}

BOOL Unicoder::Init(void)
{
   char name[3];
   int version;

   Wire.begin(); // be an I2C master
   if (!Sync())
   {
#ifdef DEBUG
      Serial.println(F("No sync"));
#endif
      return FALSE;
   }
   if (!GetName(name, version))
   {
#ifdef DEBUG
      Serial.println(F("No name"));
#endif
      return FALSE;
   }
   if ((name[0] != 'U') || (name[1] != 'c'))
   {
#ifdef DEBUG
      Serial.print(F("Name incorrect: "));
      name[2] = '\0';
      Serial.println(name);
#endif
      return FALSE;
   }
   return ready = TRUE;
}

BOOL Unicoder::waitFor(int timeout, int chars)
{
   unsigned long timeToStop = (unsigned long)timeout + millis();
   while (Wire.available() < chars)
   {
      if (millis() > timeToStop)
      {
         return FALSE;
      }
   }
   return TRUE;
}

BOOL Unicoder::checkEOL(void)
{
   return TRUE;
}

BOOL Unicoder::checkAck(int timeout)
{
   if (waitFor(timeout, 1))
   {
#if defined(ARDUINO) && ARDUINO >= 100
      if (Wire.read() == UC_ACK)
#else
      if (Wire.receive() == UC_ACK)
#endif
         if (checkEOL())
            return TRUE;
   }
   return FALSE;
}

uint8_t Unicoder::getByte()
{
#if defined(ARDUINO) && ARDUINO >= 100
   return Wire.read();
#else
   return Wire.receive();
#endif
}

uint16_t Unicoder::getWord()
{
   uint16_t val;
   val = (uint16_t)getByte();
   val += ((uint16_t)getByte()) << 8;
   return val;
}

uint32_t Unicoder::getDword()
{
   uint32_t val;
   val = (uint32_t)getWord();
   val += ((uint32_t)getWord()) << 16;
   return val;
}

void Unicoder::putByte(uint8_t val)
{
#if defined(ARDUINO) && ARDUINO >= 100
   Wire.write(val);
#else
   Wire.send(val);
#endif
}

void Unicoder::putWord(uint16_t val)
{
   putByte((uint8_t)(val & 0x0ff));
   putByte((uint8_t)(val >> 8));
}

void Unicoder::putDword(uint32_t val)
{
   putWord((uint16_t)(val & 0x0ffff));
   putWord((uint16_t)(val >> 16));
}

BOOL Unicoder::doWordCommand(char command, uint16_t &val, int timeout)
{
   Wire.beginTransmission(slave_address);
   putByte(command);
   Wire.endTransmission();
   Wire.requestFrom(slave_address, 3);
   if (!waitFor(timeout, 3))
   {
      return FALSE;
   }
   if (getByte() != command)
   {
      return FALSE;
   }
   val = getWord();
   return checkEOL();
}


BOOL Unicoder::doDwordCommand(char command, uint32_t &val, int timeout)
{
   Wire.beginTransmission(slave_address);
   putByte(command);
   Wire.endTransmission();
   Wire.requestFrom(slave_address, 5);
   if (!waitFor(timeout, 5))
   {
      return FALSE;
   }
   if (getByte() != command)
   {
      return FALSE;
   }
   val = getDword();
   return checkEOL();
}


BOOL Unicoder::Sync()
{
   for (int i = 0; i < 10; i++)
   {
      Wire.beginTransmission(slave_address);
      putByte(UC_SYNC);
      Wire.endTransmission();
      Wire.requestFrom(slave_address, 1);
      if (waitFor(50 * (i + 1), 1))
      {
         int val = getByte();
         waitFor(200, 1);
         if (val == UC_SYNC)
            return TRUE;
      }
   }
   return FALSE;
}

BOOL Unicoder::GetName(char *name, int &version, int timeout)
{
   int cmd;
   int v;

   Wire.beginTransmission(slave_address);
   putByte(UC_NAME_CMD);
   Wire.endTransmission();
   Wire.requestFrom(slave_address, 5);

   if (!waitFor(timeout, 5))
   {
      return FALSE;
   }
   if ((cmd = getByte()) != UC_NAME_CMD)
   {
#ifdef DEBUG
      Serial.print(F("Name cmd not returned: '"));
      Serial.print(cmd);
      Serial.print(F("' (0x"));
      Serial.println(cmd, HEX);
#endif
      return FALSE;
   }
   if (name)
   {
      name[0] = getByte();
      name[1] = getByte();
      name[2] = '\0';
   }
   v = getByte() - '0';
   if (v > 9)
      v -= 7;
   version = v * 16;
   v = getByte() - '0';
   if (v > 9)
      v -= 7;
   version += v;

   return checkEOL();
}

BOOL Unicoder::Reset()
{
   Wire.beginTransmission(slave_address);
   putByte(UC_RESET_CMD);
   Wire.endTransmission();
   delay(100);
   return TRUE;
}

BOOL Unicoder::CommTest(int first, int last, int step)
{
}

BOOL Unicoder::GetStatus(STAT &stat)
{
   uint16_t val;
   if (doWordCommand(UC_STAT_CMD, val))
   {
      *((uint8_t *)&stat) = (uint8_t)val;
      return TRUE;
   }
   return FALSE;
}

BOOL Unicoder::SetMode(UC_MODE mode)
{
   return SetConstant(A_Mode, mode.data);
}

BOOL Unicoder::SetI2C7BitAddr(uint8_t i2c_7bit_address)
{
   return SetConstant(A_I2CAddr, i2c_7bit_address * 2);
}

BOOL Unicoder::GetI2C7BitAddr(uint8_t &i7bitadr)
{
   i7bitadr = slave_address;
   return TRUE;
}


BOOL Unicoder::GetProg(AS5040PROG &prog)
{
   uint8_t lo, hi;
   FLADDR addr = A_ProgLo;

   if (GetConstant(addr, lo))
   {
      addr = A_ProgHi;
      if (GetConstant(addr, hi))
      {
         ((uint8_t *)&prog)[0] = lo;
         ((uint8_t *)&prog)[1] = hi;
         return TRUE;
      }
   }
   return FALSE;
}

BOOL Unicoder::SetProg(AS5040PROG prog)
{
   uint8_t lo, hi;
   FLADDR addr = A_ProgLo;

   lo = ((uint8_t *)&prog)[0];
   hi = ((uint8_t *)&prog)[1];
   if (SetConstant(addr, lo))
   {
      addr = A_ProgHi;
      if (SetConstant(addr, hi))
         return TRUE;
   }
   return FALSE;
}



BOOL Unicoder::GetEncoderMode(int &enc_type, int &num_bits, BOOL &wide_index, BOOL &ccw)
{
   AS5040PROG prog;

   if (GetProg(prog))
   {
      enc_type = prog.mode;
      switch(prog.div)
      {
         case 0:
            num_bits = 10;
            break;
         case 1:
            num_bits = 9;
            break;
         case 2:
            num_bits = 8;
            break;
         case 3:
            num_bits = 7;
            break;
      }
      ccw = prog.ccw;
      wide_index = prog.index;
      return TRUE;
   }
   return FALSE;
}

BOOL Unicoder::SetEncoderMode(int enc_type, int num_bits, BOOL wide_index, BOOL ccw)
{
   AS5040PROG prog;

   if (GetProg(prog))
   {
      prog.mode = enc_type;
      switch (num_bits)
      {
         case 10:
            prog.div = 0;
            break;
         case 9:
            prog.div = 1;
            break;
         case 8:
            prog.div = 2;
            break;
         case 7:
            prog.div = 3;
            break;
         default:
            prog.div = 0;
      }
      prog.ccw = ccw;
      prog.index = wide_index;
      return SetProg(prog);
   }
   return FALSE;
}

BOOL Unicoder::SetZeroPosition(int angle)
{
   AS5040PROG prog;

   if (GetProg(prog))
   {
      prog.z = angle;
      return SetProg(prog);
   }
   return FALSE;
}

BOOL Unicoder::GetZeroPosition(int &angle)
{
   AS5040PROG prog;

   if (GetProg(prog))
   {
      angle = prog.z;
      return TRUE;
   }
   return FALSE;
}


BOOL Unicoder::GetLogBytes(int log_num, uint8_t *bytes, int num)
{
}

BOOL Unicoder::GetDistance(long &dist, int timeout)
{
   return doDwordCommand(UC_DST_CMD, (uint32_t &)dist, timeout);
}

BOOL Unicoder::GetAngle(int &ang, int timeout)
{
   if (doWordCommand(UC_ANG_CMD, (uint16_t &)ang, timeout))
   {
      if ((ang >= 0) && (ang <= 1023))
         return TRUE;
   }
   return FALSE;
}

BOOL Unicoder::GetVelocity(int &vel, int timeout)
{
   return doWordCommand(UC_VEL_CMD, (uint16_t &)vel, timeout);
}


BOOL Unicoder::SetDistance(long int dist, int timeout)
{
   Wire.beginTransmission(slave_address);
   putByte(UC_DST_CMD);
   putDword(dist);
   Wire.endTransmission();
   return TRUE;
}

BOOL Unicoder::SetAngle(int ang, int timeout)
{
   Wire.beginTransmission(slave_address);
   putByte(UC_ANG_CMD);
   putWord(ang);
   Wire.endTransmission();
   return TRUE;
}

BOOL Unicoder::SetVelocity(int vel, int timeout)
{
   Wire.beginTransmission(slave_address);
   putByte(UC_VEL_CMD);
   putWord(vel);
   Wire.endTransmission();
   return TRUE;
}

BOOL Unicoder::GetPeriod(long &period, int timeout)
{
   return doDwordCommand(UC_PERIOD_CMD, (uint32_t &)period, timeout);
}

BOOL Unicoder::GetTime(long &the_time, int timeout)
{
   return doDwordCommand(UC_TIME_CMD, (uint32_t &)the_time, timeout);
}

BOOL Unicoder::SetTime(long the_time)
{
   Wire.beginTransmission(slave_address);
   putByte(UC_TIME_CMD);
   putDword(the_time);
   Wire.endTransmission();
   return TRUE;
}


BOOL Unicoder::SetConstant(FLADDR addr, uint8_t const_value)
{
   uint16_t val = (addr & 0x0ff) | ((const_value & 0x0ff) << 8);
   Wire.beginTransmission(slave_address);
   putByte(UC_CONSTS_CMD);
   putWord(val);
   Wire.endTransmission();
   if (addr == A_I2CAddr)
   {
      slave_address = const_value >> 1;
   }
   return TRUE;
}

BOOL Unicoder::GetConstant(FLADDR addr, uint8_t &const_value)
{
   uint16_t val;
   Wire.beginTransmission(slave_address);
   putByte(UC_CONSTS_CMD);
   putByte(addr);
   Wire.endTransmission();
   Wire.requestFrom(slave_address, 3);
   if (!waitFor(DEFAULT_TIMEOUT, 3))
   {
      return FALSE;
   }
   if (getByte() != UC_CONSTS_CMD)
   {
      return FALSE;
   }
   val = getWord();
   if (!checkEOL())
   {
      return FALSE;
   }

   const_value = (val >> 8) & 0x0ff;
   if (!(addr == (val & 0x0ff)))
      return FALSE;
   return TRUE;
}

BOOL Unicoder::SetConstant(FLADDR addr, int16_t const_value)
{
   uint8_t temp = const_value & 0x0ff;
   if (SetConstant(addr, temp))
   {
      temp = (const_value >> 8) & 0x0ff;
      return SetConstant((FLADDR)((int)addr + 1), temp);
   }
   return FALSE;
}

BOOL Unicoder::GetConstant(FLADDR addr, int16_t &const_value)
{
   uint8_t temp;
   if (GetConstant(addr, temp))
   {
      const_value = temp;
      if (GetConstant(((FLADDR)((int)addr + 1)), temp))
      {
         const_value |= ((int16_t)temp) << 8;
         return TRUE;
      }
   }
   return FALSE;
}

BOOL Unicoder::StoreConstants()
{
   FLADDR addr = (FLADDR)0xff;
   uint8_t val = 0xff;
   return SetConstant(addr, val);
}



Unicoder/Unicoder.h


////////////////////////////////////////////////////////////////////////////////////////////////////
/// \file Unicoder.h
///
/// \brief Declares the Unicoder class
////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef _UNICODER_H_
#define _UNICODER_H_

#if defined(ARDUINO) && ARDUINO >= 100
  #include <Arduino.h>
#else
  #include <WProgram.h>
#endif
#include <inttypes.h>

#define TRUE 1
#define FALSE 0
typedef unsigned char BOOL;

#define UC_SYNC '.'
#define UC_NAME_CMD 'N'
#define UC_ECHO_CMD 'E'
#define UC_RESET_CMD 'R'

#define UC_CONSTS_CMD 'F'

#define UC_STAT_CMD 'S'
#define UC_AS5040_CMD 'Z'

#define UC_DST_CMD 'D'
#define UC_ANG_CMD 'W'
#define UC_VEL_CMD 'V'

#define UC_PERIOD_CMD 'P'
#define UC_TIME_CMD 'T'

#define UC_UPDATE_CMD 'U'

#define UC_COAST_CMD 'C'
#define UC_SERVO_CMD 'M'

#define UC_ALIGN_CMD 'A'

#define UC_ACK 'a'
#define UC_NACK 'n'

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \class  Unicoder
///
/// \author Pete Skeggs
/// \date 5/10/2011
///
/// \brief This provides an interface to the ME-210 Unicoder using I2C.
////////////////////////////////////////////////////////////////////////////////////////////////////

class Unicoder
{
public:

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief Constructor. 
///
///
////////////////////////////////////////////////////////////////////////////////////////////////////

Unicoder();


   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Initializes this object. 
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL Init(void);


#pragma pack(1)

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \struct uc_stat  
///
/// \brief . 
////////////////////////////////////////////////////////////////////////////////////////////////////

typedef struct uc_stat {
   uint8_t mag_dec : 1;  // 0
   uint8_t mag_inc : 1;  // 1
   uint8_t lin : 1;      // 2
   uint8_t cof : 1;      // 3
   uint8_t ocf : 1;      // 4
   uint8_t res : 3;      // 5
} STAT;

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \brief the uc mode union. 
///
/// \retval The uc mode union. 
////////////////////////////////////////////////////////////////////////////////////////////////////

typedef union _uc_mode_union
{
struct _uc_mode {
uint8_t i2c_mode : 1;
uint8_t rs232_mode : 1;
uint8_t hex_comms : 1;
uint8_t short_mode : 1;
uint8_t invert_servo : 1;
uint8_t filter_period : 1;
uint8_t res3 : 1;
uint8_t res4 : 1;
} flags;
uint8_t data;
} UC_MODE;

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \struct _as5040: the status register from the AS5040 chip. 
///
///
/// \brief . 
////////////////////////////////////////////////////////////////////////////////////////////////////

typedef struct _as5040 {
   uint32_t par : 1;
   uint32_t mag_dec : 1;
   uint32_t mag_inc : 1;
   uint32_t lin : 1;
   uint32_t cof : 1;
   uint32_t ocf : 1;
   uint32_t angle : 10;
   uint32_t factory : 16;
} AS5040;

////////////////////////////////////////////////////////////////////////////////////////////////////
/// \struct _as5040_prog: the programming register in the AS5040 chip.
///
/// \brief . 
////////////////////////////////////////////////////////////////////////////////////////////////////

typedef struct _as5040_prog {
   uint16_t mode : 2;
   uint16_t div : 2;
   uint16_t index : 1;
   uint16_t z : 10;
   uint16_t ccw : 1;
} AS5040PROG;

#define MD_DEFAULT 0
#define MD_QUADRATURE 1
#define MD_STEPDIR 2
#define MD_COMMUTATION 3

#define DV_1 0
#define DV_2 1
#define DV_4 2
#define DV_8 3

#define AP_QUAD_512 0x0001 // 0000 0000 0000 0001
#define AP_QUAD_256 0x0005 // 0000 0000 0000 0101
#define AP_QUAD_128 0x0009 // 0000 0000 0000 1001
#define AP_QUAD_64  0x000D // 0000 0000 0000 1101
#define AP_SNMG_512 0x0002 // 0000 0000 0000 0010
#define AP_SNMG_256 0x0006 // 0000 0000 0000 0110
#define AP_SNMG_128 0x000A // 0000 0000 0000 1010
#define AP_SNMG_64  0x000E // 0000 0000 0000 1110

#define APM_MODE  0x0002
#define APR_MODE  0
#define APM_DIV   0x0002
#define APR_DIV   2
#define APM_INDEX 0x0001
#define APR_INDEX 4
#define APM_Z     0x03ff
#define APR_Z     5
#define APM_CCW   0x0001
#define APR_CCW   15

#pragma pack()


   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Gets the status. 
   ///
   /// \param stat  - [in/out] a status value. 
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL GetStatus(STAT &stat);

   // eeprom addresses

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \enum _flash_addrs
   ///
   /// \brief Values that represent non-volatile constants that can be written and read.
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   typedef enum _flash_addrs 
   {
         A_WriteLo, A_WriteHi, A_Mode, A_Baud, A_I2CAddr, 
         A_ProgLo, A_ProgHi, A_ZeroLo, A_ZeroHi, A_FilterN, A_FilterK, A_End
   } FLADDR;


   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Sets the Unicoder operating mode. 
   ///
   /// \param mode  - A mode bitfield value.
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL SetMode(UC_MODE mode);

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Sets the I2C slave address for the Unicoder.
   ///
   /// \param i2c_7bit_address - the new address.
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL SetI2C7BitAddr(uint8_t i2c_7bit_address); // this takes a 7 bit address

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Retrieve the current I2C address of the Unicoder.
   ///
   /// \param i7bitadr  - [in/out] a 7bitadr. 
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL GetI2C7BitAddr(uint8_t &i7bitadr);

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Gets the Unicoder's operating mode
   ///
   /// \param enc_type      - [in/out] type of the encoder.
   /// \param num_bits      - [in/out] number of bits of resolution. 
   /// \param wide_index  - [in/out] the index pulse will be 3 pulses wide instead of 1 pulse.
   /// \param ccw          - [in/out] the angle increases in a counter-clockwise direction.
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL GetEncoderMode(int &enc_type, int &num_bits, BOOL &wide_index, BOOL &ccw);

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Sets the Unicoder's operating mode
   ///
   /// \param enc_type      - set the type of encoding
   /// \param num_bits      - Number of bits of resolution. 
   /// \param wide_index  - true to produce a wide index pulse.
   /// \param ccw          - true to have the angle increase in a counter clockwise direction.
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL SetEncoderMode(int enc_type, int num_bits, BOOL wide_index, BOOL ccw);

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Sets the Unicoder's zero angle position to the specified current angle.
   ///
   /// \param angle - The angle that will become the zero position.
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL SetZeroPosition(int angle);

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Gets the Unicoder's zero angle position.
   ///
   /// \param angle - [in/out] an angle. 
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL GetZeroPosition(int &angle);

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Gets the most recently measured time between encoder ticks (in multiples of 489ns)
   ///
   /// \param period  - [in/out] the most recent period.
   /// \param timeout  - A timeout. 
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL GetPeriod(long &period, int timeout = -1);

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Gets Unicoder run time
   ///
   /// \param the_time  - [in/out] elapsed time since power on, in multiples of 489ns; use this to 
   /// compensate for clock drift in the Unicoder, as its clock source is only 98% accurate.
   /// \param timeout  - A timeout in milliseconds. 
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL GetTime(long &the_time, int timeout = -1);

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Sets a the Unicoder's current run time.  Not normally used.
   ///
   /// \param the_time  - Time in multiples of 489 ns. 
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL SetTime(long the_time);

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Sets an 8 bit constant (non-volatile). 
   ///
   /// \param addr          - The address of the constant to change.
   /// \param const_value  - The value to set that constant to.
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL SetConstant(FLADDR addr, uint8_t const_value);

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Gets an 8 bit constant. 
   ///
   /// \param addr          - The address of the constant to retrieve.
   /// \param const_value  - [in/out] the constant's value.
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL GetConstant(FLADDR addr, uint8_t &const_value);

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Sets a word (16 bit) constant. 
   ///
   /// \param laddr      - The address of the constant to change.
   /// \param const_value  - The value of the constant.
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL SetConstant(FLADDR laddr, int16_t const_value);

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Gets a word (16 bit) constant. 
   ///
   /// \param laddr      - The address of the constant to retrieve.
   /// \param const_value  - [in/out] The constant's value.
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL GetConstant(FLADDR laddr, int16_t &const_value);

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Stores the constants. This must be executed after modifying one or more constants
   /// in order to write the changed value to non-volatile memory.
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL StoreConstants();

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Gets the AS5040 programming register value.
   ///
   /// \param prog  - [in/out] The programming register value.
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL GetProg(AS5040PROG &prog);

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Sets the AS5040 programming register value.
   ///
   /// \param prog  - The programming register value.
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL SetProg(AS5040PROG prog);

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Gets a log bytes [for debug]. 
   ///
   /// \param log_num  - A log number. 
   /// \param bytes  - A pointer to a buffer to store the log data in.
   /// \param num      - Number of bytes to retrieve. 
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL GetLogBytes(int log_num, uint8_t *bytes, int num);


   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Gets the total distance travelled since power on.
   ///
   /// \param dist      - [in/out] The distance in encoder ticks.
   /// \param timeout  - A timeout in milliseconds. 
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL GetDistance(long &dist, int timeout = 5000);

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Gets the current absolute angle of the Unicoder's shaft.
   ///
   /// \param ang      - [in/out] The angle.  The range depends on the resolution in bits.
   /// \param timeout  - A timeout in milliseconds. 
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL GetAngle(int &ang, int timeout = 5000);

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Gets the current shaft velocity in encoder ticks per second.
   ///
   /// \param vel      - [in/out] a vel. 
   /// \param timeout  - A timeout in milliseconds. 
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL GetVelocity(int &vel, int timeout = 5000);

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Sets the current distance travelled.
   ///
   /// \param dist      - [in/out] the distance to set to.
   /// \param timeout  - A timeout in milliseconds. 
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL SetDistance(long int dist, int timeout = 5000);

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Sets the current shaft angle.  Not normally used.
   ///
   /// \param ang      - [in/out] the angle.
   /// \param timeout  - A timeout in milliseconds. 
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL SetAngle(int ang, int timeout = 5000);

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Sets the current velocity.  Not normally used.
   ///
   /// \param vel      - [in/out] the velocity.
   /// \param timeout  - A timeout in milliseconds. 
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL SetVelocity(int vel, int timeout = 5000);

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Gets the name of the device.  Used to distinguish between various Nubotics products.
   ///
   /// \param name      - If non-null, points to a buffer in which the name will be stored.
   /// \param version  - [in/out] the current firmware version.
   /// \param timeout  - A timeout in milliseconds. 
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL GetName(char *name, int &version, int timeout = 10000);

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Resets the Unicoder.
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL Reset();

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Synchronises communication with the Unicoder.
   ///
   /// \retval true if it succeeds, false if it fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL Sync();

   ////////////////////////////////////////////////////////////////////////////////////////////////////
   /// \brief Tests communication with the Unicoder. 
   ///
   /// \param first - the starting value to write.
   /// \param last  - the last value to write.
   /// \param step  - Amount to increment the value by. 
   ///
   /// \retval true if the test passes, false if the test fails. 
   ////////////////////////////////////////////////////////////////////////////////////////////////////

   BOOL CommTest(int first = 0, int last = 256, int step = 1);

   UC_MODE curmode;
   BOOL ready;
   int slave_address;

   private:
      BOOL checkAck(int timeout = 5000);
      BOOL waitFor(int timeout, int chars);
      BOOL checkEOL(void);
      uint8_t getByte(void);
      uint16_t getWord(void);
      uint32_t getDword(void);
      void putByte(uint8_t val);
      void putWord(uint16_t val);
      void putDword(uint32_t val);
      BOOL doWordCommand(char command, uint16_t &val, int timeout = 5000);
      BOOL doDwordCommand(char command, uint32_t &val, int timeout = 5000);
};

#endif


Unicoder/examples/Monitor/Monitor.ino


// UnicoderTest
#include <Wire.h> // need to include this, as Unicoder.h needs it (and it must be included in the Sketch -- just including it in Unicoder.h does not work)
#include <Unicoder.h>


Unicoder uc;

void setup()   // run once, when the sketch starts
{
  Serial.begin(115200);
  Serial.println("Unicoder Test");
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  delay(500);  
  digitalWrite(13, HIGH);  // LED off
  delay(500);  
  digitalWrite(13, LOW);
  delay(500);  
  digitalWrite(13, HIGH);  // LED off
  for (;;)
  {
    if (uc.Init())
      break;
  }
  Serial.println("Initialized");
}

void loop()    // run over and over again
{
  int vel;
  long dist;
  int ang;
  if (uc.GetVelocity(vel))
  {
    Serial.print(" vel = ");
    Serial.println(vel);
  }
  if (uc.GetAngle(ang))
  {
    Serial.print(" ang = ");
    Serial.println(ang);
  }
  if (uc.GetDistance(dist))
  {
    Serial.print("dist = ");
    Serial.println(dist);
  }
  delay(500);





 

 © 2004-2013 Noetic Design, Inc. All Rights Reserved. Nubotics, Unicoder, WheelCommander, and WheelWatcher are trademarks of Noetic Design, Inc.