Our products, Nanode, wireless, MCUs, electronics and more

Air Quality Egg: Firmware/Software Update

Posted: May 6th, 2013 | Author: | Filed under: Uncategorized | Comments Off on Air Quality Egg: Firmware/Software Update

Here’s the quickie summary. I reorganized the software on the Air Quality Egg to do the conversion math on the Nanode. Good news is this seems to be giving better results. The downside is it was a fairly broad impact, and I believe every board needs to be reprogrammed to get the system running at the latest baseline. I haven’t yet pushed the updated software and binaries up to Git Hub, but I’m running it and observing this feed, so far so good.

I’ve previously published instructions on how to reprogram the Nanodes using an FTDI-compatible programming cable in videos that are linked on the FAQ. I also plan to make a video that shows how to re-program the Sensor Shield and add-on modules, though that is admittedly not as easy as I’d like it to be for the average user.

I really want the fielded Eggs to get to latest version of the software though, so I’m willing to  reprogram units personally, at no additional cost, if you send them back to us and just pay for the round trip shipping. I know this is a real hassle for our international community members, with customs and all. If there are community members that are willing to be “local experts” for reproramming Eggs that would ease the process. If you are willing to be a volunteer in this capacity please let me know at support AT wickeddevice DOT com. It would be really great to have some local people help support Europe, Asia, and Australia.

Technical Details

Math Code Refactoring

