Dejan Levec

WiFi Car

I have been planning to make Wi-Fi enabled car for quite a while (from last October/November), and I have actually done something to get to that goal. The point where I stopped was when I was trying to use my old iPhone as car controller. I tried for a while, and I got to the point where I could control motor via iPhone from my PC and Android phone. Sadly, I couldn’t transmit video from iPhone’s camera to my PC and at that point I gave up.

Every one in a while I would remember this project and thing about it for an hour or so, but that was it. However, about two weeks ago I read about 3G router (TP-Link TL-WR703N) sold in China, that costs about 15€ and supports OpenWrt. It seemed cool and I ordered one, and I finally received it a few days ago.

I have been playing with it for the last two days and I got OpenWrt, USB, lighttpd and mjpg_streaming working. Now I can stream video from connected webcam, and control peripherals connected via Arduino.

This router seems like a good platform with OpenWrt support, 32MB of RAM, WiFi, USB and serial port for all sorts of projects from robotics to home automation. You couldn’t want more for such a low price; it’s cheaper than Arduino Uno.

It has some downsides, like only 4MB of internal EEPROM memory which means it can hold only a minimal number of applications, and you will need to install others to external memory like flash drive. Like every memory, it has limited number of write operations, so you need to be careful and use it as little as possible.

Today I added USB hub and 8GB flash drive. Hub is connected directly to router’s USB port pins, and it currently has two (out of four available) used ports. First is connected directly to flash drive, hidden below hub’s circuit, and second is wired to USB socket for webcam.

I plan to use third port for AVR micro controller connected via USB using V-USB library. Micro controller will currently only be used for control of car motors, but in the future I might use it for something more.

Need to start reading datasheets

I have been wondering for a while how to measure household electricity consumption. Usual candidates are photoresistor for detecting LED’s flashes or current transformer, but since I can’t use either of them, I need something different. A while back I tried using webcam mounted to the electric box which contains electricity meter, which worked pretty well. Downside was that I needed a computer to detect LED’s blinks which meant unnecessary use of 40W 24/7 every day for older laptop I don’t use anymore.

So I thought about it and decided to try with RGB sensor, that has filters and can detect all three colours seperately. I stumbled upon Avago ADJD-S311-CR999 which goes for about 3€ on Farnell.com, and everything seemed like I might actually start measuring electricity consumption.

Ain’t it nice?

I actually saw datasheet before I decided to buy it. After my thorough research I concluded that it contains nice graphs like this:


Sadly, when I finally received it, all I got was this:

I really need to start paying more attention to datasheets before I actually buy things, because this will be quite a challenge to solder considering that it has 9 pins.

Water Usage Meter

I needed a way to measure water used outside the house. There are some commercial products, like Gardena Smart Water Flow Meter, but they are not cheap and can’t draw nice looking graphs.
This seemed like a good weekend project and I can finally use XRF wireless modules, that I bought a few weeks ago. XRF wireless modules are Xbee-like radios with a lot of features:

  • they work out of the box,
  • have Xbee-like pinout,
  • support 128-bit AES encryption
They cost 15€ each, but because they need 3.3V supply voltage and have 2mm pitch layout, I also bought some active breakout boards. I have been using it for only one day and I already like them. Sadly, there isn’t much documentation about them on the Internet, as there is for Xbee modules.
Anyway, they have a really easy configuration mode. To enter it you need to send +++ and wait 1 second before and after you send it. I use the following configuration:

ATEA password
ATEE 1
ATID 0000
ATAC
ATDN

which enables AES encryption, sets password to ‘password’ and specify network ID as 0000. New lines are represented as \r char, and commands return OK if it’s successful.

I decided to use the following configuration:

Flow meter on regular intervals send data about water usage to Netduino Plus gateway. Netduino Plus listens to XRF network and sends every received message to webapp hosted by Google App Engine. I plan to update gateway to support two-way communication, however, firstly I need to make web GUI to display flow meter’s data nicely, since numbers without graphs are somewhat boring.

Flow meter

