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:

May 28

Arduino Leonardo Released

Back in September of last year, the Arduino team announced a new, low cost Arduino board based on the Atmega32u4 titled  “Arduino Leonardo”. The time has finally come and the Leonardo is going to start showing up in stores in the next few weeks. It is similar to the UNO but with a simpler circuit. Here is how it stacks up to the Arduino UNO:

UNOLeonardo
MicrocontrollerATmega328ATmega32u4
Operating Voltage5V5V
Input Voltage (recommended)7-12V7-12V
Input Voltage (limits)6-20V6-20V
Digital I/O Pins1420
PWM Channels67
Analog Input Pins612
DC Current per I/O Pin40 mA40 mA
DC Current for 3.3V Pin50 mA50 mA
Flash Memory32 KB32 KB
SRAM2 KB2.5 KB
EEPROM1 KB1 KB
Clock Speed16 MHz16 MHz

More information about the hardware is available at the hardware page: http://arduino.cc/en/Main/ArduinoBoardLeonardo

Besides the difference in the pins, the major feature this has over the UNO is the ability for the Leonardo to emulate USB devices. It can appear to a computer as a mouse, keyboard, serial port and more. A great potential use for this feature is RFID logon for a PC. You could set it as a USB keyboard and when it detected the correct RFID fob it would enter “CTRL+ALT+DEL” then you credentials.

As with any computer peripheral you will need drivers. There are some included in the Arduino IDE and I’m sure the community will be developing some pretty interesting ones once the board comes out. To learn more about how the whole process will work, checkout the guide: http://arduino.cc/en/Guide/ArduinoLeonardo

You will also need the 1.0.1 version of the Arduino IDE available here: http://arduino.cc/en/Main/Software

May 22

Relay Control Over I2C

Relays are pretty fun to work with. They take all of the DIY electronics stuff and bring it to the “real world” where high voltages and amps live. Relays are all around us and many people don’t even know it. Next time you turn on your TV, oven, or coffee maker and it makes a click, that’s the sound of a relay.

In a previous article I wrote about programming an ATtiny to run Arduino code. There is also a library that allows you to make ATtiny chips I2C slave devices that can be addressed by an Arduino. With this combination you can control up to 3 relays per 8 pin ATtiny. It’s actually possible to have 4 relays per ATtiny85, however, it requires burning the bootloader to disable the reset pin which also prevents you from uploading code.

Materials:

  • ArduinoISP setup from previous article
  • ATtiny85 (or any compatible ATtiny chip)
  • 3 relays (with a switching voltage of 5V)
  • 3 LEDs with resistors
  • 2 pull up resistors (4.7k Ohm)
  • Jumper wires

Program the ATtiny85

In this project the ATtiny is acting as the slave device. It simply waits for commands to be sent. When it receives a 1, 2 or 3 it switches the corresponding relay. If the relay is currently off it switches it on, if it is currently on, it switches it off.
The code that needs to be uploaded requires the I2C library for the ATtiny chips.

  1. Download the code here: http://arduino.cc/playground/Code/USIi2c
  2. Create a “libraries” folder inside the Arduino Sketch folder
  3. Extract the zip file to the libraries folder you just created.
  4. Open Arduino program and paste the code below
  5. Select the ATtiny as the board
  6. Select Arduino ISP as the programmer
  7. Upload
// ATTiny based I2C relay control
// ForkRobotics 2012
//

#include "TinyWireS.h"                  // wrapper class for I2C slave routines

#define I2C_SLAVE_ADDR  0x26            // i2c slave address
#define Relay1_PIN  1
#define Relay2_PIN  4
#define Relay3_PIN  3

void setup(){
  pinMode(Relay1_PIN,OUTPUT);
  pinMode(Relay2_PIN,OUTPUT);
  pinMode(Relay3_PIN,OUTPUT);
  TinyWireS.begin(I2C_SLAVE_ADDR);      // init I2C Slave mode
}

void loop(){
  byte byteRcvd = 0;
  if (TinyWireS.available()){           // got I2C input!
    byteRcvd = TinyWireS.receive();     // get the byte from master
      switch (byteRcvd) {
        case 0x01:
          Switch(Relay1_PIN);
        break;
        case 0x02:
          Switch(Relay2_PIN);
        break;
        case 0x03:
          Switch(Relay3_PIN);
        break;
      }

  }
}

void Switch(int relay){
    if (digitalRead(relay) == HIGH){ digitalWrite(relay,LOW);}
    else {digitalWrite(relay,HIGH);}
}

Program the Arduino

The Arduino in this equation is doing the sending of commands. The Arduino can be configured to send these commands in response to any input but for the purposes of this experiment we are using the serial console. Here is the code for the Arduino:

// Control menu for I2C relay control
// 2012 ForkRobotics
//

#include &lt;Wire.h&gt;
int selection=0;
int ATtinyAddress=0x26;

void setup(){
    Wire.begin();
    Serial.begin(9600);
    PrintMenu();
}
void loop(){
  if (Serial.available() &gt; 0){
    selection = Serial.read()-48;
    RelaySwitch(ATtinyAddress,selection);
  }
}

void PrintMenu(){
  Serial.println(&quot;--- Relay Menu ---&quot;);
  Serial.println(&quot;1: Switch Relay 1&quot;);
  Serial.println(&quot;2: Switch Relay 2&quot;);
  Serial.println(&quot;3: Switch Relay 3&quot;);
}

void RelaySwitch(byte device,byte data) {
  Wire.beginTransmission(device);
  Wire.write(data);
  Wire.endTransmission();
}

Wiring

In this example the LEDs are used as an example of a completed circuit but it could be anything that meets the capacity of the relay. Here is the wiring for the example.

Update (3/27/2013) – Here is the Fritzing File used to create this: ATtiny85 I2C Relay
I2C Relay wiringHere is what my board looks like:

I2C Relay Module
Here is the video of it working:

Next Steps

This is a simple demo of the power of controlling relays over I2C. At this point the ATtiny relay module is only capable of switching the relays, however, with a more complex function on both sides it is possible to send specific commands to power a device off, on or blink for a period of time.