We rent a house and we probably won’t be here for the rest of our lives, so spending $1,000′s on a swing set just doesn’t make sense.
HC-05 Bluetooth with Arduino
Some time ago, I bought a couple of HC-05 Bluetooth modules. They use the CSR Bluecore 04-External single chip Bluetooth system. ITead Studio has a great little datasheet for the HC-05.
I wanted to be able to configure the device from the Arduino programatically, but according to the documentation you need to power cycle the chip to get it into AT mode (the mode necessary to send AT commands to the module). Instead, I have found that you can achieve the same result by simple pulling the RESETB pin low for more than 5ms. In my code below, I have a function enterATMode() that raises PIO11 HIGH, then resets the module so that it will accept AT commands. Once I have finished setting the device up correctly with AT commands, I pull PIO11 LOW and then reset the device again, using the function enterComMode.
I list the pin connections in the DEFINES at the beginning of each code block.
HC-05 Slave Mode with Arduino:
/*
Copyright Chris Samuelson 2012
*/
#include <SoftwareSerial.h> //Software Serial Port
#define RxD 6
#define TxD 7
#define Reset 5
#define PIO11 8
#define Led 13
#define RTS 4
SoftwareSerial blueToothSerial(RxD,TxD);
void setup()
{
Serial.begin(9600);
pinMode(RxD, INPUT);
pinMode(TxD, OUTPUT);
pinMode(Led, OUTPUT);
pinMode(PIO11, OUTPUT);
digitalWrite(PIO11, HIGH);
pinMode(Reset, OUTPUT);
digitalWrite(Reset, LOW);
pinMode(RTS, INPUT);
setupBlueToothConnection();
}
void loop()
{
char recvChar;
boolean rtsStatus = true;
while(1){
if(blueToothSerial.available()){//check if there's any data sent from the remote bluetooth shield
recvChar = blueToothSerial.read();
if(recvChar == 'a'){
digitalWrite(Led, HIGH);
}
if(recvChar == 'b'){
digitalWrite(Led, LOW);
}
Serial.print(recvChar);
}
if(Serial.available()){//check if there's any data sent from the local serial terminal, you can add the other applications here
recvChar = Serial.read();
blueToothSerial.print(recvChar);
}
}
}
void setupBlueToothConnection()
{
enterATMode();
sendATCommand();
sendATCommand("UART=57600,0,0");
sendATCommand("ROLE=0");
sendATCommand("PSWD=4567");
sendATCommand("CMODE=1");
}
void resetBT()
{
digitalWrite(Reset, LOW);
delay(2000);
digitalWrite(Reset, HIGH);
}
void enterComMode()
{
blueToothSerial.flush();
delay(500);
digitalWrite(PIO11, LOW);
resetBT();
delay(500);
blueToothSerial.begin(57600);
}
void enterATMode()
{
blueToothSerial.flush();
delay(500);
digitalWrite(PIO11, HIGH);
resetBT();
delay(500);
blueToothSerial.begin(38400);
}
void sendATCommand(char *command)
{
blueToothSerial.print("AT");
if(strlen(command) > 1){
blueToothSerial.print("+");
blueToothSerial.print(command);
delay(100);
}
blueToothSerial.print("\r\n");
}
void sendATCommand()
{
blueToothSerial.print("AT\r\n");
delay(100);
}
HC-05 Master Mode
/*
Copyright Chris Samuelson 2012</pre>
*/
#include <SoftwareSerial.h> //Software Serial Port
#define RxD 6
#define TxD 7
#define Reset 5
#define PIO11 8
#define Led 13
#define RTS 4
SoftwareSerial blueToothSerial(RxD,TxD);
void setup()
{
Serial.begin(9600);
pinMode(RxD, INPUT);
pinMode(TxD, OUTPUT);
pinMode(Led, OUTPUT);
pinMode(PIO11, OUTPUT);
digitalWrite(PIO11, HIGH);
pinMode(Reset, OUTPUT);
digitalWrite(Reset, LOW);
pinMode(RTS, INPUT);
setupBlueToothConnection();
}
void loop()
{
char recvChar;
boolean rtsStatus = true;
while(1){
blueToothSerial.print("a");
delay(500);
blueToothSerial.print("b");
delay(500);
if(blueToothSerial.available()){//check if there's any data sent from the remote bluetooth shield
recvChar = blueToothSerial.read();
if(recvChar == 'a'){
digitalWrite(Led, HIGH);
}
if(recvChar == 'b'){
digitalWrite(Led, LOW);
}
Serial.print(recvChar);
}
if(Serial.available()){//check if there's any data sent from the local serial terminal, you can add the other applications here
recvChar = Serial.read();
blueToothSerial.print(recvChar);
}
if(digitalRead(RTS)){
if(!rtsStatus){
rtsStatus = true;
Serial.print("rts changed true");
}
}else{
if(rtsStatus){
rtsStatus = false;
Serial.print("rts changed false");
}
}
}
}
void setupBlueToothConnection()
{
enterATMode();
sendATCommand();
sentATCommand("UART=57600,0,0");
sendATCommand("ROLE=1");
sendATCommand("PSWD=0000");
sendATCommand("PAIR=0018,e4,0c680a");
sendATCommand("BIND=0018,e4,0c680a");
sendATCommand("CMODE=0");
enterComMode();
}
void resetBT()
{
digitalWrite(Reset, LOW);
delay(2000);
digitalWrite(Reset, HIGH);
}
void enterComMode()
{
blueToothSerial.flush();
delay(500);
digitalWrite(PIO11, LOW);
resetBT();
delay(500);
blueToothSerial.begin(57600);
}
void enterATMode()
{
blueToothSerial.flush();
delay(500);
digitalWrite(PIO11, HIGH);
resetBT();
delay(500);
blueToothSerial.begin(38400);
}
void sendATCommand(char *command)
{
blueToothSerial.print("AT");
if(strlen(command) > 1){
blueToothSerial.print("+");
blueToothSerial.print(command);
delay(100);
}
blueToothSerial.print("\r\n");
}
void sendATCommand()
{
blueToothSerial.print("AT\r\n");
delay(100);
}
<pre>
Best fighting motorcycle ever!
ATMega32u4 / Arduino Leonardo Charlieplexing
I created a small charlieplexing demo for the Arduino Leonardo that uses a frame buffer to store the pixel data, and a timer interrupt to update the display. This is all done using an ATMega32u4 breakout board by Mattair Tech LLC http://www.mattairtech.com/index.php/featured/mt-db-u4.html. I program it using the Arduino Leonardo stack. For this quick demonstration I used the Charlieplex library from http://arduino.cc/playground/Code/Charlieplex. I plan to replace this with a solution more specific to my hardware to reduce the required clock cycles. For the timer interrupt routine I used a library called TimerOne from http://arduino.cc/playground/Code/Timer1.
Why Charlieplexing and how does it work?
Using charlieplexing you can control more LEDs with fewer pins than you could with regular direct drive methods. For example, in the demo board I drive 12 LEDs with 4 micro controller pins. It also reduces other components, in the demo board I only need 4 resistors for 12 LEDs.
There are some costs to using charlieplexing though. It is more complex to design the circuit and you can only light one LED at a time.
Charlieplexing is fairly simple once you understand a couple of basic concepts:
1) LEDs only light when electricity is passed through them in one direction.
2) You only light one LED at a time, to make more than one LED appear to be on at any time you simply flash them very quickly (greater than 50hz).
3) Micro controller pins typically have 3 different states: HIGH, LOW, HIGH IMPEDANCE (INPUT). In Arduino you set the pins state in 2 different ways. To set the pin as INPUT you use pinMode(pin,INPUT). To set the pin as HIGH or LOW, first set the pins direction to OUTPUT with pinMode(pin,OUTPUT) then set the pins value with digitalWrite. To set pin 5 high would be: pinMode(5,OUTPUT); digitalWrite(5,HIGH).
Here is the most basic example, 2 LEDs with 2 micro controller pins:
In this example, electricity can either flow from Pin 1 to Pin 2 through the LEDs or from Pin 2 to Pin 1 through the LEDs.
To light LED1 in this example you would set pin1 HIGH and pin2 LOW. To light LED2 you would do the opposite and set pin1 LOW and pin2 HIGH. With only 2 pins we don’t need to set any pins to high impedance yet.
Here is a slightly more complex example, this time 3 micro controller pins:
In this example, electricity can either flow from Pin 1 to Pin 2 through the LEDs or from Pin 2 to Pin 1 through the LEDs, just like in the first example. But, now it can also flow from pin2 to pin3, pin3 to pin2, pin1 to pin3 and pin3 to pin1.
That means we can light up to 6 different LEDs. This brings up some good questions though. If we set pin1 high and pin2 low to light LED1, what do we set pin3 to? If pin3 is high then LED4 will also light, if we set pin3 low then LED6 will also light. We set pin3 to INPUT, this is similar to disconnecting the pin. It will not sink or source current when it is set to INPUT, but instead appears to be a very large resistance.
Let’s try each LED:
LED1 => pin1 = HIGH, pin2 = LOW, pin3 = INPUT
LED2 => pin1 = LOW, pin2 = HIGH, pin3 = INPUT
LED3 => pin1 = INPUT, pin2 = HIGH, pin3 = LOW
LED4 => pin1 = INPUT, pin2 = LOW, pin3 = HIGH
LED5 => pin1 = HIGH, pin2 = INPUT, pin3 = LOW
LED6 => pin1 = LOW, pin2 = INPUT, pin3 = HIGH
There are some other great resources on the web that help to explain charlieplexing if you still have questions, one of my favorites is UziMonkeys explanation.
You can see the way that the 3 pin circuit is laid out, that you basically have 3 pairs of LEDs. A pair between pins 1 and 2, a pair between pins 2 and 3 and a pair between pins 1 and 3. Each pair can be powered forward or reverse to give you 6 total LEDs.
Circuit Design
I laid out this circuit with Eagle CAD. Routing took a minute to think through, as I wanted to make this as close to a 1 layer board as I could. As it stands, I only have one jumper on the board.
Circuit Board Creation
I printed out the circuit board on parchment paper with my laser printer. Then transferred the toner to my copper clad board with a laminator. For etchant I used the trusty hydrochloric acid and peroxide formula. I will post a blog entry soon about my preferred method for creating PCBs.
Download Charlieplex Eagle Files ZIP
The code and schematic follow.
#include <TimerOne.h>
#include <Charlieplex.h>
#define NUMBER_OF_PINS 4
#define NUMBER_OF_LEDS 12
int led = A0;
charliePin cp[] = {
{
0,2 }
,{
0,3 }
,{
1,3 }
,{
2,0 }
,{
3,0 }
,{
3,1 }
,{
0,1 }
,{
1,2 }
,{
2,3 }
,{
1,0 }
,{
2,1 }
,{
3,2 }
};
int state[NUMBER_OF_LEDS];
int i = 0;
int j = 0;
byte pins[] = {
8,9,10,5};
Charlieplex charlieplex = Charlieplex(pins,NUMBER_OF_PINS);
void setup() {
// open the serial port:
Serial.begin(9600);
// pinMode(led,OUTPUT);
// digitalWrite(led,HIGH);
for(i=0;i<NUMBER_OF_LEDS;i++){
state[i] = LOW;
}
Timer1.initialize(800);
Timer1.attachInterrupt(framewriter);
// initialize control over the keyboard:
//Keyboard.begin();
for(j=0;j<NUMBER_OF_LEDS;j++){
state[j]=HIGH;
if(j>0){
state[j-1]=LOW;
}
delay(100);
}
state[NUMBER_OF_LEDS-1] = LOW;
}
void loop() {
// check for incoming serial data:
if (Serial.available() > 0) {
// read incoming serial data:
char inChar = Serial.read();
// Type the next ASCII value from what you received:
switch(inChar){
case 'z':
for(j=0;j<NUMBER_OF_LEDS;j++){
state[j]=LOW;
}
charlieplex.clear();
break;
case 'a':
if(state[0] == HIGH){
state[0] = LOW;
}
else{
state[0] = HIGH;
}
break;
case 'b':
if(state[1] == HIGH){
state[1] = LOW;
}
else{
state[1] = HIGH;
}
break;
case 'c':
if(state[2] == HIGH){
state[2] = LOW;
}
else{
state[2] = HIGH;
}
break;
case 'd':
if(state[3] == HIGH){
state[3] = LOW;
}
else{
state[3] = HIGH;
}
break;
case 'e':
if(state[4] == HIGH){
state[4] = LOW;
}
else{
state[4] = HIGH;
}
break;
case 'f':
if(state[5] == HIGH){
state[5] = LOW;
}
else{
state[5] = HIGH;
}
break;
case 'g':
if(state[6] == HIGH){
state[6] = LOW;
}
else{
state[6] = HIGH;
}
break;
case 'h':
if(state[7] == HIGH){
state[7] = LOW;
}
else{
state[7] = HIGH;
}
break;
case 'i':
if(state[8] == HIGH){
state[8] = LOW;
}
else{
state[8] = HIGH;
}
break;
case 'j':
if(state[9] == HIGH){
state[9] = LOW;
}
else{
state[9] = HIGH;
}
break;
case 'k':
if(state[10] == HIGH){
state[10] = LOW;
}
else{
state[10] = HIGH;
}
break;
case 'l':
if(state[11] == HIGH){
state[11] = LOW;
}
else{
state[11] = HIGH;
}
break;
case 'm':
for(j=0;j<NUMBER_OF_LEDS;j++){
state[j]=HIGH;
delay(100);
}
break;
case 'n':
for(j=0;j<NUMBER_OF_LEDS;j++){
state[j]=LOW;
delay(100);
}
break;
case 'o':
for(j=0;j<NUMBER_OF_LEDS;j++){
state[j]=LOW;
}
for(j=0;j<NUMBER_OF_LEDS;j++){
state[j]=HIGH;
if(j>0){
state[j-1]=LOW;
}
delay(100);
}
state[NUMBER_OF_LEDS-1]=LOW;
break;
}
// Serial.write(inChar+1);
}
}
void framewriter()
{
if(i++==NUMBER_OF_LEDS){
i=0;
}
charlieplex.clear();
charlieplex.charlieWrite(cp[i],state[i]);
}

Noisebridge
First ECG Chart
Making a coat rack.
Welding
GoodFet 31 Built
I just finished soldering the GoodFet31 board I got from Travis Goodspeed. I haven’t tried replacing my MSP430 programmer from TI samples and spare parts yet, but I ran the monitor test and it checked out. I’ll update this post after I get a chance to try it out.






