Flow meter device consists of Seeedstudio’s Water Flow sensor, XRF module, Atmega8 microcontroller, and it’s currently constructed on breadboard. I will move it to PCB, when I find enough time (next weekend sound good). Water flow sensor contains hall-effect sensor and sends pulse on every rotation of rotor. After some testing I came up with the following formula:

water flow [dcl] = pulses / 3.2 per measured period

Example: If it sends 3.2 pulses in one seconds, it means that  water flow is 1 dcl per second.
I decided to sample water flow for ten seconds period, and send sum of those values to web app every five minutes.

Netduino gateway

Netduino Plus listens to XRF wireless data and sends every received command to web app with HTTP GET request.
Commands consist of following data: start character, two digit receiver id, two digit sender id, data and end character.
Example command:

!0102hello world$

which sends hello world string from device #02 to device with id #01. Web app saves these information including current timestamp to the database.

Google App Engine
It’s first time I actually tried GAE and I kinda like it in the sense of building application. It multiple languages but I decided to use Python. Documentation and examples are really good and Python web community is quite big so it’s not hard to find different libraries. Databases are really cool, because you don’t need to specify columns in advanced, so it’s like MongoDB, which I really like. Sadly, web frameworks like Django mostly expect relational database.
Anyway, the only thing I don’t like about GAE for now are their free quotas. Yesterday, when I was testing I sometimes sent up to 10 updates per minute and I used 10% of database quota in about 1 hour. I’m a bit afraid that I might hit those limits quickly if I add additional processing to web app and additional modules to my system.

Amblight part 2: Controlling LEDs

