I think about making a robot who can give living suggestion to her Master. The Robot can tell the temperature, humidity, time and alarm, etc. This is just an initial version. I will give this Robot more function such as, sound recognizing, speaker, games. Thus the Arduino UNO R3 may not enough to this project. If someone have interesting idea, please give commends. Let us try to build up this robot. Let me introduce this project:
1. LCD custom display -- Face with eye blink
The 20x4 LCD allows user to create custom characters. This is good for me to build a face. This LCD includes 80 characters in the screen. Each character includes 8 rows and 5 columns, which totally has 40 pixels. Each row of the character has a corresponding code (number). To build a custom character, I need build an 8 byes custom type variable. For example, to create the robot eye character on the image above. The code is:
uint8_t eye_left[8] = {0xe,0x11,0x17,0x17,0x17,0x17,0x11,0xe};
According to my experiment, the row code of the LCD character has a regulation. I display the table below to show the row display and corresponding number:
According to table above, the eye display code is explained below:
Once the custom code is created, it can be used in the Arduino setup() or loop(). In the setup(), for in stance, the program code is:
// .... the LCD library and address setup is not here ...
//variable code for custom eye character
uint8_t eye_left[8] = {0xe,0x11,0x17,0x17,0x17,0x17,0x11,0xe};
void setup() {
lcd.begin(20,4);
lcd.createChar(2, eye_left);//use number '2' to mark this char
lcd.setCursor(1,1);// display position
lcd.write(2);// display the custom char
lcd.setCursor(3,1);
lcd.write(2);
}
I will not give the LCD library and address setup in the code above. Here is the test code for display the face and blink eye:
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
uint8_t empty[8] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1};
uint8_t eyebrow_happy[8] = {0x0,0x0,0x0,0xe,0x11,0x0,0x0,0x0};
uint8_t eyebrow_angry_right[8] = {0x0,0x0,0x0,0x10,0x8,0x4,0x2,0x1};
uint8_t eyebrow_close[8] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1f};
uint8_t eyebrow_angry_left[8] = {0x0,0x0,0x0,0x1,0x2,0x4,0x8,0x10};
uint8_t eye_left[8] = {0xe,0x11,0x17,0x17,0x17,0x17,0x11,0xe};
uint8_t eye_right[8] = {0xe,0x11,0x1d,0x1d,0x1d,0x1d,0x11,0xe};
uint8_t eye_front[8] = {0xe,0x11,0x15,0x15,0x15,0x15,0x11,0xe};
uint8_t eye_close[8] = {0x0,0x0,0x0,0x11,0x1f,0x0,0x0,0x0};
uint8_t mouth_happy[8] = {0x4,0xe,0xe,0x0,0x0,0x11,0xe};
uint8_t mouth_sad[8] = {0x4,0xe,0xe,0x0,0x0,0xe,0x11};
LiquidCrystal_I2C lcd(0x3f, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
void setup() {
lcd.begin(20,4);
//lcd.init();
lcd.createChar(0, empty);
lcd.createChar(1, mouth_sad);
lcd.createChar(2, eyebrow_angry_right);
lcd.createChar(3, eyebrow_angry_left);
lcd.createChar(4, eye_left);
lcd.createChar(5, eye_right);
lcd.createChar(6, eye_front);
lcd.createChar(7, eye_close);
lcd.createChar(8, mouth_happy);
lcd.createChar(9, eyebrow_happy);
lcd.createChar(10, eyebrow_close);
lcd.home();
// eyebrow
lcd.setCursor(1,0);
lcd.write(1);
lcd.setCursor(3,0);
lcd.write(1);
// eyes
lcd.setCursor(1,1);
lcd.write(4);
lcd.setCursor(3,1);
lcd.write(4);
// mouth
lcd.setCursor(2,2);
lcd.write(8);
// words
lcd.setCursor(9,1);
lcd.print("Hello!!");
lcd.setCursor(8,2);
lcd.print("I am Lily!");
delay(1000);
}
//string str[20];
void loop() {
// blink eyes
delay(4000);
// eyebrow
lcd.setCursor(1,0);
lcd.write(10);
lcd.setCursor(3,0);
lcd.write(10);
// eyes
lcd.setCursor(1,1);
lcd.write(7);
lcd.setCursor(3,1);
lcd.write(7);
// mouth
lcd.setCursor(2,2);
lcd.write(8);
delay(250);
// eyebrow
lcd.setCursor(1,0);
lcd.write(1);
lcd.setCursor(3,0);
lcd.write(1);
// eyes
lcd.setCursor(1,1);
lcd.write(4);
lcd.setCursor(3,1);
lcd.write(4);
// mouth
lcd.setCursor(2,2);
lcd.write(8);
}
My LCD is I2C Model. If Sb what to try this code, please setup your LCD following your menu. I give a link of LCD setup below:
https://arduino-info.wikispaces.com/LCD-Blue-I2C#v1
2. Clock display and time/alarm setup
I do not have external timer (RTC) for my Arduino UNO, but I make clock myself and use EEPROM to store current time for Arduino reset. The timer/clock project is in the link below:
This is my project of DIY clock with Arduino. It also introduce the IR remote setup, buzzer running and EEPROM library.
3. The humidity and temperature mode
I use DHT11 humidity and temperature model to get humidity and temperature for this project. In the program, I use library "DHT.h" to apply the mode. I also use Simon Monk's "timer.h" library to get Humi and Temp every 3 second. (In addition eye's blink in the project is also use this library.)
4. Joy stick to control the face eye
The Joy sticker is easy to use with Arduino. I create a program to see the x, y value when I play the joy sticker. In the code below, I use my LCD to display the x, y value:
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3f, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
// Arduino pin numbers
const int SW_pin = 7; // digital pin connected to switch output
const int X_pin = A0; // analog pin connected to X output
const int Y_pin = A1; // analog pin connected to Y output
void setup() {
pinMode(SW_pin, INPUT);
digitalWrite(SW_pin, HIGH);
lcd.begin(20,4);
lcd.clear();
}
void loop() {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("swtich: ");
lcd.print(digitalRead(SW_pin));
lcd.setCursor(0,1);
lcd.print("X-axis: ");
lcd.print(analogRead(X_pin));
lcd.setCursor(0,2);
lcd.print("Y-axis: ");
lcd.print(analogRead(Y_pin));
delay(500);
}
The principle of joy sticker is in this link:
https://www.brainy-bits.com/arduino-joystick-tutorial/
Video of my Project
5. Problems and future work
This project link many models together, and uses may libraries. Fortunately, there is no conflict, but it still has some problems. Maybe, sb can give me suggestion.
First, I can only create 8 custom characters at beginning, more than 8 will be have trouble. for example, with the code below.
lcd.createChar(0, empty);
lcd.createChar(1, mouth_sad);
lcd.createChar(2, eyebrow_angry_right);
lcd.createChar(3, eyebrow_angry_left);
lcd.createChar(4, eye_left);
lcd.createChar(5, eye_right);
lcd.createChar(6, eye_front);
lcd.createChar(7, eye_close);
lcd.createChar(8, mouth_happy);
lcd.createChar(9, eyebrow_happy);
lcd.createChar(10, eyebrow_close);
The character '0' will be replaced by character '8', '1' will be replaced by '9' and '2' will be replaced by '10'. To solve this problem, I just build character every time before display character. If I change eye character to display looking at up or down I will do:
lcd.createChar(2, eye_up);// create look up
lcd.setCursor(1,1);
lcd.write(2);
lcd.setCursor(3,1);
lcd.write(2);
delay(1000);// delay 1s
lcd.createChar(2, eye_down);//create look down
lcd.setCursor(1,1);
lcd.write(2);
lcd.setCursor(3,1);
lcd.write(2);
I do not know why I can not build more characters together. Maybe, the LCD memory is not enough. Can anybody tell me?
Second, I use Simon's "timer.h" to display eye blink. However, this library just display close eyes with a toggle, I give 250ms delay time to show the close eye clearly, but the delay block the whole code running. You can see the second increase has little bit time problem when the face blinks eyes.
I think about use normal timer (like "millis()") to control this without delay, but it complex. I do not know the value of millis() can be overflow or not.
Third, the IR remote is not sensitive. You can see this from the video. Maybe, my code delay is too long to get the button push, but I found sometimes the IR receiver can get wrong button address. Why the TV and Projectors remote works very well? Anyone Know more about this?
Comments