EcoModder.com

EcoModder.com (https://ecomodder.com/forum/)
-   OpenGauge / MPGuino FE computer (https://ecomodder.com/forum/opengauge-mpguino-fe-computer.html)
-   -   opengauge development: gunio technical considerations (https://ecomodder.com/forum/showthread.php/opengauge-development-gunio-technical-considerations-1725.html)

dcb 04-05-2008 08:36 PM

opengauge development: gunio technical considerations
 
The stand alone opengauge (aka MPGGuino, or guino for short), has a number of issues to consider:

Display:
1. [deleted my 8 bit ramblings, suggest using the 4 bit library that is being worked on:] http://www.arduino.cc/playground/Code/LCD4BitLibrary

2. Display Size.
Displays in general, the more the better. 20x4 would be my vote (or 1024x768), but I am only starting to understand the technical limitations facing a bigger display. But it should be at least as big as the arduino so we can hide the arduino behind it.

3. Display Interface.
[deleted interface stuff, 4 bit libraries look sufficient, moved flow to organization]

Development Environment
I like the ease of the arduino ide, and how it can drop down to AVR with relative of ease. I also like that there are a lot of people using it and posting solutions to real world problem. I also like the fact that it is free, and open source (so you can look and see how millis() is implemented) and the free version is not deliberately crippled.


Persistence:
The atmega specs list the 512 byte EEPROM memoy (where we will keep the trip data that persists when the atmega is turned off) as only allowing 1000000 writes, then apparently it turns to dust. This means we do NOT want to save the persistent trips once a second!!! One logical solution would be to save them when the key is turned off, but we will need a digital pin tied to ignition power to do that.

Trip Organization:
With only 512 bytes of persistent data storage, we need to think somewhat carefully about what we save from run to run. If we have a persistent tank trip and a handful of other trips, they should each take about 20 bytes, assuming a similiar structure as below, which means about 26 persistent trips maximum, that get updated when the ignition is switched off.

//things will start rolling over @ about 1900 hours
class Trip{
unsigned long seconds;
unsigned long injHi;
unsigned long injHiOverflow;//need more precision on the injectorHI time
unsigned long injCount;
unsigned long vssCount;
}

in the one second loop()...
make a copy of the instant trip and reset it
clear lcd
if(english)
print("MPG<TAB/>MPH<TAB/>MLS<TAB/>HRS");
else
print(something besides english);
go to next lcd line
for(int trip = 0; trip < NumLines; trip ++){
trips[trip].printData();
go to next lcd line
}

in Trip.printData(){ //functions handle conversions to english/metric
printConsumption();
printVelocity();
printDistance();
printTime();
}

add setup options to hide the header row, and to keep the instant trip row always viewable.

dcb 04-06-2008 04:46 AM

[deleted my 8 bit ramblings]

re: LCD hardware.
A bigger display would be nice, but the source we have for the freeduino only has a 16x2 offering for $10. http://www.nkcelectronics.com/16x2-l...backli162.html Simplified ordering is nice too.

Ok, I bought one of those 16x2 to play with. AND an $18 20x4 from http://www.sparkfun.com/commerce/pro...roducts_id=256
(100 or more= $14.36!!)

dcb 04-06-2008 04:50 AM

simple buttons?
 
Also want to look into simple to make touch sensitive switches: http://www.bytecraft.com/Touch_Sensitive_Switch

http://www.bytecraft.com/graphics/touchsw3.gif
Code:

char touch_switch (void)  {
  pb_direction = output;
  pb.0 = 0;    // Discharge the pin   
  delay_Ms(1);          // Wait
  pb_direction = input; // Turn on the Constant current source   
  delay_Us(5);          // Wait for 5 u_seconds   
  if (pb.0 == 1) return (0);        // No touch detected   
  else return (1);        // Touch detected 
}

Ok, I'm going back to the palmpilot stuff. Just had to get all that out before I left atmega land for a while.

dcb 04-06-2008 05:01 AM

Last thing for now, thought this was kind of cool :)

the dCoreDuino
http://www.modxhost.com/dual168-pcb-fin.jpg

dcb 04-06-2008 12:03 PM

Ok, it looks like all the action is on the 4 bit arduino library. Lots of people are working on that and the library compiled out of the box for me, and apparently it is supporting multiple lines and 20x4 displays. And it uses less pins than the 8 bit one:

http://www.arduino.cc/playground/Code/LCD4BitLibrary :thumbup:

It looks like the most promising solution at this point in time, better than the 8 bit solution.

larrydag 04-08-2008 05:50 PM

Ladyada.net - Hooking up an LCD to Arduino
 
This is a howto from Ladyada.net for LCD's and *duino's. This should be helpful for us to learn the best methods.

http://www.ladyada.net/rant/2008/04/...to-an-arduino/

MetroMPG 04-08-2008 08:58 PM

So, are you still thinking the 16x2 LCD mentioned in post #2 is the one to get? If so, I'll order one too. I'm a bit out of my depth, but I can at least be beta testing along side you guys.

Also, the Guino is boring with only a blinking LED to program. :)

dcb 04-09-2008 02:13 AM

I don't know 2 or 4. Ease of ordering vs more data display area. how about keeping gunio 1.0 simple and get the 2?

it isn't much to work with though, but it's cute :)

