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