Category Archives: arduino

Wireless switch using arduino and a mac

Ability to control lights and fans wirelessly has long moved from being an expensive proposition to having commonplace solutions neatly packaged and available for consumers. Even then, coming up with your own custom solution is a lot of fun for hobbyists and tinkerers.

This is an example of one such implementation using Arduino, solid state relay, bluetooth module and a MAC. One of the challenges of using a MAC (OSX) is that direct access to hardware resources (like serial ports etc) is sometimes difficult (especially using Cocoa and Objective C).

RobotGrrl has provided a couple of easy to use libraries (frameworks for MAC lingo) to address the above issue and has provided some great tutorials at Apps for arduino. The source code is also freely available at github (search Matatino/Wijourno). The Matatino framework provides a simple library for connecting to the serial port, while Wijourno utilizes WIFI and Apple’s Bonjour Service (I think!).

For this experiment, I wanted to go wireless! Have a simple application that I can use from my MAC to control a power switch! Since I has previously invested in a Bluetooth module, I decided to use the Matatino framework to connect to my arduino over the air. For the power switch, I used a solid state relay kit , but a simple SPDT Relay available from Radio Shacks works as well. The connections from the Arduino to the Relay kit are straightforward:
Vcc -> Vcc
Gnd -> Gnd
Cntrl -> Pin 13

The Arduino setup is shown below:

A simple sketch is uploaded to the arduino, that listens on the serial port. When it sees a 1, it sets PIN 13 to high, thereby powering or switching on the relay, and on receiving a 0, it switches it off.

int ledPin = 13;

void setup()
{
  Serial.begin(115200);
  pinMode(ledPin,OUTPUT);
}

void loop()
{
  if(Serial.available() > 0)
  {
     char cmd = Serial.read();
     Serial.print(cmd);
     if(cmd =='1')
     {
       digitalWrite(ledPin,HIGH);
     }
     else if(cmd =='0')
     {
        digitalWrite(ledPin,LOW);
     }
  }
  delay(20);
}

The Matatino framework provides an arduino delegate that can be safely used to open a connection. For my simple user interface design shown below, only a couple of methods need to be implemented.

The first method is called when the user presses the Connect button. This method tries and connects to the arduino if its not connected, else disconnects it.

- (IBAction)connectToBT:(NSButton *)sender
{
    if(![arduino isConnected])
    {
        NSString *myDevice = @"/dev/cu.RN42-9A7D-SPP";
        // Connect to your device with 9600 baud
        if([arduino connect:myDevice withBaud:B115200])
        {
            sender.title = @"Connected";
            connectionButtonState = true;
        }
    }
    else
    {
        [arduino disconnect];
        sender.title = @"Connect";
        connectionButtonState = false;
    }
}

The second function is called when the Switch button is pressed and the function just toggles between sending 1 or 0 to the Arduino.


- (IBAction)switchOnOff:(NSButton *)sender
{
    if(!powerButtonState)
    {
        if([arduino isConnected])
        {
            [arduino send:@"1"];
            powerButtonState = true;
        }
    }
    else
    {
        if([arduino isConnected])
        {
            [arduino send:@"0"];
            powerButtonState = false;
        }
    }
}

The entire source code including the Xcode Project is available at Github.

The next steps for this project is to create an iOS app that allows you to do the same. Unfortunately, as Apple does not support the SPP Bluetooth profile on iOS devices, it would take the integration of Wijourno and Matatino to create a working prototype using the above hardware.

Programming ATtiny13 using Arduino ISP (and all the hacking involved!)

I recently came across MIT’s high low tech lab and was immediately drawn into their tutorial that allowed using Arduino Uno (and older versions) to be used to program ATtiny boards. The steps were simple and they had already updated their tutorial for Arduino 1.0 release (making it even more simpler). I couldn’t wait to try this out (especially since a lot of my projects barely require more than a couple of pins) and immediately went to sparkfun to order the ATtiny85 that they support.

I was already eyeing the Magic Chassis (discussion for another post) for some time and decided I would club them together. The Magic Chassis was quickly running out and ATtiny85 were already in backorder. Being an impatient person, I decided to order the ATtiny13 and try and hack the existing setup to make it work.

With the Arduino 1.0 IDE out, the new tutorial on the website is all the more simpler and only required modifying 2 files. You can access these changes from the github https://github.com/tekstop/attiny/tree/Arduino1 (Arduino1 branch).

