PCF8574 with uno

Hi all,I am trying to control 2 LED'S via i2c with a PCF8574 module and UNO with a momentary switch connected to pin 2 via PULLUP resistor.The code below works fine except i would like the led in OPTION_1() to be turned off after seven seconds without using the delay function but i just cannot get this part of my code to work.Any advice on where i'm going wrong would be much appreciated.

#include "Wire.h"
#include <EEPROM.h>
#define PCF 0x20
int Switchcounter = 0;
int address = 0;
const int SwitchPin = 2;
unsigned long previousMillis = 0;
unsigned long interval = 7000;

void setup()
{
  Wire.begin();
  pinMode (SwitchPin, INPUT);
}


void OPTION()
{
  Wire.beginTransmission(PCF);
  Wire.write(0xFF);
  Wire.endTransmission();

}


void OPTION_1()
{
  Wire.beginTransmission(PCF);
  Wire.write(0xFE);
  Wire.endTransmission();

  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    Wire.beginTransmission(PCF);
    Wire.write(0xFF);
    Wire.endTransmission();
  }
}
void OPTION_2()
{
  Wire.beginTransmission(PCF);
  Wire.write(0xFC);
  Wire.endTransmission();

}


void loop() {

  int SwitchState = digitalRead(SwitchPin);
  if (SwitchState == LOW) {
    delay(200);
    Switchcounter ++;
    EEPROM.write(address, Switchcounter);
    delay(10);
  }
  if (Switchcounter == 3) {
    Switchcounter = 0;
    EEPROM.write(address, Switchcounter);
    delay(20);
  }
  if (Switchcounter == 0 ) {
    OPTION();
  }
  else if (Switchcounter == 1 ) {
    OPTION_1();
  }
  else if (Switchcounter == 2 ) {
    OPTION_2();
  }
}

Checkout my PCF8574 lib - Arduino/libraries/PCF8574 at master · RobTillaart/Arduino · GitHub

If the counter is not updated the The LED will be ON for a long time.

You need to move the set and the reset to the main loop() and use a flag that will be set in OPTION_1

Check code below

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

#define PCF 0x20

int Switchcounter = 0;
int address = 0;

const int SwitchPin = 2;

unsigned long previousMillis = 0;
unsigned long interval = 7000;

int flag = 0;

void OPTION()
{
  Wire.beginTransmission(PCF);
  Wire.write(0xFF);
  Wire.endTransmission();
}


void OPTION_1()
{
  Wire.beginTransmission(PCF);
  Wire.write(0xFE);
  Wire.endTransmission();
  previousMillis = millis();  // start 7 second countdown.
  flag = 1;
}

void OPTION_2()
{
  Wire.beginTransmission(PCF);
  Wire.write(0xFC);
  Wire.endTransmission();
}

void setup()
{
  Wire.begin();
  pinMode (SwitchPin, INPUT);
}



void loop()
{
  int SwitchState = digitalRead(SwitchPin);
  if (SwitchState == LOW) {
    delay(200);
    Switchcounter++;
    EEPROM.write(address, Switchcounter);
    delay(10);
  }

  if (Switchcounter == 3)
  {
    Switchcounter = 0;
    EEPROM.write(address, Switchcounter);
    delay(20);
  }
  else if (Switchcounter == 0 ) {
    OPTION();
  }
  else if (Switchcounter == 1 ) {
    OPTION_1();
  }
  else if (Switchcounter == 2 ) {
    OPTION_2();
  }

  unsigned long currentMillis = millis();
  if ((flag == 1) && (currentMillis - previousMillis >= interval))
  {
    previousMillis = currentMillis;
    flag = 0;
    Wire.beginTransmission(PCF);
    Wire.write(0xFF);
    Wire.endTransmission();
  }
}

I have added some code to your code.
Observe how many times OPTION_1 debugging prints get executed.
You may want to add some identifying prints too - Serial.print( " previousMillis = "); etc and also you may want to use debug print when "if" condition is false.

Especially pay attention to initial value of previousMillis and changes , if any.

Reply / let the group know about your progress.
Good luck

#include "Wire.h"
#include <EEPROM.h>
#define PCF 0x20
int Switchcounter = 0;
int address = 0;
const int SwitchPin = 2;
unsigned long previousMillis = 0;
unsigned long interval = 7000;

void setup()
{
  Initialze Serial here
  Serial.begin(115200);
  Wire.begin();
  pinMode (SwitchPin, INPUT);
}


void OPTION()
{
  Wire.beginTransmission(PCF);
  Wire.write(0xFF);
  Wire.endTransmission();
}


void OPTION_1()
{
  Add static counter here
  static int TestCOunter;
  Wire.beginTransmission(PCF);
  Wire.write(0xFE);
  Wire.endTransmission();
  unsigned long currentMillis = millis();
  Insert debugging code here
  Serial.println(currentMillis);
  Serial.println(previousMillis);
  Serial.println(interval);
  Serial.println(TestCOunter++);
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    Wire.beginTransmission(PCF);
    Wire.write(0xFF);
    Wire.endTransmission();
    and for test purpose here too
    Serial.println(currentMillis);
    Serial.println(previousMillis);
    Serial.println(interval);
  }
}
void OPTION_2()
{
  Wire.beginTransmission(PCF);
  Wire.write(0xFC);
  Wire.endTransmission();
}


void loop() {
  int SwitchState = digitalRead(SwitchPin);
  if (SwitchState == LOW) {
    delay(200);
    Switchcounter ++;
    EEPROM.write(address, Switchcounter);
    delay(10);
  }
  if (Switchcounter == 3) {
    Switchcounter = 0;
    EEPROM.write(address, Switchcounter);
    delay(20);
  }
  if (Switchcounter == 0 ) {
    OPTION();
  }
  else if (Switchcounter == 1 ) {
    OPTION_1();
  }
  else if (Switchcounter == 2 ) {
    OPTION_2();
  }
}

Moderator edit: More code tag correction

My version :wink: Keep a static flag that you want to start (switch led on) or wait 7 seconds before switching the led off.

void OPTION_1()
{
  static bool start = true;
  unsigned long currentMillis = millis();

  if (start == true)
  {
    // swicth LED on
    Wire.beginTransmission(PCF);
    Wire.write(0xFE);
    Wire.endTransmission();
    // set previous 'time' to current 'time'
    previousMillis = currentMillis;
    // indicate that we've switched the led on
    start = false;
  }
  else
  {
    // compare current 'time' with previous 'time'
    if (currentMillis - previousMillis >= interval) {
      // switch LED off
      Wire.beginTransmission(PCF);
      Wire.write(0xFF);
      Wire.endTransmission();
      // for the next time we call this function, indicate that we must switch the led on
      start = true;
    }
  }

}

It compiles but is not tested.

Here is a verification code - works as expected.

long  previousMillis = 0;
long interval = 7000;
unsigned long currentMillis;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
}

void loop() {
  // put your main code here, to run repeatedly:
  OPTION_1();
  //for(;;);
  
}


void OPTION_1()
{
  static bool start = true;
  currentMillis = millis();
  Serial.print ("  currentMillis = ");
  Serial.println (currentMillis);
  Serial.print ("  previousMillis = ");
  Serial.println (previousMillis);
  Serial.print (" static start = ");
  Serial.println (start);
  delay(1000);
  if (start == true)
  {
    Serial.println("switch LED on");
    //    Wire.beginTransmission(PCF);
    //    Wire.write(0xFE);
    //    Wire.endTransmission();
    // set previous 'time' to current 'time'
    previousMillis = currentMillis;
    // indicate that we've switched the led on

  Serial.print ("  new previousMillis = ");
  Serial.println (previousMillis);


    
    start = false;
  }
  else
  {
    // compare current 'time' with previous 'time'
    if (currentMillis - previousMillis >= interval) {
      Serial.println("  switch LED off");
      
      //      Wire.beginTransmission(PCF);
      //      Wire.write(0xFF);
      //      Wire.endTransmission();
      // for the next time we call this function, indicate that we must switch the led on
      start = true;
    }
  }
}

Moderator edit: Code tags corrected. {sigh}

Thanks guys for your help although it a bit over my head at the moment it's a direction 2 follow and a comparison 2 make appreciate your help

nothing workin guys can someone explain why part 2 of this code is not executed

void OPTION_1()
{
  Wire.beginTransmission(PCF);
  Wire.write(0xFE);
  Wire.endTransmission();
    delay(7000);
  
    Wire.beginTransmission(PCF);
    Wire.write(0xFF);
    Wire.endTransmission();
  }

chech the return value of Wire.endTransmission();

int x = Wire.endTransmission();

Serial.println(x);

cheers rob but if i add another delay it will blink n i jus cant get me head round that

are you sugest a for loop

i'm lost but will keep on tryin

wat ever all de combinations are not workin

Rob why does the transmit,delay,transmit again not work in that function i'm really confused.

5 consecutive posts, and no comment or response to the test that was proposed in reply #7?

Why do you expect people to help you if you act like a jerk?

You have not been providing us with information that we've requested - when you're asking for help, and people trying to help you ask a question, they're doing that because they feel they need the answer to the question to help you. You still have not answered Rob's question.

You also need to learn how to post on forums in a manner that provides people the information they need to help you. This is a great thing to read, it will teach you how to ask questions on forums in a way that gets answers and doesn't piss people off - and in this day and age, that's very powerful: How To Ask Questions The Smart Way

@piddy0504 is taking some time away from the forum.

. . . And @piddy0504's response to the timeout has earned an extension to the timeout.

That kind of language and attitude will not be tolerated here.