Jump to content
Sign in to follow this  
Master_Scythe

Linear voltage boost?

Recommended Posts

If you're familiar at all with Java or JS, then C/C++/Arduino's control block syntax should be recognisable:

if(condition){
    // code
} else {
    // code
}
But the processor inside the MCU is super fast, you should just calculate the value on the fly, rather than building a huge lookup table with if...then...else blocks.

 

analogRead() gives you an integer between 0 and 1023 representing the range of the analogue input (whether that be 0-5v, 0-1v1, or what have you).

 

So you just map that value on to the intended scale:

 

int pin = 3;                        // or whatever the pin number is that you're using
int x = analogRead(pin);            // read the value
float y = ((float)x / 1024) * 20;   // map 1-1024 to 1-20
y = round(y*10)/10;                 // round to one decimal place
leddisplay.write((string)y);        // write number to display. I dunno what the real function is called.
Edited by SquallStrife
  • Like 1

Share this post


Link to post
Share on other sites

Have a look on the Arduino.cc site language reference:

http://www.arduino.cc/en/Reference/HomePage

 

Doing it with if statements doesn't make sense from my perspective, but I guess you have to work with what you know, and you'll learn from it. Just keep in mind that instead of 2 lines of code, you're going to end up with at least 50.

 

The psuedo code will look something like this

void loop() {

TempInputVariable = analogRead(pin);

if (TempInputVariable <= X1) {
   TempOutputVariable = TempInputVariable;
}
else if (TempInputVariable > X1 && TempInputVariable <= X2) {
   TempOutputVariable = TempInputVariable;
}
else if (TempInputVariable > X2) {
   TempOutputVariable = TempInputVariable;
}

DisplayOutput(TempOutputVariable);
}

Where X1 and X2 and numerical constants you've decided on. You could move the analog read operation into the the 'if' statements, but then you're wasting a lot of cycles to process every if statement. You could also move the DisplayOutput operation into the 'if' blocks, but then if you decide to change the style of display output, you'd need to copy and paste for every 'if' block.

Edited by tastywheat

Share this post


Link to post
Share on other sites

Thanks guys, thats kinda helping.

Its why I had a hard time with maths, I felt like I needed to be doing more, when I really dont. I dont need to understand 'why' just 'how'.

But my brain feels like it needs to know WHY, regardless.

 

So, (i know you said Pseudocode, but lets pretend its correct) I just have to trust that 'DisplayOutput' is something that my display library understands, and I can put whatever I need there?

 

I ask because the test script defines each segment of the LCD individually.

 

The main benefit of doing a bunch of IF's and ELSE's is that my mind couldnt figure out how to get out of the loop of reading intergers, and display RICH or LEAN in words if i used the calculated output.

 

Where as here, I can just use IF and ELSE statements for RICH and LEAN by defining a constant.


If you're familiar at all with Java or JS,