The instructions are the same as those on the MIT high-low tech lab’s tutorials and the only real change required was adding this board to the boards.txt file. To do this, all I needed to do was look into a couple of datasheets and understand what the different settings really meant. This was the first time, I was really going into fuses and clk registers and it was pretty interesting and straight forward. My methodology in hacking this was:

Check the value of the fuse bytes in boards.txt for an existing mcu and find the values of the actual bits by going through the datasheet. The next part was just insuring that I set similar bit values for the ATtiny13 mcu. This was quite interesting especially with choosing the internal clock (9.6 Mhz) and prescaler options available.

Because the internal clock of the ATtiny13 is quite different from ATtiny85, the Software Serial library (only supports 8,16 or 20 MHz) will not work with ATtiny13 (9.6 MHz clock).

The pins_arduino.h file did not need to be touched as the pinouts for the tiny8 are the same.

With just these changes, I was ready to test my Arduino programmer.

1) Programmed the ArduinoISP sketch on my Arduino Duemilanove.
2) Copied the Github into the Arduino Sketch folder
3) Choose my Board from the IDE, selected the programmer as Arduino and connected pins as explained in the tutorials.
4) Burn the boot loader (one time). {It worked, gave some benign BS2 warning that can be safely ignored}
(At this point I was giddy with excitement, because nothing works on the first go, right!!!)
5) Chose the Blink sketch and wham uploaded it on to the board (success!)

And then reality struck! My LED didn’t blink! It just stayed on!. I reversed my commands and now saw that the LED stayed off, which gave me hope that at least something was being programmed correctly.

20111230-012614.jpg

My experiments showed that there was something wrong with the delay/millis commands. Normal read/write operations were running fine. Ofcourse, this prompted me to check my fuse values for the Clock [which seemed correct and changing them had no effect].

At this point, I started investigating the actual C code for delay and mills functions. Looking at the code in hardware/arduino/cores/arduino/wiring.c, I saw this line in code that seemed suspicious.


#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
SIGNAL(TIM0_OVF_vect)
#else
SIGNAL(TIMER0_OVF_vect)
#endif

I then further dug into the actual header file for the attiny13 (iotn13.h) to find that the interrupt macro for timer overflow for attiny13 was TIM0_OVF_vect and not TIMER0_OVF_vect. My Timer was not reporting the overflow and hence my timing functions were not working (This seems like an actual bug in the arduino 1.0 IDE). The fix is just adding an additional OR condition:


#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || (__AVR_ATtiny13__)
SIGNAL(TIM0_OVF_vect)
#else
SIGNAL(TIMER0_OVF_vect)
#endif

This shouldn’t affect anything else and making that fix has my LED blinking correctly!

20111230-012837.jpg

Temperature Sensor TMP102 with arduino

So after playing around with the Humidity sensor, it was natural for me to start playing with a simple temperature sensor. For my project, I choose the TMP102 sensor. The main reasons for choosing this sensor were:

a) I was working with a 3.3V Arduino, so I wanted a sensor that I could interface directly.

b) This sensor has great resolution, it is quite cheap (for less than $6) and sparkfun has a breakout board for the same.

c) It allowed me to play some more with the I2C interface.

20110930-033001.jpg

Arduino makes it really straightforward to play with I2C with its Wire Library that is very well documented . The sensor has multiple modes and lot of additional functionality that can be configured over I2C.

This sensor also has an additional pin that can be used to get 4 different addresses on the I2C bus. In my experiment, I connected it to GND to get an address of 72.

Great Getting Started Tutorial is available from buildr website. I have just wrapped this code around a simple library that can be downloaded from here. This library currently works with the sensor in basic mode ( I will be updating it soon to allow access to the sensor’s extended functionalities).

UPDATE: The library for Arduino 1.0 and higher can be downloaded from from here

Below is some sample code to use the sensor:

#include "WProgram.h"
#include "Wire.h" // Required to talk to the sensor and read values
#include "TMP102.h"  //TMP102 library

using namespace std;

TMP102 tmp102;

void setup()
{
    Wire.begin();
    tmp102.setup(); // Currently not required, but future versions of library will use it to set modes
    Serial.begin(9600);
}

void loop()
{
    // Get Temperature
    float tempC = tmp102.getTemperatureCelsius();
    float tempF = tmp102.getTemperatureFahrenhiet();
    Serial.println(tempC,2);
    Serial.println(tempF,2);
    delay(5000);
}

int main(void)
{
	init();
	setup();
	for (;;)
		loop();
	return 0;
}

Humidity Sensor HH10D

Sometime back, I ordered a HH10D, humidity sensor from sparkfun with the idea of integrating this sensor with an Arduino Pro (3.3V). This is a relatively cheap relative humidity sensor with an accuracy of about 3% sufficient for measuring  humidity at home.

20110921-122823.jpg

The sensor is pretty straightforward to use, once you figure out the mistakes in its data sheet. The sensor stores some calibration constants (sensitivity and an offset value) in an EEPROM packaged with sensor. The data from the EEPROM can be read using I2C (Arduino Wire Library). After that the sensor just returns frequency that can be measured and the RH can be calculated using the formula in the datasheet.

Couple of things to note about the datasheet:
– Device address is 81
– Though the device is marked as an I2C, the I2C communication is only required to read the constants from the EEPROM.

Once the constants have been read the sensor can be directly used without ever needing to connect the I2C lines. Another tricky thing with the sensor is an accurate way of measuring the frequency! A simple pulseIn approach will give wildly fluctuating results due to errors in measuring the frequency. To overcome this, there are a couple of suggestions that I discovered on the web:

– Using the FreqCounter library. This library uses the internal timers to measure the frequency accurately. You can download and get more details of this library from: http://interface.khm.de/index.php/lab/experiments/arduino-frequency-counter-library/
– Averaging the frequency measurements with pulseIn

Though the FreqCounter library is more accurate, there is something to be said for the flexibility and ease of the second method.

I have wrapped both the approaches along with all the functionalities of the sensor in a class (HH10D). The class makes it easy to choose either method and allows customizations for measurements. The code is well documented, so please feel free to check it out at: http://www.mediafire.com/?0k9efr0g38bng

UPDATE: Library for Arduino 1.0 and higher can be downloaded from https://www.box.com/s/ody8705fmjtc3zimfakt

Below is a sample program using the library!

#include "WProgram.h"
#include "FreqCounter.h" // Optional (not required by this code)
#include "Wire.h" // Required once to get the constants
#include "HH10D.h"  //HH10D library

using namespace std;

HH10D humid(6); //Not using FreqCounter library

void setup()
{
    Wire.begin();
    humid.setup();   // Reads the constants from the EEPROM
    humid.setSampleSize(2048); // Number of samples to average the humidity value
    Serial.begin(9600);
}

void loop()
{
    // Get RH
    float rh = humid.getRH();
    Serial.println(rh,2);
    delay(5000);
}

int main(void)
{
	init();
	setup();
	for (;;)
		loop();
	return 0;
}

Sharp IR sensors with arduino

One of favorite sensors of all time are the Sharp IR proximity sensors. These sensors are quite accurate and can be used for a variety of tasks. These are single package sensors that basically work on the principle of reflection. They output analog voltage corresponding to the distance measured (from 1 – 3.2V between distances of 4cm to 80cm). One of the main reasons why I love these sensors is that they are continuous and do not require a ping from the micro controllers to send out a pulse (like most ultrasonic sensors do!).

They are available in a number of configurations, each offering different distances. The page at acroname has a wonderful guide on these sensors.

The sensor that I am using for the current experiment is GP2D12. In this experiment, I will basically be reading the value from the sensor and based upon the readings changing the brightness and colors of the Tricolor Led.

The breadboard circuit is as shown below:

The nifty figure is created using a free software Fritzing (check it out!). This software allows you to assemble your circuit in Breadboard while simultaneously creating a schematic. It also creates a PCB (with a cool auto routing feature). Though it doesn’t seem to have all the bells and whistles that Eagle gives, it is really great for simpler circuits. Below, are schematic from Fritzing as well as Eagle. In my opinion, the Eagle schematic looks better or rather more circuitish!

Schematic with Fritzing

 

Schematic with Eagle

The actual setup is shown below:

Before using any sensor, it is important to calibrate the sensor. Sharp sensors are almost linear in their major range of operation. However, since they are reflection sensors, a lot depends on what you are trying to detect. I typically calibrate them over a subset of their entire range. Here, I have calibrated them over 20 – 50 cm. The experiment changes the brightness of the RED led from 20-30 cm, GREEN led from 30 – 40 cm and BLUE led above 40 cm.

The source code (not the best) is written in C/C++ instead of Processing. I find writing C++ easier, as it allows me to use a full fledged IDE (XCode in this case) and gives access to other libraries that are only in C/C++. You can configure almost any IDE to directly compile and upload code to the arduino. For Xcode, there is an excellent blog that covers all the steps. For Eclipse (free IDE across platforms), there are plenty of tutorials online.

