Jul 09

Cosm and TMP100

All of the devices around us are starting to become data collection points. Every minute of every day many data points are generated. This unwieldy mass of data needs to be logged, processed, stored and displayed in a reasonable way for it to be usable. The question becomes how to do this. One solution for the DIY community is Cosm (formerly Pachub) that allows us to do just that for free. In this article I’ll show you how to setup an account, create a feed and upload temperature readings from an I2C temperature sensor to Cosm via an Arduino Ethernet Shield.

Materials

  • Cosm Account
  • Arduino and Ethernet Shield or Arduino Ethernet
  • Breadboard and jumper wires
  • tmp100 (or other I2C temperature sensor) on a breakout board

Setup a Cosm Account

If you don’t already have one the first thing you need to do is setup a Cosm Account

  1. Go to https://cosm.com
  2. Click the big blue “Get Started” button
  3. Enter an email, username and password then click the “Sign up” button
  4. You’ll get an email with a link to verify your registration
  5. The link will bring you directly into your account
  6. Click on the big plus button
  7. Select Arduino
  8. Give the new feed a title and tags (optional) and press Create
  9. The Cosm Site will give you a sample sketch to upload data. You only need the three lines that start with:
    1. #define APIKEY
    2. #define FEEDID
    3. #define USERAGENT

Arduino wiring

In order to upload the data your Arduino needs to be connected to the internet. If you have an Arduino Ethernet you are ready to go. Otherwise you will need an Ethernet Shield. I already had a couple Arduinos so I decided to go the shield route (Note: the Ethernet Shield will not work with the Arduino Leonard).


Next we need to wire up the TMP100 sensor as shown in the Arduino and TMP100 article.

Sketch

The starter code that Cosm gives you when you create a feed (and the one included in the Arduino IDE) are written to send an analog sensor reading so there are some minor tweaks that need to be done to make it work with an I2C sensor. I’ve included the function to set the accuracy of the TMP100 sensor.
Here is the modified sketch:

/* TMP100 to Cosm
Fork Robotics 2012

Based on: http://arduino.cc/en/Tutorial/CosmClient
*/

#include
#include
#include

#define APIKEY         // your cosm api key
#define FEEDID         // your feed ID
#define USERAGENT      // user agent is the project name

// Set the TMP Address and Resolution here
int tmpAddress = B1001011;
int ResolutionBits = 12;

// assign a MAC address for the ethernet controller.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
// fill in your address here:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};

// initialize the library instance:
EthernetClient client;

char server[] = "api.cosm.com";   // name address for cosm API

unsigned long lastConnectionTime = 0;
boolean lastConnected = false;
const unsigned long postingInterval = 10*1000; //delay between updates to cosm.com

void setup() {
  // start serial port:
  Wire.begin();
  Serial.begin(9600);
  // start the Ethernet connection:
  Ethernet.begin(mac);
  SetResolution();
}

void loop() {
  // read the analog sensor:
  float sensorReading = getTemperature();
  // if there's incoming data from the net connection.
  // send it out the serial port.  This is for debugging
  // purposes only:
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  // if there's no net connection, but there was one last time
  // through the loop, then stop the client:
  if (!client.connected() && lastConnected) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
  }

  // if you're not connected, and ten seconds have passed since
  // your last connection, then connect again and send data:
  if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
    Serial.print("Sending temperature: ");
    Serial.println(sensorReading);
    sendData(sensorReading);
  }
  // store the state of the connection for next time through
  // the loop:
  lastConnected = client.connected();
}

// this method makes a HTTP connection to the server:
void sendData(float thisData) {
  // if there's a successful connection:
  if (client.connect(server, 80)) {
    Serial.println("connecting...");
    // send the HTTP PUT request:
    client.print("PUT /v2/feeds/");
    client.print(FEEDID);
    client.println(".csv HTTP/1.1");
    client.println("Host: api.cosm.com");
    client.print("X-ApiKey: ");
    client.println(APIKEY);
    client.print("User-Agent: ");
    client.println(USERAGENT);
    client.print("Content-Length: ");

    // calculate the length of the sensor reading in bytes:
    // 8 bytes for "sensor1," + number of digits of the data:
    int thisLength = 8 + getLength(thisData);
    client.println(thisLength);

    // last pieces of the HTTP PUT request:
    client.println("Content-Type: text/csv");
    client.println("Connection: close");
    client.println();

    // here's the actual content of the PUT request:
    client.print("sensor1,");
    client.println(thisData);

  }
  else {
    // if you couldn't make a connection:
    Serial.println("connection failed");
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
  }
   // note the time that the connection was made or attempted:
  lastConnectionTime = millis();
}

// This method calculates the number of digits in the
// sensor reading.  Since each digit of the ASCII decimal
// representation is a byte, the number of digits equals
// the number of bytes:

int getLength(int someValue) {
  // there's at least one byte:
  int digits = 1;
  // continually divide the value by ten,
  // adding one to the digit count for each
  // time you divide, until you're at 0:
  int dividend = someValue /10;
  while (dividend > 0) {
    dividend = dividend /10;
    digits++;
  }
  // return the number of digits:
  return digits;
}

float getTemperature(){
  Wire.requestFrom(tmpAddress,2);
  byte MSB = Wire.read();
  byte LSB = Wire.read();
  int TemperatureSum = ((MSB << 8) | LSB) >> 4;
  float celsius = TemperatureSum*0.0625;
  float fahrenheit = (1.8 * celsius) + 32;
  return fahrenheit;
}

void SetResolution(){
  if (ResolutionBits < 9 || ResolutionBits > 12) exit;
  Wire.beginTransmission(tmpAddress);
  Wire.write(B00000001); //addresses the configuration register
  Wire.write((ResolutionBits-9) << 5); //writes the resolution bits
  Wire.endTransmission();
  Wire.beginTransmission(tmpAddress); //resets to reading the temperature
  Wire.write((byte)0x00);
  Wire.endTransmission();
}

Using, modifying and troubleshooting

The address for the I2C is configured the same as it was in the previous TMP100 article but it’s possible to use your own TMP100 address and set the resolution to a finer degree.

To view the information that is uploaded to Cosm simply go to the feed at: https://cosm.com/feeds/xxxxx with “xxxxx” in the link replaced with the feed number Cosm gave you when you setup your new feed. You can also just log into Cosm and they will show you all your active feeds. Keep in mind that the feed data is public by default and you will need to modify the settings of the feed if you want to change this.

As written the code uploads the current temperature in Fahrenheit; if you want Celsius then simply change the return line of the GetTemperature function from “return Fahrenheit” to “return Celsius”

The nice thing about this project is that it doesn’t need to be connected to a computer. You just need power and Ethernet. If you do connect it to a computer you can monitor the status of the sketch by using the serial monitor.

Next Steps

This project presents a simple way to monitor and upload digital I2C readings from a single sensor to Cosm. This function can be integrated into a thermostat type project to add historical data for display or analysis. The next step is to be able to upload data from multiple locations in your home labeled for the room they are in or inside and outside temperatures. This also opens the door to more I2C devices being able to upload data. A single internet connected Arduino can upload hundreds of readings.

Jun 19

Leonardo Wiichuck Mouse

The Arduino Leonardo’s big new feature (thanks to its ATmega32u4 chip) is the ability to emulate a keyboard and/or mouse. This brings up so many possibilities for alternative control schemes for a computer. In this article I’ll show you how to grab the input from a Wii Nunchuck and get your computer to detect it as a mouse.

Wiichuck on Leonardo

I’ve worked with the Wii Nunchuck many times in the past including the Basic Robot I posted about a while back. Unfortunately the physical Wii Chuck adapter, while still a great way to breakout the pins for a nunchuck, is no longer as simple as plugging into pins A2-A5 as it was used on an UNO.
The major difference here is that the Arduino Leonard uses a different microcontroller than was used in the UNO. Because of this the pin mappings for certain functions are now different. One function that has been relocated is the pins used for I2C which is how the Wii Nunchuck communicates with the Arduino. On the UNO (and other boards based off of the ATmega328) the SDA is shared with A4 and the SCL is shared with A5. This is convenient because pin A3 can be used as power and A2 can be used as ground which allows 4 consecutive pins to be used for the Wii Chuck to plug into. However with the Leonardo and its new chip the SDA is shared with D2 and SCL is shared with D3 (they are also broken out to their own pins). In order to connect the Wii Chuck to the Arduino Leonardo you have to use a breadboard to make the appropriate connections.

