Notifications
Clear all

Powermeter using Adafruit ESP32-S2 TFT Feather and Adafruit INA219 Current Sensor Breakout - Working code, help to clean it up?

5 Posts
3 Users
2 Reactions
1,307 Views
 kabl
(@kabl)
Member
Joined: 2 years ago
Posts: 34
Topic starter  

Hello fellow tinkerers!

I put together a working code for this project, displaying the values on the TFT and simultaneously giving comma-separated values over the serial port for import into Excel to sort and display lowest and highest values. To avoid SD-card readers etc to store the values, I use "Cool Term" for Windows to write the data coming from the serial to a textfile on my computer.

 

The sketch for using the TFT was taken from Adafruit.

 

As you can see from the code, the output over serial is done without volt, mA etc. Just the values, for easier handling in Excel.

 

ESP32 and INA219

 

Though I have done some programming with Arduino I am far from experienced. So I thought this was the right place to ask for some help with improving my coding skills.

 

So, below is the code for this project. If you have any tips for cleaning up the code, making it more streamlined or other advice for improvement, I am all ears 🙂

/**************************************************************************
  This is a library for several Adafruit displays based on ST77* drivers.

  Works with the Adafruit ESP32-S2 TFT Feather
    ---->  http://www.adafruit.com/products/5300 

  Check out the links above for our tutorials and wiring diagrams.

  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.
  MIT license, all text above must be included in any redistribution
 **************************************************************************/

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_INA219.h>  // INA291 Voltage Sensor library
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h>
#include <Fonts/FreeSans9pt7b.h>

// Use dedicated hardware SPI pins
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);

//declare INA219 variables
Adafruit_INA219 ina219;
float shuntvoltage = 0;
float busvoltage = 0;
float current_mA = 0;
float loadvoltage = 0;
float energy = 0;

void setup(void) {
  Serial.begin(115200);
  ina219.begin();
  pinMode(TFT_BACKLITE, OUTPUT);
  digitalWrite(TFT_BACKLITE, HIGH);
  pinMode(TFT_I2C_POWER, OUTPUT);
  digitalWrite(TFT_I2C_POWER, HIGH);
  delay(10);

  // initialize TFT
  tft.init(135, 240);
  tft.setRotation(3);
  tft.fillScreen(ST77XX_BLACK);
  tft.setFont(&FreeSans9pt7b);
  
  uint16_t time = millis();
  time = millis() - time;
  Serial.println(time, DEC);
  delay(100);
}

void loop(void) {
    ina219values();
    displaydata();
}

 void displaydata() {
  tft.setTextColor(ST77XX_GREEN);
  tft.setTextSize(2);
  tft.setCursor(10, 30);
  tft.println(busvoltage);
  tft.setCursor(150, 30);
  tft.println("V");
  tft.setTextColor(ST77XX_RED);
  tft.setTextSize(2);
  tft.setCursor(10, 80);
  tft.println(current_mA);
  tft.setCursor(150, 80);
  tft.println("mA");
  tft.setTextColor(ST77XX_YELLOW);
  tft.setTextSize(2);
  tft.setCursor(10, 130);
  tft.println(energy);
  tft.setCursor(150, 130);
  tft.println("mWh");

  Serial.print(""); Serial.print(busvoltage);
  Serial.print(","); Serial.print(shuntvoltage);
  Serial.print(","); Serial.print(loadvoltage);
  Serial.print(","); Serial.print(current_mA);
  Serial.print(","); Serial.print(energy);
  Serial.println("");

  delay(100);
}
  
void ina219values() {
  shuntvoltage = ina219.getShuntVoltage_mV();
  busvoltage = ina219.getBusVoltage_V();
  current_mA = ina219.getCurrent_mA();
  loadvoltage = busvoltage + (shuntvoltage / 1000);
  energy = energy + loadvoltage * current_mA / 3600;
}
This topic was modified 1 year ago 2 times by kabl

   
Quote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 4 years ago
Posts: 7642
 

