Pages: [1] 2   Go Down
Author Topic: Help reading PWM on analog input  (Read 1049 times)
0 Members and 1 Guest are viewing this topic.
Leicester, MA USA
Offline Offline
Jr. Member
**
Karma: 1
Posts: 88
Arduino newbie
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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 };

void setup() {
  for (int thisredLed = 0; thisredLed < redledCount; thisredLed++) {
    pinMode(redledPins[thisredLed], OUTPUT); }
  for (int thisgrnLed = 0; thisgrnLed < grnledCount; thisgrnLed++) {
    pinMode(grnledPins[thisgrnLed], OUTPUT); }
}

void loop() {
  int sensorReading = analogRead(sensePin);
  int redledLevel = map(sensorReading, 0, 1023, 0, redledCount);
  for (int thisredLed = 0; thisredLed < redledCount; thisredLed++) {
    if (thisredLed < redledLevel) {
      digitalWrite(redledPins[thisredLed], LOW);
    }
    else {
      digitalWrite(redledPins[thisredLed], HIGH);
    }
  }
  int grnledLevel = map(sensorReading, 0, 1023, 0, grnledCount);
  for (int thisgrnLed = 0; thisgrnLed < grnledCount; thisgrnLed++) {
    if (thisgrnLed < grnledLevel) {
      digitalWrite(grnledPins[thisgrnLed], LOW);
    }
    else {
      digitalWrite(grnledPins[thisgrnLed], HIGH);
    }
  }
}

Thanks in advance!
Logged


Fort Lauderdale, FL
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6144
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.c

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12630
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Dubai, UAE
Offline Offline
Edison Member
*
Karma: 22
Posts: 1675
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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 -



it even has a link to the circuit.

Duane.

rcarduino.blogspot.com
Logged


Leicester, MA USA
Offline Offline
Jr. Member
**
Karma: 1
Posts: 88
Arduino newbie
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

So I'll use digital input then.


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 -



it even has a link to the circuit.

Duane.

rcarduino.blogspot.com

Neat idea but it needs to turn LED's off while others turn on at the same time. Thanks though.
Logged


Leicester, MA USA
Offline Offline
Jr. Member
**
Karma: 1
Posts: 88
Arduino newbie
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged


Dubai, UAE
Offline Offline
Edison Member
*
Karma: 22
Posts: 1675
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Sorry to do this, but going back to the LM3916, it supports dot mode, which would give you want ;-)

Other than that, one very simple idea is to use a photo transistor and just use light as the interface - probably safer as well.

EDIT - Link -



Duane B
Logged


Leicester, MA USA
Offline Offline
Jr. Member
**
Karma: 1
Posts: 88
Arduino newbie
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't have any LM3916's available and I don't plan on ordering them. I appreciate your suggestions but I'm trying to do with with the Arduino.
Logged


Fort Lauderdale, FL
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6144
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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)
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.c

Leicester, MA USA
Offline Offline
Jr. Member
**
Karma: 1
Posts: 88
Arduino newbie
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged


Fort Lauderdale, FL
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6144
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.c

Leicester, MA USA
Offline Offline
Jr. Member
**
Karma: 1
Posts: 88
Arduino newbie
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged


Fort Lauderdale, FL
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6144
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Post the code you use.

What does your multimeter say?
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.c

Leicester, MA USA
Offline Offline
Jr. Member
**
Karma: 1
Posts: 88
Arduino newbie
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Post the code you use.

What does your multimeter say?

Here's what I've currently got:

Code:
const int sensePin = 13;
const int ledCount = 6;
const int redledPins[] = {
  1, 2, 3, 4, 5, 6 };
const int grnledPins[] = {
  7, 8, 9, 10, 11, 12 };

void setup() {
  Serial.begin(9600);
  pinMode(sensePin, INPUT);
  for (int thisLed = 0; thisLed < ledCount; thisLed++) {
    pinMode(redledPins[thisLed], OUTPUT);
    pinMode(grnledPins[thisLed], OUTPUT);
  }
}

void loop() {
  int sensorReading = digitalRead(sensePin);
  int ledLevel = map(sensorReading, 0, 1023, 0, ledCount);
  for (int thisLed = 0; thisLed < ledCount; thisLed++) {
    if (thisLed < ledLevel) {
      digitalWrite(redledPins[thisLed], LOW);
      digitalWrite(grnledPins[thisLed], LOW);
    }
    else {
      digitalWrite(redledPins[thisLed], HIGH);
      digitalWrite(grnledPins[thisLed], HIGH);
    }
  }
}

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.
Logged


Fort Lauderdale, FL
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6144
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Why would you bother map() on a digitalRead()?  It's only values or HIGH (1) or LOW (0).
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.c

Pages: [1] 2   Go Up
Jump to: