Computing stuff tied to the physical world

Posts Tagged ‘Arduino’

Plug shield on Arduino Mega

In AVR, Hardware on Feb 7, 2010 at 00:01

The Plug Shield can also be used on an Arduino Mega:

DSC_1175.jpg

Note the two extra wire jumpers, since the I2C interface is on pins 20 and 21 on the Mega board.

The above has an RTC plug and an LCD plug hooked up, so let’s to set up a simple clock with this – and use it to demonstrate the brand-new RTClib along the way:

Screen shot 2010-02-05 at 17.22.01.png

I’ve omitted the details of the Wire coding, but you can get the full sketch here.

Fascinating concurrency

In AVR, Software on Feb 4, 2010 at 00:01

There is a new language for the Arduino / JeeNode / ATmega328, called Occam-π.

I found out about it yesterday, at http://concurrency.cc/ – it’s high level, and it supports parallel programming. The current development environment release is for Mac OS X, with Windows and Linux coming soon.

Here is a complete program with 4 blinking LED’s, one on each DIO pin of the JeeNode ports:

Screen shot 2010-02-03 at 01.13.19.png

That’s it. Compiles to roughly 2 Kb. Each extra blink adds just 20 bytes, btw.

And yes, it really makes four LEDs blink at an independent rate:

DSC_1167.jpg

There is slightly more to it than that, but this is mind-blowing stuff. The “parallelism” is simulated, of course. Looks like the ATmega can do around 6000 context switches per second (i.e. parallel task switches).

There is a roughly 20 Kb interpreter part that needs to be uploaded once (which is why this requires at least an ATmega328). After that, the IDE will upload just the bytecode for your program, i.e. 2 Kb in the above case.

B R I L L I A N T .

Imagine hooking up the RF12 driver to this – there’s plenty of room for the extra 3 Kb or so. And for doing all sorts of things… in parallel! My earlier complaint post about how awful it is to do several things at once on an ATmega board might just have been wiped off the table.

Looks like I’ve got some very serious learning ahead of me to try and get to grips with all this.

Pin I/O performance

In AVR, Hardware, Software on Jan 6, 2010 at 00:01

There was a discussion on the Arduino developer’s mailing list about the impact of a small change to the digitalWrite() function, and for some time I’ve been hearing that digitalWrite() has a huge amount of overhead.

Time to find out.

Here is the sketch I used to measure how often a pin I/O command can be issued using various mechanisms:

Screen shot 2010-01-05 at 11.42.53.png

The logic is that I’m counting how often the same command can be called between timer overflows, i.e. every 1024 µs (one byte, incrementing @ 16 MHz / 64), before the timer tick count changes again.

And here’s the sample output:

Screen shot 2010-01-05 at 11.42.14.png

There’s a small amount of jitter, which tells me the loops are syncing up almost exactly on the timer ticks. Interrupts have not been disabled, so the timer interrupt is indeed being serviced – once for each loop.

What these values tell me, is that we can do about:

  • 10 analog 10-bit readings per millisecond with analogRead()
  • 128 pwm settings per millisecond with analogWrite()
  • 220 pin reads per millisecond with digitalRead()
  • 224 pin writes per millisecond with digitalWrite()
  • 1056 pin reads per millisecond with direct port reads
  • 1059 pin writes per millisecond with direct port writes

(I’ve corrected the counts by 1000/1024 to arrive at these millisecond values)

So the Arduino’s digital I/O in IDE version 0017 can do roughly 1/5th the speed of direct port access on a 16 MHz ATmega328.

But WAIT! – There’s a large systematic error in the above calculations, due to the loop overhead. It looks like the loop takes 1024000/1251 = 819 ns overhead, so the actual values are quite different: digitalRead() -> 3712 ns, direct port read -> 151 ns. Now the values are more like 1/25th!

So let’s redo this with more I/O in each loop iteration (all 4 ports):

Screen shot 2010-01-05 at 11.55.31.png

The sample output now becomes:

Screen shot 2010-01-05 at 11.56.59.png

With these results we get: one digitalRead() takes 4134 ns, one direct port read takes 83 ns (again correcting for 819 ns loop overhead). The conclusion being that digitalRead() is 50x as slow as direct port reads.

Which one is correct? I don’t know for sure. I retried the direct port read with 16 entries per loop, and got 67 ns, which seems to indicate that a direct port read takes one processor cycle (62.5 ns), as I would indeed expect.

Conclusion: if performance is the goal, then we may need to ditch the Arduino approach.

Update – Based on JimS’s timing code (see comments): digitalRead() = 58 cycles and direct pin read = 1 cycle.

Update #2 – The “1 cycle” mentioned above is indeed what I measured, but incorrect. The bit extraction was probably optimized away. So it looks like direct pin access can’t be more than 29x faster than digitalRead(). As pointed out by WestfW in the comments, digitalRead() and digitalWrite() have predictable performance across all use cases, including when the pin number is variable. In some cases that may matter more than raw speed.

Update #3 – Another caveat – Lies, damn lies, and statistics! – is that the register allocations for the above loops make it extremely difficult to draw exact conclusions. Let me just conclude with: there are order-of-magnitude performance implications, depending on how you do things. As long as you keep that in mind, you’ll be fine.

Arduino Duemilanove

In AVR, Hardware on Dec 30, 2009 at 00:01

Not everything is about wireless. Nor about nodes, ports, or plugs. Of course not – that would be boring :)

To offer more choices, I’ve added the Arduino Duemilanove to the web shop:

Duemilanove_HI.JPG.jpeg

Jee Labs is now an official distributor for these famous boards. Woohoo!

Arduino and complexity

In Hardware, Software on Dec 28, 2009 at 00:01

This is – in a nutshell – the Arduino world:

Screen shot 2009-12-27 at 18.53.04.png

In prose: an ATmega board, some hardware peripherals, an environment for embedded software development, a front-end for visualization, and a website to bring all these facets together for a growing worldwide community.

For each of these, there are alternatives and variations. These add variety and increase the number of choices for everyone interested in this low-cost physical computing world. The “Arduino” name is conquering the world, and it sticks … even as “duino” suffix. Names are a great way to create a brand.

But what is Arduino, really? Is it an ATmega? Is it a board that fits in the palm of your hand? Is it a standard for connecting other boards? Is it a standard way of structuring software? Is it defined by a set of standard libraries? Is it the dual aspect of the IDE, i.e. Wiring vs. Processing? Is it the main web site or the discussion forum?

The answer depends no doubt on who you ask. And if this is a healthy ecosystem, then all of these will evolve and improve over time. In my opinion, the current state of an ecosystem is far less important than its ability to evolve.

That’s where complexity comes in.

It’s not hard to construct a great system, even an elaborate one. But what is extremely hard, is to come up with a system which supports evolution of all the pieces involved. Because with multiple pieces, you have to make decisions. You have to interconnect the pieces, and that requires making choices. And once you do, you reduce the number of future paths, including many you don’t even know about yet.

Making choices can be good. Hooking up an Arduino to a PC via a serial connection is a great low-cost solution for uploading, debugging, and interacting. The transition from an RS232 connection + a separate power supply to a USB connection with “built-in” 5V power is an excellent example of how evolution can lead to substantial progress.

Technological evolution can take years. And as in life, that’s where the really interesting stuff happens.

Unfortunately in the Arduino world, I’m hitting some nasty edges which tell me we need more generality or flexibility. I’ll describe a few, in terms of interfaces between the different pieces shown above:

Voltage levels – the most widely used Arduinos are based on 5V, meaning that all their I/O pins are also 5V-based. More and more sensors can only be used with a supply voltage up to 3.6V or so. Interfacing them to a standard Arduino requires the use of level converters. Often, resistors will do – but you can’t simply ignore the issue. This is an area where I2C can help.

Hardware modules – the Arduino “shield” concept doesn’t extend very far, because each shield determines which pins it needs. Pins are a scarce resource, and each pin location on the connector is fixed. It’s hard to design shields which will actually stack with others. Even more so now that there is a new Arduino Mega with slightly different pin allocations.

Software modules – libraries are a great concept: code which is there when you need it, but doesn’t get in the way (i.e. included) if you don’t. Right now, adding a library which depends on say the “Wire” library means that you have to include the Wire library in your sketch even if you don’t ever use it. This is almost a show-stopper.

