SquallStrife 545 Posted June 5, 2015 (edited) 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 June 5, 2015 by SquallStrife 1 Share this post Link to post Share on other sites
tastywheat 438 Posted June 5, 2015 (edited) 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 June 5, 2015 by tastywheat Share this post Link to post Share on other sites
Master_Scythe 541 Posted June 5, 2015 (edited) 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 June 5, 2015 by Master_Scythe Share this post Link to post Share on other sites
tastywheat 438 Posted June 5, 2015 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
Master_Scythe 541 Posted August 2, 2015 (edited) 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 August 2, 2015 by Master_Scythe Share this post Link to post Share on other sites
SquallStrife 545 Posted August 2, 2015 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
Master_Scythe 541 Posted August 2, 2015 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
Master_Scythe 541 Posted August 2, 2015 (edited) 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 August 2, 2015 by Master_Scythe 1 Share this post Link to post Share on other sites
Master_Scythe 541 Posted September 11, 2015 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
Rybags 1,164 Posted September 11, 2015 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
Master_Scythe 541 Posted September 11, 2015 (edited) 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 September 11, 2015 by Master_Scythe 1 Share this post Link to post Share on other sites