some examples, (the *'s are buttons outside the LCD area)
Code:

  INS 045mpg  mnu* 
 *< CUR 047mpg  >*

  INS 045mpg  mnu* 
 *< TNK 045mpg  >*

  INS 045mpg  mnu* 
 *< INS 2200rpm  >*

not married to it, just putting it out there as a starting point.

MetroMPG 04-09-2008 08:06 AM

Agreed: cheap & simple are good goals for 1.0.

I just ordered the 2x16 - came to $13.29 US including shipping to Canuckistan.

Your sample display interface looks good & makes sense. I like it.

Whoops 04-10-2008 06:34 PM

Ok, I've got a couple of thought's, for consideration.

In thinking about it, if we are only looking to update the display or send out the serial data, once per second, then the code and hardware don't really need to sample either the speed, injector on time or frequency any more quickly. Consequently, the code could reasonably sample the speed for 10 cycles, average that and store it. The same thing is true for the injector on time and frequency. Statistically this would give us some pretty highly reliable intervals for calculation and display. It should also make the code pretty straight forward.

One request was for RPM to be displayed. In thinking about the above, the RPM can be inferred, largely, from the frequency of the injector pulse. The exception to this would be if the injector is not turned on, as it is not when my rpm is above about 1200 and I have my foot off of the throttle.

Third, one of the things I would like to have is the ability to see if my speed is going up or down and whether my fuel mileage is going up, or down.

On the display, it may turn out that we have to not update the screen, to frequently, as at some rate of change it may become jibberish.

Although I ordered my freeduino a week ago, I still haven't received it.

MetroMPG 04-11-2008 08:21 AM

Mine took over a week to arrive. The donkey train across the border into Canuckistan is facing swollen rivers & streams from the spring runoff, dontcha know.

EDIT: Whoops, whoops. I read your post and thought it was from fellow hoser Who. Thus you can ignore this post entirely.

dcb 04-11-2008 09:20 AM

Whoops, the occasional sampling of the injectors would be reasonably accurate, but then you need to add tight timing control around the code that would enable the timer interrupts and disable them. And then make an exception for the vss signal, because on my vehicle, it is more than a second between pulses at low speed and you wouldn't want to miss one of those.

I don't think it would make it more straightforward though, since it adds code, but it would be a good optimization, a strategy to consider if reacting to the button presses and displaying prove to be too time consuming. But I think we are ok and might even be able to shorten the 1 second display rate and keep microsecond accuracy.

if you wanted to plug into the serial processor as it stands today:
http://ecomodder.com/forum/showthrea...7979#post17979
Basically in the middle of loop, get rid of the serial calls and replace it with

updateTrips(tmpInjHiMS, tmpInjCount, tmpvssCount );//quick addition in the trip objects
updateDisplay()



updateTrips might look like:
void updateTrips(long injHiMS, injCount, vssCount ){
instant.reset();
instant.update(injHiMS,injCount,vssCount);
current.update(injHiMS,injCount,vssCount);
tank.update(injHiMS,injCount,vssCount);
trip1.update(injHiMS,injCount,vssCount);
trip2.update(injHiMS,injCount,vssCount);
}

and the trips themselves would provide functions like:
current.mpg(), instant.kph(), instant.mph(), tank.dte(), trip1.lper100km()

now updateDisplay() is tricky, as well as keeping track of the button interrupts and deciding the next screen. Might want to look at how coyote did his for starters.

larrydag 04-11-2008 01:49 PM

Quote:

Originally Posted by MetroMPG (Post 18558)
So, are you still thinking the 16x2 LCD mentioned in post #2 is the one to get? If so, I'll order one too. I'm a bit out of my depth, but I can at least be beta testing along side you guys.

Also, the Guino is boring with only a blinking LED to program. :)

I'm with you MetroMPG in that this is a little out of my league. But there is hope for us. I strongly suggest checking out the Arduino code library and tutorials

http://www.arduino.cc/playground/Mai...ralCodeLibrary

This should help to understand a lot of the nuances in coding the *duino.

As a project to learn coding I'm trying to figure out how to wire up a Battlestar Galactica Cylon scanning eye. I know its a cheesy LED thing but it should be a good first step to learn about *duino's.

dcb 04-11-2008 08:43 PM

Whoops, one more note, there was a caution about the lcd and interrupts at: http://www.arduino.cc/cgi-bin/yabb2/...m=1173553276/3

it is summarized as follows:
1.) Never use a delay or any library which introduces a delay while in an interrupt (like the Wire library or LCD libraries). Serial communication, or any communication requiring a clock will also fail.
2.) Use an external pull-up on the interrupt line.

re: 1. not a problem if updateDisplay is called directly in loop() as I'm suggesting.
re: 2. This is an external hookup issue.

Also I did some scratching and I think worst case scenario (i.e. a v8 with tbi doing 150mph at 8000RPM), there should be about 10 milliseconds of overhead for all the interrupts, which leaves .99 seconds to figure out what to display and display it.

P.S the 2x16 showed up today, I still can't tell if it is the one with less built in characters but more user definable characters or not.

dcb 04-12-2008 07:02 PM

Sorry, I couldn't resist playing with the lcd. The library didn't work for me, wound up poking at it in arduino ide till I got somewhere. All those somewhat arbitrary hokey delays need to be replaced with a status check on the lcd (i.e. LCD? are you ready for another command or piece of data?) I also moved the pins all around to keep the timer1 and 2 pwm pins open (and the serial ports open).

http://opengauge.org/diympggauge/mpguino1.JPG

I call this configuration the boreduino :)
http://opengauge.org/diympggauge/boreduino.JPG

MetroMPG 04-12-2008 07:34 PM

Awesome! I love it! Can't wait for mine to come too.

I also love that you're not not blowing the project budget on mounting hardware/shields. :)

(Correct me if I'm wrong, but a "shield" is Arduino-speak for separate circuit boards that you mount additional electronics on and then connect to the 'duino, right?)

dcb 04-13-2008 08:41 AM

Quote:

Originally Posted by MetroMPG (Post 19238)
I also love that you're not not blowing the project budget on mounting hardware/shields. :)

Thanks :) I like this setup because the LCD is secure, the pins are still easy to get to, and it is low profile when sitting on the dash. Also it would be simple enough to add sides and a top after things become less experimental, and stain or paint it if desired. But hot glue and bits of wire and a chunk of balsa are good enough for me. Just need to sort out the buttons.

FYI, radio shack had a bag of 4 little buttons for $2. I'll probably mount them flush with the LCD face on the sides with some long leads for now. Or maby along the top right where it would be easier. Yah, I like easy, that looks like a plan.

Edit: easiest mounting turns out to be to jam them in under the LCD. Now how many? 2, 3 ,4? Each button takes a pin

4 buttons should be easier to navigate. I.e. a select, 2 scrolls and a back.

3 buttons isn't too bad either, I e a scroll in either direction (so you don't have to cycle through all the options if you pass it) plus a select button, but "go back" becomes a thing you have to select.

2 buttons is the easiest to hook up and simplifies the design choices. Harder on the users as there's lots more clicking, but not a big deal.


Ok Pin check: We don't have any sensors plugged in yet or buttons (or a piezo speaker), but after the LCD we have:

4 pwm pins
2 "serial" pins 0,1, I think we can give up 0, but TX might be useful for debugging.
6 analog/digital read pins
(yep, sorry blinky fans, I took pin 13 for the LCD)

So that leaves us 11 pins without buttons or car signals.

we need 3 digital read pins to talk to the car. vss,inj,ign power.
and each button will need a pin, so maybe 4 there.
piezo speaker for another 1, would be good for the "your mpg is dropping" alert.

MetroMPG 04-13-2008 12:06 PM

Can we combine 2 buttons simultaneously pressed for some fuction, such as "home"? That could let us get away with 3 buttons with 4 button functionality (assuming just one "combo" button). Might not be the best usability though. Just a thought.

dcb 04-13-2008 12:14 PM

I think the answer to the number of buttons happens to be 3 :) And they will be in the upper right corner.

I sat it in the car, it is the same height as a scangauge but about two inches narrower, and fits. I pretended to use the buttons, and am of the conclusion that a small cluster of them is better than spreading them around.

upper right corner was the easiest place I could get to them and still see the screen.

3 because that is what fits in the upper right with sufficient space between the buttons, with sitting flush with the lcd and not increasing the profile.

So just need to glue down a block there of the right thickness, solder up the switch leads, with a common ground and three signals, and glue them to the block.

edit: re chording buttons. I was actually looking at those earlier today, that is weird. I think the only chord that people might intuitively know is the soft reset, where you mash everything down.

MetroMPG 04-13-2008 12:25 PM

Agreed about combining buttons. Probably not the best (intuitive) idea.

I also agree that a cluster is best - as Trebuchet pointed out earlier, you'll learn which ones you need to press and eventually will be able to do it without looking. Cluster = useful tactile feedback for selecting the right one.

dcb 04-13-2008 06:05 PM

Buttons
 
Here is a simple approach, can be had from the 'shack

needed:
1 bag of 4 surface mount push button switches . Mine were $2 though the site says $4
1 general purpose dual pc board ~$2

Some hookup wore (cut open an old network cable or something).

Hot Glue gun

that really thin solder helps, especially inbetween the buttons. And sharpen up your iron first. Tin the iron with solder as soon as it can melt it, before it gets too hot and oxidizes.

Assembly:
Find a 12x3 group of copper circles on the board, by the edge but not on the edge. Score through the next row out in all 4 directions and snap off the extra. Tin the circles lightly that you will be using.

X=tinned
XOOXXOOXXOOX
OOOOOOOOOOOO
XOOXXOOXXOOX

Starting with the middle switch (leads touching one X each), surface mount the switches to the tinned copper spots, don't let the switch leads touch the other switches on the bottom, but do solder bridge them on the top. That That will be the ground.

Hold your breath, and (CAREFULLY) grind the top and bottom flush on the grinding wheel, bring in the sides to just outside the rings where the switches are connected.

Add the wires (and leave yourself plenty of wire for now). Pull them through the plain side and bend them over an appropriate switch leg and solder. Attach three signal wires and one for the ground.

grind the extra solder and wire off the top/bottom/

Straighten out the wires and run them to one end

Feed the wires through the top right hole in the lcd and position the buttons so the metal part is flush with the front of the lcd and they are straight, and the right side is flush with the right of the lcd board.

Pull the buttons back out just enough to put a thin layer of hot glue on the bottom of the buttons, and quickly but accurately put them in their final position. If your happy with their position and protrusion from the lcd, squirt in (caulk style) some hotglue to fill in behind the button boar.


coding:
In your code, you can use the internal pullup resistors via:
pinMode(pin, INPUT); // set pin to input
digitalWrite(pin, HIGH); // turn on pullup resistors

then attachInterrpupt (pin, function, FALLING) and or with the "button has been pressed" flag.


Hookup, the ground goes to ground and the signals go to the pin they control.



http://opengauge.org/diympggauge/buttons.JPG
http://opengauge.org/diympggauge/buttons2.JPG
http://opengauge.org/diympggauge/buttons3.JPG
http://opengauge.org/diympggauge/buttons4.JPG

dcb 04-13-2008 06:16 PM

(EDIT, this is not current information)

Oh, and here is the LCD connection setup I used to preserve the multipurpose ports
Code:

NC=Not Connected

LCD pin            16  15  14  13  12  11  10  9    8    7    6    5    4    3    2    1
Arduino Pin  GND 5V  13  12  8    7    NC  NC  NC  NC  4    6    0    5    5V  GND


MetroMPG 04-13-2008 09:18 PM

Nice placement for those 3 buttons.

dcb 04-14-2008 08:12 AM

FYI, dont take the pin assignments to seriously yet. The arduino has blocked external interrupts on most of the ports and it *might* require some rewiring.

I'm reading some things that say arduino only allows two external interrupts, and obviously we need those for the injector and the vss. the atmega can support lots more external interrupts, so it probably just needs a little digging, and dipping into AVR.

dcb 04-14-2008 09:46 AM

interrupt vectors
2 0x0002 INT0 External Interrupt Request 0
3 0x0004 INT1 External Interrupt Request 1
4 0x0006 PCINT0 Pin Change Interrupt Request 0
5 0x0008 PCINT1 Pin Change Interrupt Request 1
6 0x000A PCINT2 Pin Change Interrupt Request 2

arduino board mappings:
INT0 = digital pin 2
INT1 = digital pin 3
PCINT0= digital pin 8
PCINT1= digital pin 9
PCINT2= digital pin 10
PCINT3= digital pin 11
PCINT4= digital pin 12
PCINT5= digital pin 13

attachInterrupt only works with INT0 and INT1, so need to (INT0 example, translate for PCINT):
<chickenscratch>

#include <avr/interrupt.h>
...

int sensePin = 2;

...
ISR(INT0_vect) {
value = digitalRead(sensePin);
}
...
setup()
// Global Enable INT0 interrupt
GICR |= ( 1 < < INT0);
// Signal change triggers interrupt
MCUCR |= ( 1 << ISC00);
MCUCR |= ( 0 << ISC01);

}

</chickenscratch>

Don't know why there are not interrupt vectors for all the PCInts yet.

Note: in an ideal place we would use 6 external interrupts, 3 buttons, 1 injector signal, 1 vss signal, and one ignition power. But I recon we can poll the buttons and the ignition power if absolutely necessary.

dcb 04-14-2008 10:58 PM

Note: I Updated the pin assignments on the freeduino serial processor draft to just use pins 2 and 3 (INTR0 and INTR1), and those do seem to respond to the buttons anyway. I'm going to move LCD wire connected to Pin 2 to pin 0 and we can assure ourselves of VSS and Injector signals that way by reserving pins 2 and 3 respectively.

I think the guino should try and dip into AVR and get more interrupts going for the buttons though, it *should* be easier than polling, and less flakey. But if someone wants to come up with a "wait" that can guarantee one second accuracy on the main loop but still do things like poll buttons while it is "idle", then that is cool.

metroschultz 04-15-2008 12:40 PM

I'm still lurking,
waiting for a day when I would have something intelligent to add,
You guys are over my head, but I am patiently waiting the day you post schematics and parts list.
Thanx,
S.

Whoops 04-15-2008 01:46 PM

Well I've made miniscule progress, but heh, progress. I've been waiting and watching every day for the board I ordered to come in. I finally went to the Post Office, multiple times and they told me the package had already been delivered, like a week earlier. I checked here in the office and nobody knows what I'm talking about.

Someone finally found the package mixed in with some magazines. I presumed it was in a box and it came in a plain white plastic padded bag, so it was just presumed to be a bag.

On the inputs, if we can run the injector and the speed inputs to interupt pins on the PC, that would be better than not. The problem on the injector is that we need to measure two things, relative to the signal. First, we need to measure how long the injector is on, each cycle and second, we need to measure how long it is before the next cycle, which will give us the frequency or period of time the cycles occur, each second. This is effectively, also the same number as the rpm, unless the car is coasting, in gear, injectors off.

The problem on the injector timing is that effectively we need to measure a falling edge signal, have timing to a leading edge and then have timing to the next falling edge. Generally on edge triggered inputs, you can set it up to do one, or the other, but not both, but I haven't gotten far enough to look into that, yet.

dcb 04-16-2008 09:12 AM

Quote:

Originally Posted by Whoops (Post 19708)
Generally on edge triggered inputs, you can set it up to do one, or the other, but not both, but I haven't gotten far enough to look into that, yet.

on the ATMega, there is an interrupt mode called "CHANGE", which gets triggered on high2low and on low2high. We probably need to use that one and do a digitalRead(injPin) first thing in the interrupt, or otherwise toggle a flag, or both. I should probably reference this from the signal processing thread.

MetroMPG 04-16-2008 10:03 AM

Quote:

Originally Posted by dcb (Post 19369)
In your code, you can use the internal pullup resistors via:
pinMode(pin, INPUT); // set pin to input
digitalWrite(pin, HIGH); // turn on pullup resistors

A little OT (and revealing my noobness on the topic)....

1) I didn't know what a pull up/down resistor was until recently.

2) This simple tutorial shows an external pull up resistor in a test button circuit. http://www.arduino.cc/en/Tutorial/Button

So ... the external resistor isn't strictly needed for that tutorial?

dcb 04-16-2008 10:12 AM

Quote:

Originally Posted by MetroMPG (Post 19913)
So ... the external resistor isn't strictly needed for that tutorial?

Absolutely correct :) If your button is connecting the pin to ground, then no it isn't needed. Save your self a component and use the built in pullup resistor.

MetroMPG 04-16-2008 10:20 AM

OK - thanks.

MetroMPG 04-16-2008 09:13 PM

Quote:

Originally Posted by dcb (Post 19231)
Sorry, I couldn't resist playing with the lcd. The library didn't work for me, wound up poking at it in arduino ide till I got somewhere.

My LCD arrived today.

Can you point me in the right direction (links?) to play around with it? It sounds from your experience like it's not straightforward.

dcb 04-17-2008 12:16 AM

Well, I didn't get anywhere with the 4 bit library, and it was getting annoying recompiling the library for a bunch of trial and error, so I tried this:
http://www.arduino.cc/cgi-bin/yabb2/...m=1160586800/0

I didn't get results at first and don't recall everything that was involved (predefined timings was one of the gotchas). But here are my current pin assignments and the mpguino display code. It does a good job of highlighting the sequence of events but the delays do need to be redone as status checks and pushed back into the lcd library. Note, with this code I had to hit the reset button after downloading the script or powering up sometimes.
Code:

LCD        arduino
1        ground
2        5v
3        digital 6
4        digital 4
5        digital 0
6        digital 5
7        not connected
8        not connected
9        not connected
10        not connected
11        digital 7
12        digital 8
13        digital 12
14        digital 13
15        5v
16        ground

Code:

int DI = 4; // register select RS
int RW = 0;