#include "WProgram.h"
#include "HardwareSerial.h"
#include "SharpSensor.h"
void ledIntensity(int pin,int val)
{
if (val > 255)
{
val = 255;
}
else if (val <0)
{
val =0;
}

Serial.println(pin);
Serial.println(val);
analogWrite(pin,val);
}

void turnoff(int pin)
{
analogWrite(pin,255);
}

int analogPin = 5;
float value =0.0;
int green = 3;
int blue = 5;
int red = 6;
SharpSensor obj;
extern "C" void __cxa_pure_virtual() { while (1); }

void setup()
{
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
pinMode(green, OUTPUT);
pinMode(blue,OUTPUT);
pinMode(red,OUTPUT);
}

void loop()
{

value = obj.readInCM(analogPin);
if(value > 40.00 )
{
turnoff(red);
turnoff(green);
ledIntensity(blue,(int)(255-(value-40)*20));

}
else if (value > 30.00 && value < 40.00)
{
turnoff(red);
turnoff(blue);
ledIntensity(green,(int)(255-(value-30)*20));

}
else
{
turnoff(green);
turnoff(blue);
ledIntensity(red,(int)(255-(value-20)*20));

}

delay(100);
}

int main(void)
{
init();

setup();

for (;;)
loop();

return 0;
}

Update:
I created a small Class/ header to wrap the common functionalities of the sensor. You can download this at http://www.mediafire.com/?ddt3uu47axm2c

Blinking colors with the arduino

The Arduino is an open source project that provides an easy to use micro controller development board running various ATMEL Avrs.

Like all first micro controller projects, this one too is also about blinking a LED (‘The Hello World of embedded systems’). The only difference here is that I tried to step it up to blink different colors using a RGB tricolor LED. Again, nothing original, their is a good tutorial regarding the same on Wiring. The tutorial there uses the same LED as provided by Sparkfun. For me, personally, Sparkfun, along with Pololu, adafruit and acroname are the best places to look for electronics and other related items.

This tutorial just uses the Tricolor LED available at Radioshack. The basic difference between this LED and the other one is that this is just reversed. To drive the LED, it must be powered through the common terminal and the other pins must be held low to complete the circuit.

The complete schematic of the circuit is shown below:

The schematic sketch is created in Eagle (free software) and is amazing, especially after adding the Sparkfun components library.

The basic Arduino board is used and Pins 11, 12 and 13 are wired to the Red, Blue and Green terminals for the LED. Be sure to add resistors to limit the current (prevent overheating etc) depending upon the forward voltage for the LED. The LED above had Red at a lower voltage and hence a higher resistance in series.

The image below shows the connections:

Once the connections are set up, it’s just about writing some code! The arduino platform provides a simple IDE and the language is basically a derivation of Processing. It is straightforward and the arduino homepage has great documentation. There are limits with using Processing with arduino, as internally this still generates C/C++ code that is built into HEX before uploading it to the AVR. There are multiple C/C++ libraries for the arduino that allow for more functionality, but that’s a whole new blog post for another time.

The simplest thing to do is just go through the various example sketches (as they are called in the IDE) and just modify one of them and code up something that will continuously change the colors:


// Tricolor sketch : tekstop : Oct 7, 2010
// Constants
const int PINS[3] = { 11, 12, 13 }; // Pin numbers for Red, Blue and Green
// Globals
int ledStates[3] = { LOW, LOW, HIGH};
long interval[3] = { 500, 500, 500 }; // intervals for LED blinking for Red, Green and Blue
long previousMillis =0;
int I = 0;
int toggle(int state) {
if(state == LOW)
return HIGH;
else
return LOW;
}
void setup() {
for(int i=0; i < 3; i++) { // set the digital pins as output:
pinMode(PINS[i], OUTPUT);
}
randomSeed(analogRead(0)); // To get a random seed for the generator
}



void loop() { // This code runs continuously

if (millis() - previousMillis > interval[I]) {
I = (I+1) % 3;
previousMillis = millis();
interval[I] = random(1000);
ledStates[I] = toggle(ledStates[I]);
digitalWrite(PINS[I],ledStates[I]);
}
} //EOF

The code just sets up random intervals for the 3 led pins and just toggles them, producing different colors.

This is the most simple set up with this LED. I am just using digital pins that are sending either a high or a low pulse. This LED is capable of a lot more with PWM! Hold on to that!