Sunday, December 9, 2012

Accelerometer+Gyro

I tried my GY-521 Accelerometer+Gyro breakout today. The board come with a MPU 6050 chip and connect to Arduino through I2C, which I barely understand. The connection is really simple.

Arduino +5V to VCC
Arduino GND to GND
Arduino analog input pin A4 to SDA
Arduino analog input pin A5 to SCL

There is I2C scanner sketch to first ensure it's correctly connected through I2C bus.
Then I found a pretty complicated code on Arduino website. Then BANG! It works.

There will be a lot of work to understand how it works......So I wrote this as a place holder and hopefully will add more when I understand it better.

Another useful stuff I have discovered today is that Arduino can talk to the computer by serial monitor. Then I guess I don't need the LCD very often now.




Ultrasound range finder

http://www.youtube.com/watch?v=ayDjmjsbGKI&feature=plcp

The ultrasonic range finder I bought has 4 pins instead of commonly found 3 pin model. There is a Trig pin, which is to "trigger" the range finder and an echo pin which gives the distance (elapsed time of the echo). According to the data sheet, if the trig pin remains high for 10 microseconds, it will send short burst of ultrasonic sound, then the echo pin becomes high until it receives the echo. By measuring the time that the echo pin remains high, we can calculate the distance. Pretty straight forward.

Code:


#include <LiquidCrystal.h>


LiquidCrystal lcd(8, 9, 4, 5, 6, 7);


int Trig=11;
int Echo=12;

void setup()
{
 pinMode(Trig,OUTPUT);
 pinMode(Echo,INPUT);
 lcd.begin(16, 2);            
 lcd.setCursor(0,0);
 lcd.print("Distance=");

}

void loop()
{
 float duration, distance;
 lcd.setCursor(0,1);

 digitalWrite(Trig,LOW);
 delayMicroseconds(10);
 digitalWrite(Trig,HIGH);
 delayMicroseconds(10);
 digitalWrite(Trig,LOW);

 duration=pulseIn(Echo,HIGH);
 distance=duration/29.0/2.0;

 lcd.print(distance);
 lcd.print("                ");
 lcd.print(distance);

 delay(100);

}


Thursday, December 6, 2012

LCD

The LCD keypad shield looks pretty cool. I like the blue LCD. It is extremely easy to mount the shield onto the arduino. The pin assignment has been taken care of in the example code. However, there is a problem. The unused pins will be totally useless as there will be no easy way to connect them. This is unacceptable. Then, I'm forced to use the old school--manually connect the pins. Luckily, the LCD board on the shield has provided separately its input pins.

Arduino's liquidcrystal library can use minimum of 6 pins to control the LCD:

LiquidCrystal(rs, enable, d4, d5, d6, d7) 

Though there are other pin designation methods, I decide to use the one require least pin numbers for obvious reasons.

Rx need to be tied to GND to enable write. However, it seems to work without grounding it.

I found a website describing the functions of the input pins on the LCD
http://www.8052.com/tutlcd

Here is an example code to print the analog input readings:


#include <LiquidCrystal.h>

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

int adc_key_in  = 0;

void setup()
{
 lcd.begin(16, 2);              // start the library this is a 2 line LCD with 16 characters in each line
 lcd.setCursor(0,0);
 lcd.print("Analog Input"); // print a simple message

}

void loop()
{
 lcd.setCursor(0,1); // move cursor to second line "1" and 9 spaces over
 adc_key_in = analogRead(0);
 lcd.print(adc_key_in);
}

There is a bug that the 4th digit of the analog value does not get refreshed. I will figure something out in the future.

The simplest way turns out to be add a lcd.print("                "); line in the loop. There are probably more decent ways like compare the value with old, if it is different then do a refresh and print the new one. Anyway, it's not very important.

***********************************************************
12/9/2012 update

Regarding the shadow problem of the LCD, it turns out to be more complicated. I discovered another 'working' method:


 lcd.print(distance);
 lcd.print("                ");
 lcd.print(distance);

print the thing you want to print twice with a empty string between them. At least it works for my ultrasonic range finder code.


Saturday, December 1, 2012

Servo

12/1/2012

Arduino provides very convenient interface to servos. Simply connect red wire to +5v, brown to GND, and yellow (signal) to pin No. 9 (there seems to be limitations on which pin can be used to control a servo). There is a Servo library provides simple functions like write(angle), which commands the servo to turn to a certain angle, or read(), which returns the servo angle. However, after a few experimenting, the read() function does not return the real time angle. It makes sense as there is no feed back from the servo to Arduino. It seems that servo did all the feedback control within itself. Though this simplifies the control, it lacks flexibility. For my purpose of use, I will really need the "in position" feedback which tells the controller whether or not the servo has turned to the commanded angle. I guess I need to figure something else.

A sample control code for Arduino modified from Sweep: ()


#include <Servo.h>

Servo myservo;  // create servo object to control a servo
                // a maximum of eight servo objects can be created

int pos = 0;    // variable to store the servo position
int led=13;

void setup()
{
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  pinMode(led,OUTPUT);
}

int first=0;

void loop(){
myservo.write(pos);
//delay(15);
if (myservo.read()==pos){
  digitalWrite(led,HIGH);
  delay(50);
  digitalWrite(led,LOW);
  delay(50);
}

if (pos>=180){pos=0;}
pos+=10;

}