Pages: [1]   Go Down
Author Topic: guidance please for selecting machine state based on 2 inputs  (Read 457 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

I am doing a fairly simple project to control the headlights on my motorcycle based on 2 inputs: the high/low beam switch and a phototransistor to detect whether it is day or night. The input combinations lead to 4 possible output states, each state having different parameters for the PWM on each of 2 mosfets which switch the headlight.

The phototransistor needs a low pass filter such that it won't cause state switching at night from passing under a streetlight for example. I plan to install a capacitor such that the photocell has about a 0.1s time constant, and may also require some sort of filtering over about 1 second or more in software.

I want to be able to arbitrarily set the light level that the output state switches at, so the phototransistor needs to be read by an ADC.

I want the output state to change as fast as possible with a change in the high/low switch state, so I presume an interrupt is appropriate there.

3 of the output states are easy, consisting of some constant duty cycle set to the pwm, meaning the program can do this then quickly move on polling and filtering inputs. Unfortunately, the 4th state needs to vary the duty cycle from high (~90%) to low (~50%) at 4.66 hz. Of course this can be done with a loop and delay, but then the program is busy doing that instead of polling and filtering the photocell.

I can probably hack something together, but don't quite know enough about Arduino to do this in a decent manner. Can anybody give me some advice on the best fashion to:
1)frequently poll and filter the phototransistor?
2)alter the pwm setting at 4.66 hz in state 4?
3)a clean, fast method of selecting the output state based on 2 inputs? Something like two input bit variables, then output = 10*bit1+bit2?

Thanks!
Logged

Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 197
Posts: 12740
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I want the output state to change as fast as possible with a change in the high/low switch state, so I presume an interrupt is appropriate there.

No, interrupts are not appropriate.  You're talking about a processor that is capable of executing approximately 16 million instructions per second.  Unless there is a bug in your code, from your perspective, switching the high/low state will be instantaneous.  Using interrupts always adds a great deal of complexity and, for the task you've described, provides absolutely no benefit.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Unfortunately, the 4th state needs to vary the duty cycle from high (~90%) to low (~50%) at 4.66 hz.
Why?
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 211
Posts: 13477
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This is your application in a nutshell, it is not tested

Code:
// two constants to use for LDR reading
#define NIGHT 0
#define DAY 1
#define SWITCHPIN 8   // connects to the high/low beam switch
#define LDRPIN 0
#define THRESHOLD 500
#define LAMPPIN 9      // PWM

void setup()
{
   Serial.begin(115200);
}

void loop()
{
  L = readLDR(); // separate function;
  S = digitalRead(SWITCHPIN);

  // print the values for debugging purpose
  Serial.print("S: "); Serial.println(S);
  Serial.print("L: ");   Serial.println(L);

  if ((L == NIGHT) && (S==HIGH)) setLight(100);
  if ((L == NIGHT) && (S==LOW)) setLight(60);
  if ((L == DAY) && (S==HIGH)) setLight(50);
  if ((L == DAY) && (S==LOW)) setLight(25);
}

int readLDR()
{
  // really needs to be improved :)
  if (analogRead(LDRPIN) < THRESHOLD) return NIGHT;
  return DAY;
}

void setLight(int intensity)
{
  analogWrite(LAMPPIN, intensity);
}
 
 
 
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Pages: [1]   Go Up
Jump to: