Flip/flop to switch between two states?

Hello all!

I am trying to tackle a rather simple problem that could be done with the flip-flop. Indeed, if you think better way to approach this, do not hesitate to say!

It works to some extent... However, here the basic idea:

start with the q1 = 0, q 2 = 0 and ALS = 0
once light 1 on
Q1 = 1 and ALS = 1

accordingly
Q2 = 1
(after some time, have a look the timer) Q1 = 0
ALS = 1

wait till you get another proximity,
once proximity up,
light 2 off
Q2 = 0
ALS = 0
go back to the start !

code attached.

Please me know, what I am doing wrong :slightly_frowning_face:

Any input much appreciated.

Best.

main loop

wave();

    setLedState();

    ledAction();

    if (Sensor.getAmbient() > ALS_HT) {
      ALS = 1;
    }
    else if (Sensor.getAmbient() < ALS_HT) {
      ALS = 0;
    }

    if (myLedState == ledOn && ALS) {

      //startcounting to turn off the ledOn
      if (currentTime - startTime1 < 3000) {
        Serial.println(currentTime - startTime1);
      }
      else {
        startTime1 = currentTime;
//        if (ALS) {
//          myLedState2 = ledOn2;
//        };
        myLedState = ledOff;
      }

      myLedState2 = ledOn2;
      myLedState = ledOff;

    }
void wave() {

  OS = Sensor.getProximity();

  //above/below
  switch (currentState) {
    case WAITING_ABOVE:
      if (OS > HT) {
        belowHT = 0;
        belowHT += currentTime - startTime;
        startTime = currentTime;
        //in fading toggle fadeUp
        //          if (myLedState == ledFading) {
        //            fadeUp = !fadeUp;
        //          }
        currentState = WAITING_BELOW;
      }
      break;
    case WAITING_BELOW:
      if (OS < HT) {
        aboveHT = 0;
        aboveHT += currentTime - startTime;
        startTime = currentTime;
        currentState = WAITING_ABOVE;
        //ALS = getALS();
      }
      break;
  }
}
void setLedState() {

  if ( (aboveHT > 1 && aboveHT < 350) && belowHT > 500 ) {
    
    // if ledOn, turn
    // ledOff 1
    if ( myLedState == ledOn or myLedState == ledFading ) {
      myLedState = ledOff;
    }

    if ( myLedState2 == ledOn2 or myLedState2 == ledFading2 ) {
      myLedState2 = ledOff2;
    }

    //led on
    else if (myLedState == ledOff) {
      myLedState = ledOn;
    }

    //led on
    else if (myLedState2 == ledOff2) {
      myLedState2 = ledOn2;
    }

    aboveHT = 0;
    belowHT = 0;

  }

}
void ledAction() {
  // turn led on// ORIGINAL
  if (myLedState == ledOn ) {
    analogWrite(ledPin, pgm_read_byte(&table[brightness]));
  }
  else if (myLedState2 == ledOn2) {
    analogWrite(ledPin, pgm_read_byte(&table[brightness]));
  }

  //turn led off
  else if (myLedState == ledOff) {
    digitalWrite(ledPin, false);
  }
  //turn led2 off
  else if (myLedState2 == ledOff2) {
    digitalWrite(ledPin, false);
  }
}

Interesting but what is "q", the output of a flip-flop. Please define the terms. Is this what you are trying to say:

  1. Start with the initial state:
  • Q1 = 0, Q2 = 0, ALS = 0
  1. Once Light 1 is on:
  • Q1 = 1, ALS = 1
  1. Then:
  • Q2 = 1
  1. After some time (check the timer):
  • Q1 = 0, ALS = 1
  1. Wait until another proximity event is detected.
  2. When proximity is triggered:
  • Light 2 turns off
  • Q2 = 0

Thank you and yes, you are correct, Q is the output of the flip-flop ...

The idea is when I wave with a hand (detected by the wave() ) the time is found (see wave for more) and accordingly the setLedState() identifies that, so, it turn as the q1 on/off, here the timer starts and while running it looks at the ALS then accordingly the led2, namely Q2 is on and waits for another hand wave, which turns the LED2 off .

I have made some progress, attaching the "improved" methods - hope it helps...
Eitherway, I am missing the structure of the flip-flop idea, hard to handle the code without a structure... this is why two myLedState s are used, namely myLedState and myLedState2, Q1 and Q2 respectfully.

//get ALS
bool getALS_1() {
  if (Sensor.getAmbient() > ALS_HT) {
    ALS = 1;
  }
  else if (Sensor.getAmbient() < ALS_HT) {
    ALS = 0;
  }
  return ALS;
}
loop()

 if (true) {

    wave();

    setLedState();

    ledAction();


    if (myLedState2 == ledOff) {
      ALS = getALS_1();
      //Serial.println(ALS);
    }

    if (myLedState == ledOn) {

      Serial.println(currentTime - startTime1);
      
      if(myLedState2 == ledOff){
        ALS = getALS_1();
      }


      //start counting
      if (currentTime - startTime1 > 1000 ) {

        myLedState = ledOff;

      }

    }
    else startTime1 = currentTime;
setLedState()

if ( (aboveHT > 1 && aboveHT < 350) && belowHT > 500 ) {
    // if ledOn, turn
    // ledOff 1
    if ( myLedState == ledOn ) {  //or myLedState == ledFading
      myLedState = ledOff;
    }

    //led on
    else if (myLedState == ledOff) {
      myLedState = ledOn;
    }


    if (myLedState2 == ledOn2 && getALS_1() ) {  //or myLedState2 == ledFading2
      myLedState = ledOff;
      myLedState2 = ledOff2;
      ALS = getALS_1();
      Serial.println(ALS);
    }

    //led on
    else if (myLedState2 == ledOff2) {
      myLedState2 = ledOn2;
    }

    // reset the wave's values! 
    aboveHT = 0;
    belowHT = 0;

  }
} // end of method
ledAction()

  // turn led on// ORIGINAL
  if (myLedState == ledOn ) {
    analogWrite(ledPin, pgm_read_byte(&table[brightness]));
  }
  else if (myLedState2 == ledOn2) {
    analogWrite(ledPin, pgm_read_byte(&table[brightness]));
  }

  //turn led off
  else if (myLedState == ledOff) {
    digitalWrite(ledPin, false);
  }
  //turn led off
  else if (myLedState2 == ledOff2) {
    digitalWrite(ledPin, false);
  }
}

Sorry but could you descript "as a story" what you are trying to do? I think you are saying something like (but please correct where wrong):

You have two LEDs, when you wave your hand, if the two LEDs are off, you want the first one to come on. After 30 seconds (just as a time interval) you want the second LED to come on and the first to go off. After another 30 seconds you want the second LED to go off. If you wave your hand while either LED is on, you want both to go off.

Something like that? Thanks.

Not a prob.

the idea is to turn on the first led, with the wave, setlestate, led action, and then read the als value and according to this value turn on the led2 meanwhile the led1 turns off.
Now that the led2 is on, it waits for another wave to turn it off...

Hope this helps.

Best.

[Sorry but] if I understand, if both LEDs are off, a wave turns on first LED, another wave turns off first LED and turns on second LED, a third wave turns off second LED (resetting all).

I would use a "state machine" style for this. Something like this mock code should work fine:

bool stateLED1 = false;
bool stateLED2 = false;
bool wave = false;

loop( )
{
  wave = funcGetWaveState( );

  // if both LEDs off, turn on first...
  if wave && !stateLED1) && !stateLED2
    {
    stateLED1 = true;
    funcTurnOnLED1( );
    delay( 2000 ); // pause 2 seconds so as to not accidentally multi-read same wave...
    }
  // if first LED on turn it off and second LED on...
  else if wave && stateLED1 && !stateLED2
    {
    stateLED1 = false;
    funcTurnOffLED1( );
    stateLED2 = true;
    funcTurnOnLED2( );
    delay( 2000 );
    }
  // if second LED on turn it off...
  else if wave && stateLED2
    {
    stateLED2 - false;
    funcTurnOffLED2( );
    delay( 2000 );
    }
  else // anything else make sure all off...
    {
    stateLED1 = false;
    funcTurnOffLED1( );
    stateLED2 = false;
    funcTurnOffLED2( );
    }
}

