Category Archives: Arduino

Arduino programming, tips and research.

Configuring the TP-LINK TL-WR702N nano router for Arduino

2015-02-07 Update: Added default WiFi password.

The two most-viewed pages on this site are often the following to Arduino articles:

The first one deals with a bug (?) I found in in the Arduino Ethernet library that prevented it from properly handling multiple incoming connections to the same port. The second was sharing my discovery of the $20 TP-LINK TL-WR702N nano router. It seems I am not the only one not happy that Arduino WiFi shields can be as much as $90, while cheap ethernet shields can be found for around $10.

The TP-LINK can be configured to connect to a WiFi network and then plug in to an Ethernet-only device and link it to the WiFi. Folks use them to get Ethernet printers on WiFi (such as the Lexmark printer I have — the official Ethernet module for it is $50, but I can use this TP-Link and be wireless printing for $20). I use one to get my Arduino on WiFi. Note that the Arduino will not have any control over the WiFi connection and won’t be able to select WiFi

This article is a quick guide to getting the TP-LINK set up for use with the Arduino.

TP-LINK TL-WR702N nano router box.
TP-LINK TL-WR702N nano router box, pictured next to a pen for scale.

1. Buy the TP-LINK WR702N. I got mine from Amazon for $19.99. It comes in a tiny box and is packed almost as nicely as an Apple product.

Inside the box you will find the tiny router (about 2″x2″x.5″), a micro USB cable, an Ethernet cable, and a USB power supply. There is also a mini-CD and a few small quick start guides. The guides are put together very well and have plenty of photos.

On the back of the TP-LINK unit will be the MAC address, but unless you have multiple units, you won’t need to know this.

2. Power up the TP-LINK by either plugging it up with the USB micro cable to a USB port (on your computer or a hub), or via the power supply.

3. The unit will boot up and after a few moments a new wireless network will appear that starts with “TP-LINK_xxxxxx” with the last part being the end of the MAC address of the router. Connect your computer to it. You will be prompted for a WiFi password, which you will find under the tiny barcode on the back of the unit. (It will be the last 8 HEX digits of the Mac address.) Give it a few more moments to connect and get an IP address. (Make sure you aren’t getting an internet connection some other way, like Ethernet. There are also ways to configure this router via Ethernet, but you’ll have to check TL-LINK guides for that.)

4. Open a web browser and go to: tplinklogin.net  It should prompt you for a username and password. You will find these on the back of the router, but they should be admin and admin.

TP-LINK WR702N login
Enter “admin” for the username and “admin” for the password.

5. You should see an admin webpage that is coming from your router. The first thing we need to do is configure the router to connect to your WiFi access point and connect to the internet. Click on Quick Setup under Basic Settings and click Next.

TP-LINK WR702N quick setup
Select Quick Setup.

6. The first screen is to select the Working Mode. We want Client, so choose it then click Next.

TP-LINK WR702N working mode
Select Client mode.

6. Next we will do Wireless Client setup and choose which WiFi network this nano should connect to. You can manually type it all in, but it’s easier to just click the Survey button so it scans for networks that are available. From that list, select your own WiFi network and then you will have an easy spot to enter your WiFi network password.

TP-LINK WR702N wireless client
Click the Survey button to obtain a list of available WiFi networks.
TP-LINK WR702N survey
Select your WiFi network from the list.
TP-LINK WR702N wifi password
Enter the password to your WiFi network.

7. The unit will then reboot and attempt to connect to your WiFi network. When it does, it will begin passing the WiFi connection out to the Ethernet port. To test this, turn off WiFi on your computer, and plug it up to the TP-LINK nano router via the included Ethernet cable. You will need to configure your computer’s Ethernet connection for DHCP. If it is working, after a few moments you will get an IP address assigned to your computer by the nano. Once the connection is made, you can test by going to Google.com or a known-working site.

8. Once you know it’s working, you should update the firmware on the nano to the latest. You can download the firmware here:

http://www.tp-link.us/support/download/?model=TL-WR702N&version=V1

Look for the latest version. It should look something like this:

TP-LINK WR702N firmware
Look for the latest version of the firmware for the TP-LINK TL-WR702N on the TP-LINK website.

Download this .zip file, then extract it somewhere you will be able to find it. It will create a folder with a few files inside, including a “.bin” which is the actual firmware update.

Log back in to tplinklogin.net and go to System Tools and Firmware then browse to the .bin file you just downloaded.