After figuring out how to control LEDs with microcontroller I wanted to try controlling it from PC. Firstly I thought of USB via V-USB framework, but I quickly found out that I cannot update LEDs’ color in interrupt routine, because it would interfere with USB data transfer. Since I had additional unused AVR on my table I decided to use it as a USB to serial converter by using AVR-CDC firmware (http://www.recursion.jp/avrcdc/).


(It has a slight delay, but I haven’t been able to find out if it’s because of Stereo Mix, FMOD or both.)

Main controller is currently responsible for receiving data via USART and updating LEDs when enough data is transfered (RGB color for each of 25 LEDs). It uses additional timer interrupt to check for lost connection to remove partially received data to not mess with data received afterwards.

Timer interrupt code checks if it has already elapsed predefined time after last received byte and clears data:

ISR (SIG_OUTPUT_COMPARE0A)
{
int i=0;
time++;

if(time > 4*30) {
for(i = 0;i<25;i++) {
for(SPDR = 0x00; !(SPSR & _BV(SPIF)); );
for(SPDR = 0x00; !(SPSR & _BV(SPIF)); );
for(SPDR = 0x00; !(SPSR & _BV(SPIF)); );
}

current=0;
time=0;
}
}

USART receiver interrupt updates color channel value for current LED and checks if we already received enough data to send it to LEDs connected via SPI:

ISR(SIG_USART_RECV)
{
char ReceivedByte;
int i;

ReceivedByte = UDR0;

diodes[current++]=ReceivedByte;
time=0;

if(current>=25*3) {
current=0;
for(i = 0;i<25*3;i++) {
for(SPDR = diodes[i]; !(SPSR & _BV(SPIF)); );
}
}
}

Everything is controlled from C application using FMOD library for audio spectrum analysis, and Windows serial port communication.

Sample code for initializing and writing data to serial port:

//COM communication
int serial_start(wchar_t *port) {
DCB settings;
int r;

comPort = CreateFile( // http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
port,
GENERIC_READ | GENERIC_WRITE,
NULL,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);

if(comPort == INVALID_HANDLE_VALUE) {
return -1;
}

r = GetCommState(
comPort,
&settings
);

if(r == 0) {
return -1;
}

/*
AVR: UCSR0C = (3 << UCSZ00); = no parity, 8 bits
*/
settings.BaudRate=128000;
settings.ByteSize=8;
settings.Parity=NOPARITY;
settings.StopBits=ONESTOPBIT;

r = SetCommState(
comPort,
&settings
);

if(r == 0) {
return -1;
}

return 0;
}

void serial_write(unsigned char *buf, unsigned int length) {
DWORD written = 0;
WriteFile( // http://msdn.microsoft.com/en-us/library/windows/desktop/aa365747(v=vs.85).aspx
comPort,
buf,
length,
&written,
NULL
);
}

Ambilight part 1 & Netduino

I always liked Ambilight feature, but our TV doesn’t have it. I have seen some home made look-alikes on the Internet, however, I never really thought about buying it until I’ve seen Ladyada’s strand of 25 RGB LEDs and instantly wanted to build it myself. Since I have 42″ TV I decided to buy 2 strands, totaling 50 RGB LEDs.

Each LED has dedicated IC, which allows for individual control of color and brightness. IC is WS2801 and supports SPI like protocol which can be found on most (if not all) microcontrollers. I also like that they are waterproof in case I want to use it as christmas lights.

Since 3 years ago, when I first used microcontroller I have only used AVRs, altough I bought Arduino last year, but it’s still an AVR. I have two PIC samples, but haven’t come around to build programmer. Also have MSP-430 based board, but haven’t got a project where I could use it, so that doesn’t count.

I have been looking at .NET Micro Framework for a while and finally decided to try it. What I like about Netduino:

– Threading
– Debugging (it’s like debugging Windows application)
– C# (I like C/C++ but find that I’m more productive with a higher level language)
–  Great networking support (for Netduino Plus)

I bought them specially for prototyping & one-time projects, but may decide to use it for some big project in the future.

Let’s get back to my ambilight like system. Yesterday, I have spend a few hours trying to interface with those LEDs, but haven’t had much luck. On the end I kinda blamed Netduino for this, which turned out to not be the problem. Most of the times they didn’t even light up, when other times they were in random colors.

Today I decided to test it with ATmega168, since I know it pretty well and original code from Ladyada is based on similar microcontroller. After I figured out the chip worked, I struggled with the same problem that was present with Netduino yesterday, I couldn’t control the lights.

After another reading of technical data about this strand I noticed that I’m connecting MISO to CLK and CLK to MISO. Well, that doesn’t look right, but I was completely sure, that yellow cable was clock and green cable was data. After a simple switch everything was working fine and I was playing with different animations using same controller.

Sample code for one of the animations (walking blue light):

#include <avr/io.h>
#include <util/delay.h>
#define SPI_PORT PORTB
#define SPI_DDR DDRB
#define SPI_CS PB2

#define SPI_CLOCK_MASK 0x03
#define SPI_2XCLOCK_MASK 0x01

#define SPI_MODE_MASK 0x0C

void delay_ms(uint16_t x);

int main (void)
{
SPI_DDR = (1<<PB3)|(1<<PB5)|(1<<PB2);

SPCR |= _BV(MSTR);
SPCR |= _BV(SPE);

SPCR &= ~(_BV(DORD));
SPCR = (SPCR & ~SPI_MODE_MASK) | 0x00;

SPCR = (SPCR & ~SPI_CLOCK_MASK) | (0x01 & SPI_CLOCK_MASK);
SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((0x01 >> 2) & SPI_2XCLOCK_MASK);

SPCR &= ~(_BV(DORD));

int selected=0;
while(1) {

for(int c=0; c<25; c++) {
if(!(c==selected)) {
for(SPDR = 255; !(SPSR & _BV(SPIF)); );
for(SPDR = 0; !(SPSR & _BV(SPIF)); );
for(SPDR = 0; !(SPSR & _BV(SPIF)); );
}else{
for(SPDR = 0; !(SPSR & _BV(SPIF)); );
for(SPDR = 0; !(SPSR & _BV(SPIF)); );
for(SPDR = 255; !(SPSR & _BV(SPIF)); );
}
}

_delay_ms(50);

selected++;
if(selected==25){
selected=0;
}

}

return(0);
}

Blue and brown wires are going to LED strand, flat cable is for ISP programmer, and yellow LED was used to test accuracy of uC fuses and crystal. I used first crystal I could found and it has frequency of 19,6608 MHz.

With my problem solved I tried using it with Netduino and it worked in first try.

Sample code for Netduino:

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;

namespace NetduinoApplication2
{
public class Program
{

public static void Main()
{

SPI.Configuration Device1 = new SPI.Configuration(
Pins.GPIO_NONE, // SS-pin
false, // SS-pin active state
0, // The setup time for the SS port
0, // The hold time for the SS port
false, // The idle state of the clock
true, // The sampling clock edge
2000, // The SPI clock rate in KHz
SPI_Devices.SPI1 // The used SPI bus (refers to a MOSI MISO and SCLK pinset)
);

SPI SPIBus = new SPI(Device1);

SPIBus.Config = Device1;

byte[] WriteBuffer = new byte[3];

int t = 0;
while (true)
{

for (int c = 0; c < 25; c++)
{
if (c < 13 && t>0 || t==0 && c >= 13)
{
//R

WriteBuffer[0] = 0xFF;
WriteBuffer[1] = 0x00;
WriteBuffer[2] = 0x00;
}
else
{
//B
WriteBuffer[0] = 0x00;
WriteBuffer[1] = 0x00;
WriteBuffer[2] = 0xFF;
}

SPIBus.Write(WriteBuffer);
}

Thread.Sleep(100);

t = (t>0) ? 0 : 1;
}
}

}
}

What have I learned from this experience? Always triple-check your wiring with datasheet or other documentation, if something is not working like expected. I also decided to use AVR instead of Netduino for Ambilight project, because it costs 3x less and offers what I need, SPI to interface with lights and USB support (V-USB for AVR which I have used in a few projects).

HTPC: Windows vs Linux

When it comes to choosing operating system for HTPC you have only two options: Windows 7 or Linux distro (probably Ubuntu). This is a bigger problem than you think, because both are supposed to provide HTPC’s main ability: audio and video playback. My HTPC is 1 year old and consists of:
– i3 540 3.06GHz
– Asus P7H55M
– 4 GB RAM
– 200 GB hard drive

I tried both operating systems, firstly at the time of purchase, and secondly a few days ago and following is my experience with both setups.

Windows 7

Setup of Windows 7 took about 20 mins and I spend addional 10 minutes installing needed drivers (VGA and sound). After that I installed Chrome for web browsing, MPC-HC for watching videos from Explorer and Boxee for music/video playback (which is being used 90% of the time). So I got HTPC enabled PC in about 40 minutes which is not that bad, considering it might stay like that for a few years.

I can’t really complain about any major problems. 1080p video playback works surprisingly good (without a hitch) even on modest integrated graphics card. One minor problem I have is with 150% font scaling (kinda needed to use PC from the couch), Google Chrome and Flash. Taskbar stays visible when you use fullscreen. Only solution I found so far is to use alternative browser, IE in my case.

Pros/cons:
– cost: from 0 to 80€ (MSDNAA Pro version or Home Premium at Amazon)
+ great driver support
+ Flash for YouTube, Vimeo, Grooveshark and other sites

Ubuntu 11.04/12.04

It. just. works sucks. Plain and simple.
I like Linux and think it’s quite great, however, I still use Windows 7 as my main OS. I never trusted Linux much with video playback and driver support, but I didn’t want to give up at the beginning. So I downloaded Ubuntu and installed it. Installation was faster than on Windows and I didn’t even need any additional drivers considering that Intel keeps great relations with open source community.
After initial installation I added XBMC which at the time (1 year ago) meant adding their repository from terminal and using apt-get to install it. Everything went good, until I found out that Intel hardware accelerated video decoding wasn’t available in any useful way at the time. And not only that, software decoding wasn’t good enough for 1080p (you can’t blame the hardware, because it works on Windows).
What could I do? After some googling I found cheap graphics card that supports hardware decoding under Linux, which added 50€ to the cost of my build. Sadly, I found out, that it doesn’t work smoothly with every video, and that was the point when I gave up with Linux for this build. Don’t want to even start mentioning other things, such as constant crashing of Boxee client (yeah, I know Boxee box runs Linux) and completely useless sleep/hibernate function.

Pros/cons:
+ cost
– drivers
– software

Conclusion: Windows wins
After spending 50€ for something that I don’t even need, I got worse performance with hardware video decoding on Linux than with software decoding on Windows. And the price for this graphics card was just short of 20€ for Windows Home Premium. Don’t want to even mention, that I threw it out when I found out it’s the main noise (and probably heat) generator in my build.

C++ libraries on Windows are nightmare

How would you get C# library to work? Simple, copy .dll to VS solution.
How would you get C++ library to work on Linux? apt-get install libmysql-c++ (or equivalent for distro of your choice)
How would you get C++ library to work on Linux if previous statement fails? ./configure && make && make install

How would you get C++ library to work on Windows with Visual Studio? Wau, right now I’m not sure if that is even possible.

So why would I even try do something so impossible? Lately I have been wanting to dive into game programming and after going through some Ogre3D tutorials this morning, I want to learn how MMORPG are made (without first M, for now :-)). And how can you make MMORPG server without some way to save data? Short answer? You can’t.