In addition to the physical change in the pins there are references in the Wii Chuck Library for Ground and Power pins by using the “ports” which are also different. This requires editing the nunchuck_funcs.h file when using it with the Arduino Leonardo. With all that in mind, here is how to complete the project:

  1. Create a New Project with the following code:
    //Wiichuck Mouse
    //Fork Robotics 2012
    
    #include
    #include "nunchuck_funcs.h"
    int loop_cnt=0;
    
    // parameters for reading the joystick:
    int range = 40;               // output range of X or Y movement
    int threshold = range/10;      // resting threshold
    int center = range/2;         // resting position value
    
    boolean mouseIsActive = false;    // whether or not to control the mouse
    int lastSwitchState = LOW;        // previous switch state
    
    void setup() {
      // initilization for the Wiichuck
      nunchuck_init();
      // take control of the mouse:
      Mouse.begin();
    }
    
    void loop() {
      if( loop_cnt > 10 ) { // every 10 msecs get new data
        loop_cnt = 0;
        nunchuck_get_data();
    
        //right and left click control
        int leftState = nunchuck_cbutton();
        if (leftState) Mouse.press(MOUSE_LEFT); else Mouse.release(MOUSE_LEFT);
        int rightState = nunchuck_zbutton();
        if (rightState) Mouse.press(MOUSE_RIGHT); else Mouse.release(MOUSE_RIGHT);
    
        // read the x axis
        int xReading = nunchuck_joyx();
        xReading = map(xReading, 38, 232, 0, range);
        int xDistance = xReading - center;
        if (abs(xDistance) < threshold) {
          xDistance = 0;
        }
    
        // read the y axis
        int yReading = nunchuck_joyy();
        yReading = map(yReading, 38, 232, 0, range);
        int yDistance = yReading - center;
        if (abs(yDistance) < threshold) {
          yDistance = 0;
        }
    
        // move the mouse
        if ((xDistance != 0) || (yDistance != 0)) {
          Mouse.move(xDistance, -yDistance, 0);
        }
      }
      loop_cnt++;
      delay(1);
    }
    
  2. Save the project and close Arduino IDE
  3. Download nunchuck.funcs.h
  4. Save it to the Project folder
  5. Open the project and click the tab for nunchuck_funcs.h
  6. Remove the following lines:
    // Uses port C (analog in) pins as power & ground for Nunchuck
    static void nunchuck_setpowerpins()
    {
    #define pwrpin PORTC3
    #define gndpin PORTC2
        DDRC |= _BV(pwrpin) | _BV(gndpin);
        PORTC &=~ _BV(gndpin);
        PORTC |=  _BV(pwrpin);
        delay(100);  // wait for things to stabilize
    }
    
  7. Press upload

Once the code finishes uploading you should now be able to move the joystick to move the mouse, click C for left click and Z for right click.

Uploading code and using USB emulation

One lesson I learned from this processes is that the Leonardo uses the same processor for running sketches and communicating over USB. The challenge here is that when you emulate a USB device this can overwhelm the Arduino and prevent you from uploading new code. You can avoid this in 2 ways:

The first is to have some way to enable or disable device emulation this could be by pressing a button to enable or disable the device or only sending data when a button is held down.  The second way is to only send data when there is valid input. In this sketch I opted for the latter. It’s done with an if…then statement:

if ((xDistance != 0) || (yDistance != 0)) {
      Mouse.move(xDistance, -yDistance, 0);

What this does is eliminates the sending of null updates when the joystick is centered, allowing you to upload code.

This is a very quick and simple way to demo this feature but there are many other possibilities. It is possible to use the accelerometer in the Wii Nunchuck to move the mouse but I found it hard to control. More importantly it’s possible to use any component that you can interact with can now be a computer interface: hall sensors, distance sensors, or RFID readers. If you’re working on something similar leave a comment, I’d love to hear about it.

Jun 11

Arduino Leonardo Review

The new Arduino Leonardo board showed up last week and I’ve been having a lot of fun putting it through its paces. It’s always exciting to get my hands on a new piece of hardware and this is no exception, but it is not without its challenges.

The good

  • The USB mouse and keyboard functions are a lot of fun to work with. I don’t normally work on projects that function as human interface devices but this opens up new possibilities. The first thing I did was configure a Wii nunchuck as a mouse (Tutorial on how to set this up coming soon).
  • The microUSB connector is great. I always felt like the full sized USB Type-B connector on the UNO and earlier boards seemed straight from the 90s. I have microUSB cables everywhere because my phones have had them for the last 3 generations.
  • The layout of the board in general is much cleaner and organized than previous boards. I love that all 4 LEDs for power, blink, RX and TX are lined up between the barrel jack and the USB connector. Also the separate pins for SDA and SCL are nice (I’m still on the R2 version of the UNO so this is new for me).
  • Pin 13, which is tied to the onboard LED, is now a PWM pin so you can test fading without any additional components
  • Because the processor on the Leonardo performs the function of running sketches and communicating over USB there are less components needed which is the reason for the cleaner footprint but it also allows the board to be slightly cheaper.
  • Double the Analog Pins! A0-5 are in the same spot but D4, D6, D8, D9, D10, and D12 can also be used as analog input pins. If you have a project that happens to need more analog inputs this is a great benefit.

The challenges

  • Every time the Leonardo is reset it will create a new virtual COM port with a different number. This is different from the UNO and Duemilanove which were on the same ports regardless of where it was plugged in or if it was reset. The Leonardo will show up as different ports even when plugged into the same USB slot. The Arduino IDE 1.0.1 adapts to this by searching for a new virtual COM port but if you use other software to communicate with a project, like Putty, you will have to change it each time.
  • The pins on the Leonardo are remapped and repaired. Because the underlying chip has changed from the ATmega328 to the ATmega32u4 the functions of the physical pins on the chip and by extension the Arduino itself have different functions. A perfect example of this is the I2C pins which used to share the pins for Analog input 4 and 5. Now share the pins for Digital 2 and 3. This is going to be something to watch out for especially for shields that use hard coded pins for specific functions. To review how the pins are mapped see this graphic: PinMapping32u4
  • This pin mapping will also pose challenges to certain libraries that refer directly to the ports used on the chip itself. I ran into this with the Wiichuck code.

Conclusion

Overall the Leonardo is a great board. The new features are worth the minor frustrations that come along with it. If you have invested over the years in a large inventory of shields then you may want to consider if this is the right fit for you. However, if you want to take advantage of the USB device emulation functions, extra analog pins or plan to embed this in a project and want to save a couple bucks then I would not hesitate in purchasing one.

The Leonard is now available on Amazon:

Jun 08

Human Robotics

I recently finished reading The Singularity Is Near: When Humans Transcend Biology by Ray Kurzweil. It was a fascinating (and a little scary) read that discusses the coming merging of biological life with robotics.The book goes into how Nanotechnology, Artificial Intelligence and Robotics will transform humanity. For those of you who don’t know Ray Kurzweil he is an inventor, author and futurist.  He theorizes that we’ll see the first steps as technological solutions to biological failings and as the technology is developed and made more reliable and affordable we’ll begin to see people using it to “enhance” our native abilities. The book, written in 2005 was ahead of its time. Ray Kurzweil was right to deduce that robotics would soon be used to enhance the human race. Right now in 2012, we are in the midst of the first phase of this process; finding technological ways to duplicate natural abilities and functions.

One of the more successful examples of this is the cochlear implant which gives people who are deaf a sense of sound. This works by sending a signal through electrodes attached to the inner ear. This is an amazing device that can restore one of the 5 senses but it’s really just the beginning. It is also possible to use electrodes implanted in the brain to read the intentions of a person and the technology to do this is currently in the human clinical testing phase. This may sound like science fiction but researchers have recently release a video of a paralyzed woman who is able to control a robotic arm with just her mind:

The magic behind this is the BrainGate2 Neural Interface System. It is a microelectrode array that is implanted directly into the brain (the box you see on the woman’s head in the video is the connection point for the interface). The project originally allowed users to control a cursor on a screen. Through a training process the users learned how to move the cursor left, right, up, down and click. With the new pairing of the robotic arm the user learns to send the arm commands on a 2 dimensional plane and also send commands to grip and tilt the bottle.

This technology is still in the early testing stages however assuming it successfully completes the clinical trials and becomes a standard way to interface the brain with technology it could become possible to replace limbs with robotic versions. Beyond that it may be possible to implement a complete exoskeleton that would restore a person’s ability to walk or allow someone to take their first steps.

With the popularity of other forms of human enhancement such as cosmetic surgery, performance enhancing drugs and body modification and the increasing pace of technological acceptance (think how quickly smartphones became the norm) it is not that much of a stretch to imagine a world where people will voluntarily choose to get a neural implant or a prosthetic limb to enhance their natural abilities or give them a 6th sense not capable with natural biology. Today, with the use of our smart phones, many of us constantly have internet capabilities at our finger tips. Is it unreasonable to think that at some point in the future people may choose to have one surgically implanted? This kind of body modification may be to the next generation what tattoos and body piercings where to our generation…. taboo at first, but now widely accepted.

I for one am very excited to be living in a time when this technology is right on the horizon. It opens up the possibility of living much longer and productive lives.