TP-LINK WR702N update
Browse to the .bin file you downloaded and update the firmware.

After it updates, the nano will reboot once again. On mine, this reset all the router settings, and I had to log back in and set it up again. There is probably a better set of steps to do this, but this is how I went through it and took screen shots so that is what I am sharing.

Once this is done, you can unplug and switch your computer back to normal internet connection. Now the TP-LINK can be plugged to power and the Arduino Ethernet shield and you can use the Ethernet library to make connections via your WiFi network.

NOTE: Since the nano requires using a computer and web browser to select which WiFi it connects to, this is not a portable solution. You cannot choose what WiFi to connect with (or the password or anything) from the Arduino. If you wanted to take your Arduino somewhere else and get it online, you would have to have a computer available to connect to the TP-LINK nano and reprogram which WiFi network it connects to. If you have a real WiFi shield for the Arduino, you can do this in software.

I hope these quick notes help…

Splitting a 16-bit value to two 8-bit values in C

Recently in my day job, I came across some C code that just felt inefficient. It was code that appeared to take a 16-bit integer and split the high and low bytes in to two 8-bit integers. In all my years of C coding, I had never seen it done this way, so obviously it must be wrong.

NOTE: In this example, I am using modern C99 definitions for 8-bit and 16-bit unsigned values. “int” may be different on different systems (it only has to be “at least” 16-bits per the C standard. On the Arduino it is 16-bits, and on my PC it is 32-bits).


uint8_t  bytes[2];
uint16_t value;

value = 0x1234;

bytes[0] = *((uint8_t*)&(value)+1); //high byte (0x12)
bytes[1] = *((uint8_t*)&(value)+0); //low byte  (0x34)

This code just felt bad to me because I had previously seen how much larger a program becomes when you are accessing structure elements like “foo.a” repeatedly in code. Each access was a bit larger, so it you used it more than a few times in a block of code you were better off to put it in a temporary variable like “temp = foo.a” and use “temp” over and over. Surely all this “address of” and math (+1) would be generating something like that, right?

Traditionally, the way I always see this done is using bit shifting and logical AND:


uint8_t  bytes[2];
uint16_t value;

value = 0x1234;

bytes[0] = value >> 8;     // high byte (0x12)
bytes[1] = value & 0x00FF; // low byte (0x34)

Above, bytes[0] starts out with the 16-bit value and shifts it right 8 bits. That turns 0x1234 in to 0x0012 (the 0x34 falls off the end) so you can set bytes[0] to 0x12.

bytes[1] uses logical AND to get only the right 8-bits, turning 0x1234 in to 0x0034.

I did a quick test on an Arduino, and was surprised to see that the first example compiled in to 512 bytes, and the second (using bit shift) was 516. I had expected a simple AND and bitshift to be smaller, but apparently, on this processor/compiler, getting a byte from an address was smaller. (I did not tests to see which one used more clock cycles, and did no experiments with compiler optimizations.)

On a Windows PC under GNU-C, the first compiled to 784 bytes, and the second to 800. Interesting.

I ran across this code in a project targeting the Texas Instruments MSP430 processor. The MSP430 Launchpad is very Arduino-like, and previous developers had to do many tricks to get the most out of the limited RAM, flash and CPU cycles of these small devices.

I do not know if I can get in the habit of doing my integer splits this way, but perhaps I should retrain myself since this does appear incrementally better.

Update: Timing tests (using millis() on Arduino, and clock() on PC) show that it is also faster.

Here is my full Arduino test program. Note the use of “volatile” variable types. This prevents the compiler from optimizing them out (since they are never used unless you uncomment the prints to display them).


#define OURWAY

void setup() {
volatile char bytes[2];
volatile uint16_t  value;

//Serial.begin(9600);

value = 0x1234;

#ifdef OURWAY
// 512 bytes:
bytes[0] =  *((uint8_t*)&(value)+1); //high byte (0x12)
bytes[1] =  *((uint8_t*)&(value)+0); //low byte  (0x34)
#else
// 516 bytes:
bytes[0] = value >> 8;     // high byte (0x12)
bytes[1] = value & 0x00FF; // low byte  (0x34)
#endif

//Serial.println(bytes[0], HEX); // 0x12
//Serial.println(bytes[1], HEX); // 0x34
}

void loop() {

// put your main code here, to run repeatedly:

}

Cheap bicycle wheel LED sign (POV)

Due to finances, about the only form of recreation I have these days is riding my bike. I like to take casual rides on the many trails here in Des Moines (Iowa is famous for it’s massive bike trail network).