C/C++ code – on the surface, programming for the Arduino board is like programming in C and C++, with a bunch of very common issues resolved and a wide variety of useful functions available, ready to use. Newbies can get going fast and old hands can find their way around in no time. Except… the IDE does some funky things with headers and declarations. And it breaks a couple of fairly basic C/C++ conventions.

Automation – the IDE works with a specific scenario in mind. As of the latest 0017 release, multiple sketches and consoles are supported. This solves some of the issues, but it’s hard to automate this further: after uploading, I still have to manually launch the serial console. If I have some other app talking to the hardware, there is no mechanism to upload a new sketch and then resume that app because the serial USB connection is dedicated.

Visualization – it’s interesting to see how the Arduino / Wiring / Processing approach is bridging a huge range of hardware in an integrated manner. But there are several choices involved which reduce flexibility towards entirely different approaches. Some visualizations (as well as other types of data processing) would benefit from using a more internet-/web-centric approach. Lower-end hardware cannot support the Java environment used by Processing, so that code can’t be leveraged. There are alternatives. Scripting language support would be useful.

Don’t get me wrong: all these issues are tough ones! It’s probably impossible to solve them all and to make everyone happy. These issues are definitely not things open source software is obliged to address from day one. But my point is that this is not about where we are today, but about having the mechanisms to evolve to where we want to be tomorrow.

If you’ve followed this weblog for a while then you can probably guess that I’ve got some ideas and suggestions on how to move forward on all this. I would really like to help take the existing Arduino platform further – but I’m not sure at this point that it can be done within the current constraints. I don’t even know whether anyone else considers the issues listed above to be important. All I know is that as I continue to add more software and design new hardware, the “push-back” from the current Arduino design choices is increasing… a lot.

Do I want to change the Arduino world (i.e. make a case, convince people, find compromises) – or do I want to sidestep some of its decisions by starting all the way from scratch? I haven’t decided.

Re-flashing and ISP

In AVR, Hardware on Dec 11, 2009 at 00:01

This is the second of two posts about everything related to uploading, re-flashing, bootstraps, FTDI, and ISP.

Yesterday’s post described the process of uploading new sketches via USB or RS232 using a boot loader.

But how did that boot loader get into the ATmega328?

That’s a bit of a chicken-and-egg problem. Ya’ can’t use a boot loader to get the boot loader into flash memory!

This is where a lower-level hardware-based mechanism called In System Programming (ISP) comes in. ISP is a clever trick in the ATmega chip which in effect activates a special boot loader built into the hardware. This is done by holding the RESET line of the ATmega low, at which point the chip becomes essentially useless, since the reset prevents the chip from starting to run its firmware. The trick is that in this mode, some of the pins on the ATmega become an interface to that special hardware-based built-in boot loader.

So what we need to do, is to manipulate those pins to send commands which will store data into the flash memory. What we’re going to send in most cases, is the data for the boot loader in upper memory. With that boot loader in place we can then switch to “normal” uploading via the serial interface and USB.

ISP programming is also used to change “fuse bits” on an ATmega. There are a few configuration settings for the ATmega – what type of clock it uses, how it boots up, enabling a watchdog timer, etc. These are stored in “fuses” which can only be adjusted via ISP programming.

There are 3 I/O pins involved in ISP programming, plus the reset line and power. On the Arduino as well as on the JeeNode and JeeLink boards, these lines are available via a 2×3-pin ISP connector with the following layout:

ISP pins.png

The interesting thing is that you don’t even need an Arduino or JeeNode to set up flash memory and fuses. ISP is so low-level that it works directly on the pins of an ATmega chip. This is very useful to pre-load the boot loader (or test program – anything you like, really) onto a chip before soldering it permanently onto a board.

(continued…)

Read the rest of this entry »

Uploading and FTDI

In AVR, Hardware on Dec 10, 2009 at 00:01

This is the first of two posts about everything related to uploading, re-flashing, bootstraps, FTDI, and ISP.

First, our goal: what we want to do is get our software (“sketch”) from the PC/Mac into the AVR ATmega328 microcontroller on our Arduino or JeeNode. This is a fairly simple process once all the pieces are in place…

