Files
PowerTester/firmware/v01/v01.ino

257 lines
8.3 KiB
C++

/*********************************************************************
Powertester
Measures 2 voltages and current from an equipment(Load), and logs
the results on SD card. Control and read values from bluetooth.
By Jony Silva
Tue Jun 12 14:56:12 GMT 2018
*********************************************************************/
// Libraries to be included, non native libraries need to be included in the Makefile
#include <LiquidCrystal.h> // Handles the connection and communications with the LCD display
#include <SPI.h> // Handles the SPI connection to the SD card
#include <SD.h> // Handles communication routines with the SD card
// Configuration of pins, insert here arduino pin numbers only(not fisical)----------------------------
#define v_batt 7 // Analog pin for the battery voltage
#define volt_1 0 // Analog pin for voltage 1
#define volt_2 1 // Analog pin for voltage 2
#define load_line 17 // Line that turns load On or Off
#define LEFT 16 // Button 1 will be function Left
#define RIGHT 18 // Button 2 will be function Right
#define ACT 19 // Button 3 will be function Action
LiquidCrystal lcd(7, 6, 2, 3, 4, 5); // LCD screen pins, LiquidCrystal(rs, enable, d4, d5, d6, d7)
//-----------------------------------------------------------------------------------------------------
// Other configurations ------------------------------------------------------------------------------------
#define battery_volt 3 // Parameter position where battery voltage value is hold
#define voltage_1 0 // Parameter position where voltage one value is hold
#define voltage_2 1 // Parameter position where voltage two value is hold
#define numOfScreens 7 // Number of screen menus, select here and rearrange String screens
File myFile;
//----------------------------------------------------------------------------------------------------------
// Macros --------------------------------------------------------
#define rLEFT digitalRead(LEFT) // Read button Left
#define rRIGHT digitalRead(RIGHT) // Read button Right
#define rACT digitalRead(ACT) // Read button Action
#define sd_not_in 0 // SD card is not inserted
#define sd_in 1 // SD card is inserted
#define file_fail 2 // Can't write to file
#define writing 3 // Write on the sd card
#define load_off 0 // Turn off the load
#define load_on 1 // Turn on the load
#define off 0 // off is always zero
#define on 1 // on is always one
#define no 0 // no is always zero
#define yes 1 // yes is alyays one
//----------------------------------------------------------------
// Variables --------------------------------------------------------------------------------------------------------------
bool sd_rw = off; // Holds the state of read/write of the card
bool load_status = load_off; // Holds the state of on/off of the load
bool sd_inserted = no; // Holds the stats if sd card is in or not
int sd_status = sd_not_in; // Holds information about the sd card
int currentScreen = 0; // Current display menu
// String with the menus to be displayed
String screens[numOfScreens][2] = {{"Voltage 1","Volts"}, {"Voltage 2","Volts"},
{"Load current","Amps"},{"Batt Voltage","volts"}, {"SD Logging", ""}, {"Load", ""}, {"SD card", ""}};
String parameters_sd[2] = {"No","Yes"}; // String to display the sd card logging
String parameters_load[2] = {"Off","On"}; // String to display the load state
String sd_card[4] = {"Card missing","Card inserted","File Write fail","Writing..."}; // String to display the sd card state
float parameters[4]; // Parameters of the several voltages and current
float denominator;
int resistor1 = 22000; // Resistor one of voltage divider
int resistor2 = 2200; // Resistor two of voltage divider
// ------------------------------------------------------------------------------------------------------------------------
// Function declarations --------------------------------------------------
void menuState(void); // Read buttons and update menu
void printScreen (void); // Print menus and variables on screen
float volt_pin (int pin); // Read and display voltage
//-------------------------------------------------------------------------
void setup()
{
pinMode(LEFT, INPUT); // Button left is an input
pinMode(RIGHT, INPUT); // Button right is an input
pinMode(ACT, INPUT); // Button act is an input
pinMode(load_line, OUTPUT); // load_line is an output
lcd.begin(16, 2);
// Voltage divider --> Vout = Vin * R2 / R1 + R2
denominator = (float)resistor2 / (resistor1 + resistor2);
// initialize timer1 ---------------------------------------
noInterrupts(); // disable all interrupts
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
OCR1A = 9000; // Load value to compare
TCCR1B |= (1 << WGM12); // CTC mode
TCCR1B |= (1 << CS10); // 64 prescaler
TCCR1B |= (1 << CS11); //
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
interrupts(); // enable all interrupts
// ----------------------------------------------------------
if (SD.begin()) // Initiate SD card
{
sd_status = sd_in; // If sd card is initiated successfully change variable sd_in
sd_inserted = yes; // and change variable sd_inserted to yes
}
else {
sd_status = sd_not_in; // If sd card is not initiated change variable to sd_not_in
sd_inserted = no; // and change variable sd_inserted to no
}
}
// Timer compare interrupt service routine --
ISR(TIMER1_COMPA_vect)
{
menuState(); // Read buttons act accordingly and update menus
digitalWrite(load_line, load_status); // Turn load on or off depending on the load_status
}
//-------------------------------------------
void loop()
{
parameters[battery_volt] = volt_pin(v_batt); // Update Battery voltage value
parameters[voltage_1] = volt_pin(volt_1); // Update voltage one value
parameters[voltage_2] = volt_pin(volt_2); // Update voltage two value
if (sd_inserted == no) // If sd_rw value is turned on
{
sd_status = sd_not_in;
}
else if (sd_rw == on)
{
myFile = SD.open("measure.txt", FILE_WRITE); // Open file measure.txt for writing
if (myFile) // if succeds
{
myFile.print("Batt voltage, ");
myFile.println(volt_pin(v_batt)); // Write to card battery voltage
myFile.print("Voltage one, ");
myFile.println(volt_pin(volt_1)); // Write to card voltage one
myFile.print("Voltage two, ");
myFile.println(volt_pin(volt_2)); // Write to card voltage two
myFile.println(""); // Write to card an empty line
myFile.close(); // Close file
sd_status = writing;
}
else
{
sd_status = file_fail;
}
}
else
{
sd_status = sd_in;
}
printScreen(); // Refresh screen and print current menu and values
delay(5000); // Repeat the main loop every 5 seconds
}
void menuState()
{
if (!rRIGHT)
{
if (currentScreen == (numOfScreens - 1))
{
currentScreen = 0;
}
else
{
currentScreen++;
}
while (!rRIGHT); // Check if button is still pressed do nothing
printScreen(); // Refresh screen and print current menu and values
}
if (!rLEFT)
{
if (currentScreen == 0)
{
currentScreen = (numOfScreens - 1);
}
else
{
currentScreen--;
}
while (!rLEFT); // Check if button is still pressed do nothing
printScreen(); // Refresh screen and print current menu and values
}
if (!rACT)
{
if (currentScreen == 4)
{
sd_rw = !sd_rw;
}
if (currentScreen == 5)
{
load_status = !load_status;
}
while (!rACT); // Check if button is still pressed do nothing
printScreen(); // Refresh screen and print current menu and values
}
}
void printScreen()
{
lcd.clear();
lcd.print(screens[currentScreen][0]);
lcd.setCursor(0,1);
if (currentScreen == 4)
{
lcd.print(parameters_sd[sd_rw]);
}
else if (currentScreen == 5)
{
lcd.print(parameters_load[load_status]);
}
else if (currentScreen == 6)
{
lcd.print(sd_card[sd_status]);
}
else
{
lcd.print(parameters[currentScreen]);
lcd.print(" ");
lcd.print(screens[currentScreen][1]);
}
}
float volt_pin(int pin)
{
float voltage;
voltage = analogRead(pin); // Obtain RAW voltage data
voltage = (voltage / 1024) * 3.3; // Convert to actual voltage
voltage = voltage / denominator; // Convert to voltage after divider
return voltage;
}