ROBOTC Driver Tutorial
ROBOTC Driver Tutorial
ROBOTC Driver Tutorial
Xander Soldaat
Id Rather Be Building Robots
11-Apr-12
Contents
1
Introduction .................................................................................................................................... 2
1.1
1.2
1.3
1.3.1
Analogue ......................................................................................................................... 3
1.3.2
1.3.3
1.4
2
Prerequisites ........................................................................................................................... 3
2.2
Example 1: The fields are alive with the sound ofbeeping .................................................. 8
3.2
3.3
4.2
5.2
HiTechnic ............................................................................................................................... 21
5.3
LEGO ...................................................................................................................................... 21
5.4
Mindsensors .......................................................................................................................... 22
5.5
Others ................................................................................................................................... 22
1 Introduction
1.1 What is the ROBOTC Driver Suite?
ROBOTC comes with plenty of built in drivers for a wide variety of sensors. However, they dont
expose all of the power that some of these sensors have. They will often allow you to read the
sensors primary value and nothing more. For example, the HiTechnic Compass can only be read,
not calibrated through the standard drivers, you cant read the raw RGB values of a colour sensor.
Other sensors simply arent represented at all. There is a good reason for that, ROBOTC is a tool for
the masses, which means that it caters to it. Some of the more exotic sensors on the market cater to
a much smaller audience.
Thats where the Driver Suite comes in. It started with me wanting support for the HiTechnic IRLink
back in 2008 and now has support for 60+ sensors from many manufacturers. The aim of the Suite is
to make the drivers as easy and straight-forward to use as the ones that are built-in to ROBOTC. The
Suite will also expose most, if not all, of the functionality the sensor offers.
Sensor Driver
common.h
Additional common
includes
ROBOTC
The sensor driver contains the logic and commands that the sensor requires to function. This is the
part that you use in your own program.
The common.h include file contains the I2C communication code and a collection of utility functions.
These functions are generally not used by your program, although you are free to do so.
The Additional common includes contain functions that are common to a group of sensors, for
example, the Motor MUXes of Mindsensors and Holit Data Systems share a lot of features, so it
makes sense to de-duplicate them.
The ROBOTC layer is not part of the suite.
Analogue
Digital using I2C
Digital using RS485
1.3.1 Analogue
The analogue sensors are the simplest in their use. The NXT reads the voltage the sensor applies to
the sensor port and converts it to a 10 bit digital value between 0 and 1023. 0 means 0 volts and
1023 is between 4.3V and 4.8V, depending on the load on the NXT.
1.3.2 Digital I2C
Digital sensors that use I2C are by far the most common of the digital sensors. They use an industrystandard communications protocol called I2C, which stands for Inter-Integrated Circuit. I2C uses a
master/slave configuration where the NXT is the master and the sensor acts as the slave. Each slave
has an address between 0 and 127, with the first bit used to signal whether the master wants to
either write to (0) or read from (1) the slave.
Communicating with such sensors is a lot more complicated than simply reading a voltage on a pin.
Although LEGO has defined a standard for communicating with these sensors, not all manufacturers
adhere to this, for any number of reasons.
1.3.3 Digital using RS485
There are now several sensors on the market that use the NXTs high speed port, S4, which is able to
communicate at up to almost 1Mb/s using RS485. Compared to the max speed of 10KB/s or 30Kb/s
for I2C sensors, thats a massive speed increase.
1.4 Prerequisites
This tutorial assumes you are using at least ROBOTC 3.08. If you are not using this, or a later version,
please download it from http://www.robotc.net/download/nxt/
Please note that the Driver Suite has been written for the Mindstorms NXT and Tetrix platform and
will not work with VEX Cortex or PIC.
If you have not already purchased ROBOTC, please consider doing so through my Associate link,
doing so will help support me to continue writing sensor drivers and tutorials like this one!
http://secure.softwarekey.com/solo/products/info.asp?A=91555. Thank you!
Open the Preferences UI by navigating to the View menu and selecting Detailed Preferences
Click on the Browse button for the Source Files directory path and select whatever path youve been
using to store your ROBOTC programs. This tutorial assumes you are using D:\Programming
Click on the Browse button next to the Include files for Platform NXT and select
D:\Programming\rdpartyrobotcdr-2.5. The final result should resemble the window below:
To get access to the custom I2C sensors in your Motor and Sensors setup UI, do the following:
Open a new file:
Now open the Motor and Sensor Setup from the Robot menu
Navigate to the Sensor Management tab and ensure the Allow Custom Designed Sensors is ticked
and click OK.
3 Getting started
Now that you have a basic understanding of how the Suite has been designed and your ROBOTC
environment has been setup, it is time to get our hands dirty. I have created a number of examples
of how to create your own program from scratch. I realise that not all people who read this will have
those sensors but lucky for you, the Suite comes with at least one example program for each sensor
driver, often more. You will have to draw your own parallels between those programs and the
examples provided in this tutorial.
When using the Driver Suite, it is imperative that you dont use the built-in device specific sensor
drivers that are part of ROBOTC. They will cause a conflict and will give you very strange sensor
values or nothing at all. You must always check the example of the individual sensor driver to ensure
you are using the right sensor type.
Another important thing to note is that you should always use the functions from the Driver Suite
and not ROBOTCs own SensorValue[] variable. It will not contain any meaningful information
and may interfere with the Driver Suite.
3.1 Example 1: The fields are alive with the sound ofbeeping
The Dexter Industries dCompass is a 3D compass sensor; it can
detect magnetic field strengths on all three axes. Normally you
would use two of these axes (X and Y) to calculate your current
heading. However, using a little math, you can easily use it to
detect total magnetic field strength. This is very useful if you
want to use it to find cables in the wall or other metal objects.
To calculate the total field strength you can use the following
formula:
If we look at the documentation for the Dexter Industries dCompass, we can see there is a function
called DIMCreadAxes(), which allows us to read all three fields in one go:
Assuming the dCompass is connected to Sensor Port 1 (S1), the code for using this would looks like
this:
Before we can really use the sensor, it needs to be configured. The dCompass is a digital sensor that
uses I2C to communicate with the NXT. Open the Motors and Sensors Setup tool and navigate to
the Sensors tab. From the drop down menu, select I2C Custom and give the sensor a name like
DIMC or COMPASS
This will generate a set of pragma statements at the top of the program:
These statements are used by the compiler to ensure the sensor is configured correctly.
The dCompass needs to be initialised before we can start reading from it; the correct gain, sample
rate and mode need to be selected. This is done with DIMCinit():
In order to allow the compiler to find the driver, DIMC-driver.h in this case, well have to add an
#include statement below the pragma. Putting it all together, the program will end up looking
like this:
Our magnetic field detector is now ready to go! If you attach the sensor to the end of a beam like in
the picture below, you can wave it around like a magic wand.
10
( )
Then the robots heading ( )
at time
( )
is given as follows
( )
Here,
is defined as the start of the program, so describes the time elapsed since the
beginning of the program.
Actual measurement is not continuous. The angular velocity is measured once at each interval
. For example, if an interval is 20ms, then
. ( ) can therefore only be found as the
sum of small angle changes:
( )
( )
11
It is sometimes surprising how little code the math boils down to. This is not always the case,
though. Keep in mind that if you make
smaller, you may get more accurate results. 20ms was
chosen to allow the program to do other things as well, which well add later.
The angular velocity can be read with the HTGYROreadRot() function:
It is important to note that the Gyro is a sensor that needs to be calibrated before you use it. If you
were to read the sensors raw value, its value would be around 620 at rest. Negative angular
velocity would take away from that value, positve velocity would add to it. This isnt very useful and
around isnt the level of accuracy we need if we want to calculate the heading. This is where
HTGYROstartCal() comes in:
12
Once we have this offset value which is based on a number of measurements taken while the sensor
was at rest, it is subtracted from all measurements returned by HTGYROreadRot(). That means that
the angular velocity values are now -300 to +300 deg/sec, rather than 320 deg/s to 920 deg/s.
Assuming the Gyro is hooked up to Sensor Port 1 (S1), our code now looks like this:
ROBOTC will need to be configured to use this sensor correctly, and to do that we have to use the
Motors and Sensor Setup tool. Configure the sensor to be Analogue Raw Value (0) and give it a
meaningful name like HTGYRO:
That should generate the following pragma statements at the top of your file:
13
Next step is to add the #include statement to ensure the compiler can find the driver, delcare the
variables we need and display our current heading on the screen. Below you can see the final result:
Just mount the sensor to the side of your NXT brick and rotate
it around so you can see the heading change. You can watch a
video of it in action here:
http://www.youtube.com/watch?v=2bAcR3hktKs
This program is part of the Suite and can be found by opening
HTGYRO-test2.c in ROBOTC.
14
Multiplying the titlt data by 20 and 25 makes the frequencies a little more interesting. The max2
function takes the biggest number in the arguments given. That means that if the tilt data does go
below 0, max2() will simply return 0. This function is actually part of the Driver Suites common.h
file:
There is also a min2(), min3() and a max3(), which return the smallest of two, smallest of three
and largest of three numbers, respectively.
15
The tilt data can be read from the sensor using MSACreadTilt():
It is important to understand that the ACCEL-nNx is capable of operating on a number of scales and
needs to be configured properly before you can start reading from it. The scale were going to use is
10G. The scale is set using MSACsetRange():
Instead of the numbers 1 4, you can also use these aliases (defines):
This is a digital sensor, so well open the Motors and Sensors Setup tool and navigate to the Sensors
tab. From the drop down menu, select I2C Custom and give the sensor a name like ACCEL.
17
So now all you need to do is hook up your accelerometer to the side of your brick, connect it to
Sensor Port 1 and run it. You can find the complete program in the Driver Suite, just open MSACtest2.c in ROBOTC.
If youre curious to find out what mine sounded like, be sure to check out the video:
http://www.youtube.com/watch?v=PjGu2g-oVZk
18
4 Advanced Topics
4.1 Turning your sensor all the way to eleven
ROBOTC has a nifty feature that allows you to communicate with your your digital I2C sensors at a
much higher clock speed. The standard clock speed is around 10 KHz, which allows you to squeeze
about 1200 bytes/s. That excludes overhead of addresses, start and stop conditions. It comes down
to about 165 I2C transactions if youre only reading 1 byte from your sensor, much less if youre
looking to read multiple bytes.
You can speed things up dramatically if you use ROBOTCs fast I2C clock speed, which runs at 30KHz,
3 times the normal speed. Below are the results of some read tests that were performed a little
while ago:
Transactions per second
Bytes
Standard Clock
Fast Clock
1
167
501
2
143
500
3
125
500
4
125
334
5
111
333
6
100
333
7
91
251
8
83
250
9
77
250
10
71
220
11
67
200
12
63
200
13
59
187
14
56
167
15
53
167
16
50
166
Unfortunately, not all sensors like to communicate at this speed. HiTechnic and LEGO sensors tend
to behave better at the lower speed but Dexter Industries, Mindsensors and several others that have
been tried, seem to have no problems with the higher clock speeds.
Why you would even consider cranking up the speed? A good example would be when using
multiple sensors that require you to read 6 bytes at once, like the Mindsensors ACCEL-nx. Your
sensor reading loop can now go around much quicker, which can be a very good thing if speed is of
the essence. Who needs a soccer bot that plays in slow-mo?
Dont worry about breaking your sensor by trying out the higher speeds. The worst that can happen
is that you cause the sensor to hang, which is easily remedied by unplugging the cable and plugging
it back in. Then just reconfigure the sensor to use the normal clock speed, which is I2C Custom or
I2C Custom 9V.
The pragmas for the various types:
You dont need to change anything in your code, other than the pragmas to make use of the faster
clock speed. Do keep in mind, though, that a transaction between the NXT and sensor now takes
roughly a third of the time it did before. If you have specific timing in your code, you may need to
compensate for that.
20
Description
ROBOTC Dexter Industries dFlex Sensor driver
Dexter Industries GPS Sensor driver
Dexter Industries IMU Sensor driver
Dexter Industries IMU Sensor driver
ROBOTC dPressure Sensor Driver
ROBOTC DI Temp Probe Driver
Dexter Industries Thermal Infrared Sensor driver
5.2 HiTechnic
Name
HTAC-driver.h
HTANG-driver.h
HTBM-driver.h
HTCS-driver.h
HTCS2-driver.h
HTEOPD-driver.h
HTGYRO-driver.h
HTIRL-driver.h
HTIRR-driver.h
HTIRS-driver.h
HTIRS2-driver.h
HTMAG-driver.h
HTMC-driver.h
HTPB-driver.h
HTRCX-driver.h
HTSMUX-driver.h
HTSPB-driver.h
HTTMUX-driver.h
Description
Acceleration Sensor driver
Angle Sensor driver
Barometric Sensor driver
Color Sensor driver
Color Sensor V2 driver
EOPD Sensor driver
Gyroscopic Sensor driver
IR Link Sensor driver
IR Receiver Sensor driver
IR Seeker driver
IR Seeker V2 driver
Magnetic Field Sensor driver
Magnetic Compass Sensor Driver
Prototype Board driver
IR Link RCX Comms Driver
Commonly used SMUX functions used by drivers
SuperPro Prototype Board driver
Touch Sensor Multiplexer Sensor driver
5.3 LEGO
Name
LEGOEM-driver.h
LEGOLS-driver.h
LEGOSND-driver.h
LEGOTMP-driver.h
LEGOTS-driver.h
LEGOUS-driver.h
21
Description
RobotC Energy Meter Driver
Light Sensor driver
SMUX driver for the Lego Sound sensor
New Temperature Sensor Driver
Touch Sensor driver
SMUX driver for the Lego US sensor
5.4 Mindsensors
Name
MSAC-driver.h
MSDIST-driver.h
MSHID-driver.h
MSLL-driver.h
MSMMUX-driver.h
MSMTRMX-driver.h
MSNP-driver.h
MSPFM-driver.h
MSPM-driver.h
MSPPS-driver.h
MSRXMUX-driver.h
MSSUMO-driver.h
MSTMUX-driver.h
MSTP-driver.h
NXTCAM-driver.h
NXTServo-driver.h
Description
ACCEL-nx driver
DIST-Nx driver
HID Sensor driver
Line Tracking Sensor
Motor MUX driver
RCX Motor MUX Driver
Numeric Keypad Sensor driver
PFMate Sensor driver
Power Meter Sensor
PPS-v3 driver
MSRXMUX RCX Sensor MUX Sensor driver
Sumo Eyes Sensor driver
Touch Multiplexer Sensor driver
TouchPanel
NXTCam driver
NXTServo Sensor Driver
5.5 Others
Name
common.h
CTRFID-driver.h
EEPROM-driver.h
FLAC-driver.h
HDMMUX-driver.h
MAX127-driver.h
MCP23008-driver.h
MICC-driver.h
PCF8574-driver.h
STATS-driver.h
TMR-driver.h
22
Description
Commonly used functions used by drivers
Codatex RFID driver
EEPROM Driver
Firgelli Linear Actuator driver
Holit Data Systems Motor MUX driver
MAXIM MAX127 ADC driver
Microchip MCP23008 driver
MicroInfinity CruizCore XG1300L driver
Philips PCF8574 IO MUX driver
Statistics functions
Additional _timers
23