The effect is that the flash memory built into the ATmega is re-flashed. Being flash memory, your software will remain in the microcontroller even without power – ready to start again once power is applied.

There are two ways to get your software into the ATmega: In System Programming (ISP) and uploading. ISP will be described tomorrow, here we’re going to focus on uploading.

Uploading works with a “boot loader”. This is a small piece of software started after power-up (or a reset), which usually listens on the RX and TX pins of the serial interface for commands. These commands then tell it what data to store in which part of the flash memory:

Screen shot 2009-12-09 at 12.25.31.png

The surprising thing is that the boot loader itself is also stored in flash memory. It’s stored in a small (1..4Kbyte) area in upper memory, and the data it writes always goes to the lower part of memory. That’s why it’s called a bootstrap or boot loader – imagine lifting yourself by pulling on the straps of your own boots. In this case the ATmega is lifting its own functionality up by reprogramming its flash memory via its own boot loader.

(continued…)

Read the rest of this entry »

Plug Shield clock

In Hardware, Software on Nov 30, 2009 at 00:01

As a reminder that not everything here at Jee Labs is about JeeNodes, here’s a clock for the Arduino (which keeps track of time, even when not plugged in):

DSC_0815.jpg

This was built with an Arduino Duemilanove, a Plug Shield, an RTC Plug, and an LCD Plug piggy-backed onto a 2×16 character display.

Here’s the sketch:

Screen shot 2009-11-29 at 13.12.46.png

And here are links to the PortsLCD.h and PortsLCD.cpp source files.

But there could be some serious trouble ahead…

This code depends on an extended version of the LiquidCrystal library that comes with the Arduino IDE version 0017. Since I don’t want to modify that code, I had to use different names, so the PortsLCD.h/.cpp files use the following class names:

  • LiquidCrystalBase – an abstract class containing all the generic LCD code from the original class
  • LiquidCrystalPins – this is for use with plain pin connections, as before
  • LiquidCrystalPort – this uses bit-banged I2C with one of 4 JeeNode ports
  • LiquidCrystalI2C – this is for use with hardware I2C, using the Wire library

These names are slightly different from the previous ports-only version, btw.

So PortsLCD is a library which does everything the original did, and more. The flexibility is that you can write your sketches with this and then use any type of LCD you like with it, by just changing a single line of code. And if you’ve got a different hardware hookup, a new class can be added for it based on this same code, so that again your sketch only needs to change a single line of code to use it.

So far, so good. This is the benefit of object-oriented code and polymorphism.

But there is a price, due to the way the Arduino IDE does things: even if you don’t use the Wire library, you’ll need to include it in your sketch! For similar reasons, I’ve been forced to include the RF12 driver in all my demo sketches, even those that don’t use it. Leaving it out leads to build errors and prevents uploading.

This is not a C/C++ issue, the gcc compiler is actually quite smart about leaving out things which are never used. No – this complication is caused by the way in which the Arduino IDE tries to do some clever things to simplify naive use of libraries. I’ll go into this in another post – it is not a show stopper yet, but it may become one as I start combining more features and code, since memory on an ATmega is quite limited.

To put it bluntly: the way the Arduino IDE currently deals with libraries is a ticking time bomb…

Updated Plug Shield

In Hardware on Nov 28, 2009 at 00:01

The updated Plug Shield has come in, here pre-assembled and with all the headers soldered on:

DSC_0806.jpg

This fixes the problem with D9, and adds one extra feature: there is now a pull-up for the IRQ line, with a solder jumper to connect it to D3. See the label “JD3″ at the middle right in the above picture. This makes the IRQ pin on the port headers compatible with the JeeNodes when an IRQ pin is needed.

This shield is still called “v1″ due to an oversight, but that should not be too much of a problem because only 3 prototypes have been sent out. If you got such an “old” prototype shield and want the final one, get in touch and I’ll send it (pcb-only).

On a related note, the Memory Plug has also been updated (to “v2″, correctly this time). This fixes an addressing limitation with 128 Kbyte EEPROMs.

Onwards!

Arduino?

In AVR, Hardware, Software on Nov 23, 2009 at 00:01