A few years ago, I came across this neat LED display that attaches to a bike wheel and created images using persistence of image (i.e. lights flashing real fast as the wheel rotates, which the eye sees as a complete, though flickering, image):

http://www.ladyada.net/make/spokepov/

Go there and look at the pictures and watch the videos. It is able to display full color and even animate images (I love the Pac-Man and Ghost images they show). It works by having a row of LEDs that flicker on and off as the wheel spins. The wheel has to spin very fast to show an image, so they sell kits with multiple circuit boards of LEDs. The more on the wheel, the slower it has to turn to show an image.

It looked really cool, but it came in a kit, and I am not really that capable of an electronics person. Plus, the kit with three circuit boards was $113.

A found similar (much cheaper) devices on Amazon, though most of them just did preset patterns and didn’t let you load your own. You can find some simple LED wheel lights at Amazon for around $13 that can display short text messages:

Do some searching and you will find all kinds of cheap POV displays for bike wheels. I even found one for around $12 that was programmable via USB:

None of these are anywhere near as cool as the Adafruit SPOKEPOV kit, but they might be pretty neat for the money.

Then, I came across this one on from an e-Bay store:

http://www.ebay.com/itm/PC-Programmable-Wireless-LED-Custom-Message-Bike-Wheel-Lights-/400354534043?pt=LH_DefaultDomain_0&hash=item5d36fd629b

It had two rows of LEDs and could attach to the hub of the bike and display messages or graphics. At the time I found it, there was a seller auctioning them off, and I picked one up for $6 (shipped from the US, even). Unfortunately, the device was not like the pictures show — it was not in color, just blue (the description says this, but all the listings, including Amazon, use pictures showing one with color).

Also, the device would not fit the hub of my bike (the bolts were too short), nor the sensor on the frame (the bracket was too small). I am not sure what tiny little bikes these were made for, but my old 1998 Trek wasn’t one of them.

However, with a bit of rigging, it was easy to attach the device to the spokes of my bike (rather than clamping it around the hub) using some tape, and then I could do some quick experiments.

If I get time, I would like to experiment with a very low-cost version of this, using an Arduino-style device and a strip of the high speed LPN8806 addressable LEDs. An Arduino in a plastic enclosure with batteries could easily power two segments of 32 LEDs (wider spacing than the commercial units, though) and do full color. The only other hardware would be a magnet and a sensor so the device can tell when the led strips circle around.

Sound fun? More to come… (I already have created JavaScript code that lets me load in an image in a web browser and convert it to the format that this device would need to display it.)

Porting from 32-bit systems: 16-bit constants

I recently ran in to an issue at my day job where I had to write some time functions for a project. My work system did not have <time.h> and related functions like gmtime(), which I needed.

Unfortunately, once I implemented my version of gmtime() routine (based on some code I found online), I found it did not work on my target system. Testing on a PC using GNU-C worked fine, so I expected it had something to do with the code not being written for systems with 16-bit “ints” — like the Arduino.

I narrowed down the problematic code, and used the Arduino to test it. Here is the sample:


#define SECS_DAY          (24*60*60)

void setup()
{
long           time;
unsigned long  dayclock;

Serial.begin(9600);

time =   1396342111;

dayclock = (unsigned long)time % SECS_DAY;

Serial.println(time);
Serial.println(dayclock);
}

void loop()
{
}

On the PC, dayclock would print as 31711. On an Arduino, it would print as 18911. Initially I just tried to cast things to “unsigned long” but that did nothing. When I realized my mistake, I felt rather dumb since I learned this long ago.

Numeric constants, like that #define, are treated as “int” values meaning that on the PC (where int is 32-bits) they were different than on my target system (where int is 16-bit).

When dealing with long constants, you add “L” to the number like this:


#define THISISANINT 123456
#define THISISALONG 123456L

To fix my problem, all I did was throw in the Ls:


#define SECS_DAY          (24L*60L*60L)

The code I used as reference was written by someone who probably only considered it running on machines with 32-bit ints. Most desktop (PC/Mac/etc.) programmers tend to code this way.

Maybe this reminder will help someone else as they try to port code to an Arduino project.

Side note: Rather than use “int” and “long”, if you use a new enough compiler (C99 standard), include and use the actual type you want, such as uint8_t, uint16_t, or uint32_t. As you can see, “int” on the PC would be 32-bits, and “int” on Arduino (or MSP430, or…) would be 16-bits. It’s not portable code that way, and the C standard has finally solved this challenge.

Here’s another example for you to try… It should print out 86400 (24*60*60), which it does on a PC/32-bit system, but not on a system where ints are 16-bits. Have fun!


// This will fail (ints, 16-bit)
#define SECS_DAY  (24*60*60)

// This works (longs, 32-bit)
//#define SECS_DAY  (24L*60L*60L)

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

Serial.println(SECS_DAY);
}

void loop()
{
}

Adafruit Bluefruit EZ-Key response messages

NOTE: This page will be updated as I have time to do some more tests, but I wanted to get something posted so Google could begin indexing it…

The $20 Adafruit Bluefruit EZ-Key module sends a variety of status messages back through it’s serial port. Here is a list:

Power Up, unpaired:

Adafruit Bluefruit HID v1.2 11/30/2013
 No devices, making discoverable
Discoverable

When being paired:

Connecting to host xxxx,xx,xxxxxx
Exit discoverable
Connected

Power Up, paired – device not present:

Adafruit Bluefruit HID v1.2 11/30/2013
 Attempt to connect to xxxx,xx,xxxxxx
Failed to connect

Power Up, paired – device present:

Adafruit Bluefruit HID v1.2 11/30/2013
 Attempt to connect to xxxx,xx,xxxxxx
Connected

Pair Button Depressed to enter pairing mode:

Reset paired devices
Disconnected
Reset paired devices
Discoverable
Reset paired devices
Exit discoverable
Discoverable

* It appears to repeat those messages each time.

Power Up in remap mode (holding down PAIR button):

Adafruit Bluefruit HID v1.2 11/30/2013
Remap ready!

After sending remap HEX string:

OK
Set Mapping:64

* The tutorial on the Adafruit site indicates the number should be 128. As of yet, I do not know what the 64 and 128 represent, but I assume it’s some kind of bit mapped status.

Resending the HEX string:

OK
 Mapping:

* Not the missing “Set” but the space in front of “Mapping” is still there, and no status number. Maybe I dropped some data (it happens every time) or maybe it’s some missing stuff in the EZ-Key firmware.

At this point, I reset the EZ-Key if I wish to remap again. I am not sure (yet) if the second remapping takes effect (I will test and update this page).

When a switch is used, a key down message is sent, and then a key up message is sent when the switch is released. I’ll go through this when I get a moment and document the bits (I think I have a typo in this initial list).

K 0xFEF ... input 0 (1111 1110 1111) pressed
K 0xFFF ... input 0 (1111 1111 1111) released

K 0xFDF ... input 1 (1111 1101 1111)
K 0xFFF

K 0xFFB ... input 2 (1111 1111 1011)
K 0xFFF

K 0xF7F ... input 3 (111 0111 1111)
K 0xFFF

K 0xFEF ... input 4 (1111 1110 1111)
K 0xFFF

K 0xFDF ... input 5 (1111 1101 1111)
K 0xFFF

K 0xFBF ... input 6 (1111 1011 1111)
K 0xFFF

K 0xF7F ... input 7 (1111 0111 1111)
K 0xFFF

K 0xEFF ... input 8 (1110 1111 1111)
K 0xFFF

K 0xDFF ... input 9 (1101 1111 1111)
K 0xFFF

K 0xBFF ... input 10 (1011 1111 1111)
K 0xFFF

K 0x7FF ... input 11 (0111 1111)
K 0xFFF

Others – to be documented next update:

Adafruit Bluefruit HID v1.2 11/30/2013
No devices, making discoverable
Discoverable

…or…

Adafruit Bluefruit HID v1.2 11/30/2013
No devices, making discoverable
Discoverable
Connecting to host xxxx,xx,xxxxxx
Exit discoverable
Connected

And…

Adafruit Bluefruit HID v1.2 11/30/2013
Attempt to connect to xxxx,xx,xxxxxx
Failed to connect

Arduino-based Adafruit EZ-Key Remapper

Previously, I discussed the Adafruit Bluefruit EZ-Key module. This device comes factory-programmed to send specific key sequences via Bluetooth when one of the 12 inputs is selected. Software is available to change these key sequences, but this software runs on a host computer and requires installing an older version of a development environment called Processing.

Since it appears that the remapping is done simply by sending a text HEX sequence with a checksum to the EZ-Key, I thought it might be easier to just do this on an Arduino with a simple text user interface – no special installs needed.

I did a bit of work on this, and wanted to share my work-in-progress and maybe get some feedback on the interface.

