In this article we examine the Seeedstudio RFbee Wireless Data Transceiver nodes. An RFbee is a small wireless data transceiver that can be used as a wireless data bridge in pairs, as well as a node in mesh networking or data broadcasting. Here is an example of an RFbee:

You may have noticed that the RFbee looks similar to the Xbee-style data transceivers – and it is, in physical size and some pinouts, for example:

However this is where the similarity ends. The RFbee is in fact a small Arduino-compatible development board based on the Atmel ATmega168 microprocessor (3.3V at 8MHz – more on this later) and uses a Texas Instruments CC1101 low-power sub1-GHz RF transceiver chip for wireless transfer. Turning over an RFbee reveals this and more:

But don’t let all this worry you, the RFbee is very simple to use once connected. As a transceiver the following specifications apply:

Data rate – 9600, 19200, 38400 or 115200bps

Adjustable transmission power in stages between -30dBm and 10 dBm

Operating frequency switchable between 868MHz and 915MHz

Data transmission can be point-to-point, or broadcast point-to-many

Maximum of 256 RFbees can operate in one mesh network

draws only 19.3mA whilst transmitting at full power

The pinout for the RFbee are similar to those of an Xbee for power and data, for example:

Getting started is simple – RFbees ship with firmware which allows them to simply send and receive data at 9600bps with full power. You are going to need two or more RFbees, as they can only communicate with their own kind. However any microcontroller with a UART can be used with RFbees – just connect 3.3V, GND, and the microcontroller’s UART TX and RX to the RFbee and you’re away. For our examples we will be using Arduino-compatible boards. If Arduino is new to you, consider our tutorials first.

If you ever need to update the firmware, or reset the RFbee to factory default after some wayward experimenting – download the firmware which is in the form of an Arduino sketch (RFBee_v1_1.pde) which can be downloaded from the repository. (This has been tested with Arduino v23). In the Arduino IDE, set the board type to “Arduino Pro or Pro Mini (3.3V, 8MHz) w/ATmega168”. From a hardware perspective, the easiest way to update the firmware is via a 3.3V FTDI cable or an UartSBee board, such as:

You will also find a USB interface useful for controlling your RFbee via a PC or configuration (see below). In order to do this, you will need some basic terminal software. A favourite and simple example is called … “Terminal“. (Please donate to the author for their efforts).

Initial Testing

After connecting your RFbee to a PC, run your terminal software and set it for 9600 bps – 8 – None – no handshaking, and click the check box next to “+CR”. For example:

Select your COM: port (or click “ReScan” to find it) and then “Connect”. After a moment “OK” should appear in the received text area. Now, get yourself an Arduino or compatible board of some sort that has the LED on D13 (or substitute your own) and upload the following sketch:

Arduino

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

// RFbee demonstration sketch

intledPin=13;

byteincoming=0;

voidsetup()

{

Serial.begin(9600);

pinMode(ledPin,OUTPUT);

}

voidblinkLED(inti)

{

for(inta=0;a

voidloop()

{

if(Serial.available()>0)

{

incoming=Serial.read();

switch(incoming)

{

case'A':

blinkLED(1);

break;

case'B':

blinkLED(2);

break;

case'C':

blinkLED(3);

break;

default:

blinkLED(5);

}

Serial.println("Blinking completed!");

delay(2000);

Serial.flush();

}

}

Finally, connect the Arduino board to an RFbee in this manner:

Arduino D0 to RFbee TX

Arduino D1 to RFbee RX

Arduino 3.3V to RFbee Vcc

Arduino GND to RFbee GND

and the other RFbee to your PC and check it is connected using the terminal software described earlier. Now check the terminal is communicating with the PC-end RFbee, and then send the character ‘A’, ‘B’ or ‘C’. Note that the LED on the Arduino board will blink one, two or three times respectively – or five times if another character is received. It then reports back “Blinking completed!” to the host PC. For example (click to enlarge):

Although that was a very simple demonstration, in doing so you can prove that your RFbees are working and can send and receive serial data. If you need more than basic data transmission, it would be wise to get a pair of RFbees to experiment with before committing to a project, to ensure you are confident they will solve your problem.

More Control

If you are looking to use your RFbees in a more detailed way than just sending data at 9600 bps at full power, you will need to control and alter the parameters of your RFbees using the terminal software and simple AT-style commands. If you have not already done so, download and review the RFbee data sheet downloadable from the “Resources” section of this page. You can use the AT commands to easily change the data speed, power output (to reduce current draw), change the frequency, set transmission mode (one way or transceive) and more.

Reading and writing AT commands is simple, however at first you need to switch the RFbee into ‘command mode’ by sending +++ to it. (When sending +++ or AT commands, each must be followed with a carriage return (ASCII 13)). Then you can send commands or read parameter status. To send a command, just send AT then the command then the parameter. For example, to set the data rate (page ten of the data sheet) to 115200 bps, send ATBD3 and the RFbee will respond with OK.

You can again use the terminal software to easily send and receive the commands. To switch the RFbee from command mode back to normal data mode, use ATO0 (that’s AT then the letter O then zero) or power-cycle the RFbee.

RFbee as an Arduino-compatible board with inbuilt wireless

As mentioned previously the RFbee is based around an Atmel ATmega168 running at 8MHz with the Arduino bootloader. In other words, we have a tiny Arduino-compatible board in there to do our bidding. If you are unfamiliar with the Arduino system please see the tutorials listed here. However there are a couple of limitations to note – you will need an external USB-serial interface (as noted in Getting Started above), and not all the standard Arduino-type pins are available. Please review page four of the data sheet to see which RFbee pins match up to which Arduino pins.

If for some reason you just want to use your RFbee as an Arduino-compatible board, you can do so. However if you upload your own sketch you will lose the wireless capability. To restore your RFbee follow the instructions in Getting Started above.

The firmware that allows data transmission is also an Arduino sketch. So if you need to include RF operation in your sketch, first use a copy of the RFBee_v1_1.pde included in the repository – with all the included files. Then save this somewhere else under a different name, then work your code into the main sketch. To save you the effort you can download a fresh set of files which are used for our demonstration. But before moving forward, we need to learn about controlling data flow and device addresses…

Controlling data flow

As mentioned previously, each RFbee can have it’s own numerical address which falls between zero and 255. Giving each RFbee an address allows you to select which RFbee to exchange data with when there is more than two in the area. This is ideal for remote control and sensing applications, or to create a group of autonomous robots that can poll each other for status and so on.

To enable this method of communication in a simple form several things need to be done. First, you set the address of each RFbee with the AT command ATMAx (x=address). Then set each RFbee with ATOF2. This causes data transmitted to be formatted in a certain method – you send a byte which is the address of the transmitting RFbee, then another byte which is the address of the intended receipient RFbee, then follow with the data to send. Finally send command ATAC2 – which enables address checking between RFbees. Data is then sent using the command

Where data is … the data to send. You can send a single byte, or an array of bytes. length is the number of bytes you are sending. sourceAddress and destinationAddress are relevant to the RFbees being used – you set these addresses using the ATMAx described earlier in this section.

If you open the file rfbeewireless.pde in the download bundle, scroll to the end of the sketch which contains the following code:

Arduino

1

2

3

4

5

6

7

bytetestData[4]={'A','B','C','D'};

voidsendTestData()

{

// send the four bytes of data in the byte testData[] from address 1 to address 2

transmitData(testData,4,1,2);

delay(1000);

}

This is a simple example of sending data out from the RFbee. The RFbee with this sketch (address 1) sends the array of bytes (testdata[]) to another RFbee with address 2. You can disable address checking by a receiving RFbee with ATAC0 – then it will receive any data send by other RFbees.

The variable result will hold the incoming data, len is the number of bytes to expect, sourceAddress and destinationAddress are the source (transmitting RFbee) and destination addresses (receiving RFbee). rssi and lqi are the signal strength and link quality indicator – see the TI CC1101 datasheet for more information about these. By using more than two RFbees set with addresses you can selectively send and receive data between devices or control them remotely. Finally, please note that RFbees are still capable of sending and receiving data via the TX/RX pins as long as the sketch is not executing the sendTestData() loop.

I hope you found this introduction interesting and useful. The RFbees are an inexpensive and useful alternative to the popular Xbee modules and with the addition of the Arduino-compatible board certainly useful for portable devices, remote sensor applications or other data-gathering exercises.

RFbees are available from Seeedstudio and their network of distributors.

Disclaimer – RFbee products used in this article are promotional considerations made available by Seeedstudio.

In the meanwhile have fun and keep checking into tronixstuff.com. Why not follow things on twitter, Google+, subscribe for email updates or RSS using the links on the right-hand column? And join our friendly Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other – and we can all learn something.

In this article we will examine another product from a bundle sent for review by Snootlab, a Toulouse, France-based company that in their own words:

… designs and develops electronic products with an Open Hardware and Open Source approach. We are particularly specialized in the design of new shields for Arduino. The products we create are licensed under CC BY-SA v3.0 (as shown in documents associated with each of our creations). In accordance with the principles of the definition of Open Source Hardware (OSHW), we have signed it the 10th February 2011. We wish to contribute to the development of the ecosystem of “do it yourself” through original designs of products, uses and events.

Furthermore, all of their products are RoHS compliant and as part of the Open Hardware commitment, all the design files are available from the Snootlab website.

The subject of the review is the Snootlab Mémoire – an SD card data logging shield with on-board DS1307 real time clock [and matching backup battery] and prototyping area. It uses the standard SdFat library to write to normal SD memory cards formatted in FAT16 or FAT32. You can download the library from here. The real time clock IC is an easy to use I2C-interface model, and I have documented its use in great detail in this tutorial.

Once again, shield assembly is simple and quite straightforward. You can download an illustrated assembly guide from here, however it is in French. But everything you need to know is laid out on the PCB silk-screen, or the last page of the instructions. The it arrives in a reusable ESD bag:

… and all the required parts are included – including an IC socket and the RTC backup battery:

… the PCB is thick, with a very detailed silk-screen. Furthermore, it arrives with the SD card and 3.3V LDO (underneath) already pre-soldered – a nice touch:

The order of soldering the components is generally a subjective decision, and in this case I started with the resistors:

… and then worked my way out, but not fitting the battery nor IC until last. Intrestingly, the instructions require the crystal to be tacked down with some solder onto the PCB. Frankly I didn’t think it would withstand the temperature, however it did and all is well:

Which leaves us with a fully-assembled Mémoireshield ready for action:

Please note that a memory card is not included with the kit. If you are following along with your own Mémoire, the first thing to do after inserting the battery, IC and shield into your Arduino board and run some tests to ensure all is well. First thing is to test the DS1307 real-time clock IC. You can use the following sketch from chapter seven of my Arduino tutorial series:

Serial.print(hour,DEC);// convert the byte variable to a decimal number when being displayed

Serial.print(":");

if(minute<10)

{

Serial.print("0");

}

Serial.print(minute,DEC);

Serial.print(":");

if(second<10)

{

Serial.print("0");

}

Serial.print(second,DEC);

Serial.print(" ");

Serial.print(dayOfMonth,DEC);

Serial.print("/");

Serial.print(month,DEC);

Serial.print("/");

Serial.print(year,DEC);

Serial.print(" Day of week:");

switch(dayOfWeek){

case1:

Serial.println("Sunday");

break;

case2:

Serial.println("Monday");

break;

case3:

Serial.println("Tuesday");

break;

case4:

Serial.println("Wednesday");

break;

case5:

Serial.println("Thursday");

break;

case6:

Serial.println("Friday");

break;

case7:

Serial.println("Saturday");

break;

}

// Serial.println(dayOfWeek, DEC);

delay(1000);

}

If you are unsure about using I2C, please review my tutorial which can be found here. Don’t forget to update the time and date data in void setup(), and also comment out the setDateDS1307() function and upload the sketch a second time. The sketch output will be found on the serial monitor box – such as:

Those of you familiar with the DS1307 RTC IC know that it can generate a nice 1 Hz pulse. To take advantage of this the SQW pin has an access hole on the PCB, beetween R10 and pin 8 of the IC:

For instruction on how to activate the SQW output, please visit the last section of this tutorial.

The next test is the SD card section of the shield. If you have not already done so, download and install the SdFat libary. Then, in the Arduino IDE, select File > Examples > SdFat > SdFatInfo. Insert the formatted (FAT16/32) SD card into the shield, upload the sketch, then open the serial monitor. You should be presented with something like this:

As you can see the sketch has returned various data about the SD card. Finally, let’s log some data. You can deconstruct the excellent example that comes with the SdFat library titled SdFatAnalogLogger (select File > Examples > SdFat > SdFatAnalogLogger). Using the functions:

Arduino

1

2

file.print();

file.println();

you can “write” to the SD card in the same way as you would the serial output (that is, the serial monitor).

If you have reached this far without any errors – Congratulations! You’re ready to log. If not, remove the battery, SD card and IC from your shield (you used the IC socket, didn’t you?). Check the polarised components are in correctly, double-check your soldering and then reinsert the IC, shield and battery and try again. If that fails, support is available on the Snootlab website, and there is also a customer forum in French (use Google Translate). However as noted previously the team at Snootlab converse in excellent English and have been easy to contact via email if you have any questions. Stay tuned for the final Snootlab product review.

As always, thank you for reading and I look forward to your comments and so on. Furthermore, don’t be shy in pointing out errors or places that could use improvement. Please subscribe using one of the methods at the top-right of this web page to receive updates on new posts, follow on twitter, facebook, or join our Google Group.

[Disclaimer – the products reviewed in this article are promotional considerations made available by Snootlab]

In this article we will examine a variety of products received for review from Gravitech in the United States – the company that designed and build the Arduino Nano. We have a Nano and some very interesting additional modules to have a look at.

So let’s start out review with the Arduino Nano. What is a Nano? A very, very small version of our Arduino Duemilanove boards. It contains the same microcontroller (ATmega328) but in SMD form; has all the I/O pins (plus two extra analogue inputs); and still has a USB interface via the FT232 chip. But more on that later. Nanos arrive in reusable ESD packaging which is useful for storage when not in use:

Patriotic Americans should note that the Nano line is made in the USA. Furthermore, here is a video clip of Nanos being made:

For those who were unsure about the size of the Nano, consider the following images:

You can easily see all the pin labels and compare them to your Duemilanove or Uno board. There is also a tiny reset button, the usual LEDs, and the in circuit software programmer pins. So you don’t miss out on anything by going to a Nano. When you flip the board over, the rest of the circuitry is revealed, including the FTDI USB>serial converter IC:

Those of you familiar with Arduino systems should immediately recognise the benefit of the Nano – especially for short-run prototype production. The reduction in size really is quite large. In the following image, I have traced the outline of an Arduino Uno and placed the Nano inside for comparison:

So tiny… the board measures 43.1mm (1.7″) by 17.8mm (0.7″). The pins on this example were pre-soldered – and are spaced at standard 2.54mm (0.1″) intervals – perfect for breadboarding or designing into your own PCB – however you can purchase a Nano without the pins to suit your own mounting purposes. The Nano meets all the specifications of the standard Arduino Duemilanove-style boards, except naturally the physical dimensions.

Power can be supplied to the Nano via the USB cable; feeding 5V directly into the 5V pin, or 7~12 (20 max, not recommended) into the Vin pin. You can only draw 3.3V at up to 50 mA when the Nano is running on USB power, as the 3.3V is sourced from the FTDI USB>serial IC. And the digital I/O pins still allow a current draw up to 40 mA each. From a software perspective you will not have any problems, as the Nano falls under the same board classification as the (for example) Arduino Duemilanove:

Therefore one could take advantage of all the Arduino fun and games – except for the full-size shields. But as you will read soon, Gravitech have got us covered on that front. If the Arduino system is new to you, why not consider following my series of tutorials? They can be found here. In the meanwhile, to put the size into perspective – here is a short video of a Nano blinking some LEDs!

Now back to business. As the Nano does not use standard Arduino shields, the team at Gravitech have got us covered with a range of equivalent shields to enable all sorts of activities. The first of this is their Ethernet and microSD card add-on module:

and the underside:

Again this is designed for breadboarding, or you could most likely remove the pins if necessary. The microSD socket is connected as expected via the SPI bus, and is fully compatible with the default Arduino SD library. As shown in the following image the Nano can slot directly into the ethernet add-in module:

The Ethernet board requires an external power supply, from 7 to 12 volts DC. The controller chip is the usual Wiznet 5100 model, and therefore the Ethernet board is fully compatible with the default Ethernet Arduino library. We tested it with the example web server sketch provided with the Arduino IDE and it all just worked.

Using this module allows control of two DC motors with up to two amps of current each via pulse-width modulation. Furthermore, there is a current feedback circuit for each motor so you measure the motor load and adjust power output – interesting. So a motorised device could sense when it was working too hard and ease back a little (like me on a Saturday). All this is made possible by the use of the common L298 dual full-bridge motor driver IC. This is quite a common motor driver IC and is easy to implement in your sketches. The use of this module and the Nano will help reduce the size of any robotics or motorised project. Stay tuned for use of this board in future articles.

Next in this veritable cornucopia of add-on modules is the USBHOST board:

turning it over …

Using the Maxim MAX3421E host controller IC you can interface with all sorts of devices via USB, as well as work with the new Android ADK. The module will require an external power supply of between 7 and 12 volts DC, with enough current to deal with the board, a Nano and the USB device under control – one amp should be more than sufficient. I will be honest and note that USB and Arduino is completely new to me, however it is somewhat fascinating and I intend to write more about using this module in the near future. In the meanwhile, many examples can be found here.

For a change of scene there is also a group of Xbee wireless communication modules, starting with the Xbee add-on module:

The Xbee itself is not included, only shown for a size comparison. Turning the module over:

It is nice to see a clearly-labelled silk screen on the PCB. If you are unfamiliar with using the Xbee wireless modules for data communication, you may find my introductory tutorial of interest. Furthermore, all of the Gravitech Nano modules are fully software compatible with my tutorial examples, so getting started will be a breeze. Naturally Gravitech also produce an Xbee USB interface board, to enable PC communication over your wireless modules:

Again, note that the Xbee itself is not included, however they can be supplied by Gravitech. Turning the board over reveals another highly-detailed silk screen:

All of the Gravitech Xbee modules support both series 1.0 and 2.5 Xbees, in both standard and professional variants. The USB module also supports the X-CTU configuration software from Digi.

The MP3 board is designed around the VS1053B MP3 decoder IC. It can also decode Ogg Vorbis, AAC, WMA and MID files. There is a 3.5mm stereo output socket to connect headphones and so on. As expected, the microSD card runs from the SPI pins, however SS is pin 4. Although it may be tempting to use this to make a home-brew MP3 player, other uses could include: recorded voice messages for PA systems such as fire alarm notices, adding sound effects to various projects or amusement machines, or whatever else you can come up with.

The Arduino Nano and related boards really are tiny, fully compatible with their larger brethren, and will prove very useful. Although this article was an introductory review, stay tuned for further projects and articles that will make use of the Nano and other boards. If you have any questions or enquiries please direct them to Gravitech via their contact page. Gravitech products including the Arduino Nano family are available directly from their website or these distributors.

As always, thank you for reading and I look forward to your comments and so on. Furthermore, don’t be shy in pointing out errors or places that could use improvement. Please subscribe using one of the methods at the top-right of this web page to receive updates on new posts, follow on twitter, facebook, or join our Google Group.

[Disclaimer – the products reviewed in this article are promotional considerations made available by Gravitech]

This is the second of several chapters in which we are investigating the SPI data bus, and how we can control devices using it with our Arduino systems. If you have not done so already, please read part one of the SPI articles. Again we will learn the necessary theory, and then apply it by controlling a variety of devices. As always things will be kept as simple as possible.

First on our list today is the use of multiple SPI devices on the single bus. We briefly touched on this in part one, by showing how multiple devices are wired, for example:

Notice how the slave devices share the clock, MOSI and MISO lines – however they both have their own chip select line back to the master device. At this point a limitation of the SPI bus becomes prevalent – for each slave device we need another digital pin to control chip select for that device. If you were looking to control many devices, it would be better to consider finding I2C solutions to the problem. To implement multiple devices is very easy. Consider the example 34.1 from part one – we controlled a digital rheostat. Now we will repeat the example, but instead control four instead of one. For reference, here is the pinout diagram:

Doing so may sound complex, but it is not. We connect the SCK, MOSI and MISO pins together, then to Arduino pins D13, D11, D12 respectively. Each CS pin is wired to a separate Arduino digital pin. In our example rheostats 1 to 4 connect to D10 through to D7 respectively. To show the resistance is changing on each rheostat, there is an LED between pin 5 and GND and a 470 ohm resistor between 5V and pin 6. Next, here is the sketch:

// our MCP4162s requires data to be sent MSB (most significant byte) first

}