What is it? Hype? Hobby? Hacker stuff? Here is the best overall introduction I’ve seen so far – by Dave Jones. It’s 19 minutes – plenty of time to get used to his accent :)

(view directly on YouTube)

I think he really touches on all the important aspects and inevitable trade-offs.

Me, I use the Arduino bootloader for JeeNodes and JeeLinks all the time, and the Arduino IDE to compile and upload stuff to them, as well as the serial console in many cases. I do use my own editor environment – which is easy to do once you disable Arduino’s built-in one (this is not well documented, Google for “Arduino external editor”). So for me the Arduino is really the bootloader, plus the IDE just as compile/upload system.

As Dave points out, the Arduino is a wrapper around the avr-gcc compiler + avrdude in combination with a convenient USB-based upload/console/power hookup. The rest is libraries, conventions, a Java based IDE (based on Wiring), and optionally a Java-based PC-side front end called Processing.

On the embedded software side, it’s really standard full-scale C and C++.

Which is great, IMO. I can keep going with the Arduino-compatible JeeNodes and JeeLinks, and their built-in wireless, port conventions, 3.3V operation, and all the add-on plugs – knowing that much of this will work fine with as well as without all the stuff going on in the Arduino ecosystem right now.

Arduino plug stack

In AVR, Hardware on Nov 13, 2009 at 00:01

You could combine all these …

DSC_0750.jpg

… and create an Arduino sandwich like this – with full access to all the Arduino pins:

DSC_0751.jpg

That’s a Plug Shield with, from left to right / top to bottom:

Each of the plugs can be accessed via I2C, i.e. using the Arduino’s “Wire” library.

Would all this work? Yes, I’m pretty certain it would.

Would it be useful? Probably not in this combination…

I just wanted to show off the I2C plugs and shield ;)

Build and pinout errors on older posts

In AVR, Software on Nov 8, 2009 at 00:01

There has been an unfortunate dependency between the Ports library and the RF12 library for some time now, causing the Arduino IDE to generate errors such as these:

ide-errors.png

(etc…)

The workaround right now is to include both in your sketch, even if you only need one:

Screen shot 2009-11-04 at 10.50.42.png

I’ve been planning to do a major overhaul of the library and software in general, but until then this is the way to avoid those pesky errors. It probably affects quite a few sample sketches on this weblog.

Another thing to watch out for (thanks, Ian!) is that some older examples on this weblog use the JeeNode v2 or even v1, which have a different pinout. To uses those examples with the latest JeeNodes, you have to swap pins 4 and 5, i.e. +3V and AIO.

Please let me know when examples from earlier weblog posts don’t work as described. A small fix and note added to these posts might be all that is needed!

Meet the Plug Shield

In Hardware on Nov 5, 2009 at 00:01

There are a couple of Arduino’s lying around idly here at the Jee Labs, so I thought it’d be nice to be able to attach some JeePlugs to them. Not all interface tasks require a wireless JeeNode, after all…

The main issue is how to deal with different voltage levels, i.e. 5V logic levels on the Arduino vs 3.3V on all the Jee stuff. Luckily, this is not a problem for an I2C bus, since there are chips which automatically convert between two different I2C bus levels.

So here’s the Plug Shield, carrying an RTC plug:

DSC_0731.jpg

Check out the gold lettering!

There is room for up to 5 port connectors, all connected in parallel, with right-angle 6-pin female headers (I take straight headers and just bend their pins). This supports two plugs lying flat on the board and three pointing outwards, although many more can be attached through daisy-chaining.

The PWR pin is connected to 5V. The IRQ signal is currently not connected to any pin but could be tied to PD3 to be compatible with JeeNodes.

Note that the Plug Shield will only work with I2C-type JeePlugs – things like the Room Board and the Thermo Plug cannot be used.

There is a regulator to supply 3.3V to the port connectors on-board, as well as an I2C bus level converter. To maximize the space available to plugs, these are all SMD’s. The reset button and ISP header have been brought out as well, since the original ones on the underlying Arduino board cannot be reached.

This shield allows stacking and can be sandwiched between an Arduino and any other shields. The only requirement is that analog pins 4 + 5 must be used for hardware I2C – these are not available as I/O pins.

Here’s a demo, reading out the RTC:

Screen shot 2009-11-03 at 00.32.07.png