Basically, for each of the 12 inputs you can specify a modifier (SHIFT, CTRL, ALT, etc.) plus up to 6 keycodes which will be sent out (with a Keys-Down) via Bluetooth. When the input is released, a matching Keys-Up message is sent.

To customize, you simply need to specify an input (0-11) and then a modifier (8 available choices) and then up to 6 keycodes (about 112 options available, such as ARROW UP or “k” or numeric keypad minus). I put together a very quick user interface, and here is a sample session, with comments on what is going on:

Adafruit Bluefruit EZ-Key Remapper 0.00 by Allen C. Huffman (alsplace@pobox.com)

Enter input to configure (0-11), [L)ist, [U)pdate or [Q)uit: L

* Here, I select "L" to list the current input config.
Input Key Codes:
----- ----------
 0.   ARROW_UP
 1.   ARROW_DOWN
 2.   ARROW_LEFT
 3.   ARROW_RIGHT
 4.   RETURN
 5.   SPACE
 6.   1
 7.   2
 8.   W
 9.   A
10.   S
11.   D

Enter input to configure (0-11), [L)ist, [U)pdate or [Q)uit: 6

* I select "6" to change input 7 (currently sends "1").
Editing Input 6 Configuration:

Modifier: NONE - Enter new modifier # (0-8), [L)ist, [ENTER)Skip or [Q)uit: L

* To see a list of available modifiers, I select "L".
  0. NONE             3. ALT_LEFT         6. SHIFT_RIGHT  
  1. CTRL_LEFT        4. GUI_LEFT         7. ALT_RIGHT    
  2. SHIFT_LEFT       5. CTRL_RIGHT       8. GUI_RIGHT      
Modifier: NONE - Enter new modifier # (0-8), [L)ist, [ENTER)Skip or [Q)uit: 1
Setting new modifier value to: CTRL_LEFT

* By selecting "1", I am choosing the modifier to be "CTRL_LEFT".
Modifier: CTRL_LEFT - Enter new modifier # (0-8), [L)ist, [ENTER)Skip or [Q)uit: 

* It shows the Modifier line again, and by pressing ENTER, it skips and moves to the next item - Keycodes 0-5:
Keycode0: 1 - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: 0

* By entering "0", I am selecting "KEY_NONW" - no key. In this example, I am making this input simply send the left CTRL key.
Setting new keycode value to: NONE

Keycode0: NONE - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: 

* By pressing ENTER five more times, it skips over key codes 1, 2, 3, 4 and 5, leaving them to their current values of "NONE".
Keycode1: NONE - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: 

Keycode2: NONE - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: 

Keycode3: NONE - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: 

Keycode4: NONE - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: 

Keycode5: NONE - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: 

Enter input to configure (0-11), [L)ist, [U)pdate or [Q)uit: L

* Now I use "L" to list the input config again, and can see that input 6 is now set to send the left CTRL key:
Input Key Codes:
----- ----------
 0.   ARROW_UP
 1.   ARROW_DOWN
 2.   ARROW_LEFT
 3.   ARROW_RIGHT
 4.   RETURN
 5.   SPACE
 6.   CTRL_LEFT
 7.   2
 8.   W
 9.   A
10.   S
11.   D

Enter input to configure (0-11), [L)ist, [U)pdate or [Q)uit: 7

* I then change input 7:
Editing Input 7 Configuration:

Modifier: NONE - Enter new modifier # (0-8), [L)ist, [ENTER)Skip or [Q)uit: L

* I want to make this input send ALT-Q, but I forgot what modifiers are available so I "L" to list them again.
  0. NONE             3. ALT_LEFT         6. SHIFT_RIGHT  
  1. CTRL_LEFT        4. GUI_LEFT         7. ALT_RIGHT    
  2. SHIFT_LEFT       5. CTRL_RIGHT       8. GUI_RIGHT      
Modifier: NONE - Enter new modifier # (0-8), [L)ist, [ENTER)Skip or [Q)uit: 3

* "3" is the left ALT key.
Setting new modifier value to: ALT_LEFT

Modifier: ALT_LEFT - Enter new modifier # (0-8), [L)ist, [ENTER)Skip or [Q)uit: 

* Then I press ENTER, and it goes to key code 0, which is currently the "2" key. I want to change that.
Keycode0: 2 - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: L

