Quantcast
Channel: Arduino Forum - Latest topics
Viewing all articles
Browse latest Browse all 15374

Slight delay in digitalRead and writing to TFT display

$
0
0

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;
}

7 posts - 4 participants

Read full topic


Viewing all articles
Browse latest Browse all 15374

Trending Articles