The sensor shield code now responds with a record containing the following information in response to the EGG_BUS_SENSOR_BLOCK_RAW_VALUE request:

   uint32_t adc_value     :: the analog-to-digital conversion (ADC) count
   uint32_t low_side_r    :: the low side resistance associated with the ADC count
   uint32_t sensor_vcc    :: the high side voltage applied to the sensor divider circuit
   uint32_t adc_vcc       :: the reference voltage of the ADC
   uint32_t max_adc_value :: 2^(ADC # of bits), e.g. 2^10 = 1024 for a 10-bit ADC

Given this information, the Nanode computes the measured resistance as follows (using floating point math):

   vx = (adc_value / max_adc_value) * adc_vcc; // this is the voltage divider output voltage
   sensor_resistance = (sensor_vcc - vx) * low_side_r / vx;

And the value of the independent variable used for computing the interpolated response is calculated as sensor_resistance / R0, where the (mutable) calibration value R0 and the piece-wise linear response function table is retrieved from the sensor shield and applied as previously.

A few side note here:

  • This refactoring effectively deprecates the EGG_BUS_SENSOR_BLOCK_MEASURED_INDEPENDENT field, as that quantity is now computed on the Nanode as a derived value. This is all obviously “hidden” in the EggBus library, but I did want to make that clear.
  • I tried to keep enough information on the endpoint to allow for future flexibility. I could have included less information in the EGG_BUS_SENSOR_BLOCK_RAW_VALUE response, but it would be less generic. With the interface defined as above, a sensor endpoint could for example use a 24-bit ADC, or a different voltage reference, and so forth, without loss of generality.
  • The terms may mean different things to different sensor endpoints, but they can rely on the Nanode to use them in downstream calculations as described above. The dust sensor, for example, has “occupancy” in “hundredths of a percent” as it’s raw value. To respect the calculation stream, the dust sensor now reports adc_value = 1, max_adc_value=1, adc_vcc=1, low_side_r=1, sensor_vcc=(occupancy + 1), and r0=100.

Data Refactoring

In the updated software, for each sensor there are three values reported to Cosm on every sample interval:

  • Raw Value := the result of the sensor_resistance calculation above. Tagged with “aqe:data_origin=raw”
  • Computed Value := the result of the interpolation calculation derived from the Raw Value, R0, and the piece-wise linear transfer function. Tagged with “aqe:data_origin=computed”
  • R0 := reporting this to Cosm once calibration enters the picture we’ll need to recognize that this value may vary over time, but this should be a mostly constant. Tagged with “aqe:data_origin=r0”

One thing to note, I’m changing the meaning of the raw value feed here. Where previously it reflected the “independent variable” (i.e. the quantity resistance / r0), it now reflects the sensor resistance.

Library Updates

There have been some updates to the Ethercard library in recent months. I’m not sure, but perhaps the latest library baseline addresses the issue causing some Air Quality Eggs to freeze up in the field, requiring a restart to resume publishing data to the web.


AQE Bug: Ridiculously High Readings

Posted: February 4th, 2013 | Author: | Filed under: Uncategorized | Comments Off on AQE Bug: Ridiculously High Readings

Short Story

I’ve been reading reports of really high (some would say ‘ridiculous’) values being reported by Air Quality Eggs in recent weeks as they’ve started to reach their homes. I think I’ve figured it out, and I’ve pushed an update to the Remote Egg software (more specifically, the Egg Bus Arduino Library). Basically there was a bug in the ‘extrapolation’ case of the getSensorValue function. If you want to skip reading the rest and go patch your Egg with the fix, just go download the latest zip from Git-Hub and reload the software as described in the tutorial videos we recently produced <LINK HERE>.

Details

In EggBus.c in the getSensorValue function, the way it works is it searches a table of (x, y) samples from the sensor hosting device (i.e. the Egg Shield) that relates the “raw” value from the sensor to a computed value that is something we are more used to thinking about.  For example, the table might take us from measured resistance in ohms (the raw value of the NO2 sensor) to concentration in ppb (parts per billion). The way the Nanode uses this table is it look for the two rows in this table that the raw value falls between and performs a linear interpolation – this is the most common case we should expect to see. There are of course a few other ‘edge cases’ that need to be handled: namely (1) exact matches to a table row, (2) values that are smaller than the smallest value represented in the table, and (3) values hat are larger than the largest value in the table. Exact matches are trivial, as we just return the mapped value with no further maths applied. The other two cases are slightly less trivial, but the principle is to calculate the slope of the sampled curve at either extreme and then perform a linear extrapolation in the corresponding direction off the sampled curve.

The problem was in the handling of the third case above – an extrapolation above the highest value in the table. Notably:

float EggBus::getSensorValue(uint8_t sensorIndex){

  // some setup code omitted here
  while(getTableRow(sensorIndex, row++, &xval, &yval)){
    real_table_value_x = x_scaler * xval;
    real_table_value_y = y_scaler * yval;

    // bunch of code here for the other cases omitted here...

    // store into the previous values for use in interpolation/extrapolation
    previous_real_table_value_x = real_table_value_x;
    previous_real_table_value_y = real_table_value_y;
  }

  // case 4: the independent variable is must be greater than the largest value in the table, so we need to extrapolate forward
  // if you got through the entire table without an early return that means the independent_variable_value
  // the last values stored should be used for the slope calculation
  slope = (real_table_value_y - previous_real_table_value_y) / (real_table_value_x - previous_real_table_value_x);
  return real_table_value_y + slope * (independent_variable_value - real_table_value_x);
}

I removed all the irrelevant stuff. Do you see the problem? Basically at the slope calculation right before the return is *guaranteed* to result in the calculation 0 / 0 which turns out to be Not-a-Number (nan) in floating-point-speak. So in the case where the “measured value” turns out to be on the high side, things would sort of fly off the handle. There is still the ‘problem’ that the values are coming out high to begin with, but that’s because we don’t have a calibration procedure at this point, and is a topic for a different post. Thanks for reading!


Air Quality Egg: The Making of a Sensor Data Point

Posted: January 15th, 2013 | Author: | Filed under: Uncategorized | Comments Off on Air Quality Egg: The Making of a Sensor Data Point

I have been wanting to write this blog post for a while. I hope this article will give some insight to the Air Quality Egg community about how the system works end-to-end. I want to provide details about how the Air Quality Egg software and hardware work hand in hand to provide an extensible platform for getting data from the a transducer (sensor) to the internet. I’ll try and structure this in into sections are data-centric, framing it in the context of the “lifespan” of a sensor reading. I chose to write it with a biologically inspired vantage point, hopefully it’s not too lame.

Inception

When you turn on your Base Egg, it broadcasts its MAC address (unique ID) for a period of about 30 seconds (the pairing interval) while illuminating the shell with a yellow pulse. During this time, the Base Egg is offering itself for pairing in order to establish a data link with a Remote Egg. A Remote Egg, in turn, listens patiently for Base Egg advertisement broadcasts for about a 15 second period after power up. A Remote Egg hearing a Base Egg stores away that Base Egg address in persistent memory (EEPROM). Base Eggs are not “monogamous” and willingly accept data from any Remote Egg that is within range and has learned the Base Egg’s advertised address during the pairing interval. Neither do Remote Eggs “mate for life.” They can always be paired to a new Base through the same procedure. They are nevertheless “loyal” in that if they reset, hear no new Base Egg advertisements, and have previously paired with a Base Egg, they will resume communicating with that previously paired Base Egg.

Nurturing

Every sensor hosted by the system has a small microcontroller attached to it. The job of this microcontroller is three-fold. It:

  1. Provides the interface to the Egg Bus.
  2. Performs any tasks necessary to keep the sensor happy and safe, for example regulating the heater power for a CMOS ozone sensor.
  3. Is responsible for actually reading the sensor at the lowest level, be it through analog-to-digital conversion like the CMOS gas sensors, or a time-based digital occupancy measurement like the dust sensor.

This federated sensor management architecture separates the concern of how each sensor is dealt with into bite-sized, compartmentalized fragments, and allows the system to scale well locally. A major upside to the standardized interactions is that it allows you to plug in new sensors into the system without needing to change the software running on your Air Quality Egg. Another big upside is that new sensors can be developed by anyone because of the openness of the interface, software, and hardware.

Discovery

In the Remote Egg, Sensors are attached to the Egg Shield through the Egg Bus. The Remote Egg, at one minute intervals, searches the Egg Bus and finds attached sensors. Upon encountering a sensor, it interrogates it for a variety of information. Using the information gleaned by the Egg Bus, the Remote Egg calculates both a “raw” and “computed” sensor reading.

In a similar theme of discovery, the first time you plug your Base Egg into your network it reaches out to Cosm over the internet and attempt to negotiate the creation a feed where it will ultimately store your Egg’s data. This mechanism is enabled by the fact that each and every Air Quality Egg is labeled with a Unique ID that is also bound to the physical hardware, sort of like your Egg’s fingerprint! When you enter your Egg Serial Number into airqualityegg.com and fill out the form, this process is enabled.

Migration

Having discovered a sensor, and having calculated the raw and computed data points, the Remote Egg ships it wirelessly to its paired Base Egg in a Sensor Packet. The Base Egg, upon receiving, a Sensor Packet addressed to it, illuminates its shell a color (chosen from a predefined sequence) to give you, the proud parent of your Air Quality Egg, feedback that your Remote and Base Eggs are getting along.

Metamorphosis

The Base Egg then restructures the information it receives wirelessly into a format suitable for Cosm’s API. The Base Egg also decorates the datapoint with various tags to help applications search, filter, and group the data more efficiently. The Base Egg transmits the datapoint over the internet where it can live out the rest of its days as part of the world’s first open public Air Quality data set, and doing its part to give us a better understanding of air quality across time and space.

 Evolution

As the data set becomes larger and more dense, and as our understanding of the data grows, the hope is that our community will develop algorithms and procedures to improve the quality of the data through further post-processing. Techniques will also be hopefully be developed to help ‘calibrate’ your Egg’s sensors in a low cost, DIY way. As new sensors become available modules will be developed that will seamlessly plug into your existing Egg through the aforementioned Egg Bus connection, giving us an ever richer set of correlated data.


Air Quality Egg Sensor Shield – HowTo

Posted: December 6th, 2012 | Author: | Filed under: AQE, Nanode | Tags: , , | Comments Off on Air Quality Egg Sensor Shield – HowTo

This one is for everyone who only got an Air Quality Egg Egg  Sensor Shield. I wanted to write it as a way of aggregating a bunch of information that is scattered across the interwebs presently. I’m also going to write it from the perspective of a Nanode as the host processor as that’s what I’m most familiar with and that’s what I wrote some code for. Here is the basic idea of how to get up and running quickly.

  1. Send us your MAC address (e.g. 00:04:a1:3c:11:22) from your Nanode to support AT wickeddevice DOT com (you know the drill). We need to register your device with Cosm to fold it into the Air Quality Egg network. If you run the sketch below and look at the serial data output, the MAC address gets printed out for your convenience.
  2. We will respond by email and let you know you’re hooked up on the back end.
  3. Download the software from Git Hub.
  4. Copy everything from the libraries folder to your arduino libraries folder.
  5. Load the AQEBaseSensor sketch onto your Nanode.
  6. Go to http://airqualityegg.com and type in your MAC address .
  7. Enjoy your data!

For people who got full-up Air Quality Eggs, we will have basically done everything up to step 6 for you (with different sketches). I’m completely swamped through December at least… it would be totally amazing if someone from the Air Quality Egg community could port this sketch to Arduino/Wiznet… I think it should be a relatively straightforward exercise.


Air Quality Egg: Gas Sensor Parameters

Posted: December 2nd, 2012 | Author: | Filed under: Uncategorized | Comments Off on Air Quality Egg: Gas Sensor Parameters

I thought I’d write a little bit about how the sensors are “mapped” to software for the technically interested. First some quick background. The NO2, CO, VOC, and Ozone sensors used in the Air Quality Egg have a lot in common. They are all CMOS sensors whose resistance varies in proportion to the amount concentration of gas present. The sensors’ operate based on surface chemistry, and the surfaces react selectively with a their target gas under prescribed surface temperatures. They differ in the following ways:

  • Nominal resistance in clean air (R0)
  • Response curve relating measured resistance to gas concentration (T)
  • The range of resistance values over which the sensor varies (S)
  • Required heater power (P)
  • Maximum sensor voltage (Vs)
In the software that runs on the ATtiny88 on the Sensor Interface Shield and the Gas Sensor Add-on modules, these parameters are captured as follows:
  • R0: The value is stored in EEPROM, associated with the variable array egg_bus_sensor_r0 (declared in eggbus.c)
  • T: The table is stored in FLASH,  associated with an assortment of variables that store the table in a compressed integer format (declared in interpolation.c)
  • S: The span of resistances is accounted for by the R1, R2, R3 configurable scale voltage divider, which are associated with defined constants, e.g. NO2_SENSOR_R1 (declared in utility.h)
  • P: The value is stored as a defined constant, e.g.NO2_HEATER_TARGET_POWER_MW (declared in main.h)
  • Vs: The value is stored as a defined constant, e.g. NO2_VCC_TENTH_VOLTS (declared in utility.h)
The software that runs on the Sensor Interface Shield and the Gas Sensor Add-ons is very similar except for the definitions above. I tried to organize the software in a logical way. I ended up just copying the project files and renaming variables for clarity for each module. The software developer side of me cringes a little at this approach, that the sensor dependencies are a bit distributed throughout the code rather than collected into one source file somehow. But the rest of me says it works and that’s the important thing. Writing a blog entry about it is, in a sense, my way of reminding myself where these dependencies live. All part of the compromises of limited time and resources.

Air Quality Egg: Setting R0 Values

Posted: November 17th, 2012 | Author: | Filed under: AQE, Uncategorized | Tags: , | Comments Off on Air Quality Egg: Setting R0 Values

Some people have been trying to update their fielded Egg Shields and running into trouble with really small values being reported (like 0). One reason this could happen is a mistake made here at the “factory” during programming. The sensors rely on a value stored per sensor called R0 – which is to say the nominal resistance of the sensor in ambient conditions. During device programming, we should have set these value to something reasonable. We set R0 for the NO2 sensors to 2200 (ohms) and R0 for the CO sensors to 750000 (ohms).

To do this procedure, you’ll need an FTDI cable or equivalent to program the device using the Arduino IDE. If you download the EggBus library from Git-Hub, it comes with a few useful examples. If you start by loading up the PollEggBus example (File => Examples => EggBus => PollEggBus”), it will show you, for each sensor it finds on the bus, a bunch of useful information. You’re going to want to look closely at what it says for “R0:”  – and if it’s a “really big value” (like 4294967295, which turns out to be 0xffffffff to the binary initiated) we’ll have to run a quick sketch to get things back on track. Load up the PollEggBus_WriteTest example (File => Examples => EggBus => PollEggBus_WriteTest) and run it. After it runs you should see NO2’s R0 value is 2200 and CO’s R0 value is 750000 as advertised.

You can change these values to whatever you want actually, and I’m going to write up a derivative example that lets you perform a targeted calibration procedure in the near future.

Load back your Air Quality Egg sketch back onto your Nanode after you run this program (for standalone eggs this is probably the AQEBaseSensor sketch, and for Egg pairs it’s probable the AQERemote sketch). Hopefully this helps you out if it seems like your Egg is always outputting zero.


AVR Stack Overflow

Posted: October 5th, 2012 | Author: | Filed under: Uncategorized | Comments Off on AVR Stack Overflow

No. I’m not talking about yet another stack exchange. I’m talking about an embedded programmers worst nightmare. Consider this fair warning, this post will provide a glimpse into one of the darkest recesses of nerd-dom, a topic that doesn’t really get talked about enough. Hopefully it will do its small part to spread awareness and provide relief to some troubled soul. I think this will be very interesting to some people.

When a program starts doing things that are completely inexplicable and random, very often the reason is what is known as stack overflow. I’ll give some background on “the problem,” then I’ll aggregate some useful information from around the web that can be helpful (with citations). I’m going to try and confine my discussion to the realm of embedded programming for microcontrollers, in particular in the context of avr-gcc (Arduino falls into this category). In order to do that, I will briefly describe the anatomy of an executable program (this is all fairly generalized). When your program is running, a whole bunch of stuff gets stored and manipulated in RAM (SRAM to be precise when it comes to AVRs). The Mega328 you find on most Arduino platforms these days has 2K bytes of SRAM as a point of reference. The “stuff” can be vaguely grouped into three categories:

This picture from the avr-gcc manual actually does good job of graphically depicting this memory model.

Basically the compiler takes all the global variables in your program and allocates them to RAM in the Global Data section (.data + .bss in the picture). That’s the easy part to get your head around. The Stack takes marginally more thought, and is a bit confusing to new programmers. In a nutshell its there to support function calls and interrupts. Whenever you call a function or take an interrupt, the stack is used to store away all the register state needed to restore execution to the callers context after the function or interrupt returns control. This includes things like the Status Register, the Program Counter, and other somewhat esoteric things that the compiler hides from you, and you’ve probably never heard of unless you’ve found yourself needing to write some assembly language to speed things up at some point. It also includes space for any local variables used by the called function. There is another register under the covers that keeps track of the address at the “head” of the stack, called the Stack Pointer. The stack pointer is typically initialized to the end of RAM and “grows” toward the beginning of RAM as functions get called and interrupts get taken (i.e. the Stack Pointer address becomes ‘lower’). Whenever functions return, the stack recedes back toward the end of RAM (i.e. the Stack Pointer address becomes ‘higher’). Compiler magic, basically.

Why does the Stack grow “down” from the end of RAM? The idea, in principle, is to accommodate the Heap, which is the place where dynamic memory allocation happens (in C++ the new keyword triggers this). The heap sits on top of your Global Data and grows toward the end of RAM (i.e. toward the Stack). If you’re not careful, your Heap and your Stack can trample all over each other and that is bad news. I won’t waste any more time talking about that though, since I have a firm belief that you should avoid dynamic memory allocation like the plague in embedded programming, it’s just not worth the headache and added complexity. So from here on, lets assume RAM only contains the Stack and Global Data.

That gives you the idea of the playing field. Now for the practical information (sorry it took so long!). Oftentimes with a big program, or an Arduino program that uses a number of libraries, users don’t have a firm grasp of how much global data they are allocating. While RAM is 2K bytes, we know from above that the amount of head-room the stack has for growth is actually 2K less the amount of Global Data that is allocated. If you declare some large buffers (as is commonly done with the EtherCard / EtherShield libraries) you really start to eat into that 2K. Call a couple of nested functions and before you know it, your stack has grown into the Global Data space. The result? All bets are off. Global variables could change their values in arbitrary ways not related to your programmed logic.  In general, there is no way to recover once this happens, you are pretty much hosed.

So how do we handle this? The answer is unfortunately complicated. Since the depth of your stack depends on runtime execution of your program, it is generally not possible to predict its depth. You can be defensive by avoiding certain programming pitfalls. Do not use recursion in embedded programs, for a start – there’s always a way to write a recursive algorithm as an iterative algorithm. Try not to nest your function calls too deeply for another.

The best thing you can do though, is pay attention to what the tools tell you. There is a handy tool in the avr-gcc toolchain (binutils) called avr-size that can help a lot in understanding the amount of free RAM you have out of the gates.

There is a handy tool in the avr-gcc toolchain (binutils) called avr-size that can help with this. As described in this handy article you can run avr-size on an ELF file (a compiler build artifact, you can find where it is by enabling verbose output in Arduino IDE). It gives output like this:

avr-size /path/to/temporary_compile_dir/compiled.cpp.elf
text    data     bss     dec     hex                                                                                                      
17696   382      1366    19444   4bf4

Combine that with this little tidbit from the avr-gcc manual:

The avr-size program (part of binutils), coming from a Unix background, doesn’t account for the .data initialization space added to the .text section, so in order to know how much flash the final program will consume, one needs to add the values for both, .text and .data (but not .bss), while the amount of pre-allocated SRAM is the sum of .data and .bss.

In the example output above, that tells us that the amount of “pre-allocated” SRAM (i.e. global data) is 1366 + 382 = 1748 bytes. We have 2048 bytes (= 2K = 2 * 2^10) of RAM total, leaving us 2048 – 1748 = 300 bytes of space left for the Stack. If your data and bss add up to more than 2048 (or close to it even), your almost certain to experience stack overflow (say once your main program calls the setup() function in an Arduino program). It’s a shame that the Arduino IDE doesn’t report the static size information available from binutils avr-size command at the time of this writing. There’s an open issue for it, lets hope it gets in someday.

The next natural question is, how on earth do you know how deep your stack can get at runtime once your actual program flow starts happening. There are fancy programs out there that can try and figure that out based on static analysis of your program control graph, but that is an area of active research as far as I know. The “tried and true” method that I found on avr-freaks forums is to paint your RAM with a known value at startup then count bytes at runtime till you find the known value.

The gist of it is to add the following bunch of code to your program. The following is a bare bones Arduino sketch that you can use to “measure” the maximum depth of the Stack at any point in your program execution. It’s not a flawless method, but it is pretty good.

extern uint8_t _end;
extern uint8_t __stack;

#define STACK_CANARY  0xc5
void StackPaint(void) __attribute__ ((naked)) __attribute__ ((section (".init1")));

void StackPaint(void)
{
  #if 0
  uint8_t *p = &_end;

  while(p <= &__stack)
  {
  *p = STACK_CANARY;
  p++; 
  }
  #else
  __asm volatile ("    ldi r30,lo8(_end)\n"
  "    ldi r31,hi8(_end)\n"
  "    ldi r24,lo8(0xc5)\n" /* STACK_CANARY = 0xc5 */
  "    ldi r25,hi8(__stack)\n"
  "    rjmp .cmp\n"
  ".loop:\n"
  "    st Z+,r24\n"
  ".cmp:\n"
  "    cpi r30,lo8(__stack)\n"
  "    cpc r31,r25\n"
  "    brlo .loop\n"
  "    breq .loop"::);
  #endif
  }

  uint16_t StackCount(void)
  {
  const uint8_t *p = &_end;
  uint16_t       c = 0;

  while(*p == STACK_CANARY && p <= &__stack)
  {    
    p++;
    c++;
  }

  return c;
}

#define PRINT_STACK_SPACE do{ \
  Serial.print("Stack: "); \
  Serial.println(StackCount()); \
} while(0)

void setup(){
  Serial.begin(9600);
  PRINT_STACK_SPACE;
}

void loop(){

}

When I run that sketch (in Ubuntu 12.04 with avr-gcc 4.5.3) I get 1811 of Stack space bytes remaining, which tells me that the Arduino 1.0.1 core takes up about 237 bytes of RAM out of the box (that’s about 11% of the total RAM), before you write hardly any lines of code. Keep that in mind when you’re building up your programs, and don’t forget that while you have 32K of FLASH memory in an Arduino, the 2K of SRAM is what you really need to keep an eye on. Hopefully you found this to be useful and not too long winded. If I got anything pretty much, but not exactly right, I’m totally playing the “I’m a hardware guy” card :-). Now go makes some LEDs blink over the Internet already.


Debugging Network Software

Posted: November 7th, 2011 | Author: | Filed under: Software | Tags: , , , , , | Comments Off on Debugging Network Software

WireShark network analyzer

I want to spend a couple paragraphs writing about Networks and debugging code running on the Nanode (or Arduino Ethernet for fthat matter) that uses them. I realize this blog entry is not for everyone, and probably will get it’s share of <yawns>, but it’s super important knowledge for when everything doesn’t go your way on networks. With Arduino sketches, you are kind of stuck with Serial.print(...) and LEDs to get insight into what’s going on, but that’s really pretty ineffective when it comes to network interactions. Honestly, for most users the network stuff better “just work” or they are going to be turned off pretty quickly. I , however, am not one to throw in the towel when the networking stuff doesn’t work, and hopefully I can shed some light onto what can be a shadowy space in the programming / debugging landscape. There’s no substitute for using the right tool for the job.