My first thought was to use some kind of NoSQL database like MongoDB which I previously used on some Python/PHP projects. First thing I did was to Google “MongoDB C++” and I happily found out, that there is a full featured C++ connector. Sadly, there is a catch. Because libraries don’t mix well between compilers, there is no prebuild library I can simply use with Visual Studio.
I guess the only way is to manually compile it from the source code. Of course, this doesn’t seem so simple as it would be on Windows and after an hour I gave up thinking, that there must be a database with prebuild library.

My next thought was Drizzle, especially because I heard it has asynchronous C++ bindings. Sadly, there is no precompiled and ready to use server for Windows, much less would there be any such bindings.

MySQL C++ Connector
And I’m back where I started, to my dear old friend MySQL. No big suprise here, I actually found precompiled library that should work with VS. However, that doesn’t mean it would work. After some Googling I got it to the point where my program compiles, but it fails to connection with some unknown problem (and I mean it, error message was “Unknown exception”).

Yay I thought, don’t have much choice but to compile it from the source. This was more like a breeze compared to MongoDB, although I spend a few minutes on one particular error:

I entirely gave up on trying to set custom MySQL directory for CMake. No matter what I changed, cmake failed to find MySQL include directory. Mind you, that was necessary only because I have x64 version of MySQL installed and need 32-bit library because I don’t want to deal with another series of problems. Although I have a feeling that cmake wouldn’t be able to find MySQL installed in C:\Program Files considering that environmental variable ProgramFiles points to C:\Program Files (x86).