Uses the standard “Wire” library that’s included with the Arduino IDE.

There is a wiring mistake in the shield, causing PB1 to be shorted to ground, so as a result digital pin 9 can’t be used with this shield. I placed one of the headers the wrong way around. Doh!

I’ve added this shield in the shop anyway. Got only a handful of ‘em for those who don’t care too much about that PB1/D9 issue. New shields will be made soon.

Apart from that, it’s working great. All I2C-based JeePlugs can now be used with standard Arduinos, without plug-stacking conflicts or voltage translation hassles. Want an RTC? LCD? UARTs? More I/O lines? You got it.

Arduino Mega + shield

In AVR, Hardware on Jun 28, 2009 at 00:01

Got myself an Arduino Mega – an Arduino on steroids:

Arduino Mega + shield

Compatible with current Arduino shields, but extended to support a lot more pins.

Ordered it from NKCelectronics, along with their new extended shield for it:

Arduino Mega + shield

There’s a lot of them pins on there…

I decided to attach a solder-less breadboard to it, to be able to experiment with projects which need more I/O lines or comms than a standard Arduino:

Arduino Mega + shield

It fits, but just barely. Had to cut off the little hooks on the plastic. Using a breadboard in this way covers up all the identifying pin texts on the silkscreen, alas.

Actually, it doesn’t quite fit – couldn’t get all headers on:

Arduino Mega + shield

I’m using a mix of 4- and 6-pin headers, since I had them lying around. As you can see, the last 4-pin header makes it impossible to fit that other header in, so I left off pins 22 and 24. It might have worked with an 8-pin header i.s.o. 2x 4-pin.

And here’s the final “stack”:

Arduino Mega + shield

Conclusion so far? I’m not sure this is the way to go. I think it’s an abomination, to be honest. There are so many pins to connect that the two boards are very hard to separate once stacked up. You don’t want to pull too hard on one side and end up with bent pins when the thing finally comes apart.

And how often do you need that many I/O pins one one fixed board setup? Sure, the ATmega1280 has 128 Kb of flash memory, which is plenty to get fairly complex sketches going. But it also builds on that trend of using stacked shields – and let’s face it: a single shield is often great, but with 2 or 3 you end up with pin allocation nightmares (for designers) or conflicts (for users). Multi-stacking is tricky, requiring special stacking headers.

Nah, I’d much rather go with ports, and extensions for that, and connecting two or three independent units over a bus if need be. But then of course I would, that’s why I went for such an approach with JeeNodes after all.

Better delays

In AVR, Software on Mar 31, 2009 at 00:01

As described in this post on an Arduino forum, I’ve suggested some small changes to the delay() and delayMicroseconds() code in the Arduino/Wiring libraries:

Picture 3.png

(rest of delayMicroseconds unchanged)

Note that both changes only add new code, no lines have been removed or changed (the comments need to be adjusted, though).

The above changes only affect microsecond delays > 500 us and millisecond delays < 50 ms. In that range, a loop is used which should be accurate in the couple-of-microsecond scale and which does not lock out interrupts.

It should lead to a more accurate millis() value since interrupts can be serviced more often, and to a far more accurate delay for low-millisecond values. I hope something like this makes it into a future release of the Arduino IDE – timing capabilities are still a bit limited on the Arduino, IMO.

Multiplexing code for Arduino

In AVR, Software on Mar 25, 2009 at 00:01

Here is an extract of the code to multiplex 5 serial ports in software on an Arduino Duemilanove:

Picture 3.png

It’s a big bag of tricks, really. There is a timer running at 3x the baudrate, which detects start bits and then picks out data bits every three ticks. The crucial issue for the receivers is that the work is done in parallel for 5 input streams, but that these events are not happening at the same time. There are in fact 5 little state machine, each with their own independent state.

For the output, it’s slightly simpler: a buffer with all the 5 transmit bit states is scanned and sent out. The trick here is to fill that buffer with the proper bit patterns. When nothing is sent on a channel, its corresponding bit remains high in all values in the buffer. The transmit buffer has 30 entries, 3 per bit plus the start and stop bits. A simplification here is that all bytes are sent at the same time, i.e. start and stop bits occur at the same time on all active transmit channels.