So given that printing to the console can only get you so far with network code debugging, what is a perplexed programmer to do? Well your best choice at that point is to look at what’s going on “on the wire.” In most realms, that means busting out an oscilloscope or logic analyzer, but in the networking world, we have much better / more appropriate tools available for the job. There’s an excellent, indispensible, and free(!) program called WireShark that you can download for just about any platform. WireShark allows you to capture all the traffic on any Ethernet interface (e.g. your network card) and dig into the details of the packets, which, I might add, it conveniently parses out for you for all but the most obscure protocols. You can also set up your capture with filters on pretty much anything you can imagine related to the packet contents (MAC addresses, IP addresses, whatever). And get this, you can check a box in the capture that will have your network card capture all the traffic that it sees (not just the stuff destined for it).

Here’s the rub, though. Unfortunately (or fortunately depending on your perspective) most networks today are equiped with “smart switches,” which eliminate collision domains, which means your network card only ever “sees” those packets which are legitimately destined for it (or broadcast / multicast). So while Wireshark is an awesome tool, it alone can probably not help you debug what’s going wrong with your Nanode software. To unleash the debugging power of WireShark on your Nanode, you’re going to need some “dummer” hardware, namely an Ethernet Hub. Good luck finding one at a retail store – I had to resort to the E-bay for mine, and got an 8-port hub for about $10.

