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.

Filereader API and HTML 5 to display images in forms

So,  recently  I was working on creating a HTML form for users to register for a website and being no expert on HTML I ran across multiple issues. Most of them were fairly trivial and could be easily solved by reading through HTML, javascript and PHP help or searching the internet, but one of them stood out. I wanted to provide a form that allowed users to upload images (self), but I did not want to store the images on the server until they submit the whole form. There are multiple articles on how to upload the images into a temporary folder on the server and then display them or use one of the many available services, but not a very a clear article on how to do just read and display the image on the client itself.

It is only then that I came across this tutorial that a HTML 5 file reader API even  existed. I have just tweaked this tutorial for my needs to allow the browser to read the selected file and display it in the form itself before the form is submitted. My simple form does not provide additional image services (like cropping, resizing etc) , but those are easily available using either of the following services that  I came across: webresizer.com or aviary.com that provide easy integration APIs.

<!DOCTYPE html>
<html>
	<head>
		<title>Test File Upload </title>
		<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
		<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
		<link rel="stylesheet" type="text/css" href="./testFile.css"></link>
	</head>
	<body>
		<form method="post" action="" enctype="multipart/form-data">
			<div id="li_photo" class="imageuploader" >
					<label class="description" for="element_photo" class="element_7">Upload a Photo:</label>
					<input id="element_photo" name="element_photo" class="file" type="file" accept ="image/gif,image/jpeg,image/png"/>
					<div id="dropbox">
						<span class="message">Image Preview<br /></span>
					</div>       			
			</div>
			<div class="buttons" >
					<input id="saveForm" class="button_text" type="submit" name="Submit" value="Submit"/>
					<br/><br/>
			</div>
		</form>
		<script type="text/javascript" src="./test.js"></script>
	</body>
</html>

The java script is shown below:

var dropbox = $('#dropbox'),
		message = $('.message', dropbox);
	
	

var template = '<div id="template">'+
						'<span class="imageHolder">'+
							'<img />'+
							'<span></span>'+
						'</span>'+
					'</div>'; 

jQuery('#element_photo').change(
	function() {
		// This starts
		if(this.files!=undefined) {
			createImage(this.files[0]);
		}
		else {
			showMessage('Your Browser does not support HTML5 uploads! Cannot show preview!');
		}
	}
);
	
	
function createImage(file) {

   		var preview = $(template), 
			image = $('img', preview);
			
		var reader;
		try
		{
			reader = new FileReader();
			var max_file_size = 1048576 * 2;
			if (file.size > max_file_size) {
				showMessage('File size is too big, limit under 2MB');
				return;
			}
			if($('#template') !=[]) {
				$('#template').remove();
			}
		} catch (err) {
			showMessage('Your Browser does not support HTML5 uploads! Cannot show preview!');
			return;
		}
			
		
		reader.onload = function(e){
			
			// e.target.result holds the DataURL which
			// can be used as a source of the image:
			
			image.attr('src',e.target.result);
			image.attr('width','192');
			image.attr('height','192');
		};
		
		// Reading the file as a DataURL. When finished,
		// this will trigger the onload function above:
		reader.readAsDataURL(file);
		
		message.hide();
		preview.appendTo(dropbox);
		
		// Associating a preview container
		// with the file, using jQuery's $.data():
		$.data(file,preview);
}

function showMessage(msg) {
		message.html(msg);
}

The createImage function in the script uses the File Reader API to read the image file which is then displayed on to the page. A working link with the example can be found at fileupload.thechimerical.kodingen.com (Try out kodingen.com for easy prototyping and testing). You can download the actual files from the BOX folder.

The FileReader API is a HTML5 API that does not work on all the browsers (IE9, and Safari 5.1.7 don’t support it yet) while it works like a charm on Chrome and Firefox on both MACs and Windows. One note about Chrome is that the FileReader API will throw a Security exception if you try and test the scripts using this API on a local folder using file:/// access (Mozilla is more lenient).

Online courses galore!

I’ve been busy recently! Rather, I’ve been kept extremely busy with the sudden extraordinary explosion of online courses (all for free!). I know there is tons of information out there on the web, but still having quality professors teach you stuff is quite amazing.

For example, I am currently taking a course on Udacity on Programming a Robotic Car taught by Prof Sebastian Thrun.  The experience has been quite amazing so far. I had taken a similar course during my Graduate School based out of his Probabilistic Robotics book and really enjoyed the class then, but to have him teach it, is quite fantastic.

Previously, most of the course ware offered online were in the form of lecture notes, some videos (MIT OCW site, and some other universities) and limited access to the HWs and tests. However, now all of a sudden, there are multiple high level online courses that are being offered and I am enrolling in all that I can find ( I currently have a heavier load then during some of the semesters I was in school). These courses are all free, with HWs, tests (that have deadlines and grades and almost all material required) and with a completion certificate on passing the course. Of course, you could just attend the course for the knowledge too without worrying about any grades.

While most of the courses are software related (CS101, Programming, Machine Learning, Computer Vision etc),  it seems other topics are also popping up.  MIT has just launched an introductory course on Electrical Design running as a part of their MITx initiative. CalTech is stepping it up further offering live lectures directly from the university.

Though nothing beats hacking around to learn new stuff, some formal classes only open up new things to play with! Here are some of the sites offering free online courses:

Udacity : CS101, Programming Languages, Program a Robotic Car etc

Coursera : offering courses from multiple universities- Machine Learning, Computer Vision, Software As a Service etc

MITx : Circuits and Electronics

iTunes University

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

My Eagle Guide

Eagle is one of the more popular PCB design softwares out there! One of the major plusses for the software is that it provides different license versions for the users (starting from the Free version to hobbyist version and all the way to a professional version). For me, personally the free version is more than enough!

I use Eagle to document some of my schematics and try and design custom arduino shields for my projects. I have compiled the following list of links (tutorials) from the web that I refer to all the time.

Firstly I recommend the set of video lessons by Jason from RPC electronics. He has these tutorials recorded and available in Youtube. The links to the individual lessons are below:

Lesson 1:  Creating a new project (1:28)
Lesson 2: Eagle Schematics (Description of basic tools) (6:20)
Lesson 3: Basic Design using Eagle schematics I (6:16)
Lesson 4: Basic Design using Eagle schematics II (6:31)
Lesson 5: Basic Design using Eagle schematics III (4:49)
Lesson 6: Creating the PCB Board from schematics I (8:43)
Lesson 7: Creating the PCB Board from schematics II (7:22)
Lesson 8: Creating the PCB Board from schematics III (Routing) (8:41)
Lesson 9: Auto routing and Ground planing (9:20)
Lesson 10: Silk screen generation (6:17)
(Script files and cam files)
Lesson 11: Gerber file generation (8:44)
Lesson 12: Q & A (17:38)

I also heavily use the library made available by spark fun. Apart from the library, Sparkfun also has some Eagle tutorials:
a) Getting started with Eagle I
b) Getting Started with Eagle II

For creating a custom part in eagle, I use the following sparkfun tutorial as well as the instructable:
a) Instructable
b) Sparkfun tutorial

Hope this is helpful and saves some google searches ;)

“volatile” can cost you!

In an earlier post, I mentioned how I am going to get back into embedded progarmmming using the fantastic launchpad from TI.

Well, I got started with a book and various resources online, using the open source msp430 gcc chain (since i don’t have access to a win machine for IAR tools, the only negative thing for the launchpad in my opinion) with my hello world program (blinking leds).

Though there are plenty of blinking led programs using the Timers on the lanchpad, I really wanted to write a simple program without any timers. Below is the sample code I started with:


#include <io.h>
#include <signal.h>

 /* Program toggles Pin 1.6 in MSP430 */

 void delay()
 {
    int i;
   for(i=0;i < 32000;i++);
}

void main(void)
 {
   // Stop the watchdog timer
   WDTCTL = WDTPW | WDTHOLD;
  // Set the direction of PIN1.6
   P1DIR = P1DIR | BIT6;
   P1OUT |= BIT6;
   // Toggle Pin 1.6
   for(;;) //forever
     {
       P1OUT ^=BIT6;
       delay();
     }
 }

The code seems simple enough! The delay function should provide for sufficient delay to see the blinking of the LED. However on running this code, the LED never blinks!

As a beginner in embedded programming, it took me an hour of debugging and searching to come up with this article . The key point is:

An automatic object declared in a function that calls setjmp and whose value is-changed between the call to setjmp and a corresponding call to longjmp

Changing my delay function to use volatile fixes the issue!


void delay()
 {
    volatile int i;
   for(i=0; i< 32000;i++);
}

You can compare the objdump between the two, using:

You can check out the objdmp using:

msp430-gcc -S -mmcu=msp430x2012 main.c
msp430-as main.s -mmcu=msp430x2012
msp430-objdump -D a.out

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;
}

MSP430 launchpad!

TI launched  this crazy package of a microcontroller with all the bells and whistles that an arduino has for just $4.30. This includes a USB cable, the assembled board as well as the free IDE tools to get you started. There are a couple of catches though:

a) The free ide tools are only available for windows

b) There is no easy language for the board as there is one for arduino. (There is a graphical tool Grace available for win)

However, if you are willing to delve in to the embedded world and don’t mind getting dirty with C, this is an amazing deal.

Though there are no official tools available for other platforms, there are many wikis out there that outline the creation of the toolchain for linux and OSX.

I have personally managed to get this up and running in Linux Ubuntu (11.04) using the hackaday wiki and I recommend this wiki for OSX. Though, I have had some issues setting this up with rf2500 and permission. It seems that the solution is documented here,  I just haven’t had the time to set it up.

The basic code that I have uploaded works great!

Since, I am completely out of touch with core C Assembly programming, this micro controller provides a great opportunity to learn this architecture at a meagre cost of just $4.50.

scorecards (mysql) on the web!

I love cricket! For those of you unfamiliar with it, its a sport kind of like baseball. I play this local league with 3 teams generally after work and we take it pretty seriously! We like to keep scorecards of the games, store them someplace analyze them incessantly and use them to brag! Up till now these were in paper (impossible to share, maintain and aggregate).

With mobile phones theses days, its become easy to store data electronically. It was quite easy to find an Iphone App (CricMitra) that could be used for scoring and exporting the scorecards in HTML. Initially having scorecards available online was a huge thrill, but it was quickly passed over by the need to aggregate data and see statistics for the season.

This is typically done using databases and that’s where MySql comes in. Storing data in the database allows one to easily mine the data and get various statistics. Without going in details about the schema of my database, the real difficulty comes in using them comes from a) insertion of data (in our case HTML scorecards) and b) hosting this database so that it is easily accessible by webpages online.

There were typically 3 options for a novice in web like me and I tried them all. I list each below:

1) The original solution was to setup a linux server, install LAMP on the server and use this server as the website. The basic idea being to parse the HTML scorecards and store the information in the MySQL database. This database is then accessed using PHP to display contents online. I do believe that this was the best option, and I had everything setup but for the issue of a static IP. Websites, typically have static IPs (you can get around it using dynamic dns with daemon running), but my ISP blocks common ports like 80. So while I had a great website for my home network, it was useless outside!

2) To use a web hosting service. Most Web hosting services provide a LAMP setup available for users. This is really useful in setting up forms on your websites for easy storage in to databases. Here, I ran in to basic issue that the databases on the servers (MySQL) are not remotely accessible. What this means is that the databases do not accept remote connections. So I cannot connect to the database using an SQL client (I recommend Sequel Pro for Mac)  externally. Typically this is a good security design, but for my case where I had code written that parses the exported scorecard (html) and then exports data to a database, access to My SQL remotely was a must.

3) This is when I ran across db4free.net. They offer a free service of hosting MySQL databases online that can be remotely accessed. This is a test server and they do not recommend hosting production level details on the server. But for a small website, where the traffic is fairly limited, this is an ideal solution.

Currently, my database is set up in db4free.net and I have free web hosting using 000webhost. There are simple PHP pages that query the database for information and we have our own league statistics. Pretty cool and easy (provided you know a bit of coding, a bit of databases and a bit of the web).

Check it out at mplrocks.comze.com. I know that the website still needs some design, but the data is pretty cool.

The options I listed out are again in the order I feel are the best. My third option is not ideal and I would like to move to option 2, where I can use the MySQL database provided my 000webhost to store data, but that would require me to write some PHP code that could parse HTML into the database (something I am still working on :) ).