Part3:DIGITAL LPG METER PROJECT: Measuring and caculating
-which wires do we use on the LPG Switch?
-what values do we measure on those wires (empty and full tank)
The Arduino can be used for all kinds of projects. It's perfect for in car use because of its wide power input range. The car (or other vehicle) has 12volts. The arduino can be used on this voltage without any customization. It's an ideal platform for you project.
Part2:DIGITAL LPG METER PROJECT: Connecting and identifying the LCD
LCD Model: LCD-AC-0802E-MIA A/K-E6 C
Bought it on Ebay from Artronic for less than 6 Euro, shipping included.
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
If you like you can change the pin connections to keep the PWM channels free.
Change the physical wire and make sure you change this pin number in the code.
sources http://pa6.nl/
http://www.dancefusion.nl/
https://sites.google.com/view/nl-marketing/
http://likes-kopen.simplesite.com/
Bought it on Ebay from Artronic for less than 6 Euro, shipping included.
PIN | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | A | K |
CONNECTION | VSS | VDD | VO | RS | R/W | E | DB0 | DB1 | DB2 | DB3 | DB4 | DB5 | DB6 | DB7 | LED+ | LED- |
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
If you like you can change the pin connections to keep the PWM channels free.
Change the physical wire and make sure you change this pin number in the code.
sources http://pa6.nl/
http://www.dancefusion.nl/
https://sites.google.com/view/nl-marketing/
http://likes-kopen.simplesite.com/
Part1:Introduction:Digital LPG Fuel Meter with radius of action counter in KM
Introduction
My car has a bi-fuel system. This means I can drive on regular Euro95 Benzine and LPG gas.
To toggle between these different fuel types there is a switchbox.
This (Necam) switchbox has 4 leds to indicate the fuel level of the LPG.
Because of the poor indication I would like to get a better view how much is left in the fuel tank and how far I can drive with it.
To get a better view I would like to present this information on a LCD.
The 4 leds or the signal which controls these leds are gonna be used for a 0-100% scale.
I use a math formula to calculate the distance how far I can drive based on the scale and the total radius of action.
Because this LCD must be small and I don't have many characters to display I choose for a 2x8 LCD. This LCD is based on the HD44780 controller and has 2 lines with 8 characters each.
I want to use the Arduino/Atmega328 to calculate the output of the switchbox and drive the LCD.
With the little test code you can see how it looks (animation) on the LCD.
// include the library
#include <LiquidCrystal.h>
int i;
unsigned int KM = 4.2; //How much KM I can you drive on a full tank divided by 100
// initialize the interface pins
LiquidCrystal lcd(4,5,6,7,8,9 ); // digital pins which are used by the LCD
void setup()
{
// sets the LCD's rows and colums:
lcd.begin(16, 2);lcd.clear();delay(500);
}
void loop(){
//{lcd.setCursor(0,0);lcd.print("LPG CHK");delay(2000);lcd.clear();delay(1000);
for (int i=100 ; i>=1 ; i--) {lcd.setCursor(0,0);lcd.print("LPG ");lcd.print(i);lcd.print("% ");
lcd.setCursor(0,1); lcd.print("+/-");lcd.print(i*KM); lcd.print("KM");delay(1300);
}
}
The video below gives you an example of the above script. This is just a test with a different LCD.
My car has a bi-fuel system. This means I can drive on regular Euro95 Benzine and LPG gas.
To toggle between these different fuel types there is a switchbox.
This (Necam) switchbox has 4 leds to indicate the fuel level of the LPG.
Because of the poor indication I would like to get a better view how much is left in the fuel tank and how far I can drive with it.
To get a better view I would like to present this information on a LCD.
The 4 leds or the signal which controls these leds are gonna be used for a 0-100% scale.
I use a math formula to calculate the distance how far I can drive based on the scale and the total radius of action.
Because this LCD must be small and I don't have many characters to display I choose for a 2x8 LCD. This LCD is based on the HD44780 controller and has 2 lines with 8 characters each.
With the little test code you can see how it looks (animation) on the LCD.
// include the library
#include <LiquidCrystal.h>
int i;
unsigned int KM = 4.2; //How much KM I can you drive on a full tank divided by 100
// initialize the interface pins
LiquidCrystal lcd(4,5,6,7,8,9 ); // digital pins which are used by the LCD
void setup()
{
// sets the LCD's rows and colums:
lcd.begin(16, 2);lcd.clear();delay(500);
}
void loop(){
//{lcd.setCursor(0,0);lcd.print("LPG CHK");delay(2000);lcd.clear();delay(1000);
for (int i=100 ; i>=1 ; i--) {lcd.setCursor(0,0);lcd.print("LPG ");lcd.print(i);lcd.print("% ");
lcd.setCursor(0,1); lcd.print("+/-");lcd.print(i*KM); lcd.print("KM");delay(1300);
}
}
The video below gives you an example of the above script. This is just a test with a different LCD.
Nokia 3310 LCD
The Nokia 3310 LCD assy on your Arduino:
Nokia 3310 LCD is low-cost, monochrome LCD with 84x48 display. It is popular for 8-bit AVR/PIC projects.
I bought mine on nuelectronics.com
The joystick uses 1 analog port with 5 resistors.
You can program your own logo if you like and store it in the char.
Keywords:
LCD_3310_init
LCD_3310_write_byte
LCD_3310_draw_bmp_pixel
LCD_3310_write_string
LCD_3310_write_string_big
LCD_3310_write_char_big
LCD_3310_write_char
LCD_3310_set_XY
LCD_3310_clear
The code from the movie is below:
#include "nokia_3310_lcd.h"
#include "avr_bmp.h"
//keypad debounce parameter
#define DEBOUNCE_MAX 15
#define DEBOUNCE_ON 10
#define DEBOUNCE_OFF 3
#define NUM_KEYS 5
#define NUM_MENU_ITEM 4
// joystick number
#define UP_KEY 3
#define LEFT_KEY 0
#define CENTER_KEY 1
#define DOWN_KEY 2
#define RIGHT_KEY 4
// menu starting points
#define MENU_X 10 // 0-83
#define MENU_Y 1 // 0-5
// adc preset value, represent top value,incl. noise & margin,that the adc reads, when a key is pressed
// set noise & margin = 30 (0.15V@5V)
int adc_key_val[5] ={30, 150, 360, 535, 760 };
// debounce counters
byte button_count[NUM_KEYS];
// button status - pressed/released
byte button_status[NUM_KEYS];
// button on flags for user program
byte button_flag[NUM_KEYS];
// menu definition
char menu_items[NUM_MENU_ITEM][12]={
"TEMPERATURE",
"CHAR MAP",
"BITMAP",
"ABOUT"
};
void (*menu_funcs[NUM_MENU_ITEM])(void) = {
temperature,
charmap,
bitmap,
about
};
char current_menu_item;
Nokia_3310_lcd lcd=Nokia_3310_lcd();
void setup()
{
// setup interrupt-driven keypad arrays
// reset button arrays
for(byte i=0; i<NUM_KEYS; i++){
button_count[i]=0;
button_status[i]=0;
button_flag[i]=0;
}
// Setup timer2 -- Prescaler/256
TCCR2A &= ~((1<<WGM21) | (1<<WGM20));
TCCR2B &= ~(1<<WGM22);
TCCR2B = (1<<CS22)|(1<<CS21);
ASSR |=(0<<AS2);
// Use normal mode
TCCR2A =0;
//Timer2 Overflow Interrupt Enable
TIMSK2 |= (0<<OCIE2A);
TCNT2=0x6; // counting starts from 6;
TIMSK2 = (1<<TOIE2);
SREG|=1<<SREG_I;
lcd.LCD_3310_init();
lcd.LCD_3310_clear();
//menu initialization
init_MENU();
current_menu_item = 0;
}
/* loop */
void loop()
{
byte i;
for(i=0; i<NUM_KEYS; i++){
if(button_flag[i] !=0){
button_flag[i]=0; // reset button flag
switch(i){
case UP_KEY:
// current item to normal display
lcd.LCD_3310_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_NORMAL );
current_menu_item -=1;
if(current_menu_item <0) current_menu_item = NUM_MENU_ITEM -1;
// next item to highlight display
lcd.LCD_3310_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_HIGHLIGHT );
break;
case DOWN_KEY:
// current item to normal display
lcd.LCD_3310_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_NORMAL );
current_menu_item +=1;
if(current_menu_item >(NUM_MENU_ITEM-1)) current_menu_item = 0;
// next item to highlight display
lcd.LCD_3310_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_HIGHLIGHT );
break;
case LEFT_KEY:
init_MENU();
current_menu_item = 0;
break;
case RIGHT_KEY:
lcd.LCD_3310_clear();
(*menu_funcs[current_menu_item])();
lcd.LCD_3310_clear();
init_MENU();
current_menu_item = 0;
break;
}
}
}
}
/* menu functions */
void init_MENU(void){
byte i;
lcd.LCD_3310_clear();
lcd.LCD_3310_write_string(MENU_X, MENU_Y, menu_items[0], MENU_HIGHLIGHT );
for (i=1; i<NUM_MENU_ITEM; i++){
lcd.LCD_3310_write_string(MENU_X, MENU_Y+i, menu_items[i], MENU_NORMAL);
}
}
// waiting for center key press
void waitfor_OKkey(){
byte i;
byte key = 0xFF;
while (key!= CENTER_KEY){
for(i=0; i<NUM_KEYS; i++){
if(button_flag[i] !=0){
button_flag[i]=0; // reset button flag
if(i== CENTER_KEY) key=CENTER_KEY;
}
}
}
}
void temperature()
{
lcd.LCD_3310_write_string_big(10, 1, "+12.30", MENU_NORMAL);
lcd.LCD_3310_write_string(78, 2, "C", MENU_NORMAL);
lcd.LCD_3310_write_string(38, 5, "OK", MENU_HIGHLIGHT );
waitfor_OKkey();
}
void charmap(){
char i,j;
for(i=0; i<5; i++){
for(j=0; j<14; j++){
lcd.LCD_3310_set_XY(j*6,i);
lcd.LCD_3310_write_char(i*14+j+32, MENU_NORMAL);
}
}
lcd.LCD_3310_write_string(38, 5, "OK", MENU_HIGHLIGHT );
waitfor_OKkey();
}
void bitmap(){
lcd.LCD_3310_draw_bmp_pixel(20,1, AVR_bmp, 48,24);
lcd.LCD_3310_write_string(38, 5, "OK", MENU_HIGHLIGHT );
waitfor_OKkey();
}
void about(){
lcd.LCD_3310_write_string( 0, 1, "Nokia 3310 LCD", MENU_NORMAL);
lcd.LCD_3310_write_string( 0, 3, "nuelectronics", MENU_NORMAL);
lcd.LCD_3310_write_string(38, 5, "OK", MENU_HIGHLIGHT );
waitfor_OKkey();
}
// The followinging are interrupt-driven keypad reading functions
// which includes DEBOUNCE ON/OFF mechanism, and continuous pressing detection
// Convert ADC value to key number
char get_key(unsigned int input)
{
char k;
for (k = 0; k < NUM_KEYS; k++)
{
if (input < adc_key_val[k])
{
return k;
}
}
if (k >= NUM_KEYS)
k = -1; // No valid key pressed
return k;
}
void update_adc_key(){
int adc_key_in;
char key_in;
byte i;
adc_key_in = analogRead(0);
key_in = get_key(adc_key_in);
for(i=0; i<NUM_KEYS; i++)
{
if(key_in==i) //one key is pressed
{
if(button_count[i]<DEBOUNCE_MAX)
{
button_count[i]++;
if(button_count[i]>DEBOUNCE_ON)
{
if(button_status[i] == 0)
{
button_flag[i] = 1;
button_status[i] = 1; //button debounced to 'pressed' status
}
}
}
}
else // no button pressed
{
if (button_count[i] >0)
{
button_flag[i] = 0;
button_count[i]--;
if(button_count[i]<DEBOUNCE_OFF){
button_status[i]=0; //button debounced to 'released' status
}
}
}
}
}
// Timer2 interrupt routine -
// 1/(160000000/256/(256-6)) = 4ms interval
ISR(TIMER2_OVF_vect) {
TCNT2 = 6;
update_adc_key();
}
Nokia 3310 LCD is low-cost, monochrome LCD with 84x48 display. It is popular for 8-bit AVR/PIC projects.
I bought mine on nuelectronics.com
The joystick uses 1 analog port with 5 resistors.
You can program your own logo if you like and store it in the char.
Keywords:
LCD_3310_init
LCD_3310_write_byte
LCD_3310_draw_bmp_pixel
LCD_3310_write_string
LCD_3310_write_string_big
LCD_3310_write_char_big
LCD_3310_write_char
LCD_3310_set_XY
LCD_3310_clear
You can use the tool LCD Assistant to convert your own logo's into binairy code.
Here you can download the zip file:
The code from the movie is below:
#include "nokia_3310_lcd.h"
#include "avr_bmp.h"
//keypad debounce parameter
#define DEBOUNCE_MAX 15
#define DEBOUNCE_ON 10
#define DEBOUNCE_OFF 3
#define NUM_KEYS 5
#define NUM_MENU_ITEM 4
// joystick number
#define UP_KEY 3
#define LEFT_KEY 0
#define CENTER_KEY 1
#define DOWN_KEY 2
#define RIGHT_KEY 4
// menu starting points
#define MENU_X 10 // 0-83
#define MENU_Y 1 // 0-5
// adc preset value, represent top value,incl. noise & margin,that the adc reads, when a key is pressed
// set noise & margin = 30 (0.15V@5V)
int adc_key_val[5] ={30, 150, 360, 535, 760 };
// debounce counters
byte button_count[NUM_KEYS];
// button status - pressed/released
byte button_status[NUM_KEYS];
// button on flags for user program
byte button_flag[NUM_KEYS];
// menu definition
char menu_items[NUM_MENU_ITEM][12]={
"TEMPERATURE",
"CHAR MAP",
"BITMAP",
"ABOUT"
};
void (*menu_funcs[NUM_MENU_ITEM])(void) = {
temperature,
charmap,
bitmap,
about
};
char current_menu_item;
Nokia_3310_lcd lcd=Nokia_3310_lcd();
void setup()
{
// setup interrupt-driven keypad arrays
// reset button arrays
for(byte i=0; i<NUM_KEYS; i++){
button_count[i]=0;
button_status[i]=0;
button_flag[i]=0;
}
// Setup timer2 -- Prescaler/256
TCCR2A &= ~((1<<WGM21) | (1<<WGM20));
TCCR2B &= ~(1<<WGM22);
TCCR2B = (1<<CS22)|(1<<CS21);
ASSR |=(0<<AS2);
// Use normal mode
TCCR2A =0;
//Timer2 Overflow Interrupt Enable
TIMSK2 |= (0<<OCIE2A);
TCNT2=0x6; // counting starts from 6;
TIMSK2 = (1<<TOIE2);
SREG|=1<<SREG_I;
lcd.LCD_3310_init();
lcd.LCD_3310_clear();
//menu initialization
init_MENU();
current_menu_item = 0;
}
/* loop */
void loop()
{
byte i;
for(i=0; i<NUM_KEYS; i++){
if(button_flag[i] !=0){
button_flag[i]=0; // reset button flag
switch(i){
case UP_KEY:
// current item to normal display
lcd.LCD_3310_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_NORMAL );
current_menu_item -=1;
if(current_menu_item <0) current_menu_item = NUM_MENU_ITEM -1;
// next item to highlight display
lcd.LCD_3310_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_HIGHLIGHT );
break;
case DOWN_KEY:
// current item to normal display
lcd.LCD_3310_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_NORMAL );
current_menu_item +=1;
if(current_menu_item >(NUM_MENU_ITEM-1)) current_menu_item = 0;
// next item to highlight display
lcd.LCD_3310_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_HIGHLIGHT );
break;
case LEFT_KEY:
init_MENU();
current_menu_item = 0;
break;
case RIGHT_KEY:
lcd.LCD_3310_clear();
(*menu_funcs[current_menu_item])();
lcd.LCD_3310_clear();
init_MENU();
current_menu_item = 0;
break;
}
}
}
}
/* menu functions */
void init_MENU(void){
byte i;
lcd.LCD_3310_clear();
lcd.LCD_3310_write_string(MENU_X, MENU_Y, menu_items[0], MENU_HIGHLIGHT );
for (i=1; i<NUM_MENU_ITEM; i++){
lcd.LCD_3310_write_string(MENU_X, MENU_Y+i, menu_items[i], MENU_NORMAL);
}
}
// waiting for center key press
void waitfor_OKkey(){
byte i;
byte key = 0xFF;
while (key!= CENTER_KEY){
for(i=0; i<NUM_KEYS; i++){
if(button_flag[i] !=0){
button_flag[i]=0; // reset button flag
if(i== CENTER_KEY) key=CENTER_KEY;
}
}
}
}
void temperature()
{
lcd.LCD_3310_write_string_big(10, 1, "+12.30", MENU_NORMAL);
lcd.LCD_3310_write_string(78, 2, "C", MENU_NORMAL);
lcd.LCD_3310_write_string(38, 5, "OK", MENU_HIGHLIGHT );
waitfor_OKkey();
}
void charmap(){
char i,j;
for(i=0; i<5; i++){
for(j=0; j<14; j++){
lcd.LCD_3310_set_XY(j*6,i);
lcd.LCD_3310_write_char(i*14+j+32, MENU_NORMAL);
}
}
lcd.LCD_3310_write_string(38, 5, "OK", MENU_HIGHLIGHT );
waitfor_OKkey();
}
void bitmap(){
lcd.LCD_3310_draw_bmp_pixel(20,1, AVR_bmp, 48,24);
lcd.LCD_3310_write_string(38, 5, "OK", MENU_HIGHLIGHT );
waitfor_OKkey();
}
void about(){
lcd.LCD_3310_write_string( 0, 1, "Nokia 3310 LCD", MENU_NORMAL);
lcd.LCD_3310_write_string( 0, 3, "nuelectronics", MENU_NORMAL);
lcd.LCD_3310_write_string(38, 5, "OK", MENU_HIGHLIGHT );
waitfor_OKkey();
}
// The followinging are interrupt-driven keypad reading functions
// which includes DEBOUNCE ON/OFF mechanism, and continuous pressing detection
// Convert ADC value to key number
char get_key(unsigned int input)
{
char k;
for (k = 0; k < NUM_KEYS; k++)
{
if (input < adc_key_val[k])
{
return k;
}
}
if (k >= NUM_KEYS)
k = -1; // No valid key pressed
return k;
}
void update_adc_key(){
int adc_key_in;
char key_in;
byte i;
adc_key_in = analogRead(0);
key_in = get_key(adc_key_in);
for(i=0; i<NUM_KEYS; i++)
{
if(key_in==i) //one key is pressed
{
if(button_count[i]<DEBOUNCE_MAX)
{
button_count[i]++;
if(button_count[i]>DEBOUNCE_ON)
{
if(button_status[i] == 0)
{
button_flag[i] = 1;
button_status[i] = 1; //button debounced to 'pressed' status
}
}
}
}
else // no button pressed
{
if (button_count[i] >0)
{
button_flag[i] = 0;
button_count[i]--;
if(button_count[i]<DEBOUNCE_OFF){
button_status[i]=0; //button debounced to 'released' status
}
}
}
}
}
// Timer2 interrupt routine -
// 1/(160000000/256/(256-6)) = 4ms interval
ISR(TIMER2_OVF_vect) {
TCNT2 = 6;
update_adc_key();
}
Arduino introduction
The Arduino is a AVR chip with a Arduino bootloader in it. The program language is C++.
I am using the ATmega328 28pin Dil Arduino chip.The chip has 14 digital Ports which can be set as inputs and outputs and 6 analog inputs. The range for these Ports is between 0 and 5 volts. For the analog port the value is between 0 and 1023 That is equivalent for 0 and 5 volts.
different sources:
https://likeskopenfacebook.wordpress.com/
https://www.oranje-web.nl/waarom-nederlandse-facebook-likes-kopen/
Abonneren op:
Posts (Atom)