LiquidCrystal lcd(4, 5, 6, 7, 8, 9); // Assign LCD to pins 4-9 const int redPin = 10; // Red LCD LED to pin 10 const int grnPin = 11; // Green LCD LED to pin 11 const int tempPin = A0; // Temp sensor on Analog 0 int ledState = LOW; // ledState used to set the LED long previousMillis = 0; // will store last time LED was updated long interval = 500; // interval at which to blink (milliseconds) double temp;
// Variables used for calculations volatile int NbTopsFan; int Calc;
// The pin location of the flow sensor int flow = 2;
typedef struct{ //Defines the structure for multiple fans and their dividers char fantype; unsigned int fandiv; }fanspec;
// Definitions of the fans fanspec fanspace[3]={{0,1},{1,2},{2,8}};
char fan = 1; // This is the varible used to select the fan and it's divider, set 1 for unipole hall effect sensor // and 2 for bipole hall effect sensor void rpm () { // This is the function that the interrupt calls NbTopsFan++; }
void setup() { pinMode(redPin, OUTPUT); // Set red LED pin to output pinMode(grnPin, OUTPUT); // Set green LED pin to output pinMode(tempPin, INPUT); // Set temp sensor pin to input pinMode(flow, INPUT); // Set flow sensor pin to input attachInterrupt(0, rpm, RISING); // Attach interrupt for flow sensor digitalWrite(redPin, LOW); // Turn red LCD LED on digitalWrite(grnPin, LOW); // Turn green LCD LED pin on lcd.begin(16,2); // Set LCD to 16x2 lcd.setCursor(0,0); lcd.print(" Circuit Box "); // Line 1 opening message lcd.setCursor(0,1); lcd.print(" By SXRguyinMA "); // Line 2 opening message delay(5000); lcd.clear(); digitalWrite(redPin, HIGH); digitalWrite(grnPin, LOW); } double Thermister(int RawADC) { double Temp; // See http://en.wikipedia.org/wiki/Thermistor for explanation of formula Temp = log(((10240000/RawADC) - 10000)); Temp = 1 / (0.001129158 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp)); Temp = Temp - 274.15; // Convert Kelvin to Celcius return Temp; }
Well the point is the apparently useless code actually works just fine in serial monitor so I don't see what the fuss is about TBH. Second the only issue I have is the flow reading not displaying on the LCD.
Hey guys, I'm working on a temp/flow meter system for my PC. For whatever reason I can't seem to figure out why the flow won't display on the LCD. It works fine in serial but not on the LCD. The temp works fine as is. Thoughts?
Code:
// Code for Circuit Box // Written by Will Lyon // Computers And Circuits // www.computersandcircuits.com
// Libraries #include <LiquidCrystal.h> #include "math.h" LiquidCrystal lcd(4, 5, 6, 7, 8, 9); // Assign LCD to pins 4-9 const int redledPin = 10; // Red LCD LED to pin 10 const int grnledPin = 11; // Green LCD LED to pin 11 const int temp = A0; // Temp sensor on Analog 0
// Variables used for calculations int NbTopsFan; int Calc;
// The pin location of the flow sensor int hallsensor = 2;
typedef struct{ //Defines the structure for multiple fans and their dividers char fantype; unsigned int fandiv; }fanspec;
// Definitions of the fans fanspec fanspace[3]={{0,1},{1,2},{2,8}};
char fan = 1; // This is the varible used to select the fan and it's divider, set 1 for unipole hall effect sensor // and 2 for bipole hall effect sensor void rpm () // This is the function that the interrupt calls { NbTopsFan++; }
void setup() { pinMode(temp, INPUT); // Set temp sensor pin to input pinMode(hallsensor, INPUT); // Set flow sensor pin to input attachInterrupt(0, rpm, RISING); // Attach interrupt for flow sensor digitalWrite(redledPin, LOW); // Turn red LCD LED on digitalWrite(grnledPin, LOW); // Turn green LCD LED pin on lcd.begin(16,2); // Set LCD to 16x2 lcd.setCursor(0,0); lcd.print(" Circuit Box "); // Line 1 opening message lcd.setCursor(0,1); lcd.print(" By SXRguyinMA "); // Line 2 opening message delay(5000); lcd.clear(); } double Thermister(int RawADC) { double Temp; // See http://en.wikipedia.org/wiki/Thermistor for explanation of formula Temp = log(((10240000/RawADC) - 10000)); Temp = 1 / (0.001129158 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp)); Temp = Temp - 274.15; // Convert Kelvin to Celcius return Temp; }
Your original question was how to show 5 screens by pushing one button?
This shows the general idea. It outputs to serial so you can test by just grounding pin 8 (to act as your switch).
Code:
const byte mySwitch = 8;
// these "states" are what screen is currently being displayed. typedef enum { POWER_ON, COOLANT, INTAKE_SPEED, EXHAUST_FAN1, EXHAUST_FAN2, // add more here ...
// was it pressed? if (switchValue == LOW) { state++; // next state if (state >= LAST_STATE) state = COOLANT;
switch (state) { case POWER_ON: powerOn (); break; case COOLANT: showCoolant (); break; case INTAKE_SPEED: showIntakeSpeed (); break; case EXHAUST_FAN1: showExhaustFan1 (); break; case EXHAUST_FAN2: showExhaustFan2 (); break; } // end of switch } // end of switch being pressed
oldSwitch = switchValue; } // end of switch changing state
} // end of loop
OK that makes much more sense now that I see it laid out. I'm going much simpler than originally planned with only 2 options instead of 5 - automatic mode (temp-sensor controlled PWM fan speed) and manual mode (potentiometer-controlled PWM fan speed). I'll also be upgrading to a 20x4 LCD (when it arrives). The top 2 lines will display coolant temp and flow rate all the time with the bottom 2 lines switching between manual and auto modes with fan speed shown (which is what I'm trying to get working right now on the 16x2 I'm currently using)
Here's what I've got so far. It works as is with the commented-out lines (kinda - I can't get the % to display if it's showing 100). Am I on the right track?
const int buttonPin = 11; const int potPin = A0; const int tempPin = A1; const int fan = 10; const int buttonMin = 0; const int buttonMax = 1; int buttonState; int lastButtonState = LOW; long lastDebounceTime = 0; long debounceDelay = 50;
button=read_button(button_pin); //read button on button_pin switch (button) { case 'U': //up button is pressed app_index = (app_index)?(app_index-1):MAX_APP; //update app_index break; case 'D': //down button is pressed app_index = (app_index==MAX_APP)?0:(app_index+1_; //update app_index break; default: do_something(); //illegal key press. do something / nothing }
switch (app_index) { case 0: app0(); //run 1st application break; case 1: app1(); //run 2nd application break; ... }
You can start to fill the various boxes / functions. For example, if you use analog buttons, you just need to implement it in read_button(); and you can put your coolant / flowrate display in app0(); your fan speed/voltage in app1(); ...
It cannot be simpler than that, once you cut it down to logical blocks and implement those blocks one at a time.
ok so where exactly do I put my functions? do I put it in app0(xxxx);?
I've searched and searched and can't seem to find exactly what I'm looking for. I want to create a basic menu (if you can even call it that) for my LCD display with just a single button to change the menus, and up/down buttons for fan speeds (that'll be controlled only when that fan's menu is displayed). Here's how I want it to go:
Welcome screen (on power-up) | | Display 1 (coolant temp/flow rate) | | Display 2 (Intake fan speed/voltage) | | Display 3 (Exhaust fan 1 speed/voltage) | | Display 5 (Exhaust fan 2 speed/voltage) | | Back to display 1 and so on
There will also be a button-controlled servo to open and close a door but that will be independent of the menu system and not displayed.
Obviously I need 5 interrupts (flow meter, fan 1, fan 2, fan 3, servo button) and only have 2, which is why I'm going to use a ChipKIT MAX32 which has 5 interrupts and plenty of I/O for controlling fan speeds, etc. so that problem it solved.
I've got each system (except fan speed control) working independently with separate coding and each works fine (temp/flow works fine, fan speed display works fine). I just can't figure out how to merge them all together into a single working unit. I've seen several different menu libraries but they seem way more complex than what I need. I was thinking button state change or something but can't figure out how to get it all working properly.
Haven't checked with a meter but if I plug the + side of the HDD LED header from the motherboard into the breadboard then hook an LED from it to ground the LED is always on, it never goes out. If I hook an LED to 3v then ground it to the - side of the HDD LED header it works as intended.
You are over thinking, or not realizing how switches work (transistor or physical.)
When the mother board opens the circuit it turns off led by putting its cathode high. In this case you will read and measure a high when the led is off.
When the circuit is closed, youll measure a low. This I because the motherboard closes the switch leaving a 0v drop.
But when I test it it doesn't change. If I open the serial monitor and set it to display high or low depending on the state of the LED header's ground side it never changes. It always says that the pin is low beecause there is no voltage sensed on the pin for it to read high.
It turns out my motherboard has the + side of the HDD LED high all the time and switched the GND to turn it on. How would I go about reading that kind of setup on a digital input?
if (pin == LOW)
instead of
if (pin == HIGH)
That won't work though as it's just a ground. I tried reading it that way and it doesn't change in any way. There is no high ever present on that pin. It simply connects the ground side of the HDD LED. If it were switching the V+ side it'd work fine as it would either be off or on. However this is not the case. Now I'm not sure if all motherboards are this way or just this particular one I'm using.
OK new problem. I switched it to a digital input rather than analog. I noticed however that the input was always high, even with zero HDD activity. It turns out my motherboard has the + side of the HDD LED high all the time and switched the GND to turn it on. How would I go about reading that kind of setup on a digital input?
Don't use an analog input, because the signal you are looking at is a digital signal. You'd have to build a small filter circuit to create an analog signal.
I think you need to poll the LED state (on or off) repeatedly. Then you need to derive a number from the current and recent states of the LED. The number would represent the instantaneous 'activity level' of the LED at the current instant which would tell you which red and green LEDs to illuminate.
There are lots of different ways to derive the activity level. For example you could increment a number each time you saw the LED was on and decrement it each time you saw was off. I think you will have to do some trial and error to see what level of activity you wanted to make each LED go red. For example, you may want to use a logarithmic display so that you get some indication of very low levels of activity but can see show the activity reaching very high levels.
Any idea how to go about this? I'm decent with beginner programming but this is a tad beyond my skill level.
Just use and LM3916 ( or 4 or 5, all similar) , you can use this with a low pass filter - which is simply a resistor and capacitor, no need to an Arduino, just a two dollar chip and some LEDs.
Lots of examples on your favorite video site - this being one of them -
Hi guys! I have a friend who asked me to make him an LED HDD meter for his PC. It consists of 6 bi-color LED's. Right now I modified the bar graph code example to work how I want. At the start, all the green LED's are lit. As the pot gets turned, it turns off a green LED and turns on a red one at the same time.
What I want to to is make it so it will read the input from the motherboard header for the HDD LED and scale the LED's accordingly. I.E. - the more HDD activity the more green LED's will go out and red ones go on, kinda like a VU meter.
Here's the code I have now, I'm just not sure where to go from here.
Code:
const int sensePin = A0; const int redledCount = 6; const int grnledCount = 6; int redledPins[] = { 1, 2, 3, 4, 5, 6 }; int grnledPins[] = { 7, 8, 9, 10, 11, 12 };