A Hub is very similar to a switch in that it gives you more places to plug into your network. The big difference with a hub is that it internally connects all the ethernet wires together (well sort of) so that all the devices connected to the hub get to “see” each others packets, unfettered by the intelligent filtering of a switch. So if you plug in the ethernet cable from your computer into the hub, plug in the ethernet cable from your Nanode into the hub, connect your hub to your router, and run WireShark, both your computer and your Nanode should be able to get “on the internet.” More importantly, your computer running WireShark will be able to “snoop” on the internet traffic going to and from your Nanode! Now we’re in business. Often times you can look at what the network traffic is supposed to look like using your computer (by filtering on traffic coming to/from your computer’s MAC address for example) and all the fancy-pants network tools that come with it (especially if you’re on a linux box), then compare that to what happens when your Nanode participates in an analogous network exchange (by filtering on the Nanode’s MAC address for example).

Armed with these tools (and some practice, and some reading about protocols), you’ll be able to get to the bottom of your network problems in no time!


A Spin on previous Nanode + Pachube Sketch

Posted: September 23rd, 2011 | Author: | Filed under: Uncategorized | Comments Off on A Spin on previous Nanode + Pachube Sketch
Nanode

Nanode

Due to popular demand I made some mods to the sketch I previously posted, which was receiving data from the Wicked Node and posting it to Pachube using the Nanode‘s excellent internet connectedness. The version I’m posting with in this blog entry has no dependence on the WickedReceiver library and instead posts the Nanode’s native Analog sensor input readings to Pachube.