Can combine the LED on/off functions into one each that turns on or off that LED based on the passed in LED state flag. Other "optimizations" possible. Good luck!

can you simply explain "what" you are trying to doing rather than "how" you think you need to accomplish it?

for example, toggle an LED on/off whenever i wave my hand

i'm confused by your symbols (ALS ??) and what events are occurring

@mu234 - if you really want a JK flip flop, or any type, you can code it directly.

See

where she wants to emulate a bunch of them for counting, and starts with a function that implements all the logic.

I found other sites as well googling

flip-flop coded in C++

and similar.

a7

Dear @mu234

what you want to do will become much easier to understand if your description follows these rules

in one line of text either a condition
or
an action

example:
condition: if waving a hand is detected by the PIR-sensor
action: switch on LED1

condition: if 30 seconds of time have passed by since LED1 was switched on
actions: switch off LED1 and switch on LED2

condition: if 30 seconds have passed by since LED2 was switched on
action: switch off LED2

conditions:

  • if LED1 or LED2 is switched on
  • or
  • if LED2 or LED2 is switched on
    AND
  • if waving hand is detcted by the PIR-sensor
  • switch LED1 off and switch LED2 off

making it very short with keywords and keeping a constant structure of
condtion:
action:
makes it much easier to understand

if this is a correct description most of the things is a sequence which can be programmed using a technique called state-machine.

state_0:

  • led1 switched off led 2 switched of
  • checking if a hand-waving is detected by the PIR-sensor
    if hand-waving is detected change to state_1

state_1: switch LED1 on store timestamp change to state_3

state_3 check if 30 seconds have passed by
if 30 seconds have passed by change to state_4

state_4: switch off LED1 switch on LED2 store timestamp change to state_5

state_5: check if 30 seconds of time have passed by
if 30 seconds really have passed by switch off LED2 change to state_0

independant of the state_s
if actual state is not state_0 and hand-waving is detected by the PIR-sensor
switch off LED1 switch off LED 2 change to state_0

Thanks for the input, indeed, I am already using the switch and state for measuring the time when using the wave(), anyway, I will need to study what you are saying.

Meanwhile, I have made more progress and it is generally working, however, I am not sure how to integrate the reading of the ALS. Maybe its another state machine...

For example, at the begining of loop() somehow the ALS should be read, and that would tell,
wether the light should be turned manually on, it it will be turned automatically.
Indeed, if it is manually then it automatically turns off, and vice versa, more in the attached code.

Any idea about how to tackle the reading of the ALS would be much appreciated.
Wondering, if toggle would help...

Best.

void loop() { 
  currentTime = millis();

  //automatics on due to the ALS, manual off with the wave()
  if (ALS) {
    myLedState2 = ledOn2;
    //wait for manual off
    wave();
    setLedState();
    ledAction();
  }
  //manual on with wave(), automatic off due to time e.g. 100ms
  else {
    wave();
    setLedState();
    ledAction();

    // keep the led1 on for 1000ms, afterward turn it off
    if (myLedState == ledOn) {
 
      //Serial.print(currentTime - startTime1);
      //start counting to turn off the led1
      // ALS ?

      if (currentTime - startTime1 > 100 ) {
        myLedState = ledOff;
        ALS = 1;
      }
    }
    else startTime1 = currentTime;
  }
} // end of the main loop

Isn't that what getALS_1() is for?

a7

True! However, I am not sure how to use it yet :slight_smile:

So far I have tried to use it at the start, namely

if (getALS_1()) {
    ALS = true;
  }

But, it does not yet fit into the logic... its to fast ...

Best.

First of all:
if I write bolded in capital letters it is not meant as shouting.
The meaning is: emphasizing that this detail is really important.
And to make sure that you will not overread it it is written in bolded in CAPITAL red LETTERS

From your answer I can conclude that you have no idea yet what a state-machine is.

additionally: you should

ALWAYS

post your

COMPLETE SKETCH.

Really I beg you do it !