voidsetValue(intl,intvalue)

// sends value 'value' to SPI device on CS digital out pin 'l'

{

digitalWrite(l,LOW);

SPI.transfer(0);// send command byte

SPI.transfer(value);// send value (0~255)

digitalWrite(l,HIGH);

}

voidallOff()

// sets all pots to max resistance

{

setValue(led1,255);

setValue(led2,255);

setValue(led3,255);

setValue(led4,255);

}

voidpulse(intl)

{

allOff();

for(inta=255;a>=0;--a)

{

setValue(l,a);

delay(del);

}

for(inta=0;a<256;a++)

{

setValue(l,a);

delay(del);

}

}

voidpulseAll()

{

allOff();

for(inta=255;a>=0;--a)

{

setValue(led1,a);

setValue(led2,a);

setValue(led3,a);

setValue(led4,a);

delay(del);

}

for(inta=0;a<256;a++)

{

setValue(led1,a);

setValue(led2,a);

setValue(led3,a);

setValue(led4,a);

delay(del);

}

}

voidloop()

{

pulse(led1);

pulse(led2);

pulse(led3);

pulse(led4);

pulseAll();

}

Although the example sketch may be longer than necessary, it is quite simple. We have four SPI devices each controlling one LED, so to keep things easy to track we have defined led1~led4 to match the chip select digital out pins used for each SPI device. Then see the first four lines in void setup(); these pins are set to output in order to function as required. Next – this is very important – we set the pins’ state to HIGH. You must do this to every chip select line! Otherwise more than one CS pins may be initially low in some instances and cause the first data sent from MOSI to travel along to two or more SPI devices. With LEDs this may not be an issue, but for motor controllers … well it could be.

The other point of interest is the function

Arduino

1

voidsetValue(intl,intvalue)

We pass the value for the SPI device we want to control, and the value to send to the device. The value for l is the chip select value for the SPI device to control, and ranges from 10~7 – or as defined earlier, led1~4. The rest of the sketch is involved in controlling the LED’s brightness by varying the resistance of the rheostats. Now to see example 36.1 in action via the following video clip:

Next on the agenda is a digital-to-analogue converter, to be referred to using the acronym DAC. What is a DAC? In simple terms, it accepts a numerical value between zero and a maximum value (digital) and outputs a voltage between the range of zero and a maximum relative to the input value (analogue). One could consider this to be the opposite of the what we use the function analogRead(); for. For our example we will use a Microchip MCP4921 (data sheet.pdf):

(Please note that this is a beginners’ tutorial and is somewhat simplified). This DAC has a 12-bit resolution. This means that it can accept a decimal number between 0 and 4095 – in binary this is 0 to 1111 1111 1111 (see why it is called 12-bit) – and the outpout voltage is divided into 4096 steps. The output voltage for this particular DAC can fall between 0 and just under the supply voltage (5V). So for each increase of 1 in the decimal input value, the DAC will output around 1.221 millivolts.

It is also possible to reduce the size of the voltage output steps by using a lower reference voltage. Then the DAC will consider the reference voltage to be the maximum output with a value of 4095. So (for example) if the reference voltage was 2.5V, each increase of 1 in the decimal input value, the DAC will output around 0.6105 millivolts. The minimum reference voltage possible is 0.8V, which offers a step of 200 microvolts (uV).