As a technical note on this one, Pachube rate limits the number of posts it will accept and we were exploiting the transmit interval of the Wicked Node in the previous sketch to throttle our posts to Pachube. In this sketch we have to be a bit more explicit in our throttling using the timestamp technique.

Make sure you get the latest and greatest EtherShield Arduino library from Andrew Lindsay’s (@thiseldo) GitHub repository. It contains some important fixes with respect to TCP, DHCP, and DNS that I ran into in my initial development. Check out the code and it should make pretty good sense, all the settings are up top just like before. Enjoy!

Cheers, Vic

Download: PachubeV3_WithoutNode

Pachube

Pachube

 Update: 12/14/2012 – The EtherShield library was retired earlier this year in favor of the EtherCard library. At some point I may get around to making another update to this post, but the EtherCard library already comes with a pretty easy to follow Cosm (the new name for Pachube) sketch. As always, feel free to post to our forum if you have questions.


Nanode + WickedNode + DHCP + DNS + Pachube!

Posted: August 13th, 2011 | Author: | Filed under: Wireless | Tags: , , , , , , , | Comments Off on Nanode + WickedNode + DHCP + DNS + Pachube!

The other day I got my Nanode talking to Pachube! That in and of itself is pretty cool, and it was also pretty easy given that there are a fair number of examples out on the web and a well documented API for interacting with Pachube. I extended some of these examples to use our Wicked Node and post received data to a Pachube sensor feed. I think my biggest contribution here perhaps was a bit of refactoring of the code so that the major chunks are re-usable in future sketches. Maybe some of it can maybe even make it’s way into the EtherShield library. I’ll provide my sketch attached to this post for anyone who wants to check out the details. I also want to share some general knowledge about debugging networks and software that interacts with networks, which I’ll dedicate my next post to.