The last resort was to copy 32-bit MySQL files to folder where they would reside should I installed MySQL Server with 32-bit installer.

Steps to compile C++ Connector with VS2010:
– download MySQL C++ Connector source code to anywhere you want
– download MySQL 32-bit Server if you don’t have it already and copy files to C:\Program Files (x86)\MySQL\MySQL Server 5.5
– download and install CMake
– move to directory where you unzipped connector and execute: cmake -G “Visual Studio 10”
– open ALL_BUILD project with VS2010
– compile everything

Or you can just download precompiled connector: mysql-connector-c++ (32-bit MySQL C++ connector 1.1.0 for MySQL Server 5.5)
Archive contains static and dynamic connector, compiled as both, Debug and Release version.

DS28EA00 and Arduino

Recently I found two sample Maxim DS28EA00 temperature sensors that I requested for a project I haven’t finished. I’m currently working on a project requiring somewhat accurate temperature measuring and I will finally be able to use this sensor.

Firstly I needed a way to connect this sensor to Arduino and I made simple breakout board that allows to connect MSOP8 package sensor to breadboard. I wanted to expose three pins: ground, IO and Vcc. Unfortunately I didn’t remember that SMD parts aren’t through holes and therefore they need to be mirrored. Because of this mistake (that I noticed after etching) 3rd outer pin is connected to NC pin on chip and not on the Vcc. Thankfully, 1-wire protocols allows for parasite mode which means that voltage can be sourced from data line, so my breakout board is still useful.