Trying to be quick by posting code-snippets slows down finding the solution for the following reasons:

  • annyoing your helpers that your helpers have to scroll through the thread trying to find a complete version of your code
  • this can cause helpers turning away from your thread helping other users that follow this rule
  • making assumptions about the rest of your code where these assumptions could be wrong causing even more postings to clarify things

So as the next step post your complete and actual sketch.

not sure this is what you want

getAmbient() returns a boolean. (needed hysterisis because i used a pot)

loop() recognizes a state change and when als becomes true it toggles (i.e. flip-flop) ledState

enum { Off = HIGH, On = LOW };

const byte PinLeds [] = { 12, 11 };
      byte ledState   = Off;

char s [90];

// -----------------------------------------------------------------------------
bool alsState;

void loop()
{
    byte als = getAmbient ();
    if (alsState != als)  {             // state change
        alsState  = als;

        if (alsState)  {                // turning on
            if (Off == ledState)        // toggle ledState
                ledState = On;
            else
                ledState = Off;
            digitalWrite (PinLeds [0], ledState);
        }
    }
}

// -----------------------------------------------------------------------------
const int ALS_HT = 100;
bool
getAmbient ()
{
    static bool st;

    int val =  analogRead (A0);
    if (st)  {
        if (val < ALS_HT - 2)       // hysterisis
            st = false;
    }
    else  {
        if (val > ALS_HT + 2)
            st = true;
    }

    digitalWrite (PinLeds [1], st ? On : Off);

    return st;
}

// -----------------------------------------------------------------------------
void
setup ()
{
    Serial.begin (9600);
    for (unsigned n = 0; n < sizeof(PinLeds); n++)  {
        pinMode (PinLeds [n], ledState);
        digitalWrite (PinLeds [n], Off);
    }

    alsState = getAmbient ();
}
1 Like

Hello all!
1st, thank for the input, it really helps, I have made more progress, for example, I am only turning on one led, not two, however, still does not work, stuck, see bellow for more!

With regard to the ALS reading, in the setup, the ALS threshold is created, so when more light is in the room it can be read, works. However, what @gcjr posted will have to be studied, looks very useful! Thank you, the idea about the toggle is perfect, need to implement it into my setup, I am reading the ALS from the sensor via the i2c, namely wire in Arduino... so it is just a library call Sensor.getAmbient(), which gives me a number, so, this number is compared to the threshold... so no worries about readings of the pins, I guess I got you right here... love the hysteresis idea...

With regard to the proximity, within the wave() the debounce is tackled with timing switch, gate, works just fine. For example if the timings are ok, the ledState is defined, eventually it only used for the led on or off, if you wave it turns on, if off, and vice versa. The toggle could be implemented here as well, namely within the ledState...

The main idea is to turn on/off the light. The concept is as follows, if light is off, wave with the hand, turn it on for some time, the als should get that, however, the light turns off and get away, and because the als got the information that the light was on, it now automatically turns on the light and waits for the manual wave to turn the light off. In short, manual on->automatic off, automatic on->manual off...

I have introduced the "doors", enum to keep the switching more explicit, I guess. Trying to help myself, maybe is not necessary...

@StefanL38 Stefan sorry to posting only snippets. However, only for you, I am posting the state machine that I have in the setup:

//master enumeration
enum {
  ledOff,
  ledOn,
  ledFading,
  ALS_1
} myLedState;

// *** new state machine project FOR proximity ***
enum : byte {WAITING_ABOVE, WAITING_BELOW} currentState;
unsigned long aboveHT;
unsigned long belowHT;

 // *** using state machine for measuring time of sensor Proximity level ***
  if (Sensor.getProximity() > HT) {
    currentState = WAITING_BELOW;
  }
  else {
    currentState = WAITING_ABOVE;
  }
  // *** end of using state machine for measuring time of sensor level ***


The problem is that the whole code is prepared for the "demo design" that I am working on, and it is cluttered allover the place, so, this is why only snippets... I hope that once it works, the whole sketch will be much shorter, ready for posting, etc, sorry I am rather new to this...

Attaching the full loop() code,

