Im new here and need help with an array

Ok so i am pretty new,(never wrote code be4 a month ago) i have my automotive automation project going now finally, data logger, keyless entry, remote start, hard cut rev limiter working together so far. Im not sure how to even describe what i want to do to someone who hasnt seen an afr data logging histogram, but basically i have 3 variables to compare. Manifold absolute pressure, ranges from 0 to 100
Rpm 0 to 6000
And air fuel ratio in lamda 0.45 to 2.
If you think of the table as a graph it would be
Rpm. Afr
Rpm. Afr
Rpm. Afr
Rpm. Afr.
++
Map map map map ++

Basically at this rpm and map pressure afr = x. Afr would be a running average in each cell. I hope i explained what im trying to accomplish well enough some1 can understand it🤦‍♂️ thanks any help or direction Would be appreciated.

Something like this?

How many columns and rows do you expect?

Are the values of the rows and columns evenly spaced?

so you have a 3D surface AFR = function(RPM, MAP)

what's the issue you are trying to solve? interpolate and guess the AFR value for a given couple (RPM; MAP) based on a number of samples (some dots on the surface)

Yes to red car. I would like map to go up in increments of 5 and rpm in increments of 200. So 30x 20. If thats what you mean by evenly spaced. Im still learning how to write code in general and havent used arrays yet. Ive done a bit of reading but couldnt phrase my question well enough to get the answers i was looking for. Ty for the reply. Could u point me towards some literature that might help me?

That would work as well but no guess work. It will be live data. I just want it plotted for easy analysis to tune my ve table

Sorry didn't see the reply button so i posted another comment as a reply to u🤦‍♂️

I’m still unclear about your exact question…

Do you have a formula for this? Or you measure the 3 values?

A 30x20 array is just defined as

int afr[30][20];

map to go up in increments of 5 and rpm in increments of 200

As your rpm and map are evenly split, for a given index you know the corresponding value

For example afr[3][5] would be for map=3x5 and rpm=5x200 (if both started at 0)

They values will be fed in via serial communication with the pcm, except afr it comes from serial communication with the wide band o2. But yes short answer is i have the values. Im just having trouble understanding how to use an array i guess. Im. Still reading but the turn these leds off with this array of pins isnt very helpful so im trying to read all i can to grasp the concept.

Also seeing as afr will ranging from .45 to 2.0 would have to be a float array wouldn't it?

can you clarify exactly what's coming from where and how the arduino is connected. What's the format of the data?

are you receive ascii data like "RPM, MAP, AFR" triplets on a line or something else ?

knowing how the data is transmitted and under which format would strongly influence the code

Im using the elmduino library to collect rpm, and map (as well as a few other values i may make a different but similar array for later)from the pcm via bluetooth serial. The afr is coming in from the aem uego x series as rs232 through a rs232 to ttl converter and into a defined sofware serial port. To an esp32 wrover B. Atm they are printing in the order i have them in a switch, but i just realized i could use a work around kinda and basically make the switch a monitor macro and not actually print data individually as it gets it but instead upon recieving the last of the 3 print all 3 at the same time. Gives me the info i want, but the array would be nice. Also all data is collecting and printing properly. Just trying to organize it to make tuning more convenient. Sorry if im a bit slow. I started from literally 0 knowledge of code or micro controllers about a month ago. It took me forever to get the nested switch in my code to work so i could start and stop logging and use other commands as well, as the logger is only part of the project.

Sorry. Post was flagged as spam for a min. If you don't mind, could you also point me towards where i can learn more about your 1st suggestion? 3d surface with 2 variables. I tried google. No luck so far, but im also working atm(rv service tech) so i haven't had a whole lot of time to look yet. Would be appreciated if you had a link though.

so if I understand well, you receive the 3 data points over two serial lines (two data point over one hardware Serial and one data point over SofwtareSerial).

is that in an answer from a query or is there just a stream of constant values? if so, how do you know how to sync the data?

probably time to post some code to understand better what you do but he code structure would be

you define gloablly

const byte maxMap = 30;
const byte maxRPM = 20;
int afr[maxMap][maxRPM];

and if you have a way to get the data you iterate over something like this

int mapIndex;  // map increments of 5. the index is [0,29] ➜ map varies [0, 145]
int rpmIndex;  // // rpm increments of 200. the index is [0,19] ➜ map varies [0, 3800]

mapIndex = readMAP() / 5;            // function to get the MAP value from the serial port
rpmIndex = readRPM() / 200;          // function to get the RMP value from the serial port
afr[mapIndex][rpmIndex] = readAFR(); // function to get the corresponding AFR from the other serial port

PS: also the ESP32 has 3 hardware serial ports may be you don't need to use SoftwareSerial

Yes im aware of the hardware serial ports, just got frustrated trying to dechipher what pins and how to use them exactly as the esp dev board pins are not in order and in general a cluster fuck to wade through😅 i plan to work that out and switch to hardware at a later date, but its only 9600 baud so no problems as of now. Yes u understand correct. Ill go copy some code. Im not sure how to post it as I've seen ppl be scolded for copy paste😂
i cant reply for 17 hours cus new member. heres the code i quickly modified to output a triplet. ill have to go back through and add a function to show the other values if i request them.

    ```
  #include "BluetoothSerial.h"

#include "ELMduino.h"
#include <SoftwareSerial.h>
#define ELM_PORT SerialBT
#define DEBUG_PORT Serial
SoftwareSerial cereal(35, 34);
SoftwareSerial wb (18, 19);
BluetoothSerial SerialBT;
ELM327 myELM327;
int set_point=6000;
bool Set=false;
bool DATA_LOGGER = false;
const int TIME_OUT = 2000;
const bool HALT_ON_FAIL = false;
typedef enum
{ ENG_RPM, SPEED, MAP, SPARK, TPS, TEMP, AFR, END}
obd_pid_states;obd_pid_states obd_state = ENG_RPM;
int commands;
float rpm = 0;
float mph = 0;
float mapp = 0;
float spark = 0;
float tps = 0;
float temp = 0;
bool button = false;

void setup()
{
pinMode (35, INPUT);
pinMode (25, INPUT_PULLUP);
pinMode (26, INPUT_PULLUP);
pinMode (27, INPUT_PULLUP);
pinMode (33, INPUT_PULLUP);
pinMode (22, OUTPUT);
cereal_overide(); ///
DEBUG_PORT.begin(115200);
Serial.println("Welcome Back");
cereal.begin(9600);
cereal.println("Welcome Back");
Serial.println("Initiating ELM327");
elm_init();
print_tasks();
}

//ALL TASKS ON TASK LIST WORK!!!(saved as DO_NOT_TOUCH)

void loop()
{
cereal_overide(); /////modified

if (DATA_LOGGER==false) 
 {
   listen_linda();
  }
    if (DATA_LOGGER==true)
   {
      data_log();
    }  
       if (button==true) 
        {
          tewZ();
        }
        }

//DYSFUNCTIONS()

void tewZ() //WORKS IN SKETCH
{
Serial.println("what rpm sir?");
for (Set==false;:wink:
{
if (!Serial.available())
{
set_point=6000;
}

if (Serial.available()>0)
  {
    set_point=Serial.parseInt();
     Serial.print("yes Sir");
      Serial.println(set_point);
       Set=true;               
        break;
   }                         
 } 

for (button==true;:wink:
{
int button_off=Serial.read();
rpm = myELM327.rpm();
if (myELM327.nb_rx_state == ELM_SUCCESS)
{
Serial.print("RPM: ");
Serial.println(rpm);
if (rpm>set_point)
{
digitalWrite(22, HIGH);
Serial.println("pop pop");
}
if(rpm<set_point)
{
digitalWrite(22, LOW);
}
}
if (button_off=='R')
{
Serial.println("Yes Sir");
Serial.println("no more pop pop");
Set=false;
break;
}
}
}

void data_log() //ON/OFF WORKS FLAWLESSLY, DEBUG MODE OFF
{
switch (obd_state)
{
obd_state=ENG_RPM;

  case ENG_RPM: 
   { 
    rpm = myELM327.rpm();
        
      if (myELM327.nb_rx_state == ELM_SUCCESS) 
       {                           
        //Serial.print("RPM: ");
         //Serial.println(rpm);
          obd_state = SPEED; 
        }   
        else if (myELM327.nb_rx_state != ELM_GETTING_MSG) 
         { 
           myELM327.printError();
            obd_state = SPEED;    
          } 
              break;                         
           }       

case SPEED:
{
mph = myELM327.mph();
if (myELM327.nb_rx_state == ELM_SUCCESS)
{
// Serial.print("MPH: ");
//Serial.println(mph);
obd_state = MAP;
}
else if (myELM327.nb_rx_state != ELM_GETTING_MSG)
{
myELM327.printError();
obd_state = MAP;

  } 
           break;
  }      

case MAP:
{
mapp = myELM327.manifoldPressure();
if (myELM327.nb_rx_state == ELM_SUCCESS)
{
// Serial.print("MAP: ");
//Serial.println(mapp);
obd_state = SPARK;
}
else if (myELM327.nb_rx_state != ELM_GETTING_MSG)
{
myELM327.printError();
obd_state = SPARK;
}
break;
}
case SPARK:
{
spark = myELM327.timingAdvance();
if (myELM327.nb_rx_state == ELM_SUCCESS)
{
//Serial.print("SPARK: ");
// Serial.println(spark);
obd_state = TPS;
}
else if (myELM327.nb_rx_state != ELM_GETTING_MSG)
{
myELM327.printError();
obd_state = TPS;
}
break;
}

case TPS:
{
tps = myELM327.throttle();
if (myELM327.nb_rx_state == ELM_SUCCESS)
{
// Serial.print("TPS: ");
// Serial.println(tps);
obd_state = TEMP;
}
else if (myELM327.nb_rx_state != ELM_GETTING_MSG)
{
myELM327.printError();
obd_state = TEMP;
}
break;
}
case TEMP:
{
float tempC = myELM327.engineCoolantTemp();
temp = (tempC*9/5)+ 32;
if (myELM327.nb_rx_state == ELM_SUCCESS)
{
//Serial.print("TEMP: ");
//Serial.println(temp);
obd_state = AFR;
}
else if (myELM327.nb_rx_state != ELM_GETTING_MSG)
{
myELM327.printError();
obd_state = AFR;
}
break;
}
case AFR:
{
if (wb.available()>0)
{
// Serial.print("AFR:");
// Serial.print(wb.parseFloat()/10);
// Serial.println("LAMBDA");
}
log_data();
obd_state=ENG_RPM;
break;
}
}
}

void listen_linda() //ALL COMMANDS WORK
{
switch(commands)
{
case 'U':
{
Serial.println("Yes Sir");
Serial.println("UNLOCKED");
analogWrite (26, 0);
delay(1000);
analogWrite(26, 255);
digitalRead(26);
break;
}
case 'L':
{
Serial.println("Yes Sir");
Serial.println("LOCKED");
analogWrite (25, 0);
delay(1000);
analogWrite (25, 255);
digitalRead(25);
break;
}
case 'P':
{
Serial.println("Yes Sir");
Serial.println("PANIC");
analogWrite (27, 0);
delay(1000);
analogWrite (27, 255);
digitalRead(27);
break;
}
case 'S':
{
Serial.println("Yes Sir");
Serial.println("Starting");
analogWrite (33, 0);
delay(8000);
analogWrite (33, 255);
digitalRead(33);
Serial.println("Running");
break;
}
case 'H': //HOLD
{
Serial.println("Yes Sir");
Serial.println("All functions paused for 2 mins");
delay(120000);
break;
}
case 'E': //END DATALOG
{
DATA_LOGGER=false;
Serial.println("Yes Sir");
Serial.println("Log Ended");
break;
}
case 'D': //DATALOG
{
wb_init();
DATA_LOGGER=true;
break;
}
case 'T': //TASK LIST
{
Serial.println("Yes Sir");
print_tasks();
break;
}
case 'B': //BUTTON
{
Serial.println("Yes Sir");
Serial.println("1TewZ");
tewZ();
break;
}
case 'R': //RELEASE BUTTON
{
Serial.println("Yes Sir");
Serial.println("No more pop pop");
button=false;
break;
}
}
}

void wb_init() //WORKS
{
wb.begin(9600);
if (wb.available()>0)
{
Serial.println("Wideband online");
}
if (!wb.available()>0)
{
Serial.println("wideband INOP");
}
}

void elm_init() //WORKS,BTSERIAL,DEBUG OFF
{
SerialBT.setPin("1234");
ELM_PORT.begin("ArduHUD", true);

if (!ELM_PORT.connect("OBDII"))
{
DEBUG_PORT.println("Couldn't connect to OBD scanner - Phase 1");
while(1);
}

if (!myELM327.begin(ELM_PORT, false, 2000))
{
Serial.println("Couldn't connect to OBD scanner - Phase 2");
while (1);
}

Serial.println("Connected to ELM327");
}

     void print_tasks()                       //WORKS

{
Serial.println("What can i do for you?");
Serial.println("'D': DATALOG");
Serial.println("'E': END DATALOG");
Serial.println("'H': HOLD");
Serial.println("'L': LOCK DOORS");
Serial.println("'U': UNLOCK DOORS");
Serial.println("'S': REMOTE START");
Serial.println("'P': PANIC");
Serial.println("'T': TASK LIST");
Serial.println("'B': BUTTON");
Serial.println("'R': RELEASE BUTTON");
}

void cereal_overide() //NEEDS TO BE TESTED
{
if (cereal.available()>0)
{
commands=cereal.read();
}
if (Serial.available()>0)
{
commands=Serial.read();
}
int dat_duh=Serial.read();
cereal.print(dat_duh);
cereal.println();
}

void log_data()
{

Serial.print("AFR:");
Serial.print(wb.parseFloat()/10);
Serial.print("RPM: ");
Serial.print(rpm);
Serial.print("MAP: ");
Serial.println(mapp);
}

type or paste code here

Jfc​:man_facepalming: i just went through the effort of figuring out how to send the ino file to find out new users can upload attachments :rofl:

void setup()
{  
  pinMode (35, INPUT); 
   pinMode (25, INPUT_PULLUP); 
    pinMode (26, INPUT_PULLUP);
     pinMode (27, INPUT_PULLUP);
      pinMode (33, INPUT_PULLUP);
       pinMode (22, OUTPUT);
DEBUG_PORT.begin(115200);
 Serial.println("Welcome Back");
    Serial.println("Initiating ELM327");
     elm_init();
      print_tasks();
}//ALL TASKS ON TASK LIST WORK!!!(saved as DO_NOT_TOUCH)
void loop()
{ 
    if (DATA_LOGGER==false) 
     {
       listen_linda();
      }
        if (DATA_LOGGER==true)
       {
          datalog();
        }  
           if (button==true) 
            {
              tewZ();
            }
            }

       void print_tasks()                       //WORKS
{
  Serial.println("What can i do for you?");
   Serial.println("'D':   DATALOG");
    Serial.println("'E':   END DATALOG");
     Serial.println("'H':   HOLD");
      Serial.println("'L':   LOCK DOORS");
       Serial.println("'U':   UNLOCK DOORS");
        Serial.println("'S':   REMOTE START");
         Serial.println("'P':   PANIC");
          Serial.println("'T':   TASK LIST");
           Serial.println("'B':   BUTTON");
            Serial.println("'R':   RELEASE BUTTON");  
}

void datalog()                                //ON/OFF WORKS FLAWLESSLY, DEBUG MODE OFF
 {   
  switch (obd_state) 
   {
    obd_state=ENG_RPM;

      case ENG_RPM: 
       { 
        rpm = myELM327.rpm();
            
          if (myELM327.nb_rx_state == ELM_SUCCESS) 
           {                
            Serial.print("RPM: ");
             Serial.println(rpm);
              obd_state = SPEED; 
            } 
case AFR:
  {
   if (wb.available()>0)
  {
     Serial.print("AFR:");
       Serial.print(wb.parseFloat()/10); 
         Serial.println("LAMBDA");
   }
             obd_state=ENG_RPM;
               break;  
       }
   }   
}

////// theres several more but to save space this is what each does. cycling through printing values until i send a stop command. then it returns to my original switchcase of commands listen linda() aka (task list)

(read How to get the best out of this forum if you don't want to get scolded :innocent: )

+1 and congrats for finding the code tags :slight_smile:
-1 for not indenting the code :woozy_face:

unfortunately I can't do much with that, it's just a snippet

is it right to say that at some point in time you get through serial ports a triplet (MAP, RPM, AFR) that are related and the process repeats and you get tons (600?) of those and you want to save that information.

could you show us what a dump of what the 50 first triplets look like?

Still learnin😂 and i can post a full copy was just saving space. Idk what u mean by triplet tbh. Rn it just prints each value as it reads it. Im actually changing it now though to instead print all 3 at once if that's what you mean? I know exactly nothing about micro controllers or code of any kind shape or form except what ive learned in the last month so this is all still very new to me. I work with my hands. Im good at building, fixing, creating things. Micro controllers just became a necessity to accomplish a goal if I'm honest.

What I call triplets was a set of the three values.

Can your code get them in variables all at the same time ?
That’s what you want to get into the array isn’t it?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.