Jump button integration to next parameter

Good afternoon, please help me, I'm new to this.
I have a small problem: I can't integrate a button that will be used to toggle options:

int engineGroups[NENGINEGROUPS] = { 2, 3, 20, 31, 118, 115, 15 };
int dashboardGroups[NDASHBOARDGROUPS] = { 2 };

Currently the options update automatically every 5 seconds, I would like to be able to integrate a button to update them myself.

The complete code is provided below. It's not mine, but I want to use it for my project.

#include "KWP.h"
#include "FISLib.h"

#define MAX_CONNECT_RETRIES 5
#define NENGINEGROUPS 7
#define NDASHBOARDGROUPS 1
#define NMODULES 2

// KWP
#define pinKLineRX 2
#define pinKLineTX 3
KWP kwp(pinKLineRX, pinKLineTX);

//FIS
#define pinENABLE 4
#define pinCLOCK 5
#define pinDATA 6
FISLib LCD(pinENABLE, pinCLOCK, pinDATA);

int engineGroups[NENGINEGROUPS] = { 2, 3, 20, 31, 118, 115, 15 };
int dashboardGroups[NDASHBOARDGROUPS] = { 2 };

// Note: Each unit can have his own baudrate.
// If 10400 not works whit your unit try whit other, posible values are:
// 115200, 57600, 38400, 31250, 28800, 19200,  14400, 10400, 9600, 4800, 2400, 1200, 600, 300

KWP_MODULE engine    = { "ECU",     ADR_Engine,    10400, engineGroups,    NENGINEGROUPS};
KWP_MODULE dashboard = { "CLUSTER", ADR_Dashboard, 10400, dashboardGroups, NDASHBOARDGROUPS};
KWP_MODULE *modules[NMODULES]={ &dashboard, &engine };

KWP_MODULE *currentModule=modules[0];
int currentGroup=0;
int currentSensor=0;
int nSensors=0;
int maxSensors=4;
int connRetries=0;

int count=0;

// Will return:
// 0 - Nothing
// 1 - Key Up pressed
// 2 - Key Down pressed
int getKeyStatusRandom(){
  int key1=random(0,2);
  int key2=random(0,2);
  if(key1 == 1 && key2 == 0) return 1;
  if(key1 == 0 && key2 == 1) return 2;
  if(key1 == 0 && key2 == 0) return 0;
  if(key1 == 1 && key2 == 1){
    if(random(0,2)==1) return 1;
    else return 2;
  }
}

// 0 - Nothing
// 1 - Up
// 2 - Down
void refreshParams(int type){
  if(type==1){
    if(currentSensor < nSensors -1) currentSensor++;
    else{
      currentSensor=0;
      if(currentGroup < (currentModule->ngroups) - 1) currentGroup++;
      else{
        if(currentModule->addr == ADR_Dashboard) currentModule=modules[1];
        else currentModule=modules[0];
        currentGroup=0;
        kwp.disconnect();
      }
    }
  }
  else if(type==2){
    if(currentSensor > 0) currentSensor--;
    else{
      currentSensor=nSensors-1;
      if(currentGroup > 0) currentGroup--;
      else{
        if(currentModule->addr == ADR_Dashboard) currentModule=modules[1];
        else currentModule=modules[0];
        currentGroup=currentModule->ngroups-1;
        kwp.disconnect();
      }
    }
  }
}

void setup(){
  Serial.begin(9600);
  for(int i=0; i<8; i++){
    LCD.showText("IS FIS","BLOCKS!");
    delay(500);
  }
  for(int i=0; i<8; i++){
    LCD.showText("HI! I AM","A GTI :)");
    delay(500);
  }
}

void loop(){
  if(!kwp.isConnected()){
    LCD.showText("Starting",currentModule->name);
    if(kwp.connect(currentModule->addr, currentModule->baudrate)){
      LCD.showText("Con. OK!","Reading");
      connRetries=0;
    }
    else{ // Antiblocking
      if(connRetries > MAX_CONNECT_RETRIES){
        if(currentModule->addr == ADR_Dashboard) currentModule=modules[1];
        else currentModule=modules[0];
        currentGroup=0;
        currentSensor=0;
        nSensors=0;
        connRetries=0;
      }
      else connRetries++;
    }

  }
  else{
    SENSOR resultBlock[maxSensors];
    nSensors=kwp.readBlock(currentModule->addr, currentModule->groups[currentGroup], maxSensors, resultBlock);
    if(resultBlock[currentSensor].value != ""){
      LCD.showText(resultBlock[currentSensor].desc, resultBlock[currentSensor].value+" "+resultBlock[currentSensor].units);
      if(count>8){
        refreshParams(1);
        count=0;
      }
      else count++;
    }
    else{
      refreshParams(1);
      count=0;
    }
  }
}

I found a similar request that was not resolved. Help please.

Welcome to the forum

What have you tried so far ?

1 Like

toggle or cycle? Like you press a button, it goes to the next option, then press it again, it goes to the next, then at the end of the options, it cycles back to the first option?

If so, that's a state machine. So what's a state machine? NesHacker on YouTube explains in examples that are culturally easy to follow (everyone has played a Nintendo game):

So in your case, to implement a state machine in the way i think you mean to, first take a look at the IDE example sketch "StateChangeDetection" File > Examples > 02. Digital > StateChangeDetection by Tom Igoe.

Then look at another example sketch "switchCase" (also by Tom Igoe) File > Examples > 05. Control > switchCase. Switch/case/default is going to replace your if/else if/else control structure.

You see how in the switchCase example, the variable (range) is driving the state of the machine? What you can do is this:

Create a variable in your global definitions called something meaningful to you, maybe

const int engineGroupsStateButton = 2; // pin D2 for button from 2 to GND
int engineGroupsState = 0; // this is a container to hold the variable to drive the state machine

Then in

void setup(){
// preferred way, use internal pullup resistor. Note button pressed will read LOW
pinMode(engineGroupsStateButton, INPUT_PULLUP);
}

Then in void loop() use the stateChangeDetection sketch as a guide to getting a value, replacing that buttonPushCounter++; with your engineGroupsState+=1;.

Then below the state change detection stuff, set up your state machine:

switch(engineGroupsState){
  case 0:
// whatever function you want to start with
  break;
  case 1:
// the next block of code you wanted to control via button press
  break;
  case 2:
// and so on until they're done
  break; // don't skip any of these break statements
  default:
// anything, or nothing, your choice
  break; // but this is still mandatory
}
// after whatever your last number ^ is, loop back to 0
if (engineGroupsState >= 6) { // one higher than you last one ^, maybe you had 5?
 engineGroupsState = 0;
}
1 Like