* But since I don't know what key codes are available, I choose "L" to get a huge list of all of them.
  0. NONE            28. 2               56. F2              84. KEYPAD_PLUS    
  1. A               29. 3               57. F3              85. KEYPAD_ENTER   
  2. B               30. 4               58. F4              86. KEYPAD_1       
  3. C               31. 5               59. F5              87. KEYPAD_2       
  4. D               32. 6               60. F6              88. KEYPAD_3       
  5. E               33. 7               61. F7              89. KEYPAD_4       
  6. F               34. 8               62. F8              90. KEYPAD_5       
  7. G               35. 9               63. F9              91. KEYPAD_6       
  8. H               36. 0               64. F10             92. KEYPAD_7       
  9. I               37. RETURN          65. F11             93. KEYPAD_8       
 10. J               38. ESCAPE          66. F12             94. KEYPAD_9       
 11. K               39. BACKSPACE       67. PRINT_SCREEN    95. KEYPAD_0       
 12. L               40. TAB             68. SCROLL_LOCK     96. KEYPAD_PERIOD  
 13. M               41. SPACE           69. PAUSE           97. EUROPE_2       
 14. N               42. MINUS           70. INSERT          98. APPLICATION    
 15. O               43. EQUAL           71. HOME            99. POWER          
 16. P               44. BRACKET_LEFT    72. PAGE_UP        100. KEYPAD_EQUAL   
 17. Q               45. BRACKET_RIGHT   73. DELETE         101. F13            
 18. R               46. BACKSLASH       74. END            102. F14            
 19. S               47. EUROPE_1        75. PAGE_DOWN      103. F15            
 20. T               48. SEMICOLON       76. ARROW_RIGHT    104. CONTROL_LEFT   
 21. U               49. APOSTROPHE      77. ARROW_LEFT     105. SHIFT_LEFT     
 22. V               50. GRAVE           78. ARROW_DOWN     106. ALT_LEFT       
 23. W               51. COMMA           79. ARROW_UP       107. GUI_LEFT       
 24. X               52. PERIOD          80. NUM_LOCK       108. CONTROL_RIGHT  
 25. Y               53. SLASH           81. KEYPAD_SLASH   109. SHIFT_RIGHT    
 26. Z               54. CAPS_LOCK       82. KEYPAD_*       110. ALT_RIGHT      
 27. 1               55. F1              83. KEYPAD_MINUS   111. GUI_RIGHT      

Keycode0: 2 - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: 17

* Since I want to send a "q" key, that is 17.
Setting new keycode value to: Q

Keycode0: Q - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: 

* Above, it confirms that key code 0 is now "Q". I can then press ENTER to skip the next five optional key codes for this input.
Keycode1: NONE - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: 

Keycode2: NONE - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: 

Keycode3: NONE - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: 

Keycode4: NONE - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: 

Keycode5: NONE - Enter new key code # (0-111), [L)ist, [ENTER)Skip or [Q)uit: 
Enter input to configure (0-11), [L)ist, [U)pdate or [Q)uit: L

* Back to the main menu, I do an "L" to list the current input config.
Input Key Codes:
----- ----------
 0.   ARROW_UP
 1.   ARROW_DOWN
 2.   ARROW_LEFT
 3.   ARROW_RIGHT
 4.   RETURN
 5.   SPACE
 6.   CTRL_LEFT
 7.   ALT_LEFT + Q
 8.   W
 9.   A
10.   S
11.   D

Enter input to configure (0-11), [L)ist, [U)pdate or [Q)uit: U

* And they look good. Input 6 is now left CTRL, and input 7 is now left ALT + the Q key. Cool. Selecting "U" will update the EZ-Key to use this new config.

...update device here...

…and there you have it. A very simple and easy-to-use “BIOS-like” interface to remap the Adafruit EZ-Key directly from an Arduino, without touching a line of source code or installing anything special.

Does this seem useful? Should I polish it up and post it? I just created it because I was too lazy to download stuff and writing my own seemed more fun.

Let me know what you think in the comments…

Adafruit Bluefruit EZ-Key

Last year, my friend Mike tipped me off to a new Bluetooth product that had been released by Adafruit. The tiny EZ-Key device…

http://www.adafruit.com/products/1535

…was a $19.95 “ready to go” switches-to-Bluetooth board. All you had to do was feed it power (3V-16V) and then hook switches (say, joysticks or arcade buttons) to the 12 input pins and ground and you were set. Power it up, hold down the pair button for a few moments, and let it connect to your computer. After that, any press of those switches would send a preprogrammed character. By default, they were:

  • #0 – Up Arrow
  • #1 – Down Arrow
  • #2 – Left Arrow
  • #3 – Right Arrow
  • #4 – Return
  • #5 – Space
  • #6 – the number ‘1’
  • #7 – the number ‘2’
  • #8 – lowercase ‘w’
  • #9 – lowercase ‘a’
  • #10 – lowercase ‘s’
  • #11 – lowercase ‘d’

You can find a full tutorial here:

http://learn.adafruit.com/introducing-bluefruit-ez-key-diy-bluetooth-hid-keyboard/overview

And the online user manual (with pinouts, wiring examples, etc.) here:

http://learn.adafruit.com/introducing-bluefruit-ez-key-diy-bluetooth-hid-keyboard/user-manual

If the default keys are not good for you, the device can be reprogrammed to send a different single character when a switch is pressed. This seems to involve using an adapter to hook the EZ-Key’s TX/RX pins to the PC, then running a special program that sends sequences to the EZ-Key to remap it.

The device can also be remapped over Bluetooth, which sounds like an easier option since you probably have Bluetooth (if you are using a Bluetooth adapter like this) and probably don’t have a TTL-to-Serial USB adapter. (Okay, some of you reading this probably do, but I don’t…) ((Actually, maybe I do. That may be the thing I use to program BASIC Stamps, though I didn’t know that at the time I bought it.)) (((But I digress…)))

For simple projects, the EZ-Key and a power supply is all you would need, provided whatever you are hooking to (like the MAME emulator) uses simple key presses. One emulator I have on my Mac uses the CTRL key for the FIRE button, so I would at the very least have to remap the EZ-Key to send a CTRL press.

For things like the iCade, which uses dual keypresses (one key for “press button down” and another for “release button”), this will not work. The EZ-Key only does single key presses.

Fortunately, the EZ-Key can also act as a Bluetooth gateway. You can hook it up to a serial port on an Arduino (or Teensy, or anything else with a UART) and write data to it at 9600 baud. This data is either sent out as a simple key down/key up press, or you can do more advanced things like send modifier keys (CTR+ALT+DEL) or even mouse movement and button clicks.

Using four wires, I connected an Arduino up to the EZ-Key:

Arduino hooked to EZ-Key
Arduino hooked to EZ-Key

I was using the Software Serial Arduino library to turn pins 10 and 11 in to TX and RX:

http://arduino.cc/en/Reference/SoftwareSerial

This let me open the EZ-Key just like I would open the console and read/write data to it:


#define RX_PIN         10
#define TX_PIN         11

// Initialize the Software Serial port.
SoftwareSerial EZKey(RX_PIN, TX_PIN); // RX, TX

// We talk to the EZ-Key at 9600 baud.
EZKey.begin(9600);

EZKey.write('x'); // send 'x'

It would be very easy to make a sketch that read data through the Arduino serial console port, and sent that out via Bluetooth:


#include <SoftwareSerial.h>

#define RX_PIN         10
#define TX_PIN         11

// Initialize the Software Serial port.
SoftwareSerial EZKey(RX_PIN, TX_PIN); // RX, TX

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

// We talk to the EZ-Key at 9600 baud.
EZKey.begin(9600);
}

void loop()
{
char ch;

// If data is available from the USB serial console...
while(Serial.available()>0)
{
// Read a character from the Serial console.
ch = Serial.read();

// If nothing was read, it returns -1...
if (ch>=0)
{
// Write that character out to the EZKey via UART.
EZKey.write(ch);
// Echo back to the serial console.
Serial.write(ch);
}
}
}

I paired the EZ-Key to my iPad, then opened the Serial Monitor on the Arduino IDE and was able to type things there and see them show up on the iPad (inside of Notepad, or anything else that accepted keyboard input).

The next step, for me, will be to integrate EZ-Key support in my iCade interface. Right now, I support reading digital inputs and writing out iCade commands as USB keyboard presses. With just a few lines of code, I should be able to expand this to use the EZ-Key and support Bluetooth as well.

Eventually, I will roll this in to my experimental USB Host Shield version, so it can also read USB joysticks (rather than just digital input switches) and output them as iCade USB keyboard or Bluetooth messages.

My EZ-Key sample program is now on GitHub:

https://github.com/allenhuffman/EZKeyTest

Stay tuned…

Simple scrolling LED Sign for NeoPixel (WS2811) or LPN8806

  • 2014/03/16 Update: The source code to this is now on GitHub. Check the Arduino link at the top of each page of this site.