void loop() {

  currentTime = millis();

  OS = Sensor.getProximity();
  ALS = Sensor.getAmbient();

 
  if (doors == open) {
    Serial.print("> open ");
  }
  else if (doors == close) {
    Serial.print("< close ");
  }

  //automatic on due to the ALS, manual off with the wave()
  // doors are close, 
  if ((ALS > ALS_HT) and doors == close and myLedState == ledOff) {
    //tuen the led on!
    myLedState = ledOn;
    //wait for manual off

**HERE I AM NOT SURE HOW TO KEEP THIS IN A LOOP TILL THE LED IS TURNED OFF, **
**WITH THE CODE BELOW** 



    wave();
    setLedState();
    ledAction();


FOR EXAMPLE, IT SHOULD STAY HERE UNTIL IT IS INTERRUPTED WITH CHANGING THE STATE EG. TO LED OFF


  }
  // if it is not automatic on, it is manual
  // in this case the ALS < ALS_HT
  //manual on with wave(), automatic off due to time  // if (ALS < ALS_HT && doors == close)
  else if(doors == open) {

    wave(); //gives me the above and below HT timings
    setLedState(); // timings are used to defined the wave
    ledAction(); // the led is turned on/off

    // keep the led on some time, afterwards turn it off
    if (myLedState == ledOn) {
      Serial.print(currentTime - startTime1);
      Serial.print(" ");
      
      //start counting to turn off the led
      if (currentTime - startTime1 > 2000 ) {
         // turn off the led 
        myLedState = ledOff;
        //doors are closed for manual 
        doors = close;

      }
    }
    else startTime1 = currentTime;
  }
  // we are done with this, move to the automatic, 
  //now the als should be "on" alow this, 
  //and doors are closed for manual, or the led is off 
}

Currently, this works to some extent, however, I am confused with the fact that I am reading myLedState = ledOff via Serial.print, while the led actually is on :slight_smile:

Anyway, the above code should work as follows in respectful order of operation:

when manual, the ALS<ALS_HT hence the manual to turn on.
wave(), SetLedState(), LedAction() are used,
once the ledOn, the ALS should be stored, ideally as @gcjr suggests toggle
afterwards it should turn off after some time
it should stay , wait in a loop turned off.

However, the automatic on should take care of keeping the light on, due to the ALS,
so, the ledOn is running in a loop, waiting for the manual to occur again to if the with is to turned it off - the so called manual off, and that is it!

Best.

as long as you post code-snippets nobody will be able to help you efficiently.

It might be that you have hundreds of lines of code that are just commented out or do non-relevant things. All more or less experienced code-writers will be able to skip over these parts of your code to find the relevant parts.

As long as you only post code-snippets there will be always the suspect that something weird is happening in the lines of code that you haven't posted.

As long as you only post code-snippets there will be always the suspect that there might be a single line of code with a very easy to overlook bug just beeing a single semicolon
that changes the behaviour of your code dramatically.

The less you know about coding the more important it is to post your complete sketch.

If you don't know yet why a single semicolon can change the baviour of your code dramatically that indicates that you really should post your complete sketch.

Your "state-machine" - Yes in some way - somehow - you could call it a state-machine.
Though all it is is a single if-else-condition.

A real state-machine uses a switch-case-break-statement with at least three cases not only two.

A real state-machine minimizes the number of flag variables and if-conditions,

because the switch-case-break-statement achieves the goal that only that parts of code get executed that are relevant in the related situation.

Here is one of many many tutorials explaining what a state-machine is

1 Like

I have managed to put this code into one chunk of code, have a look!

#include <Wire.h>
#include "SparkFun_VCNL4040_Arduino_Library.h"

//sensor
VCNL4040 Sensor;

//timer new
unsigned long currentTime;
unsigned long startTime;  //time for entering the fading
unsigned long startTime1; //time for prolonging the fade

const byte ledPin = 7;    // main LED OUT!

//SENSOR THRESHOLDS
uint16_t OS; // offSet // proximity
uint16_t ALS; // offSet // ambient light

uint16_t HT; // high threshold
uint16_t ALS_HT;

//ALS bool
bool ALS_bool;