i am not :(

 

This is my first jump in, in over 10 years. I've retained 0% it seems :P

Edited by Master_Scythe

Share this post


Link to post
Share on other sites

So, (i know you said Pseudocode, but lets pretend its correct) I just have to trust that 'DisplayOutput' is something that my display library understands, and I can put whatever I need there?

 

There's two ways to figure this out in this particular instance, given that the library is poorly documented. The first is to look through the library .cpp file, and see what functions are defined. I'm going to assume that this probably isn't the best route for you right now, but keep it in mind if you ever get stuck in the future.

 

The second is to look at examples, and reverse engineer them. The default example is actually quite complicated, so it's probably not the best starting point. Google 'TM1637 Arduino example' or 'TM1637 arduino project', and you'll get an abundance of code examples. This was found on the second page of results, and is simple enough that the functions can be easily understood:

 

http://www.techmonkeybusiness.com/tm1637-4-digit-display-example-sketch.html

/* TM1637_4_Digit_Display_Basics.ino
The purpose of this sketch is to provide the basic
structure for using the TM1637 based 4-Digit Displays
like the Grove 4 digit display or other equivalents
available through the likes of www.dx.com. 

This makes use of the TM1637Display library developed by avishorp.
https://github.com/avishorp/TM1637

This has been developed to run on any Arduino.

Pin assignments are:
CLK - D9
DIO - D8
5V or 3.3V supply to Display
GND to Display

The operation is very simple. The sketch initialises the display
and then steps through the loop incrementing the value of a
variable which is then displayed on the 4-Digit display.
Essentially it is the most basic function you would want from
such a display. If you want more sophisticated functionality
then use the example that ships with the library.

*/

#include <TM1637Display.h>

const int CLK = 9; //Set the CLK pin connection to the display
const int DIO = 8; //Set the DIO pin connection to the display


int NumStep = 0; //Variable to iterate

TM1637Display display(CLK, DIO); //set up the 4-Digit Display.

void setup()
{
  display.setBrightness(0x0a); //set the diplay to maximum brightness
}


void loop()
{
  for(NumStep = 0; NumStep < 9999; NumStep++) //Interrate NumStep
  {
    display.showNumberDec(NumStep); //Display the Variable value;
    delay(500); //A half second delay between steps.
  }
}

The first thing to pick up on is that the example uses different pins. You'll need to set these to what you've wired it up as (this won't effect how the code works in the slightest).

 

The second is this line:

display.showNumberDec(NumStep); //Display the Variable value;

From this, you should be able to work out that 'display' is the display object, as defined at the start of the code, and .showNumberDec(); will display a decimal number on the display for whatever you call.

 

You can build your understanding by playing around with this code, stripping it back to it's essentials, and calling different values using 'display.showNumberDec(yourValueHere)'

Share this post


Link to post
Share on other sites

If you're familiar at all with Java or JS, then C/C++/Arduino's control block syntax should be recognisable:

 

Nope, I'm new to it all. Maybe 10 years ago, but I remember nill.

 

 

Anyway, this is what I have so far.

#include <Arduino.h>
#include <TM1637Display.h>

// Module connection pins (Digital Pins)
#define CLK 2
#define DIO 3

TM1637Display display(CLK, DIO);


float AirFuel;
float Sensor;

void setup()
{
  //set the diplay to maximum brightness
    display.setBrightness(0x1a);
    analogReference(INTERNAL);
}



void loop()
{
Sensor = analogRead(A1);
AirFuel = (Sensor/1023 * 20);

  //Display AirFuel
  display.showNumberDec(AirFuel,false,3,0);
 
}

So the problem I'm having is that no matter what I do, my display will only show 0V if I ground out Analogue Pin 1, or will show (in this instance) 200 if I apply ANY voltage at all.

 

What have I missed?

 

I'm doing my A1 pin testing with a 1.5V Alkaline.

 

I'm pretty chuffed I got this far actually for a first time :P

Edited by Master_Scythe

Share this post


Link to post
Share on other sites

This line: analogReference(INTERNAL);

 

Means that the analogue reference voltage is 1.1v. So your alkaline battery at 1.5v will produce 1023 from the ADC.

 

If you want to use Vcc (or 5V) as your reference, change that line to:

 

analogReference(DEFAULT);

 

Or omit it completely.

Share this post


Link to post
Share on other sites

changed it to DEFAULT and I'm now reading "6" .... dont see how thats relevant... but its a different number to 20 :P


This line: analogReference(INTERNAL);

Means that the analogue reference voltage is 1.1v. So your alkaline battery at 1.5v will produce 1023 from the ADC.

If you want to use Vcc (or 5V) as your reference, change that line to:

analogReference(DEFAULT);

Or omit it completely.

Share this post


Link to post
Share on other sites

This line: analogReference(INTERNAL);

 

 

Figured it out.

 

Needed to do OTHER math.

 

Considering I'm trying to take 0-5v to 10-20 display;

 

AirFuel = 10+(Sensor/1023*10);

 

Only problem is now, its not doing decimals.....

 

 

 

Got it, just timed the ouput by 10, so it moves up past the hardware decimal on the display, and turned on the hardware decimal :D

 

well.... still trying to learn how to turn on the display decimal without causing flicker....

#include <Arduino.h>
#include <TM1637Display.h>

// Module connection pins (Digital Pins)
#define CLK 2
#define DIO 3

TM1637Display display(CLK, DIO);


float AirFuel;
float Sensor;

void setup()
{
  //set the diplay to maximum brightness
    display.setBrightness(0x1a);
    analogReference(DEFAULT);
}



void loop()
{
Sensor = analogRead(A1);
AirFuel = (10+(Sensor/1023*10))*10;

  //Display AirFuel
  display.showNumberDec(AirFuel,false,3,0);
 
//Max displays 5 a second
delay(200);
}

Edited by Master_Scythe
  • Like 1

Share this post


Link to post
Share on other sites

This line: analogReference(INTERNAL);

 

Means that the analogue reference voltage is 1.1v. So your alkaline battery at 1.5v will produce 1023 from the ADC.

 

If you want to use Vcc (or 5V) as your reference, change that line to:

 

analogReference(DEFAULT);

 

Or omit it completely.

 

Squall, could I grab a hand for a minute please?

 

My gauge is working wonderfully on the test bench, with one major flaw.

 

It's to do with:

//Max displays 5 a second

delay(200);

 

When I upped that to 333 (3 times a second) the problem became very visible.

The delay this puts on my LED's for 'lean' and 'rich' is VERY significant. seems like almost a full second, and I'm not sure why.

 

I was going to remove the delay (which makes my LEDs respond instantaneously) but then the Numeric output is so fast that its a blur to human eyes.

 

I then thought maybe there's a way to smooth it:

https://www.arduino.cc/en/Tutorial/Smoothing

 

Problem with this, is that an average isnt very useful for accurate car tuning, because a lift off on the throttle will see a spike to 5v right after a possible 0.1v at Wide Open Throttle; and the average will be bogus.

 

How would I go about delaying either the write to the display function, or the read function from the analogue input without applying that delay to the LED part of my code?

 

 

Here's my LED part:

// Turn on 'ALL GOOD' light below 12
if(Sensor <= 204)
  
 { 
  // turn the LED on (HIGH is the voltage level)
  analogWrite(10, 255);
 }
else  
{  analogWrite(10, 0);
  
   }

// Turn on 'LEAN DECEL' light above 15
if (Sensor >= 512 )
{ 
  analogWrite(11, 255);
}
else
{ analogWrite(11,0);
  

Share this post


Link to post
Share on other sites

Is there a reference clock variable or something you can use?

 

Then you could change your code to only display on certain multiples.

 

e.g. a variable with values 0-999 of milliseconds, only have the display occur at 0 or multiples of 200.

Actually to be sure you don't miss events you might want to have a tenths of a second value which gives more leeway.

Share this post


Link to post
Share on other sites

Hmm... thats something to look into.

I coudl use an IF and the Millis() command...

 

For now, I'm going to try this guy's Class

 

http://www.element14.com/community/groups/arduino/blog/2014/06/05/a-non-blocking-delay

 

It looks like he's put the Millis() delay code that arduino provide as an example into a class, making it VERY easy to use.

 

I cant find my arduino right now though, so I can't upload and try it, but it looks promising.

Anyone with expereince know if this new

NonBlockingDelay.Delay (333);

will work as advertised?

 

 

EDIT: and just like that, I found my arduino, and it works!

LEDs respond instantaneously (meaning if my face turns red while driving, I get the hell off of the gas) while I can still safely read the display updating somewhere between 3 and 5 times a second.

Edited by Master_Scythe
  • Like 1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×