Yesterday evening, I coded up a simple scrolling message sign that uses addressable LED strips like the Adafruit NeoPixels (WS2811) or LPN8806. The code I created is built for NeoPixels, since those were the ones I had access to, but it would be trivial to make it work with the Adafruit LPN8806 library. Future versions will make this simpler.

First, let’s talk about LED signs.

The BetaBrite is a commercially available scrolling message sign that’s been around for ages. I bought one at SAM’S CLUB back in the late 1990s. The BetaBrite that I have uses an 80×7 array of LEDs. This is what I will be trying to replicate.

If you shop around (ahem, e-Bay), you can find 1 meter long WS2811 LED strips with 60 RGB LEDs for around $8-$9. If you had seven of those, you could make a 60×7 LED sign. It wouldn’t be able to show as many characters at the same time as a BetaBrite does, but it would be good enough to experiment with. (There are strips with 144 pixels per meter, but they are very expensive. And, when you get past 500 or so LEDs, you start running out of memory on the Arduino. I plan to fix this with some updates to the LED library, eventually.)

Consider this wonderful drawing as I discuss a few possible ways to present a sign made out of LED strips:

LED Sign ideas

A. At the top is an example of one of these LED strips with LED number 0 to “n”. One end hooks to the Arduino and power, and the other end can be used to daisy chain multiple strips together. The first LED will be 0, and they count up to the end of the last strip. If you have three 60 LED strips, you have LEDs 0 to 179. The green arrow shows the direction of the data (the LEDs count up in that direction).

B. Next is an example of how you might arrange multiple strips so they could make up an LED sign. Each strip is shown running left-to-right, so at the end of the first strip the cables go all the way back to the left to connect to the start of the next strip. Wiring them like this makes it real easy to do things with. Notice that the green arrow runs left-to-right on each row.

C. However, it would be much much easier to just connect them like this, without all the extra wires running around. But, this causes every other row to run in the opposite direction (again, see the green arrows). This means the software has to be smart enough to know how to reverse drawing the pixels for every other row.

ALSO, based on where you decide to make LED 0, that changes everything. In these drawings, we are hooking the Arduino up at the top left. But, if it was easier to hook up at the bottom right, the entire numbering system would be backwards.

I decided to write a simple LED message program that could handle all of this. It’s not pretty, but it (maybe) works. I configure it with the number of LEDs in use, and how many are in each row, then I set where the start pixel is (TOPLEFT, TOPRIGHT, BOTTOMLEFT or BOTTOMRIGHT). I support running the rows STRAIGHT (A) or ZIGZAG (B). It can even do something fun…

D. This is the only thing I have actually done. I had two 1 meter strips, so I decided to spiral them with 20 LEDs in each spiral before the next row starts. These 120 LEDs can be split up in my program as six rows of 20 LEDs each, and then (with a small enough font), a message can rotate around it.

If you’d like to try out my code, I have posted it to GitHub:

https://github.com/allenhuffman/LEDSign

I have only tested it in the D configuration, but I have done some debug prints that make me think it should be handling all the other variations. Until I have access to more LED strips, I won’t know for sure.

Anyone want to try it out and let me know how it works for you?

Poor documentation, and the code could be cleaned up and optimized quite a bit. Perhaps I will have that done when I reach version 1.0.

Here’s a video of my first working version:

Cheap Arduino Wiznet 5100 ethernet shield

e-Bay seller kbellenterprises has a Wiznet 5100 ethernet shield for the Arduino for just $11.49 with free shipping. And, it ships from Missouri (fast). I have not used this shield, but it’s a great price if it works:

http://www.ebay.com/itm/Wiznet-W5100-Ethernet-Shield-for-Arduino-MicroSD-UNO-MEGA2560-FAST-US-SHIP-/171264625782?pt=LH_DefaultDomain_0&hash=item27e02acc76

This seller also has various Arduino clones (a Leonardo clone for $12.75 and a Leonardo mini for $9.99) with free shipping as well.

Arduino WS2811 scrolling message sign

I have two 1m 60 LED WS2811 strips, and expect to receive several more in coming weeks from Chinese suppliers. Once I have seven of them, I plan to use them as a scrolling message sign.

However, with two 1m strips (120 LEDs total), you can spiral them loosely (not tight enough to break the strip) and end up with six rows… Sorta. And, with a quick Arduino sketch (making use of some TVout fonts)… You can create a mini-circular scrolling message sign.

Here is “HELLO WORLD”:

Just for fun…