@kabl That code looks much better than 95% of what gets posted. Since the majority of folks here are amateurs asking your question is pointless since they are amateurs. The pros will each create their own take, and determining the best is the subject of countless Ph.D. papers. I am sure I can always 'improve,' but why? I can list a lot of reasons why, but again why? You say the sketch is from Adafruit, so are you saying they wrote all or the majority and you are asking us if you copied well? A lot depends on what you want from the forum, from the hobby and from your efforts. What if anything did you learn that will help you in future applications you actually have a hand in creating some years down the road, that is the real question.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.


   
ReplyQuote
 kabl
(@kabl)
Member
Joined: 2 years ago
Posts: 34
Topic starter  

@zander 

 

Hi Ron, and thank you for shooting straight - as always.

 

I have been looking at several different sketches/scripts, and trying to figure out how/what it does and how it works. 

 

Part of the code was taken from the guide given at the product page for the INA219 and from the examples given in the Arduino program. The code for using the TFT was taken from the example sketch "graphicstest_feather_esp32s2_tft" provided by the Arduino program, and tweaked a bit.

 

I have added a different font, changed the colors of the text, the placement of the text, and the format of the output to the serial. The result is pretty far from the sources. Some code was adapted from GreatScotts project at https://github.com/gilleshenrard/datalogger .

 

I actually learned a lot from this process. I guess what I am asking is if I have made the code unnecessary complicated, or if I can remove some statements from the code to cut it down. It compiles and runs without errors. Part of the problem with learning these things in the beginning is that I do not know what I dont know and should read up on. I was not able to formulate a better sentence, but I hope you catch my meaning.

 

My aim is to learn to make the code as simple as possible, and by doing so learning even more about coding. Even though it compiles without errors doesnt mean it is the most efficient 🙂

This post was modified 1 year ago 4 times by kabl

   
ReplyQuote
Will
 Will
(@will)
Member
Joined: 3 years ago
Posts: 2571
 

@kabl 

Looks pretty good to me.

Setup is well grouped, subroutines for data collection and display, all code relevant to one device collected together, no unnecessary variables ... good stuff 🙂 

Anything seems possible when you don't know what you're talking about.


   
kabl reacted
ReplyQuote
Ron
 Ron
(@zander)
Father of a miniature Wookie
Joined: 4 years ago
Posts: 7642
 

@kabl EXCELLENT. Sorry, but I don't have enough time to investigate that deeply, so thank you for telling me. The merging of different source file snippets is something we pros do all the time, so you are catching on quickly. Things like fonts and colour are just fluff. Yes, they have to be right (didn't know there was a right?) Think social, handicap, and science. Clues are the Picket slide rule, screen comfort and visibility. Large commercial software houses will have specialists in a department that create UI standards. These specialists are from such fields as human sight, psy fields and, of course, tech, science and physics, plus some I probably forgot.

I don't think we care too much about efficiency as these devices are memory limited, so I won't address that. Based on 5 minutes of reading, I would separate the print and TFT code, but I wouldn't withhold approval for just that. Variable names are a religious issue, but research and follow a standard. both too short and too long are to be avoided. tft is too short, something like LCD20x4TFT might be a possibility, but all caps need attention.

I am not a fan of declaring variables all over the place. Keep globals (to be avoided if at all possible) in one commented-off section. Understand what ALL the memory attributes mean. Understand what all the scoping attributes mean.

If you want to try something, design a procedure that takes as parameters textColor, textSize, X , Y, and data. Now the up to 4 lines in your procedure DisplayData is one line. Try something similar for the Serial output.

I am suspicious of the science behind the last two lines of the procedure ina219values (also, the procedure name is weak)

The setup logic around your millis() time makes no sense.

Finally, if full marks are 10, then the fact that all tests so far have produced the correct result is worth 1 mark. MOST marks are for writing code that others can understand. I seldom find comments help with understanding, and in fact, when I am on the other side of the world debugging some customers' code, I either delete or otherwise hide it since experience has taught me that comments seldom get updated when the code gets updated and is therefore misleading. Well-written code is code that is self-commenting in most cases. Of course, there are exceptions as in complex formulas which in that case should have a link to the appropriate external source like a Wiki.

First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.


   
kabl reacted
ReplyQuote