Slight delay in digitalRead and writing to TFT display

Hi,

I am using Arduino nano every to read BMS data and show it to a TFT display. Everything is working nicely but a small addition is bothering me.

I am adding an external output to be read by digitalRead() function. If its 5V, then write something on the screen. There are 4 inputs of which one is 5V at a time, so it overwrites the older value.

Right now I am doing it manually (to simulate) as I don't have that switch. But there has been slight delay in changing it on the text depending on when I give a 5V input. All of them are ground at first and I switch one to 5V.

So, sometimes, its instantaneous and sometimes, I am getting like 1 sec delay in the screen. I have not used delay() on the code but millis() and the code is pretty long with other things being calculated and shown on screen. I have even removed all the serial.print codes but to no avail.. even serial.print lines refreshes like every second when I have that to check on Serial Monitor...

so I wonder if there is something by default that delays things by 1 second or so in arduino.. I am new to this and this is my first project. If you have any solutions for an instant reaction, please do let me know.

I have included the code but the display delay is coming from this part:

  // drive mode
  // REAR, NEUTRAL, ECO, SPORT, LIMP
  if(rearState) {
    strcpy(mode, "R"); 
  } else if(forwardState) {
    strcpy(mode, "F"); 
  } else if(boostState) {
    strcpy(mode, "B"); 
  } else if(neutralState){
    strcpy(mode, "N"); 
  }

  if(stateOfCharge<10) {
    strcpy(mode, "L"); // also set output pin so it can connect to limp mode wire
  }
  // int wid = 25; // character width
  // int row = 190;   // y coordinate     
  // int len = strlen(mode);
  tft.setCursor(110, 190);
  //tft.setCursor(120 - ((len*wid) / 2), row); // center text
  tft.setFont(&FreeSansBold18pt7b);
  Data5.setTextColor(C_CYAN, C_BLACK);
  Data5.print(mode);

Here is the full code

// Xiaoxiang Smart BMS Display
// For Arduino Pro mini / Arduino Nano
// Code is based on a heavily modified version of: https://github.com/bres55/Smart-BMS-arduino-Reader

// This program reads data from the BMS via a secondary software serial port. 
// It then prints it out to the computer via the arduino's main serial port. 
// Additionally, it prints the important data to an OLED display. 
// Note that the Display code only works for 4S batteries and will need to be heavily modified for other configurations. 
// It shouldn't be too hard to modify this code to work with other display types as well, 
// since the display code is mostly contained within its own subroutine.  

#include <SoftwareSerial.h> // Second serial port for connecting to the BMS
#include <SPI.h> // Needed for the display
// For ILI 9341 display
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include <FlickerFreePrint.h> // For refresh free display
#include <Fonts/FreeSans9pt7b.h>
#include <Fonts/FreeSans12pt7b.h>
#include <Fonts/FreeSansBold18pt7b.h>

#define C_BLACK       0x0000
#define C_GREY        0x2945
#define C_BLUE        0x001F
#define C_RED         0xF800
#define C_GREEN       0x07E0
#define C_CYAN        0x07FF
#define C_MAGENTA     0xF81F
#define C_YELLOW      0xFFE0
#define C_WHITE       0xFFFF

// For the Adafruit shield, these are the default.
#define TFT_DC 9
#define TFT_CS 10
#define TFT_RST 8

Adafruit_ILI9341 tft(TFT_CS, TFT_DC, TFT_RST);

// create a flicker free pnject for each data to be printed with the flicker free option
// the library used template scheme so you need to pass the data type in <>
FlickerFreePrint<Adafruit_ILI9341> Data1(&tft, C_WHITE, C_BLACK);
FlickerFreePrint<Adafruit_ILI9341> Data2(&tft, C_WHITE, C_BLACK);
FlickerFreePrint<Adafruit_ILI9341> Data3(&tft, C_WHITE, C_BLACK);
FlickerFreePrint<Adafruit_ILI9341> Data4(&tft, C_WHITE, C_BLACK);
FlickerFreePrint<Adafruit_ILI9341> Data5(&tft, C_WHITE, C_BLACK);
FlickerFreePrint<Adafruit_ILI9341> Data6(&tft, C_WHITE, C_BLACK);
FlickerFreePrint<Adafruit_ILI9341> Data7(&tft, C_WHITE, C_BLACK);
FlickerFreePrint<Adafruit_ILI9341> Data8(&tft, C_WHITE, C_BLACK);
FlickerFreePrint<Adafruit_ILI9341> Data9(&tft, C_WHITE, C_BLACK);
FlickerFreePrint<Adafruit_ILI9341> Data10(&tft, C_WHITE, C_BLACK);
FlickerFreePrint<Adafruit_ILI9341> Data11(&tft, C_WHITE, C_BLACK);
FlickerFreePrint<Adafruit_ILI9341> Data12(&tft, C_WHITE, C_BLACK);

SoftwareSerial MySoftSerial(0, 1); // RX, TX 
#define MySerial MySoftSerial
#define RPIN A4
#define NPIN A5
#define FPIN A6
#define BPIN A7

// Variables
String inString = ""; // string to hold input
int incomingByte, BalanceCode, Length, highbyte, lowbyte;
byte Mosfet_control, mosfetnow, BatteryConfigH, BatteryConfigL, bcl, bcln, bch, Checksum, switche;
uint8_t BYTE1, BYTE2, BYTE3, BYTE4, BYTE5, BYTE6, BYTE7, BYTE8, BYTE9, BYTE10;
uint8_t inInts[40], data[9];   // an array to hold incoming data, not seen any longer than 34 bytes, or 9
uint16_t a16bitvar;
float eresultf; //Cellv1, Cellv2, Cellv3, Cellv4, Cellv5, Cellv6, Cellv7, Cellv8,

// Global battery stat variables (For printing to displays)
float CellMin = 5; // Default value > max possible cell votlage
float CellMax = 0;
float Cellavg = 0; 
float Celldiff=0;
float myCellVoltages[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int balancerStates[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int myNumCells = 0;
float PackVoltagef = 0;
float PackCurrentf = 0;
float RemainCapacityf = 0;
int RSOC = 0;
float Temp_probe_1f = 0;
float Temp_probe_2f = 0;
bool chargeFet = 0;
bool dischargeFet = 0;
bool cellOver = 0;
bool cellUnder = 0;
bool packOver = 0;
bool PackUnder = 0;
bool chargeOverTemp = 0;
bool chargeUnderTemp = 0;
bool dischargeOverTemp = 0;
bool dischargeUnderTemp = 0;
bool chargeOvercurrent = 0;
bool dischargeOvercurrent = 0;
bool shortCircuit = 0;
bool AFEerror = 0;
int CellHigh = 0;
int CellLow = 0;
int i;
int soc = 100;
int socpx = 196;
char buffer[40];
char buffer1[40];
int brightness = 0;
// A0 is Charge State Pin that goes to pin 5 of charger connector
int VoutPin = 3; // for reva charger connector pin 8 & 9 / 6th pin on right from bottom
int fanPin = 4; // for fan relay pin

unsigned long previousTime1 = 0;
unsigned long previousTime2 = 0;
const long chargeInterval = 100;  // Every 100ms second
const long blinkInterval = 2000;  // Every 2000ms second
const long fanOnInterval = 300000; // 5 mins
const long steps = 5;
char mode[20];
int charge = 0;
float maxCharge = 3.45; // max cell voltage when charging
float floatCharge = 3.4;
float minCharge = 3.25;  // min cell voltage before reset charge
// int maxPercentCharge = 70;
int oldbrightness = 0;

int rearState = 0;
int neutralState = 0;
int forwardState = 0;
int boostState = 0;


void setup() {
  MySerial.begin(9600);
  Serial.begin(250000);
  tft.begin();
  tft.fillScreen(C_BLACK);
  tft.drawRect(20, 40, 200, 76, C_WHITE);
  tft.fillRect(221, 55, 6, 46, C_WHITE);
  tft.fillRect(22, 42, 0, 72, C_GREEN);
  // for charge state
  pinMode(A0, INPUT);
  pinMode(fanPin, OUTPUT);
  pinMode(VoutPin, OUTPUT);

  // for drive modes
  pinMode(RPIN, INPUT);
  pinMode(FPIN, INPUT);
  pinMode(NPIN, INPUT);
  pinMode(BPIN, INPUT);
}

void loop() {

  takeMeasurements();

  float stateOfCharge = RSOC;
  int soc = stateOfCharge;
  int socWidth = (float)socpx/100 * stateOfCharge;

  int chargeState = digitalRead(A0);

  rearState = digitalRead(RPIN);
  neutralState = digitalRead(NPIN);
  forwardState = digitalRead(FPIN);
  boostState = digitalRead(BPIN);

  


  // if charger is connected pin is LOW
  if(chargeState==HIGH) {

    // disconnected charger
    //Serial.println("Charger is disconnected.");
    brightness=0;
    charge = 0; // reset charge full state only after charger disconnects
    analogWrite(VoutPin, brightness);
    digitalWrite(fanPin, LOW);

    if(stateOfCharge<40) {
      if(stateOfCharge<25){
        if(stateOfCharge<1) {
          tft.fillRect(22, 42, 1, 72, C_RED);
        } else {
          tft.fillRect(22, 42, socWidth, 72, C_RED);
        }
      } else {
        tft.fillRect(22, 42, socWidth, 72, C_YELLOW);
      } 
    } else {
      tft.fillRect(22, 42, socWidth, 72, C_GREEN);
    }
    if(stateOfCharge<1) {
      tft.fillRect(socWidth+22+1, 42, socpx-socWidth-1, 72, C_BLACK);
    } else {
      tft.fillRect(socWidth+22, 42, socpx-socWidth, 72, C_BLACK);
    }
    
    
  } else {
    // charger is connected
    //Serial.println("Charger is connected.");
    digitalWrite(fanPin, HIGH);
    
    // soft start charge
    unsigned long currentTime = millis();

    if(CellMin < minCharge) { // holiday mode, turn on charging after cell reaches low voltage
      charge = 0;
    }

    if(brightness <= 255 && CellMax<maxCharge && !charge) {     
      oldbrightness = brightness;
      // if charger is on do this
      if (currentTime - previousTime1 >= chargeInterval) {
        if(brightness < 255 && CellMax < floatCharge) {
          brightness += 5;
        }

        if(brightness > 100 && CellMax >= floatCharge) {
          brightness -= 5;
        }
        if(brightness != oldbrightness) {
          //Serial.println(brightness);
          analogWrite(VoutPin, brightness);
        }
        
        
        previousTime1 = currentTime;
      }
    }

    // blink the battery icon
    if (currentTime - previousTime2 >= blinkInterval) {
      previousTime2 = currentTime;
      
      if(CellMax>maxCharge) {
        tft.fillRect(22, 42, socWidth, 72, C_GREEN);
        // set charge pin 8 & 9 to 0V to disable charger
        brightness = 0;
        analogWrite(VoutPin, brightness);
        //Serial.println(brightness);
        charge = 1;

      }
      if(stateOfCharge<40) {
        if(stateOfCharge<25){
          if(stateOfCharge<1) {
            tft.fillRect(22, 42, 1, 72, C_RED);
          } else {
            tft.fillRect(22, 42, socWidth, 72, C_RED);
          }
        } else {
          tft.fillRect(22, 42, socWidth, 72, C_YELLOW);
        }
        if(stateOfCharge<1) {
          tft.fillRect(socWidth+22+1, 42, socpx-socWidth-1, 72, C_BLACK);
        } else {
        tft.fillRect(socWidth+22, 42, socpx-socWidth, 72, C_BLACK);
        }
      } else {
        tft.fillRect(22, 42, socWidth, 72, C_GREEN);
        tft.fillRect(socWidth+22, 42, socpx-socWidth, 72, C_BLACK);
      }
      
    } else {
      // fill black for 2 secs
      if(!charge) {
          tft.fillRect(22, 42, socpx, 72, C_BLACK);
      }
    }    
  }

  tft.setFont(&FreeSans12pt7b);
  tft.setTextSize(1);
  tft.setCursor(0, 200);

  // Total Voltage
  tft.setCursor(20, 30);
  Data1.setTextColor(C_WHITE, C_BLACK);
  dtostrf(PackVoltagef, -6, 2, buffer); // convert float to str
  sprintf(buffer, "%sV", buffer);
  Data1.print(buffer);
  free(buffer);

  // Current
  tft.setCursor(130, 30);

  if(PackCurrentf>0) {
    Data2.setTextColor(C_GREEN, C_BLACK);
  } 
  else if(PackCurrentf<0) {
    Data2.setTextColor(C_YELLOW, C_BLACK);
  } else {
    Data2.setTextColor(C_WHITE, C_BLACK);
  }
  dtostrf(PackCurrentf, 6, 2, buffer);
  sprintf(buffer, "%sA", buffer);
  Data2.print(buffer);
  free(buffer);

  // SoC %
  tft.setCursor(20, 140);
  Data3.setTextColor(C_WHITE, C_BLACK);
  sprintf(buffer, "%d%s", soc, "%");
  Data3.print(buffer);
  free(buffer);

  // Remaining Capacity
  tft.setCursor(120, 140);
  dtostrf(RemainCapacityf, 6, 2, buffer);
  sprintf(buffer, "%sAh", buffer);
  Data4.setTextColor(C_WHITE, C_BLACK);
  Data4.print(buffer);
  free(buffer);

  // drive mode
  // REAR, NEUTRAL, ECO, SPORT, LIMP
  if(rearState) {
    strcpy(mode, "R"); 
  } else if(forwardState) {
    strcpy(mode, "F"); 
  } else if(boostState) {
    strcpy(mode, "B"); 
  } else if(neutralState){
    strcpy(mode, "N"); 
  }

  if(stateOfCharge<10) {
    strcpy(mode, "L"); // also set output pin so it can connect to limp mode wire
  }
  // int wid = 25; // character width
  // int row = 190;   // y coordinate     
  // int len = strlen(mode);
  tft.setCursor(110, 190);
  //tft.setCursor(120 - ((len*wid) / 2), row); // center text
  tft.setFont(&FreeSansBold18pt7b);
  Data5.setTextColor(C_CYAN, C_BLACK);
  Data5.print(mode);

  // set the stroke color to white
  tft.drawLine(0, 210, 240, 210, C_GREY);

  tft.setFont(&FreeSans12pt7b);
  tft.setTextSize(1);

  // Vmax
  tft.setCursor(5, 240);
  dtostrf(CellMax, 5, 3, buffer1);
  sprintf(buffer, "Hi %s (%d)", buffer1, CellHigh);
  Data6.setTextColor(C_WHITE, C_BLACK);
  Data6.print(buffer);
  free(buffer);
  
  // Vmin
  tft.setCursor(5, 270);
  dtostrf(CellMin, 5, 3, buffer1);
  sprintf(buffer, "Lo %s (%d)", buffer1, CellLow);
  Data7.setTextColor(C_WHITE, C_BLACK);
  Data7.print(buffer);
  free(buffer);

  // Delta
  tft.setCursor(5, 300);
  if(Celldiff > 0.02) {
    Data8.setTextColor(C_YELLOW, C_BLACK);
  } else {
    Data8.setTextColor(C_WHITE, C_BLACK);
  }
  dtostrf(Celldiff, 5, 3, buffer1);
  sprintf(buffer, "Dv %s", buffer1);
  Data8.print(buffer);
  free(buffer);

  // Temp 1
  tft.setCursor(145, 240);
  tft.setFont(&FreeSans9pt7b);
  Data9.setTextColor(C_WHITE, C_BLACK);
  dtostrf(Temp_probe_1f, 5, 1, buffer1);
  sprintf(buffer, "T1 %sC", buffer1);
  Data9.print(buffer);
  free(buffer);

  // Temp 2
  tft.setCursor(145, 270);
  tft.setFont(&FreeSans9pt7b);
  Data10.setTextColor(C_WHITE, C_BLACK);
  dtostrf(Temp_probe_2f, 5, 1, buffer1);
  sprintf(buffer, "T2 %sC", buffer1);
  Data10.print(buffer);
  free(buffer);
    
  // Charge Mosfet
  tft.setCursor(135, 300);
  Data11.setTextColor(C_WHITE, C_BLACK);
  tft.drawRect(160, 288, 15, 15, C_WHITE); 
  Data11.print("Cr");
  if(chargeFet) { 
    tft.fillRect(162, 290, 11, 11, C_GREEN);
  } else {
    tft.fillRect(162, 290, 11, 11, C_RED);
  }

  // Discharge Mosfet
  tft.setCursor(185, 300);
  Data12.setTextColor(C_WHITE, C_BLACK);  
  tft.drawRect(210, 288, 15, 15, C_WHITE);
  Data12.print("Dr");
  if(dischargeFet) { 
    tft.fillRect(212, 290, 11, 11, C_GREEN);
  } else {
    tft.fillRect(212, 290, 11, 11, C_RED);
  }

}










void takeMeasurements(void){
  //Serial.println(".");
  //Serial.println(".");
  //Serial.println(".");
  write_request_start();// Found this helps timing issue, by saying hello, hello.
  write_request_end() ; // Or maybe it flushes out any rogue data.
  write_request_start();// Any way it works,
  write_request_end() ; // And accomodates long delays if you want them at the end
  
  // CELLS VOLTAGE 04 /////////////////////////////////////////////////////////////////////////////
  call_get_cells_v();      // requests cells voltage
  get_bms_feedback();     // returns with up to date, inString= chars, inInts[]= numbers, chksum in last 2 bytes
  //                       Length (length of data string)
  //  got cell voltages, bytes 0 and 1, its 16 bit, high and low
  //  go through and print them
  // Length = Length - 2;
  // print headings
  for (int i = 2; i < (Length + 1); i = i + 2) {
    // Serial.print (" Cell ");
    // Serial.print (i / 2);
    // Serial.print("  ");
  }

  // Serial.print("  ");
  // Serial.print ("H"); // CellMax heading
  // Serial.print(" ");
  // Serial.print ("L"); // CellMax heading
  // Serial.print("  ");
  // Serial.print (" CellMax "); // CellMax heading
  // Serial.print("  ");
  // Serial.print (" CellMin "); // CellMin heading
  // Serial.print("  ");
  // Serial.print (" Diff "); // diference heading
  // Serial.print("  ");
  // Serial.print ("  Avg "); // Average heading
  // Serial.print("  ");
  myNumCells = Length/2;
  // Serial.print (" NumCells:");
  // Serial.print (myNumCells);
  // Serial.println ("");
  // and the values
  Cellavg = 0;
  CellMax = 0;
  CellMin = 5;
  for (int i = 0; i < Length; i = i + 2) {
    highbyte = (inInts[i]);
    lowbyte = (inInts[i + 1]);
    uint16_t Cellnow = two_ints_into16(highbyte, lowbyte);
    float Cellnowf = Cellnow / 1000.0f; // convert to float
    myCellVoltages[i/2] = Cellnowf; // Update value in array
    Cellavg = Cellavg + Cellnowf;
    if (Cellnowf > CellMax) {   // get high and low
      CellMax = Cellnowf;
      CellHigh = (i/2)+1;
    }
    if (Cellnowf < CellMin) {
      CellMin = Cellnowf;
      CellLow = (i/2)+1;
    }
    
    // Serial.print(" ");
    // Serial.print(Cellnowf, 3); // 3 decimal places
    // Serial.print("   ");
  }
  // Serial.print("  ");
  //   Serial.print(CellHigh);
  //   Serial.print("  ");
  //   Serial.print(CellLow);
  // Serial.print("  ");
  // Serial.print(CellMax, 3); // 3 decimal places
  // Serial.print("   ");
  // Serial.print("   ");
  // Serial.print(CellMin, 3); // 3 decimal places
  // Serial.print("   ");
  Celldiff = CellMax - CellMin; // difference between highest and lowest
  // Serial.print("   ");
  // Serial.print(Celldiff, 3); // 3 decimal places
  // Serial.print("   ");
  Cellavg = Cellavg / (Length / 2); // Average of Cells
  // Serial.print(" ");
  // Serial.print(Cellavg, 3); // 3 decimal places
  // Serial.print("   ");


  // USING BASIC INFO 03 get //////////////////////////////////////////////////////////////////////
  //  CELL BALANCE... info
  call_Basic_info();      // requests basic info.
  get_bms_feedback();   // get that data, used to get BALANCE STATE byte 17 less 4, decimal=byte 13
  //  Serial.print(" BC= ");
  BalanceCode = inInts[13]; //  the 13th byte
  BalanceCode = Bit_Reverse( BalanceCode ) ; // reverse the bits, so they are in same order as cells
  //  Serial.print(BalanceCode, BIN); // works, but, loses leading zeros and get confusing on screen
  print_binary(BalanceCode, 8);// print balance state as binary, cell 1 on the right, cell 8 on left
  //                                    Reversed this. 1 on left, 8 on right
  // Serial.print ("  Balancer States ");
  // Serial.println(" ");
  
  // PACK VOLTAGE,, bytes 0 and 1, its 16 bit, high and low
  highbyte = (inInts[0]); // bytes 0 and 1
  lowbyte = (inInts[1]);
  uint16_t PackVoltage = two_ints_into16(highbyte, lowbyte);
  PackVoltagef = PackVoltage / 100.0f; // convert to float and leave at 2 dec places
  // Serial.print("Pack Voltage = ");
  // Serial.print(PackVoltagef);

  // CURRENT
  highbyte = (inInts[2]); // bytes 2 and 3
  lowbyte = (inInts[3]);
  int PackCurrent = two_ints_into16(highbyte, lowbyte);
  // uint16_t PackCurrent = two_ints_into16(highbyte, lowbyte);
  PackCurrentf = PackCurrent / 100.0f; // convert to float and leave at 2 dec places
  // Serial.print("   Current = ");
  // Serial.print(PackCurrentf);

  //REMAINING CAPACITY
  highbyte = (inInts[4]);
  lowbyte = (inInts[5]);
  uint16_t RemainCapacity = two_ints_into16(highbyte, lowbyte);
  RemainCapacityf = RemainCapacity / 100.0f; // convert to float and leave at 2 dec places
  // Serial.print("   Remaining Capacity = ");
  // Serial.print(RemainCapacityf);
  // Serial.print("Ah");

  //RSOC
  RSOC = (inInts[19]);
  // Serial.print("   RSOC = ");
  // Serial.print(RSOC);
  // Serial.print("%");

  //Temp probe 1
  highbyte = (inInts[23]);
  lowbyte = (inInts[24]);
  float Temp_probe_1 = two_ints_into16(highbyte, lowbyte);
  Temp_probe_1f = (Temp_probe_1 - 2731) / 10.00f; // convert to float and leave at 2 dec places
  // Serial.println("");
  // Serial.print("Temp probe 1 = ");
  // Serial.print(Temp_probe_1f);
  // Serial.print(" ");

  //Temp probe 2
  highbyte = (inInts[25]);
  lowbyte = (inInts[26]);
  float Temp_probe_2 = two_ints_into16(highbyte, lowbyte);
  Temp_probe_2f = (Temp_probe_2 - 2731) / 10.00f; // convert to float and leave at 2 dec places
  // Serial.print("   Temp probe 2 = ");
  // Serial.print(Temp_probe_2f);
  // Serial.println(" ");

  // Mosfets
  chargeFet = inInts[20] & 1; //bit0
  dischargeFet = (inInts[20] >> 1) & 1; //bit1
  // Serial.print(F("Mosfet Charge = "));
  // Serial.print(chargeFet);
  // Serial.print(F("  Mosfet DisCharge = "));
  // Serial.println(dischargeFet);

  // Pack Protection states
  cellOver = (inInts[17] >> 0) & 1; 
  cellUnder = (inInts[17] >> 1) & 1; 
  packOver = (inInts[17] >> 2) & 1; 
  PackUnder = (inInts[17] >> 3) & 1; 
  chargeOverTemp = (inInts[17] >> 4) & 1; 
  chargeUnderTemp = (inInts[17] >> 5) & 1; 
  dischargeOverTemp = (inInts[17] >> 6) & 1; 
  dischargeUnderTemp = (inInts[17] >> 7) & 1; 
  chargeOvercurrent = (inInts[16] >> 0) & 1; 
  dischargeOvercurrent = (inInts[16] >> 1) & 1; 
  shortCircuit = (inInts[16] >> 2) & 1; 
  AFEerror = (inInts[16] >> 3) & 1; 

  // Serial.print("Protection Status: ");
  // Serial.print(cellOver);
  // Serial.print(cellUnder);
  // Serial.print(packOver);
  // Serial.print(PackUnder);
  // Serial.print(chargeOverTemp);
  // Serial.print(chargeUnderTemp);
  // Serial.print(dischargeOverTemp);
  // Serial.print(dischargeUnderTemp);
  // Serial.print(chargeOvercurrent);
  // Serial.print(dischargeOvercurrent);
  // Serial.print(shortCircuit);
  // Serial.print(AFEerror);
  // Serial.println("");
  
  inString = "";
  Length = 0;
}

//------------------------------------------------------------------------------------------
// Do not edit anything below this line
//------------------------------------------------------------------------------------------
//  uint16_t PackCurrent = two_ints_into16(highbyte, lowbyte);
uint16_t two_ints_into16(int highbyte, int lowbyte) // turns two bytes into a single long integer
{
  a16bitvar = (highbyte);
  a16bitvar <<= 8; //Left shift 8 bits,
  a16bitvar = (a16bitvar | lowbyte); //OR operation, merge the two
  return a16bitvar;
}
// ----------------------------------------------------------------------------------------------------
void call_Basic_info()
// total voltage, current, Residual capacity, Balanced state, MOSFET control status
{
  flush(); // flush first

  //  DD  A5 03 00  FF  FD  77
  // 221 165  3  0 255 253 119
  uint8_t data[7] = {221, 165, 3, 0, 255, 253, 119};
  MySerial.write(data, 7);
}
//--------------------------------------------------------------------------
void call_get_cells_v()
{
  flush(); // flush first

  // DD  A5  4 0 FF  FC  77
  // 221 165 4 0 255 252 119
  uint8_t data[7] = {221, 165, 4, 0, 255, 252, 119};
  MySerial.write(data, 7);
}
//--------------------------------------------------------------------------
void call_Hardware_info()
{
  flush(); // flush first

  //  DD  A5 05 00  FF  FB  77
  // 221 165  5  0 255 251 119
  uint8_t data[7] = {221, 165, 5, 0, 255, 251, 119};
  // uint8_t data[7] = {DD, A5, 05, 00, FF, FB, 77};
  MySerial.write(data, 7);
}
//--------------------------------------------------------------------------
void write_request_start()
{
  flush(); // flush first

  //   DD 5A 00  02 56  78  FF 30   77
  uint8_t data[9] = {221, 90, 0, 2, 86, 120, 255, 48, 119};
  MySerial.write(data, 9);
}
//----------------------------------------------------------------------------
void write_request_end()
{
  flush(); // flush first

  //   DD 5A 01  02 00 00   FF  FD 77
  uint8_t data[9] = {221, 90, 1, 2, 0, 0, 255, 253, 119};
  MySerial.write(data, 9);
}
//-------------------------------------------------------------------------
void eprom_read()   //BAR CODE
{
  flush(); // flush first
  //delay(5);
  // SENT CODE depends on WHAT IS REQD???
  //   DD  A5  A2 0  FF 5E  77...BAR CODE
  //  221 165 162 0 255 94 119
  // uint8_t data[7] = {221, 165, 162, 0, 255, 94, 119};
  uint8_t data[7] = {221, 165, 32, 0, 255, 224, 119};
  MySerial.write(data, 7);
}

//-------------------------------------------------------------------------
void eprom_end() // no need at mo
{
  flush(); // flush first
  // delay(5);
  //DD  A5  AA  0 FF  56  77
  //221 165 170 0 255 86  119
  // from eprom read
  uint8_t data[7] = {221, 165, 170, 0, 255, 86, 119};
  MySerial.write(data, 7);
}
//------------------------------------------------------------------------------
void flush()
{ // FLUSH
  delay(100); // give it a mo to settle, seems to miss occasionally without this
  while (MySerial.available() > 0)
  { MySerial.read();
  }
  delay(50); // give it a mo to settle, seems to miss occasionally without this
}
//--------------------------------------------------------------------------
void get_bms_feedback()  // returns with up to date, inString= chars, inInts= numbers, chksum in last 2 bytes
//                          Length
//                          Data only, exclude first 3 bytes
{
  inString = ""; // clear instring for new incoming
  delay(100); // give it a mo to settle, seems to miss occasionally without this
  if (MySerial.available() > 0) {
    {
      for (int i = 0; i < 4; i++)               // just get first 4 bytes
      {
        incomingByte = MySerial.read();
        if (i == 3)
        { // could look at 3rd byte, it's the ok signal
          Length = (incomingByte); // The fourth byte holds the length of data, excluding last 3 bytes checksum etc
          // Serial.print(" inc ");
          //Serial.print(incomingByte);
        }
        if (Length == 0) {
          Length = 1; // in some responses, length=0, dont want that, so, make Length=1
        }
      }
      //  Length = Length + 2; // want to get the checksum too, for writing back, saves calculating it later
      for (int i = 0; i < Length + 2; i++) { // get the checksum in last two bytes, just in case need later
        incomingByte = MySerial.read(); // get the rest of the data, how long it might be.
        inString += (char)incomingByte; // convert the incoming byte to a char and add it to the string
        inInts[i] = incomingByte;       // save incoming byte to array as int
      }
    }
  }
}
//-----------------------------------------------------------------------------------------------------
void print_binary(int v, int num_places) // prints integer in binary format, nibbles, with leading zeros
// altered a bit, but got from here,  https://phanderson.com/arduino/arduino_display.html
{
  // Serial.println("");
  // Serial.print("  ");
  int mask = 0, n;
  for (n = 1; n <= num_places; n++)
  {
    mask = (mask << 1) | 0x0001;
  }
  v = v & mask;  // truncate v to specified number of places
  int cellNum = 0;
  while (num_places)
  {
    if (v & (0x0001 << num_places - 1))
    {
      // Serial.print("1        ");
      balancerStates[cellNum] = 1;
    }
    else
    {
      // Serial.print("0        ");
      balancerStates[cellNum] = 0;
    }
    --num_places;
    if (((num_places % 4) == 0) && (num_places != 0))
    {
      // Serial.print("");
    }
    cellNum++;
  }
}
//-----------------------------------------------------------------------------------------------------
byte Bit_Reverse( byte x )
// http://www.nrtm.org/index.php/2013/07/25/reverse-bits-in-a-byte/
{
  //          01010101  |         10101010
  x = ((x >> 1) & 0x55) | ((x << 1) & 0xaa);
  //          00110011  |         11001100
  x = ((x >> 2) & 0x33) | ((x << 2) & 0xcc);
  //          00001111  |         11110000
  x = ((x >> 4) & 0x0f) | ((x << 4) & 0xf0);
  return x;
}

OH now I do see delay() functions on the reference functions down below.. but they seem to be required. I wonder if that is playing some role.

Yes your use of delay() will certainly be a contributing factor.

Another factor could be all that complex printing of text, lines and boxes to the TFT, which happen every time loop() runs, even if nothing has changed.

I don't think I can help, but why SoftwareSerial on pins 0 and 1. On a Nano Every, those pins are connected to a hardware serial (Serial1).

I am connecting them to the TX/RX pin of UART connection from BMS. It seems natural to connect to them and its working. The pin diagram didn't mention their pin numbers.. it just says TX RX so later found they are 0 and 1 pins so I used that. Is there a better way?

As @sterretje already stated - don't use SoftwareSerial but Serial1.

It is indeed natural. But you don't need SoftwareSerial; there is a hardware UART connected to those pins.

Remove the following line:

#include <SoftwareSerial.h> // Second serial port for connecting to the BMS

Replace

SoftwareSerial MySoftSerial(0, 1); // RX, TX 

by

#define MySoftwareSerial Serial1

That is the easy way to test. You can later replace all MySoftwareSerial by e.g. bmsSerial so you have a clear indication which port is used for what.

1 Like

Thanks, Serial1 is working. 1 Library less. :slight_smile: Still the delay issue is haunting me. :slight_smile:

I just ran the "mode" changing code removing everything and its quick and responsive, so I guess the data collection part from BMS is slowing things down. Is there a way to bypass the whole loop and get the "mode" selection parallelly? I mean, whenever signal changes you get the result instantly and also run the "getting data" part separately?

I tried to remove all the delays or even decrease the 100ms delays but it seems we don't get data if we remove the delays. looks like it takes time to get and process the data before showing to the display which makes sense.

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