Hardware

To connect this sensor to Arduino you need to:

  • connect sensor GND to Arduino GND,
  • connect sensor IO to one of the digital pins (pin 10 in my case),
  • connect 4.7k ohm resistor from IO line at Arduino to 5V.

In my case it works fine with 2.7k ohm resistor, but 4.7k is recommended. This pull-up resistor allows the use of parasite mode by providing 5V to IO pins of devices.

 

Software

I haven’t found any examples of connecting this sensor to Arduino, so I had to read datasheet and understand what I need to send and what I get back from the sensor. After I finished my code, I found out that the communication is the same as for DS18*20 sensors which is very popular and you can find many examples. I actually started with example for that sensor and removed sensor specific code.

Anyway, here is the code:

#include <OneWire.h>
OneWire ds(10);

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

void loop(void) {
  byte i;
  byte present = 0;
  byte data[12];
  byte addr[8];

  if ( !ds.search(addr)) {
     Serial.print("No more addresses.\n");
     delay(1000000);
     ds.reset_search();
      return;
  }

  Serial.print("R=");
  for( i = 0; i < 8; i++) {
    Serial.print(addr[i], HEX);
    Serial.print(" ");
  }

  if ( OneWire::crc8( addr, 7) != addr[7]) {
      Serial.print("CRC is not valid!\n");
      return;
  }

  if ( addr[0] == 0x42) {
      Serial.print("DS28EA00 detected\n");
  }else{
    return;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44,1); //convert temperature, parasite mode

  delay(1000); //wait at least 750ms for the conversion to finish

  present = ds.reset();
  ds.select(addr);
  ds.write(0xBE); //read scratchpad

  Serial.print("P=");
  Serial.print(present,HEX);
  Serial.print(" ");
  for ( i = 0; i < 9; i++) {
    data[i] = ds.read();
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" CRC=");
  Serial.print( OneWire::crc8( data, 8), HEX);
  Serial.println();

  byte lsb = data[0];
  byte msb = data[1];
  int16_t temp = (((int16_t)msb) << 8 ) | lsb;
  Serial.println((float)temp * 0.0625, DEC);//0.0625 for 12bit
}

One thing missing with examples for DS18*20 sensors was the explanation of the code. I really like to understand what I’m using and I like to discover how things works.

ds.search searches for OneWire devices on that Arduino pin and continues with the code if it finds one.

if ( OneWire::crc8( addr, 7) != addr[7]) {
      Serial.print("CRC is not valid!\n");
      return;
  }

crc8(byte array, count) calculates CRC code of first 7 bytes and compares it to precalculated CRC code in 8th item of array. If it matches, it means that we received right data, otherwise there is obviously problem with data transfer.

 if ( addr[0] == 0x42) {
      Serial.print("DS28EA00 detected\n");
  }else{
    return;
  }

This checks if first byte matches 0x42, because address of DS28EA00 family of temperature sensors starts with this byte. Otherwise we just return and the loop starts again.

ds.reset();
 ds.select(addr);
 ds.write(0x44,1); //convert temperature, parasite mode

 delay(1000); //wait at least 750ms for the conversion to finish

According to datasheet we need to send reset, select our device and then send the code for starting the conversion (in this case it’s 0x44). Second parameter in write call is used to tell OneWire library that we use it in parasite mode and that the IC needs to source 5V from IO pin.

Datasheet specifies that the conversion will took at most 750ms. We don’t want to push the limits and we will survive to wait additional 250ms.

present = ds.reset();
 ds.select(addr);
 ds.write(0xBE); //read scratchpad


Again, we reset OneWire, select the device and write code for reading the scratchpad (0xBE).

for ( i = 0; i < 9; i++) {
    data[i] = ds.read();
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }

We read first 9 bytes from the device and print it to serial port.

First and second bytes are temperature, third and fourth are for high and low temperature alarm, fifth is for setting precision, and others are reserved.

Ninth byte is CRC of first 8 bytes and we match it to see if there were any transmission errors.

byte lsb = data[0];
 byte msb = data[1];

We save LSB in MSB bytes so sepeperate variables.

int16_t temp = (((int16_t)msb) << 8 ) | lsb;

Temperature is 16-bit number divided to least and most significat byte.

Serial.println((float)temp * 0.0625, DEC);//0.0625 for 12bit

We need to multimly calculated 16-bit integer with 0.0625 (in case of 12bit resolution) and convert it to float. Then we print it to serial port.

Output on serial port:

R=42 F0 25 5 0 0 0 64 DS28EA00 detected
P=1 5D 1 3 3 7F FF 3 10 63 CRC=63
21.8125000000

How to display certain page content only to users who have liked our page on Facebook?

Sometimes it would be convenient if we could display portion of our web page only to people who have liked our page on Facebook.

For example, we decide to giveaway five concert tickets to random participants. We can get more recognizable if participants have to liked our page and possible publish that on their profile page. So let’s create example web page that where people can participate after following this procedure:

1. person connects our web site with Facebook

2. person likes our Facebook page

3. person fill out form with his information to participate in giveaway

 

Firstly we need to create Facebook page for our web site and get URL like this:

https://www.facebook.com/pages/Lemnin/145152362222716

Secondly, we need Facebook application which can be created in a few minutes on Facebook. We will get application id and secret key to use Facebook API.

Our giveaway page will look like this (step 1):

After clicking on Login with Facebook button, we get a nice popup saying what information will this application be able to access:

After user successfully connects our web site (application) with his Facebook profile, we show step 2:

In this step, user has to like our Facebook page, and after that we show him step 3 – final giveaway form:

We automatically fill out name field with information we get through Facebook API. Mind you, step 3 loads via AJAX, because requests to Facebook servers can sometimes be slow and we want to load our page as quickly as possible.

 

How will we do it?

We will use Facebook’s javascript API which allows us to connect our website with user’s Facebook account and allow them to like our page. As far as i know, we don’t even need server-side scripting to check Facebook Like status, however, user’s can bypass JS-only solution and therefore we will be using client-side javascript in connection with server-side PHP.

 

1. How to connect to Facebook API with PHP?

Connecting to Facebook API is pretty simple and everything you need is to create new instance of Facebook class and pass it array with your appId and secret key.

<?php
include (“facebook.php”);
$facebook = new Facebook(array(  ‘appId’  => ‘172133412841299’,
‘secret’ => ‘<secret key>’,
‘cookie’ => true,));

 

2. Is user logged in?

Facebook JS API creates session cookie when user logged in to Facebook comes to our page, so that we can get user’s information with PHP.

<?php
$session = $facebook->getSession();
$fbme = null;
if ($session) {
try {
$uid = $facebook->getUser();
$fbme = $facebook->api(‘/me’);
} catch (FacebookApiException $e) {                }
}
?>

This code gets FB’s session, checks if user allowed us access to his information and fills variable $fbme with his data (username, first_name, last_name, etc.)

 

3. Has user liked our Facebook page?

<?php
$created_time = $facebook->api(
array( ‘method’ => ‘fql.query’,
‘query’ => ‘SELECT created_time FROM page_fan WHERE uid= ‘.intval($uid).’ AND page_id = 145152362222716′ )
);
?>

This uses FQL to check if user liked our page and returns date and time of when that happend. If user hasn’t liked our page, $created_time is empty.

 

With a bit of javascript magic and PHP we can create web page, that checks if user liked our page and if he is logged in.

Here is the download link: download

Weather map

Weather map for Slovenia and Europe.

  • – written in PHP
  • – uses Google Maps API
  • – weather data gathered from website of Environmental Agency of the Republic of Slovenia
  • – supports caching of data in xml files

Download:

weather.zip

Previous Posts Next posts