//myLedState 
enum {
  ledOff,
  ledOn,
  ledFading,
  ALS_1
} myLedState;

// manual / doors
// the idea of the doors is to control the manual vs auto of turning on/ off the led, 
// it may be better to call this mode: manual, automatic ?
enum {
  open,
  close
} doors;

//PWM
byte brightness;

// *** new state machine project FOR proximity ***
enum : byte {WAITING_ABOVE, WAITING_BELOW} currentState;
unsigned long aboveHT;
unsigned long belowHT;

// *** new state machine project FOR ambient light ***
enum : byte {WAITING_ABOVE_ALS, WAITING_BELOW_ALS} currentState_ALS;
unsigned long aboveHT_ALS;
unsigned long belowHT_ALS;



void setup() {
  Wire.begin(); //Join i2c bus
  Wire.setClock(100000); //Run the I2C bus at fat 400kHz

  Serial.swap(1);// alternative pins (PA2 = pin 18, PA1 = pin 17 )
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  //start the sensors setup, works well!
  //start the sensors setup
  startVCNL4040();
  delay(20);
  setT();  //VCNL4040 set threshold
  delay(20);
  //get ambient level to be aware about the ALS conditions
  setALS();
  //ALS_HT = 50;
  delay(20);

    // *** using state machine for measuring time of sensor Proximity level ***
  if (Sensor.getProximity() > HT) {
    currentState = WAITING_BELOW;
  }
  else {
    currentState = WAITING_ABOVE;
  }
  // *** end of using state machine for measuring time of sensor level ***

  // *** using state machine for measuring time of sensor Ambient Light level ***
  if (Sensor.getAmbient() > ALS_HT) {
    currentState_ALS = WAITING_BELOW_ALS;
  }
  else {
    currentState_ALS = WAITING_ABOVE_ALS;
  }
  // *** end of using state machine for measuring time of sensor level ***

  //start time
  startTime = millis();
  // brightness max
  brightness = 255;
  // start with light off, manual on!
  if (Sensor.getAmbient() < ALS_HT) {
    doors = open;  // if you want to turn on the light manually
  }

}

void loop() {

  currentTime = millis();

  OS = Sensor.getProximity();
  ALS = Sensor.getAmbient();

  Serial.println(doors);
  //  Serial.println(ALS);

  // ******* manual on, automatic off
  // here the led is off and we can turn in On manually
  // it turns off in a time automatically, 
  // the case is that during that time when the led is on, the als sensor notes that,
  // and consequently during that time the automatic on, turns the led on.
  if (doors == open) {
    Serial.println("ready for manual");

    // waiting for manual
    wave();
    setLedState();
    ledAction();

    // if manual happens
    // automatic off, start counting
    if (myLedState == ledOn) {

      Serial.print(currentTime - startTime1);
      Serial.print(" ");
      //here the led is on,
      // pick up the als !?
      if (Sensor.getAmbient() > ALS_HT) {
        ALS_bool = true;
        // ready for the manual off...
        
      }

      //start counting to turn off the led1
      if (currentTime - startTime1 > 2000 ) {
        // turn off the led
        myLedState = ledOff;
      }
    }
    else startTime1 = currentTime;

    //    if (myLedState == ledOn) {
    //      doors = close;
    //    }

  }

  // ****** automatic on, manual off
  // here the led should be on according to the als, 
  // however, it should ber possible to turn the led of manually, 
  

  // ALS is true, 
  if (ALS && Sensor.getAmbient() > ALS_HT && doors == close) {
    
    
    Serial.print("waiting for manual off");
    // open the doors
    doors = open;
    
    //automatic manual off
    // waiting for manual
    wave();
    setLedState();
    ledAction();

    if (myLedState == ledOff) {
      doors = close;
    }
  }


  // automatic on, manual off
  // ALS is true, 
  if (ALS && Sensor.getAmbient() > ALS_HT && doors == close) {
    
    
    Serial.print("waiting for manual off");
    // open the doors
    doors = open;
    
    //automatic manual off
    // waiting for manual
    wave();
    setLedState();
    ledAction();

    if (myLedState == ledOff) {
      doors = close;
    }
  }
}