int db4=7; int db5=8; int db6=12; int db7=13;
int contrast=6;
int Enable = 5;
 
 
void tickleEnable()
{
 // send a pulse to enable
 digitalWrite(Enable,HIGH);
 delayMicroseconds(1);  // pause 1 ms according to datasheet
 digitalWrite(Enable,LOW);
 delayMicroseconds(1);  // pause 1 ms according to datasheet

 
void cmdWriteSet()
{
 digitalWrite(Enable,LOW);
 delayMicroseconds(1);  // pause 1 ms according to datasheet
  digitalWrite(DI,0);
  digitalWrite(RW,0);
}
void LcdCommandWrite(int value) 
{
 int i = 0;
 
    digitalWrite(db7, value & 128);
    value <<= 1;
    digitalWrite(db6, value & 128);
    value <<= 1;
    digitalWrite(db5, value & 128);
    value <<= 1;
    digitalWrite(db4, value & 128);
    value <<= 1;
    cmdWriteSet();
    tickleEnable();

    digitalWrite(db7, value & 128);
    value <<= 1;
    digitalWrite(db6, value & 128);
    value <<= 1;
    digitalWrite(db5, value & 128);
    value <<= 1;
    digitalWrite(db4, value & 128);
    value <<= 1;
    cmdWriteSet();
    tickleEnable();
}
 
void LcdDataWrite(int value) 
{
 int i = 0;
 
 digitalWrite(DI, HIGH);
 digitalWrite(RW, LOW);
 
    digitalWrite(db7, value & 128);
    value <<= 1;
    digitalWrite(db6, value & 128);
    value <<= 1;
    digitalWrite(db5, value & 128);
    value <<= 1;
    digitalWrite(db4, value & 128);
  value <<= 1;

    tickleEnable();
 
    digitalWrite(db7, value & 128);
    value <<= 1;
    digitalWrite(db6, value & 128);
    value <<= 1;
    digitalWrite(db5, value & 128);
    value <<= 1;
    digitalWrite(db4, value & 128);
value <<= 1;
    tickleEnable();
    delay(5);
}
 
void setup (void) 
{
 pinMode(Enable,OUTPUT);
 pinMode(RW,OUTPUT);
 pinMode(DI,OUTPUT);
 pinMode(db4,OUTPUT);
 pinMode(db5,OUTPUT);
 pinMode(db6,OUTPUT);
 pinMode(db7,OUTPUT);
 
 delay(100);
 LcdCommandWrite(0x2c);  // function set:
  delay(64);            // 4-bit interface, 2 display lines, 5x7 font
                        // other interaces:
                        // 0x20 = 4 bit, 1 display line
 
 LcdCommandWrite(0x06);  // entry mode set:
                        // increment automatically, no display shift
 delay(20);                     
 LcdCommandWrite(0x0c);  // display control:
                        // turn display on, cursor on, no blinking
 delay(20);                     
 LcdCommandWrite(0x01);  // clear display, set cursor position to zero 
 
 delay(100);                     
LcdCommandWrite(0x80);  // set dram to zero (necessary?
 delay(20);     

 analogWrite(contrast,75);
 delay(20);     

}
  int i='0';
 
void loop (void) 
{
 
  delay(500);                  // stop the program for some time

  LcdCommandWrite(0x01);  // set cursor position to zero 
  delay(20);                     
  firstDisplay();
 
boolean asc=true;
  while(true){
    for(int x = 0; x < 256; x++){
    analogWrite(contrast,x);
    delay(8);
    }
    for(int x = 255; x >0; x--){
    analogWrite(contrast,x);
    delay(8);
    }
  };
}
 


void firstDisplay()
{
//    LcdDataWrite(value);
    LcdDataWrite('O');
    LcdDataWrite('P');
    LcdDataWrite('E');
    LcdDataWrite('N');
    LcdDataWrite('G');
    LcdDataWrite('A');
    LcdDataWrite('U');
    LcdDataWrite('G');
    LcdDataWrite('E');
LcdCommandWrite(0xC9);  // C0 would be start of second line
 delay(20);     

    LcdDataWrite('M');
    LcdDataWrite('P');
    LcdDataWrite('G');
    LcdDataWrite('U');
    LcdDataWrite('I');
    LcdDataWrite('N');
    LcdDataWrite('O');
 }


dcb 04-17-2008 08:44 AM

Here is a data sheet on the LCD controller. The LCD itself has a 5x10 character format.
http://www.electronic-engineering.ch...cd/hd44780.pdf

One of the possible tweaks might be to create custom characters that use the whole 5x8 character box. They could be larger numbers perhaps for easier reading or maybe custom characters to conserve display real estate , i.e. MPG might have this in front of it instead of three characters:
(Note, just realized the lcd is 5x8, not 5x10!!!)
http://planetchampions.org/diympggauge/mgfont.GIF
(just using paintbrush at 800% zoom)

I don't know how many user defined characters are on this display yet, however.

larrydag 04-21-2008 11:23 PM

I've gotten my LCD to work. It actually is a pretty nice display. Can't wait to see it posting some real data. dcb, i like the little fading feature you setup in the code.

dcb 04-22-2008 07:27 AM

Very Cool :)

The only thing to add to it is LCD pin 15 (Backlight power) should probably be controlled by an arduino pin and a transistor, so you can controll the brightness from a menu option, and turn off the LED when the ignition is off.

larrydag 04-22-2008 09:05 AM

Do you mean turn off the LCD when the ignition is off? I assume you mean that you would want a pin to turn off the LCD when you want to release the keys from the igninition. Otherwise you want the LCD to stay on when you cut the engine during P&G'ing. Is this correct?

Otherwise why not use a power source from the car that cuts off when the keys are in the OFF position.

dcb 04-22-2008 08:29 PM

You have a point about the key, I had kill switch in my head so it didn't occur to me that folks might be turning off the ignition.

I need to list out my assumptions I think.

1. The arduino is powered by battery power. Because:
A. there are a limited number of eeprom writes, the trips should be saved when the key is turned off, but the arduino can't do that if you are turning off it's power also.

B. there are some sleep modes for the arduino that it could utilize when the ignition is off, but I don't think the drain will be terribly noticable.

2. The arduino should sense the ignition power, Because:
A. it needs to write out the current state of the trips to the eeprom on the ignition off event.

B. If the arduino has control of the LED Backlight (i.e. fancy schmancy menu brightness option) it can turn it off on the ignition off event and save ~200 milliamps. This adds one component (transistor) to the design. Switching it with the ignition directly will add one component in the form of a resistor to limit the current, and not give user control.

So I was thinking have the arduino turn off the LED, since the arduino was already connected to ignition power (in my head) and it was a simple task to have a menu driven brightness. The LCD only takes about ~4ma so I'm not worried about it yet.

But, maybe, it just has to be a (hokey) delay thing. Like if the car hasnt shown any rpm or travelled any distance in, say, 10 minutes, then it saves the trips in their 10 minutes ago state, and turns off the backlight? Saves us a ignition power pin.

dcb 04-28-2008 11:18 PM

button interrupts have been sorted out.
 
Phew, finally got the buttons to be read reliably with interrupts in arduino IDE. No polling required, though we might want to elaborate on the debouncing at some point. This also means there are a lot more pins for doing external interrupts with than arduino allows "out of the box", though only pins 2&3 do RISING/FALLING, the rest are state change, not a big deal.


Code:

#include <avr/interrupt.h>   
#include <avr/io.h> 

int lbuttonPin = 17; // Left Button, on analog 3
int mbuttonPin = 18; // Middle Button, on analog 4
int rbuttonPin = 19; // Right Button, on analog 5

//button signals are inverted (internal pullup resistor), so true is not pressed
boolean  lbutton = true;
boolean  mbutton = true;
boolean  rbutton = true;
 
//attach the interrupt
ISR( PCINT1_vect ){
  PCICR &= !(1 << PCIE1);//disable interrupts in the interrupt
  if (!digitalRead(lbuttonPin)) lbutton = false;
  if (!digitalRead(mbuttonPin)) mbutton = false;
  if (!digitalRead(rbuttonPin)) rbutton = false;
  PCICR |= (1 << PCIE1);
}
 
void setup() {
  Serial.begin(9600);
  pinMode( lbuttonPin, INPUT );
  pinMode( mbuttonPin, INPUT );
  pinMode( rbuttonPin, INPUT );

//"turn on" the internal pullup resistors
  digitalWrite( lbuttonPin, HIGH);
  digitalWrite( mbuttonPin, HIGH);
  digitalWrite( rbuttonPin, HIGH);

//low level interrupt stuff
  PCICR |= (1 << PCIE1);
  PCMSK1 |= (1 << PCINT11);
  PCMSK1 |= (1 << PCINT12);
  PCMSK1 |= (1 << PCINT13); 
}
 
void loop() {   
  //print out what buttons have been pressed
  if(!lbutton) Serial.print("lbutton");
  Serial.print(",");
  if(!mbutton) Serial.print("mbutton");
  Serial.print(",");
  if(!rbutton) Serial.print("rbutton");
  Serial.println("");
 
  //reset the buttons
  lbutton = true;
  mbutton = true;
  rbutton = true;
 
  delay(500);
}



All times are GMT -4. The time now is 03:36 AM.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Content Relevant URLs by vBSEO 3.5.2
All content copyright EcoModder.com