The output of a DAC can be used for many things, such as a function generator or the playback of audio recorded in a digital form. For now we will examine how to use the hardware, and monitoring output on an oscilloscope. First we need the pinouts:

By now these sorts of diagrams shouldn’t present any problems. In this example, we keep pin 5 permanently set to GND; pin 6 is where you feed in the reference voltage – we will set this to +5V; AVss is GND; and Vouta is the output signal pin – where the magic comes from 🙂 The next thing to investigate is the MCP4921’s write command register:

Bits 0 to 11 are the 12 bits of the output value; bit 15 is an output selector (unused on the MPC4921); bit 14 controls the input buffer; bit 13 controls an inbuilt output amplifier; and bit 12 can shutdown the DAC. Unlike previous devices, the input data is spread across two bytes (or a word of data). Therefore a small amount of work needs to be done to format the data ready for the DAC. Let’s explain this through looking at the sketch for example 36.2 that follows. The purpose of the sketch is to go through all possible DAC values, from 0 to 4095, then back to 0 and so on.

First. note the variable outputvalue – it is a word, a 16-bit unsigned variable. This is perfect as we will be sending a word of data to the DAC. We put the increasing/decreasing value for a into outputValue. However as we can only send bytes of data at a time down the SPI bus, we will use the function highbyte() to separate the high side of the word (bits 15~8) into a byte variable called data.

We then use the bitwise AND and OR operators to set the parameter bits 15~12. Then this byte is sent to the SPI bus. Finally, the function lowbyte() is used to send the low side of the word (bits 7~0) into data and thence down the SPI bus as well.

By now we have covered in detail how to send data to a device on the SPI bus. But how do we receive data from a device?

Doing so is quite simple, but some information is required about the particular device. For the rest of this chapter, we will use the Maxim DS3234 “extremely accurate” real-time clock. Please download the data sheet (.pdf) now, as it will be referred to many times.

The DS3234 is not available in through-hole packaging, so we will be using one that comes pre-soldered onto a very convenient breakout board:

It only takes a few moments to solder in some header pins for breadboard use. The battery type is CR1220 (12 x 2.0mm, 3V); if you don’t have a battery you will need to short out the battery holder with some wire otherwise the IC will not work. Readers have reported that the IC doesn’t keep time if the USB and external power are both applied to the Arduino at the same time.

A device will have one or more registers where information is read from and written to. Look at page twelve of the DS3234 data sheet, there are twenty-three registers, each containing eight bits (one byte) of data. Please take note that each register has a read and write address. An example – to retrieve the contents of the register at location 08h (alarm minutes) and place it into the byte data we need to do the following:

Arduino

1

2

3

4

digitalWrite(10,LOW);// select the DS3234 that has its CS line on digital 10

SPI.transfer(0x08);// tell the DS3234 device we're requesting data from the register at 08h

data=SPI.transfer(0);// the DS3234 sends the data back and stores it in the byte data

digitalWrite(10,HIGH);// deselect the DS3234 if finished with it

Don’t forget to take note of the function SPI.setBitOrder(MSBFIRST); in your sketch, as this also determines the bit order of the data coming from the device. To write data to a specific address is also quite simple, for example:

Arduino

1

2

3

4

digitalWrite(10,LOW);

SPI.transfer(0x80);// tells the device which address to write to

SPI.transfer(b00001010);// you can send any representation of a byte

digitalWrite(10,HIGH);

Up to this point, we have not concerned ourselves with what is called the SPI data mode. The mode determines how the SPI device interprets the ‘pulses’ of data going in and out of the device. For a well-defined explanation, please read this article. With some devices (and in our forthcoming example) the data mode needs to be defined. So we use:

Arduino

1

SPI.setDataMode(SPI_MODE1);

to set the data mode, within void(setup);. To determine a device’s data mode, as always – consult the data sheet. With our DS3234 example, the mode is mentioned on page 1 under Features List.

Finally, let’s delve a little deeper into SPI via the DS3234. The interesting people at Sparkfun have already written a good demonstration sketch for the DS3234, so let’s have a look at that and deconstruct it a little to see what is going on. You can download the sketch below from here, then change the file extension from .c to .pde.

Don’t let the use of custom functions and loops put you off, they are there to save time. Looking in the function SetTimeDate();, you can see that the data is written to the registers 80h through to 86h (skipping 83h – day of week) in the way as described earlier (set CS low, send out address to write to, send out data, set CS high). You will also notice some bitwise arithmetic going on as well. This is done to convert data between binary-coded decimal and decimal numbers.

Why? Go back to page twelve of the DS3234 data sheet and look at (e.g.) register 00h/80h – seconds. The bits 7~4 are used to represent the ‘tens’ column of the value, and bits 3~0 represent the ‘ones’ column of the value. So some bit shifting is necessary to isolate the digit for each column in order to convert the data to decimal. For other ways to convert between BCD and decimal, see the examples using the Maxim DS1307 in chapter seven.

Finally here is another example of reading the time data from the DS3234:

So there you have it – more about the world of the SPI bus and how to control the devices within.

In the meanwhile have fun and keep checking into tronixstuff.com. Why not follow things on twitter, Google+, subscribe for email updates or RSS using the links on the right-hand column? And join our friendly Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other – and we can all learn something.

This is the first of two chapters in which we are going to start investigating the SPI data bus, and how we can control devices using it with our Arduino systems. The SPI bus may seem to be a complex interface to master, however with some brief study of this explanation and practical examples you will soon become a bus master! To do this we will learn the necessary theory, and then apply it by controlling a variety of devices. In this tutorial things will be kept as simple as possible.

But first of all, what is it? And some theory…

SPI is an acronym for “Serial Peripheral Interface”. It is a synchronous serial data bus – data can travel in both directions at the same time, as opposed to (for example) the I2C bus that cannot do so. To allow synchronous data transmission, the SPI bus uses four wires. They are called:

MOSI – Master-out, Slave-in. This line carries data from our Arduino to the SPI-controlled device(s);

MISO – Master-in, Slave out. This line carries data from the SPI-controlled device(s) back to the Arduino;

SS – Slave-select. This line tells the device on the bus we wish to communicate with it. Each SPI device needs a unique SS line back to the Arduino;

SCK – Serial clock.

Within these tutorials we consider the Arduino board to be the master and the SPI devices to be slaves. On our Arduino Duemilanove/Uno and compatible boards the pins used are:

SS – digital 10. You can use other digital pins, but 10 is generally the default as it is next to the other SPI pins;

MOSI – digital 11;

MISO – digital 12;

SCK – digital 13;

Arduino Mega users – MISO is 50, MOSI is 51, SCK is 52 and SS is usually 53. If you are using an Arduino Leonardo, the SPI pins are on the ICSP header pins. See here for more information. You can control one or more devices with the SPI bus. For example, for one device the wiring would be:

Data travels back and forth along the MOSI and MISO lines between our Arduino and the SPI device. This can only happen when the SS line is set to LOW. In other words, to communicate with a particular SPI device on the bus, we set the SS line to that device to LOW, then communicate with it, then set the line back to HIGH. If we have two or more SPI devices on the bus, the wiring would resemble the following:

Notice how there are two SS lines – we need one for each SPI device on the bus. You can use any free digital output pin on your Arduino as an SS line. Just remember to have all SS lines high except for the line connected to the SPI device you wish to use at the time.

Data is sent to the SPI device in byte form. You should know by now that eight bits make one byte, therefore representing a binary number with a value of between zero and 255. When communicating with our SPI devices, we need to know which way the device deals with the data – MSB or LSB first. MSB (most significant bit) is the left-hand side of the binary number, and LSB (least significant bit) is the right-hand side of the number. That is:

Apart from sending numerical values along the SPI bus, binary numbers can also represent commands. You can represent eight on/off settings using one byte of data, so a device’s parameters can be set by sending a byte of data. These parameters will vary with each device and should be illustrated in the particular device’s data sheet. For example, a digital potentiometer IC with six pots:

This device requires two bytes of data. The ADDR byte tells the device which of six potentiometers to control (numbered 0 to 5), and the DATA byte is the value for the potentiometer (0~255). We can use integers to represent these two values. For example, to set potentiometer number two to 125, we would send 2 then 125 to the device.

How do we send data to SPI devices in our sketches?

First of all, we need to use the SPI library. It is included with the default Arduino IDE installation, so put the following at the start of your sketch:

Arduino

1

#include "SPI.h"

Next, in void.setup() declare which pin(s) will be used for SS and set them as OUTPUT. For example,

Arduino

1

pinMode(ss,OUTPUT);

where ss has previously been declared as an integer of value ten. Now, to activate the SPI bus:

Arduino

1

SPI.begin();

and finally we need to tell the sketch which way to send data, MSB or LSB first by using

Arduino

1

SPI.setBitOrder(MSBFIRST);

or

Arduino

1

SPI.setBitOrder(LSBFIRST);

When it is time to send data down the SPI bus to our device, three things need to happen. First, set the digital pin with SS to low:

Arduino

1

digitalWrite(SS,LOW);

Then send the data in bytes, one byte at a time using:

Arduino

1

SPI.transfer(value);

Value can be an integer/byte between zero and 255. Finally, when finished sending data to your device, end the transmission by setting SS high:

Arduino

1

digitalWrite(ss,HIGH);

Sending data is quite simple. Generally the most difficult part for people is interpreting the device data sheet to understand how commands and data need to be structured for transmission. But with some practice, these small hurdles can be overcome.

Now for some practical examples!

Time to get on the SPI bus and control some devices. By following the examples below, you should gain a practical understanding of how the SPI bus and devices can be used with our Arduino boards.

Example 34.1

Our first example will use a simple yet interesting part – a digital potentiometer (we also used one in the I2C tutorial). This time we have a Microchip MCP4162-series 10k rheostat:

Here is the data sheet.pdf for your perusal. To control it we need to send two bytes of data – the first byte is the control byte, and thankfully for this example it is always zero (as the address for the wiper value is 00h [see table 4-1 of the data sheet]). The second byte is the the value to set the wiper, which controls the resistance. So to set the wiper we need to do three things in our sketch…

// our MCP4162 requires data to be sent MSB (most significant byte) first

}

voidsetValue(intvalue)

{

digitalWrite(ss,LOW);

SPI.transfer(0);// send command byte

SPI.transfer(value);// send value (0~255)

digitalWrite(ss,HIGH);

}

voidloop()

{

for(inta=0;a<256;a++)

{

setValue(a);

delay(del);

}

for(inta=255;a>=0;--a)

{

setValue(a);

delay(del);

}

}

Now to see the results of the sketch. In the following video clip, a we run up through the resistance range and measure the rheostat value with a multimeter:

Before moving forward, if digital potentiometers are new for you, consider reading this short guide written by Microchip about the differences between mechanical and digital potentiometers.

Example 34.2

In this example, we will use the Analog Devices AD5204 four-channel digital potentiometer (data sheet.pdf). It contains four 10k ohm linear potentiometers, and each potentiometer is adjustable to one of 256 positions. The settings are volatile, which means they are not remembered when the power is turned off. Therefore when power is applied the potentiometers are all pre set to the middle of the scale. Our example is the SOIC-24 surface mount example, however it is also manufactured in DIP format as well.

To make life easier it can be soldered onto a SOIC breakout board which converts it to a through-hole package:

In this example, we will control the brightness of four LEDs. Wiring is very simple. Pinouts are in the data sheet.pdf.

The function allOff() and allOn() are used to set the potentiometers to minimum and maximum respectively. We use allOff() at the start of the sketch to turn the LEDs off. This is necessary as on power-up the wipers are generally set half-way. Furthermore we use them in the blinkAll() function to … blink the LEDs. The function setPot() accepts a wiper number (0~3) and value to set that wiper (0~255). Finally the function indFade() does a nice job of fading each LED on and off in order – causing an effect very similar to pulse-width modulation.

Finally, here it is in action:

Example 34.3

In this example, we will use use a four-digit, seven-segment LED display that has an SPI interface. Using such a display considerably reduces the amount of pins required on the micro controller and also negates the use of shift register ICs which helps reduce power consumption and component count. The front of our example:

and the rear:

Thankfully the pins are labelled quite clearly. Please note that the board does not include header pins – they were soldered in after receiving the board. Although this board is documented by Sparkfun there seems to be issues in the operation, so instead we will use a sketch designed by members of the Arduino forum. Not wanting to ignore this nice piece of hardware we will see how it works and use it with the new sketch from the forum.

Again, wiring is quite simple:

Board GND to Arduino GND

Board VCC to Arduino 5V

Board SCK to Arduino D12

Board SI to Arduino D11

Board CSN to Arduino D10

The sketch is easy to use, you need to replicate all the functions as well as the library calls and variable definitions. To display numbers (or the letters A~F) on the display, call the function

Arduino

1

write_led(a,b,c);

where a is the number to display, b is the base system used (2 for binary, 8 for octal, 10 for usual, and 16 for hexadecimal), and c is for padded zeros (0 =off, 1=on). If you look at the void loop() part of the example sketch, we use all four number systems in the demonstration. If your number is too large for the display, it will show OF for overflow. To control the decimal points, colon and the LED at the top-right the third digit, we can use the following:

In the meanwhile have fun and keep checking into tronixstuff.com. Why not follow things on twitter, Google+, subscribe for email updates or RSS usng the links on the right-hand column? And join our friendly Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other – and we can all learn something.

Today we will take a first look at the Ikalogic “Scanalogic2” PC-based logic analyser and signal generator. This is a tiny and useful piece of test equipment that should be useful for beginners and experienced engineers alike. It has been developed by two guys in Europe that are dedicated to the craft, and I wish them well. First of all, let’s pull it out of the box and see what we have:

Upon opening the box, one finds a USB cable, the connector leads and the unit itself. It really is small, around 60 x 35 x 20mm. The USB cable is just under 900mm long. Finally a small instruction and welcome postcard which details a quick overview of the software and the unit’s specifications. Ikalogic are to be congratulated for the minimal level of packaging – finally a company that realises one can download the required items instead of printing books, burning DVDs and causing an increase in shipping weight.

The first thing you will need to do is download the latest software. It needs a Windows-based PC with .net framework. Installing took about two minutes, then the ubiquitous system restart. Finally the last preparation is to check for the latest firmware and update it. This is a simple procedure – download a .zip file, extract the .hexe file, then just file>update device firmware in the software. The desktop software checks for new versions before every startup, so you can be sure of having the latest version.

Here are the specifications of the unit from their web page:

Certainly there is a lot there to take advantage of. Personally I consider the logic analyser functions to be of great interest, and will now demonstrate those to see how they can be useful in debugging and generally figuring out what my designs are up to.

One can capture data in two ways, either by using a live sampling mode, or capture mode where you set the device to sample data into its memory, and then reviewing the data using the software. If you are using the live mode, the quality of the sampling will be affected by your PC resources. For example, consider this first demonstration. A very simple Arduino is setting a pin high and low:

In live mode you can still use the horizontal scroll feature to move backwards and forwards through the captured data. One can also expand the data display to the full width of the window. When using the live mode, I found that there was still some variation in the logic levels that was not programmed for. My PC is fairly up to date, consisting of an AMD PhenonII dual-core 3.1 GHz CPU, 2GB RAM at 1066 MHz, running Windows 7 x64. Perhaps I could use some more RAM? A better video chipset? Who knows… Unfortunately I don’t have a more powerful PC to test. Therefore I will stick to the normal capture mode. Doing so is also quite easy – here is the basic setup tab:

It is pretty self-explanatory. If you have a fair idea of your sampling rate, you can drop it down to increase the available sampling time. Here I have selected the lowest sampling rate, as I will just capture the pulses as shown in the earlier demonstration. Once your sample has been collected, you can scroll through it at your leisure, and also save the sample to disk.

In being able to save the data for later retrieval, there are three things that can be done with the data:

As anyone can download the software, you can share your samples by emailing or sharing the files with colleagues – they can playback the sample without owning a Scanalogic themselves, by just using the software;

You can keep the sample for later analysis

You can blast out the captured data using the function generator feature. Neat! Let’s do that now…

Earlier on I captured the following from an Arduino board:

And now I can just right-click on the data (channel one) and select run data generator for this channel then click start on the left. Which results in the following output:

Very good (except for my old CRO). Also notice the log area at the bottom of the application screen – it relays unit status, error messages and so on. Now let’s capture and look at some more interesting sample data. The following example is an example of captured data from an Arduino serial-out pin, which was programmed to send the letter “A” out at 2400 bps using serial.write();

Once you have captured the sample, you can select the parameters of the data stream and decode the sample. As you can see in the image above, the decoder shows the data stream in hexadecimal and the ASCII equivalent.

Next on the test is I2C. This is a common two wire data bus from Philips/NXP, used in many systems. More about I2C with Arduino is here. A very popular example of an I2C IC is the Maxim DS1307 real-time clock. We can use our Scanalogic to eavesdrop on the SCA and SCL data lines to see what is being said between the microcontroller and the DS1307:

So in the example above, the value 0x68 (binary 1101000) is sent down the bus. This is the unique identifier (slave address) for a DS1307 IC. So the Arduino is saying “Hey – DS1307 – wake up”. This is then followed by a 0x00 or directional bit. The DS1307 then replies by sending the time data back to the bus. The first piece of data in the reply is 0x68, which identifies to the I2C bus (recall that 0x68 is the DS1307 identifier) that the data is from the DS1307. Following this is the time and data data in hexadecimal, which is converted to binary-coded decimal in the microcontroller software.

When working with I2C, it really pays to have the data sheet for your IC with you. Then you can decipher the data, direction and timing with the sample data on one side and the timing diagrams on the other. For example, page twelve of the DS1307 data sheet. In doing so, it reminds me how much I dislike I2C 🙂

Moving along. Next we will have a look at some data from the SPI (serial peripheral interface) lines. Again, this is quite simple, you just connect the four hooks into the clock, MOSI, MISO and CS lines, and capture away. The software allows you to select which hook is connected to which line, so you can connect up quickly. At this point I will note that the IC hooks are somewhat inexpensive, and the designers could have spent a few more Euro on including some decent ones. Anyhow, here is the screen dump:

At this point one can realise all sorts of monitoring possibilities. I wish I had one of these years ago when learning digital electronics – you could just monitor the highs and lows over four channels and debug things very quickly. Will keep this in mind when I get around to making a TTL clock.

Anyhow – the Scanalogic2 has a lot going for it in terms of data capturing ability, the price is right, you can update the software and firmware very easily, and the desktop software is freely available in order to share samples with others. There are a few cons though – the IC hooks could be better (I couldn’t connect four in a row onto an IC for the life of me); the unit could use some documentation in terms of a “Getting Started” guide or webpage – so due to this the learning curve is quite high. There is their version here, but I feel it could be expanded upon. Many beginners and amateurs will be attracted to this unit due to the price. However there is a support forum and so on, but answers can vary in quality and time. However, don’t let the cons put you off – this thing is cheap, the software is very good – and it works. Two thumbs up!

To purchase a Scanalogic2, visit the Ikalogic home page. If you need to analyse some data, and don’t want to spend a bucket of money – this is for you.