So part one – the general program flow goes like this:

setup()
   1. Set Serial to 2400 baud (for radio interface)
   2. Initialize the Ethernet interface with a MAC address
   3. Get an IP address using DHCP (optional)
   4. Initialize the IP/UDP/TCP stack with a MAC address, IP address, and WWW port
   5. Set the Gateway and DNS IP addresses
   6. Wait for the Gateway to recognize the Nanode
   7. Resolve "api.pachube.com" to an IP address using DNS
   8. Initialize the Web Client part of the EtherShield library
loop()
   1. Wait for wireless sensor data to be recieved
   2. When data is received populate a template string and post it to Pachube

Pretty simple, right!? Well there is an example with the EtherShield library for demonstrating DNS and a separate example for demonstrating DHCP, and another example that demonstrates Pachube (getting information *from* Pachube actually), but besides the DHCP example, nothing really tied in DHCP; the other examples just use static IP addresses and call it day. So I refactored the code in the DHCP example so as to make the acquisition of an IP address over DHCP into a function call that I could just call from setup(). I insightfully named this function acquireIPAddress, and I’m pretty sure it will be useful in many a sketch in the future (for me and others I hope). Similarly in looking at the DNS example, it was kind of hard to see how you ended up with a resolved address, so I made another function that I think is a little more intuitive from an API standpoint that takes a null-terminated string as the address to resolves and a buffer into which it puts the resolved IP address. I decided not to get too creative and named this function resolveHost.

I think factoring out these two functions really makes reading the setup and loop functions a whole lot more digestible to the average human. As a last step I tidied up my code and moved things around so that all the configuration for the sketch is up top, including whether you want to use static of dynamic IP parameters, your Pachube API key and how you format and populate your Pachube post template. If you want to use the sketch as a basis for your own application, you’ll have to download the EtherShield library and WickedReceiver library and drop them in your Arduino libraries folder to get it all to compile.

Have fun getting your Nanode onto the internet and let us know what cool things you’re doing it!

Download the Sketch Here: Pachube_WickedNode

Check out this other blog post for a variation on the sketch that doesn’t use the Wicked Node, but instead posts ADC inputs directly from the Nanode.

Update: 12/14/2012 – The EtherShield library was retired earlier this year in favor of the EtherCard library. At some point I may get around to making another update to this post, but the EtherCard library already comes with a pretty easy to follow Cosm (the new name for Pachube) sketch. As always, feel free to post to our forum if you have questions.