The idea of multiplexing is that all received data is collected and sent out to the main (hardware) serial port, running at 57600 baud. Extra character codes 0×01 .. 0×05 are inserted into the multiplexed data stream to identify from which channel the data is coming. On the transmit / de-multiplexing side, the character codes 0×01 .. 0×05 are filtered out and used to indicate to which channel to send out the next characters.

If you connect two of these multiplexing shields back-to-back, you can send 5 independent bi-directional serial streams over a single 3-wire cable. Come to think of it, the following setup would make a great test for these multiplexing shields:

Picture 2.png

The full source code for the multiplexing sketch can be found here. It has been tested at 9600 baud (all receivers must run at the same speed). It probably works at higher speeds even, but this hasn’t been tested. At some point, the Atmega chip is going to get swamped while handling the barrage of timer 1 interrupts. I haven’t really tested the transmit part yet, i.e. the de-multiplexing side of things.

Ports on a standard Arduino

In AVR, Software on Mar 1, 2009 at 00:01

The Ports library described in recent posts works fine with any type of Arduino, Freeduino, etc – not just JeeNodes. It merely uses some conventions for the “DIO” and “AIO” pins of each of the 4 ports.

Here is an example using a HM55B compass module from Parallax, using an Arduino Duemilanove with a Proto Shield from AdaFruit:

Ports on a standard Arduino

There are actually two sensors in the above setup – the bigger sensor is a Parallax H48C 3-axis accelerometer (more on that below). Both need +5V to operate, so they won’t work with simple 4-pin ports on a JeeNode.

Ports are mapped to the Arduino pins as follows:

  • Port 1 DIO = Arduino digital pin 4 (PD4)
  • Port 1 AIO = Arduino analog pin 0 (PC0)
  • Port 2 DIO = Arduino digital pin 5 (PD5)
  • Port 2 AIO = Arduino analog pin 1 (PC1)
  • Port 3 DIO = Arduino digital pin 6 (PD6)
  • Port 3 AIO = Arduino analog pin 2 (PC2)
  • Port 4 DIO = Arduino digital pin 7 (PD7)
  • Port 4 AIO = Arduino analog pin 3 (PC3)

The ATmega register bits are listed in parentheses.

Here is the full code of the HM55B driver plus demo:

Picture 2.png

Sample output:

Ports on a standard Arduino

The H48C 3-axis accelerometer demo is very similar, source code can be found here. Sample output:

Ports on a standard Arduino

These two hookups both use some new utility code in the Ports library to shift a specified number of bits in and out of the DIO line while clocking the AIO line. Note also that these sensors needs two ports each, since they both use 3 IO lines for their SPI-like interface.

RFM12B library for Arduino

In AVR, Software on Feb 10, 2009 at 00:03

Here’s a driver for the RFM12B radio with Arduino’s and similar AVR boards. The radio is connected as follows:

RFM12B

The code is available as RF12.zip or via subversion. It’s packaged as an Arduino library. To try out the included example, you’ll obviously need two Arduino’s + radio modules, connected as above. Then:

  • unpack the above zip as new directory in your Arduino IDE’s “libraries/” folder
  • build and upload the included example sketch to both systems
  • check proper operation by opening the serial port at 57600 baud
  • you should see a “[RF12DEMO]” greeting on both
  • on one unit, type “0i 0i 1i” to set its node ID to 1
  • on the other, type “0i 0i 2i” to set its node ID to 2
  • send a test packet of 7x <N> bytes by typing “<N>s” (<N> = 0..9)
  • you should see the test packet on the other node
  • use “<N>a” to send a test packet and request an ack

The node ID is stored in EEPROM (the demo uses byte 0), so you only need to initialize ID’s once in each node.

This code uses interrupts to do most of the work in the background for transmission as well as reception. The packet buffer is limited to 66 bytes of data. All packets are verified with a 16-bit CRC.

Packets can be sent to a specific node (ID 1..30) or broadcast to all (ID 0). The demo code sends its test packets as broadcasts, but replies with acknowledgements to just the originator. Note that requesting an acknowledgement for broadcast packets only makes sense with two nodes.

Update – instructions for the demo are now slightly different (see the README).