void wave() {

  //OS = Sensor.getProximity();

  //above/below
  switch (currentState) {
    case WAITING_ABOVE:
      if (OS > HT) {
        belowHT = 0;
        belowHT += currentTime - startTime;
        startTime = currentTime;
        currentState = WAITING_BELOW;
      }
      break;
    case WAITING_BELOW:
      if (OS < HT) {
        aboveHT = 0;
        aboveHT += currentTime - startTime;
        startTime = currentTime;
        currentState = WAITING_ABOVE;
        //ALS = getALS();
      }
      break;
  }
}


void setLedState() {
  //myLedState1 - uporabim za vklop
  if ( ((aboveHT > 1 && aboveHT < 350) && belowHT > 500 ) ) {
    if (myLedState == ledOff) {
      myLedState = ledOn; 
      //doors = open;  
    }
    else if (myLedState == ledOn) {
      myLedState = ledOff;
      //doors = close;
    } 
    aboveHT = 0;
    belowHT = 0;
  }
} 


void ledAction() {
  // turn led on// ORIGINAL
  if (myLedState == ledOn ) {
    analogWrite(ledPin, brightness);
  }
  //turn led off
  else if (myLedState == ledOff) {   
    digitalWrite(ledPin, false);
  }
}

// set the OS threshold
void setT() {

  static uint16_t offSet;
  offSet = Sensor.getProximity();
  delay(20);
  
  HT = ( offSet + 3);
  
  delay(20);
}

// set the ALS threshold
void setALS() {

//store the level of ALS to be aware of the light in the ambient!
static uint16_t ALS_offSet;

  ALS_offSet = Sensor.getAmbient();

  delay(20);
  
  //HT = ( (offSet / 100) * percentage );
  ALS_HT = ( ALS_offSet + 20);
  
  delay(20);

}


void startVCNL4040() {

  Sensor.begin();
  
  delay(50); //min 50m

  Sensor.powerOnAmbient();
  Sensor.enableWhiteChannel(); //what is white channel?

  //Set the current used to drive the IR LED - 50mA to 200mA is allowed.
  Sensor.setLEDCurrent(200); 
  delay(40);
  
  //set IR LED duty cycle: 40, 80, 160, 320
  Sensor.setIRDutyCycle(320);
  delay(40);
                                                
  //Prox resolution: 12bit or 16bit output 
  // 12bit: 4096 steps
  // 16bit: 65 535 steps
  Sensor.setProxResolution(16);
  delay(40);
  
  //The sensor will average readings together by default 8 times.
  //Reduce this to one so we can take readings as fast as possible
  Sensor.setProxIntegrationTime(1); //1 to 8 is valid and 8 is max!
  delay(40);
  
  //ALS setup
  //Set the integration time for the ambient light sensor in milliseconds
  //80 to 640ms is valid
  
  Sensor.setAmbientIntegrationTime(80);
  delay(40);
  
  //Turn on the ambient sensor
  Sensor.powerOnAmbient(); 
  delay(40);
  
  //Turn on the prox sensor
  Sensor.powerOnProximity();
  delay(40);
}

I've leafed through this thread a bit and find your descriptions invariably muddy and confusing (possibly confused, although maybe it's more clear to you than to the rest of us, although I'm hesitant to believe so).

What you're working with essentially is a finite state machine. To model it, make a diagram (some variant to a flow chart will work) that describes each state and each transition. For each state, describe what the machine (the controller & peripherals) are doing at that point. For each transition, describe which event(s) will make the machine go from one state to another (of course specify which state it is).

Once you've got that diagram, it will be a lot easier to code it efficiently and with less risk of unanticipated behavior.

The code you posted above indicates that to an extent, you've figured out the concept of a finite state machine (as evidenced by the enums and e.g. the switch-case bit in the wave() function), but a quick reading of it also tells me that you're not following through on it yet. There's a lot of procedural, conditional programming that is likely to make your system end up in an unanticipated state.

Sorry to be critical, I hope it helps in any way.

PS: forget about the flip-flops. Save them for summer.

2 Likes

And that by itself can introduce/obscure problems.

1 Like